mirror of
https://github.com/azahar-emu/azahar
synced 2025-11-06 23:19:57 +01:00
Check that the country setting is valid for selected region (#847)
* Check that the country setting is valid for selected region * `SystemSaveGame.checkCountryCompatibility` -> `SystemSaveGame.getCountryCompatibility` * SettingsFragmentPresenter.kt: Moved `checkCountryCompatibility` definition out of `addSystemSettings` * SettingsFragmentPresenter.kt: Renamed `compat` value to `compatFlags` for better readability * configure_system.ui: Corrected indentation --------- Co-authored-by: OpenSauce04 <opensauce04@gmail.com>
This commit is contained in:
parent
eda2d6f9fa
commit
5c7622100b
@ -73,7 +73,7 @@ import kotlin.math.roundToInt
|
|||||||
|
|
||||||
class SettingsAdapter(
|
class SettingsAdapter(
|
||||||
private val fragmentView: SettingsFragmentView,
|
private val fragmentView: SettingsFragmentView,
|
||||||
private val context: Context
|
public val context: Context
|
||||||
) : RecyclerView.Adapter<SettingViewHolder?>(), DialogInterface.OnClickListener {
|
) : RecyclerView.Adapter<SettingViewHolder?>(), DialogInterface.OnClickListener {
|
||||||
private var settings: ArrayList<SettingsItem>? = null
|
private var settings: ArrayList<SettingsItem>? = null
|
||||||
private var clickedItem: SettingsItem? = null
|
private var clickedItem: SettingsItem? = null
|
||||||
|
|||||||
@ -13,6 +13,7 @@ import android.hardware.camera2.CameraManager
|
|||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
import org.citra.citra_emu.CitraApplication
|
import org.citra.citra_emu.CitraApplication
|
||||||
import org.citra.citra_emu.R
|
import org.citra.citra_emu.R
|
||||||
@ -239,6 +240,30 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private var countryCompatibilityChanged = true
|
||||||
|
|
||||||
|
private fun checkCountryCompatibility() {
|
||||||
|
if (countryCompatibilityChanged) {
|
||||||
|
countryCompatibilityChanged = false
|
||||||
|
val compatFlags = SystemSaveGame.getCountryCompatibility(IntSetting.EMULATED_REGION.int)
|
||||||
|
if (compatFlags != 0) {
|
||||||
|
var message = ""
|
||||||
|
if (compatFlags and 1 != 0) {
|
||||||
|
message += settingsAdapter.context.getString(R.string.region_mismatch_emulated)
|
||||||
|
}
|
||||||
|
if (compatFlags and 2 != 0) {
|
||||||
|
if (message.isNotEmpty()) message += "\n\n"
|
||||||
|
message += settingsAdapter.context.getString(R.string.region_mismatch_console)
|
||||||
|
}
|
||||||
|
MaterialAlertDialogBuilder(settingsAdapter.context)
|
||||||
|
.setTitle(R.string.region_mismatch)
|
||||||
|
.setMessage(message)
|
||||||
|
.setPositiveButton(android.R.string.ok, null)
|
||||||
|
.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@OptIn(ExperimentalStdlibApi::class)
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
|
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_system))
|
settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_system))
|
||||||
@ -282,51 +307,45 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(HeaderSetting(R.string.profile_settings))
|
add(HeaderSetting(R.string.profile_settings))
|
||||||
add(
|
val regionSetting = object : AbstractIntSetting {
|
||||||
StringInputSetting(
|
override var int: Int
|
||||||
usernameSetting,
|
get() {
|
||||||
R.string.username,
|
val ret = IntSetting.EMULATED_REGION.int
|
||||||
0,
|
checkCountryCompatibility()
|
||||||
"AZAHAR",
|
return ret
|
||||||
10
|
}
|
||||||
)
|
set(value) {
|
||||||
)
|
IntSetting.EMULATED_REGION.int = value
|
||||||
|
countryCompatibilityChanged = true
|
||||||
|
checkCountryCompatibility()
|
||||||
|
}
|
||||||
|
override val key = IntSetting.EMULATED_REGION.key
|
||||||
|
override val section = null
|
||||||
|
override val isRuntimeEditable = false
|
||||||
|
override val valueAsString get() = int.toString()
|
||||||
|
override val defaultValue = IntSetting.EMULATED_REGION.defaultValue
|
||||||
|
}
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
IntSetting.EMULATED_REGION,
|
regionSetting,
|
||||||
R.string.emulated_region,
|
R.string.emulated_region,
|
||||||
0,
|
0,
|
||||||
R.array.regionNames,
|
R.array.regionNames,
|
||||||
R.array.regionValues,
|
R.array.regionValues,
|
||||||
IntSetting.EMULATED_REGION.key,
|
|
||||||
IntSetting.EMULATED_REGION.defaultValue
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val systemLanguageSetting = object : AbstractIntSetting {
|
|
||||||
override var int: Int
|
|
||||||
get() = SystemSaveGame.getSystemLanguage()
|
|
||||||
set(value) = SystemSaveGame.setSystemLanguage(value)
|
|
||||||
override val key = null
|
|
||||||
override val section = null
|
|
||||||
override val isRuntimeEditable = false
|
|
||||||
override val valueAsString get() = int.toString()
|
|
||||||
override val defaultValue = 1
|
|
||||||
}
|
|
||||||
add(
|
|
||||||
SingleChoiceSetting(
|
|
||||||
systemLanguageSetting,
|
|
||||||
R.string.emulated_language,
|
|
||||||
0,
|
|
||||||
R.array.languageNames,
|
|
||||||
R.array.languageValues
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
val systemCountrySetting = object : AbstractShortSetting {
|
val systemCountrySetting = object : AbstractShortSetting {
|
||||||
override var short: Short
|
override var short: Short
|
||||||
get() = SystemSaveGame.getCountryCode()
|
get() {
|
||||||
set(value) = SystemSaveGame.setCountryCode(value)
|
val ret = SystemSaveGame.getCountryCode()
|
||||||
|
checkCountryCompatibility()
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
SystemSaveGame.setCountryCode(value)
|
||||||
|
countryCompatibilityChanged = true
|
||||||
|
checkCountryCompatibility()
|
||||||
|
}
|
||||||
override val key = null
|
override val key = null
|
||||||
override val section = null
|
override val section = null
|
||||||
override val isRuntimeEditable = false
|
override val isRuntimeEditable = false
|
||||||
@ -348,7 +367,34 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
|||||||
countries.map { it.second }.toTypedArray()
|
countries.map { it.second }.toTypedArray()
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
val systemLanguageSetting = object : AbstractIntSetting {
|
||||||
|
override var int: Int
|
||||||
|
get() = SystemSaveGame.getSystemLanguage()
|
||||||
|
set(value) = SystemSaveGame.setSystemLanguage(value)
|
||||||
|
override val key = null
|
||||||
|
override val section = null
|
||||||
|
override val isRuntimeEditable = false
|
||||||
|
override val valueAsString get() = int.toString()
|
||||||
|
override val defaultValue = 1
|
||||||
|
}
|
||||||
|
add(
|
||||||
|
SingleChoiceSetting(
|
||||||
|
systemLanguageSetting,
|
||||||
|
R.string.emulated_language,
|
||||||
|
0,
|
||||||
|
R.array.languageNames,
|
||||||
|
R.array.languageValues
|
||||||
|
)
|
||||||
|
)
|
||||||
|
add(
|
||||||
|
StringInputSetting(
|
||||||
|
usernameSetting,
|
||||||
|
R.string.username,
|
||||||
|
0,
|
||||||
|
"AZAHAR",
|
||||||
|
10
|
||||||
|
)
|
||||||
|
)
|
||||||
val playCoinSettings = object : AbstractIntSetting {
|
val playCoinSettings = object : AbstractIntSetting {
|
||||||
override var int: Int
|
override var int: Int
|
||||||
get() = SystemSaveGame.getPlayCoins()
|
get() = SystemSaveGame.getPlayCoins()
|
||||||
|
|||||||
@ -48,6 +48,8 @@ object SystemSaveGame {
|
|||||||
external fun getMac(): String
|
external fun getMac(): String
|
||||||
|
|
||||||
external fun regenerateMac()
|
external fun regenerateMac()
|
||||||
|
|
||||||
|
external fun getCountryCompatibility(region: Int): Int
|
||||||
}
|
}
|
||||||
|
|
||||||
enum class BirthdayMonth(val code: Int, val days: Int) {
|
enum class BirthdayMonth(val code: Int, val days: Int) {
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
#include <core/core.h>
|
#include <core/core.h>
|
||||||
#include <core/hle/service/cfg/cfg.h>
|
#include <core/hle/service/cfg/cfg.h>
|
||||||
#include <core/hle/service/ptm/ptm.h>
|
#include <core/hle/service/ptm/ptm.h>
|
||||||
|
#include <core/hw/unique_data.h>
|
||||||
#include "android_common/android_common.h"
|
#include "android_common/android_common.h"
|
||||||
|
|
||||||
static bool changes_pending = false;
|
static bool changes_pending = false;
|
||||||
@ -138,4 +139,21 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_regenerateMac(JNIEnv* env,
|
|||||||
cfg->SaveMacAddress();
|
cfg->SaveMacAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jint Java_org_citra_citra_1emu_utils_SystemSaveGame_getCountryCompatibility(
|
||||||
|
JNIEnv* env, [[maybe_unused]] jobject obj, jint region) {
|
||||||
|
int res = 0;
|
||||||
|
u8 country = cfg->GetCountryCode();
|
||||||
|
if (region != Settings::REGION_VALUE_AUTO_SELECT &&
|
||||||
|
!Service::CFG::Module::IsValidRegionCountry(static_cast<u32>(region), country)) {
|
||||||
|
res |= 1;
|
||||||
|
}
|
||||||
|
if (HW::UniqueData::GetSecureInfoA().IsValid()) {
|
||||||
|
region = static_cast<jint>(cfg->GetRegionValue(true));
|
||||||
|
if (!Service::CFG::Module::IsValidRegionCountry(static_cast<u32>(region), country)) {
|
||||||
|
res |= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
|
|||||||
@ -200,6 +200,9 @@
|
|||||||
<string name="plugin_loader_description">Loads 3GX plugins from the emulated SD card if they are available.</string>
|
<string name="plugin_loader_description">Loads 3GX plugins from the emulated SD card if they are available.</string>
|
||||||
<string name="allow_plugin_loader">Allow Applications to Change Plugin Loader State</string>
|
<string name="allow_plugin_loader">Allow Applications to Change Plugin Loader State</string>
|
||||||
<string name="allow_plugin_loader_description">Allows homebrew apps to enable the plugin loader even when it is disabled.</string>
|
<string name="allow_plugin_loader_description">Allows homebrew apps to enable the plugin loader even when it is disabled.</string>
|
||||||
|
<string name="region_mismatch">Region Mismatch Warning</string>
|
||||||
|
<string name="region_mismatch_emulated">The country setting is not valid for the selected emulated region.</string>
|
||||||
|
<string name="region_mismatch_console">The country setting is not valid for the current linked console.</string>
|
||||||
|
|
||||||
<!-- Camera settings strings -->
|
<!-- Camera settings strings -->
|
||||||
<string name="inner_camera">Inner Camera</string>
|
<string name="inner_camera">Inner Camera</string>
|
||||||
|
|||||||
@ -121,16 +121,6 @@ void ConfigureGeneral::SetConfiguration() {
|
|||||||
!UISettings::values.screenshot_path.UsingGlobal());
|
!UISettings::values.screenshot_path.UsingGlobal());
|
||||||
ConfigurationShared::SetHighlight(ui->emulation_speed_layout,
|
ConfigurationShared::SetHighlight(ui->emulation_speed_layout,
|
||||||
!Settings::values.frame_limit.UsingGlobal());
|
!Settings::values.frame_limit.UsingGlobal());
|
||||||
ConfigurationShared::SetHighlight(ui->widget_region,
|
|
||||||
!Settings::values.region_value.UsingGlobal());
|
|
||||||
const bool is_region_global = Settings::values.region_value.UsingGlobal();
|
|
||||||
ui->region_combobox->setCurrentIndex(
|
|
||||||
is_region_global ? ConfigurationShared::USE_GLOBAL_INDEX
|
|
||||||
: static_cast<int>(Settings::values.region_value.GetValue()) +
|
|
||||||
ConfigurationShared::USE_GLOBAL_OFFSET + 1);
|
|
||||||
} else {
|
|
||||||
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
|
||||||
ui->region_combobox->setCurrentIndex(Settings::values.region_value.GetValue() + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UISettings::values.screenshot_path.SetGlobal(ui->screenshot_combo->currentIndex() ==
|
UISettings::values.screenshot_path.SetGlobal(ui->screenshot_combo->currentIndex() ==
|
||||||
@ -160,9 +150,6 @@ void ConfigureGeneral::ResetDefaults() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ConfigureGeneral::ApplyConfiguration() {
|
void ConfigureGeneral::ApplyConfiguration() {
|
||||||
ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_value, ui->region_combobox,
|
|
||||||
[](s32 index) { return index - 1; });
|
|
||||||
|
|
||||||
ConfigurationShared::ApplyPerGameSetting(
|
ConfigurationShared::ApplyPerGameSetting(
|
||||||
&Settings::values.frame_limit, ui->emulation_speed_combo, [this](s32) {
|
&Settings::values.frame_limit, ui->emulation_speed_combo, [this](s32) {
|
||||||
const bool is_maximum = ui->frame_limit->value() == ui->frame_limit->maximum();
|
const bool is_maximum = ui->frame_limit->value() == ui->frame_limit->maximum();
|
||||||
@ -191,7 +178,6 @@ void ConfigureGeneral::RetranslateUI() {
|
|||||||
|
|
||||||
void ConfigureGeneral::SetupPerGameUI() {
|
void ConfigureGeneral::SetupPerGameUI() {
|
||||||
if (Settings::IsConfiguringGlobal()) {
|
if (Settings::IsConfiguringGlobal()) {
|
||||||
ui->region_combobox->setEnabled(Settings::values.region_value.UsingGlobal());
|
|
||||||
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
|
ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -212,8 +198,4 @@ void ConfigureGeneral::SetupPerGameUI() {
|
|||||||
ui->button_reset_defaults->setVisible(false);
|
ui->button_reset_defaults->setVisible(false);
|
||||||
ui->toggle_gamemode->setVisible(false);
|
ui->toggle_gamemode->setVisible(false);
|
||||||
ui->toggle_update_checker->setVisible(false);
|
ui->toggle_update_checker->setVisible(false);
|
||||||
|
|
||||||
ConfigurationShared::SetColoredComboBox(
|
|
||||||
ui->region_combobox, ui->widget_region,
|
|
||||||
static_cast<u32>(Settings::values.region_value.GetValue(true) + 1));
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -73,75 +73,6 @@
|
|||||||
<string>Emulation</string>
|
<string>Emulation</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||||
<item>
|
|
||||||
<widget class="QWidget" name="widget_region" native="true">
|
|
||||||
<layout class="QHBoxLayout" name="region_layout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="region_label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Region:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QComboBox" name="region_combobox">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Auto-select</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">JPN</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">USA</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">EUR</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">AUS</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">CHN</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">KOR</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string notr="true">TWN</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
<item>
|
||||||
<widget class="QWidget" name="emulation_speed_layout" native="true">
|
<widget class="QWidget" name="emulation_speed_layout" native="true">
|
||||||
<layout class="QHBoxLayout" name="emulation_speed_layout_inner">
|
<layout class="QHBoxLayout" name="emulation_speed_layout_inner">
|
||||||
|
|||||||
@ -240,6 +240,14 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
|||||||
connect(ui->button_regenerate_mac, &QPushButton::clicked, this, &ConfigureSystem::RefreshMAC);
|
connect(ui->button_regenerate_mac, &QPushButton::clicked, this, &ConfigureSystem::RefreshMAC);
|
||||||
connect(ui->button_linked_console, &QPushButton::clicked, this,
|
connect(ui->button_linked_console, &QPushButton::clicked, this,
|
||||||
&ConfigureSystem::UnlinkConsole);
|
&ConfigureSystem::UnlinkConsole);
|
||||||
|
connect(ui->combo_country, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
|
[this](int index) {
|
||||||
|
CheckCountryValid(static_cast<u8>(ui->combo_country->itemData(index).toInt()));
|
||||||
|
});
|
||||||
|
connect(ui->region_combobox, qOverload<int>(&QComboBox::currentIndexChanged), this,
|
||||||
|
[this]([[maybe_unused]] int index) {
|
||||||
|
CheckCountryValid(static_cast<u8>(ui->combo_country->currentData().toInt()));
|
||||||
|
});
|
||||||
|
|
||||||
connect(ui->button_secure_info, &QPushButton::clicked, this, [this] {
|
connect(ui->button_secure_info, &QPushButton::clicked, this, [this] {
|
||||||
ui->button_secure_info->setEnabled(false);
|
ui->button_secure_info->setEnabled(false);
|
||||||
@ -280,6 +288,8 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent)
|
|||||||
ui->combo_country->addItem(tr(country_names.at(i)), i);
|
ui->combo_country->addItem(tr(country_names.at(i)), i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ui->label_country_invalid->setVisible(false);
|
||||||
|
ui->label_country_invalid->setStyleSheet(QStringLiteral("QLabel { color: #ff3333; }"));
|
||||||
|
|
||||||
SetupPerGameUI();
|
SetupPerGameUI();
|
||||||
ConfigureTime();
|
ConfigureTime();
|
||||||
@ -290,6 +300,19 @@ ConfigureSystem::~ConfigureSystem() = default;
|
|||||||
void ConfigureSystem::SetConfiguration() {
|
void ConfigureSystem::SetConfiguration() {
|
||||||
enabled = !system.IsPoweredOn();
|
enabled = !system.IsPoweredOn();
|
||||||
|
|
||||||
|
if (!Settings::IsConfiguringGlobal()) {
|
||||||
|
ConfigurationShared::SetHighlight(ui->region_label,
|
||||||
|
!Settings::values.region_value.UsingGlobal());
|
||||||
|
const bool is_region_global = Settings::values.region_value.UsingGlobal();
|
||||||
|
ui->region_combobox->setCurrentIndex(
|
||||||
|
is_region_global ? ConfigurationShared::USE_GLOBAL_INDEX
|
||||||
|
: static_cast<int>(Settings::values.region_value.GetValue()) +
|
||||||
|
ConfigurationShared::USE_GLOBAL_OFFSET + 1);
|
||||||
|
} else {
|
||||||
|
// The first item is "auto-select" with actual value -1, so plus one here will do the trick
|
||||||
|
ui->region_combobox->setCurrentIndex(Settings::values.region_value.GetValue() + 1);
|
||||||
|
}
|
||||||
|
|
||||||
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
|
ui->combo_init_clock->setCurrentIndex(static_cast<u8>(Settings::values.init_clock.GetValue()));
|
||||||
QDateTime date_time;
|
QDateTime date_time;
|
||||||
date_time.setSecsSinceEpoch(Settings::values.init_time.GetValue());
|
date_time.setSecsSinceEpoch(Settings::values.init_time.GetValue());
|
||||||
@ -351,6 +374,7 @@ void ConfigureSystem::ReadSystemSettings() {
|
|||||||
// set the country code
|
// set the country code
|
||||||
country_code = cfg->GetCountryCode();
|
country_code = cfg->GetCountryCode();
|
||||||
ui->combo_country->setCurrentIndex(ui->combo_country->findData(country_code));
|
ui->combo_country->setCurrentIndex(ui->combo_country->findData(country_code));
|
||||||
|
CheckCountryValid(country_code);
|
||||||
|
|
||||||
// set whether system setup is needed
|
// set whether system setup is needed
|
||||||
system_setup = cfg->IsSystemSetupNeeded();
|
system_setup = cfg->IsSystemSetupNeeded();
|
||||||
@ -373,6 +397,10 @@ void ConfigureSystem::ReadSystemSettings() {
|
|||||||
|
|
||||||
void ConfigureSystem::ApplyConfiguration() {
|
void ConfigureSystem::ApplyConfiguration() {
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
|
ConfigurationShared::ApplyPerGameSetting(&Settings::values.region_value,
|
||||||
|
ui->region_combobox,
|
||||||
|
[](s32 index) { return index - 1; });
|
||||||
|
|
||||||
bool modified = false;
|
bool modified = false;
|
||||||
|
|
||||||
// apply username
|
// apply username
|
||||||
@ -582,6 +610,32 @@ void ConfigureSystem::UnlinkConsole() {
|
|||||||
RefreshSecureDataStatus();
|
RefreshSecureDataStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ConfigureSystem::CheckCountryValid(u8 country) {
|
||||||
|
// TODO(PabloMK7): Make this per-game compatible
|
||||||
|
if (!Settings::IsConfiguringGlobal())
|
||||||
|
return;
|
||||||
|
|
||||||
|
s32 region = ui->region_combobox->currentIndex() - 1;
|
||||||
|
QString label_text;
|
||||||
|
|
||||||
|
if (region != Settings::REGION_VALUE_AUTO_SELECT &&
|
||||||
|
!cfg->IsValidRegionCountry(static_cast<u32>(region), country)) {
|
||||||
|
label_text = tr("Invalid country for configured region");
|
||||||
|
}
|
||||||
|
if (HW::UniqueData::GetSecureInfoA().IsValid()) {
|
||||||
|
region = static_cast<u32>(cfg->GetRegionValue(true));
|
||||||
|
if (!cfg->IsValidRegionCountry(static_cast<u32>(region), country)) {
|
||||||
|
if (!label_text.isEmpty()) {
|
||||||
|
label_text += QString::fromStdString("\n");
|
||||||
|
}
|
||||||
|
label_text += tr("Invalid country for console unique data");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ui->label_country_invalid->setText(label_text);
|
||||||
|
ui->label_country_invalid->setVisible(!label_text.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
void ConfigureSystem::InstallSecureData(const std::string& from_path, const std::string& to_path) {
|
void ConfigureSystem::InstallSecureData(const std::string& from_path, const std::string& to_path) {
|
||||||
std::string from =
|
std::string from =
|
||||||
FileUtil::SanitizePath(from_path, FileUtil::DirectorySeparator::PlatformDefault);
|
FileUtil::SanitizePath(from_path, FileUtil::DirectorySeparator::PlatformDefault);
|
||||||
@ -644,6 +698,7 @@ void ConfigureSystem::SetupPerGameUI() {
|
|||||||
ui->toggle_lle_applets->setEnabled(Settings::values.lle_applets.UsingGlobal());
|
ui->toggle_lle_applets->setEnabled(Settings::values.lle_applets.UsingGlobal());
|
||||||
ui->enable_required_online_lle_modules->setEnabled(
|
ui->enable_required_online_lle_modules->setEnabled(
|
||||||
Settings::values.enable_required_online_lle_modules.UsingGlobal());
|
Settings::values.enable_required_online_lle_modules.UsingGlobal());
|
||||||
|
ui->region_combobox->setEnabled(Settings::values.region_value.UsingGlobal());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,4 +749,7 @@ void ConfigureSystem::SetupPerGameUI() {
|
|||||||
ConfigurationShared::SetColoredTristate(ui->enable_required_online_lle_modules,
|
ConfigurationShared::SetColoredTristate(ui->enable_required_online_lle_modules,
|
||||||
Settings::values.enable_required_online_lle_modules,
|
Settings::values.enable_required_online_lle_modules,
|
||||||
required_online_lle_modules);
|
required_online_lle_modules);
|
||||||
|
ConfigurationShared::SetColoredComboBox(
|
||||||
|
ui->region_combobox, ui->region_label,
|
||||||
|
static_cast<u32>(Settings::values.region_value.GetValue(true) + 1));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,7 @@ private:
|
|||||||
void RefreshConsoleID();
|
void RefreshConsoleID();
|
||||||
void RefreshMAC();
|
void RefreshMAC();
|
||||||
void UnlinkConsole();
|
void UnlinkConsole();
|
||||||
|
void CheckCountryValid(u8 country);
|
||||||
|
|
||||||
void InstallSecureData(const std::string& from_path, const std::string& to_path);
|
void InstallSecureData(const std::string& from_path, const std::string& to_path);
|
||||||
void RefreshSecureDataStatus();
|
void RefreshSecureDataStatus();
|
||||||
|
|||||||
@ -64,21 +64,21 @@
|
|||||||
<string>System Settings</string>
|
<string>System Settings</string>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout">
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
<item row="1" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QCheckBox" name="toggle_new_3ds">
|
<widget class="QCheckBox" name="toggle_new_3ds">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable New 3DS mode</string>
|
<string>Enable New 3DS mode</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="1" column="0">
|
||||||
<widget class="QCheckBox" name="toggle_lle_applets">
|
<widget class="QCheckBox" name="toggle_lle_applets">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use LLE applets (if installed)</string>
|
<string>Use LLE applets (if installed)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="enable_required_online_lle_modules">
|
<widget class="QCheckBox" name="enable_required_online_lle_modules">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable required LLE modules for
|
<string>Enable required LLE modules for
|
||||||
@ -89,6 +89,57 @@ online features (if installed)</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="region_label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Region:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="region_combobox">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Auto-select</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">JPN</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">USA</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">EUR</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">AUS</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">CHN</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">KOR</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string notr="true">TWN</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="4" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QLineEdit" name="edit_username">
|
<widget class="QLineEdit" name="edit_username">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
@ -297,14 +348,21 @@ online features (if installed)</string>
|
|||||||
<item row="8" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QComboBox" name="combo_country"/>
|
<widget class="QComboBox" name="combo_country"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0">
|
<item row="9" column="1">
|
||||||
|
<widget class="QLabel" name="label_country_invalid">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="10" column="0">
|
||||||
<widget class="QLabel" name="label_init_clock">
|
<widget class="QLabel" name="label_init_clock">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Clock</string>
|
<string>Clock</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="1">
|
<item row="10" column="1">
|
||||||
<widget class="QComboBox" name="combo_init_clock">
|
<widget class="QComboBox" name="combo_init_clock">
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -318,28 +376,28 @@ online features (if installed)</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0">
|
<item row="11" column="0">
|
||||||
<widget class="QLabel" name="label_init_time">
|
<widget class="QLabel" name="label_init_time">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Startup time</string>
|
<string>Startup time</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="1">
|
<item row="11" column="1">
|
||||||
<widget class="QDateTimeEdit" name="edit_init_time">
|
<widget class="QDateTimeEdit" name="edit_init_time">
|
||||||
<property name="displayFormat">
|
<property name="displayFormat">
|
||||||
<string>yyyy-MM-ddTHH:mm:ss</string>
|
<string>yyyy-MM-ddTHH:mm:ss</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0">
|
<item row="12" column="0">
|
||||||
<widget class="QLabel" name="label_init_time_offset">
|
<widget class="QLabel" name="label_init_time_offset">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Offset time</string>
|
<string>Offset time</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="12" column="1">
|
||||||
<layout class="QGridLayout" name="edit_init_time_offset_grid">
|
<layout class="QGridLayout" name="edit_init_time_offset_grid">
|
||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QSpinBox" name="edit_init_time_offset_days">
|
<widget class="QSpinBox" name="edit_init_time_offset_days">
|
||||||
@ -363,14 +421,14 @@ online features (if installed)</string>
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0">
|
<item row="13" column="0">
|
||||||
<widget class="QLabel" name="label_init_ticks_type">
|
<widget class="QLabel" name="label_init_ticks_type">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Initial System Ticks</string>
|
<string>Initial System Ticks</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="1">
|
<item row="13" column="1">
|
||||||
<widget class="QComboBox" name="combo_init_ticks_type">
|
<widget class="QComboBox" name="combo_init_ticks_type">
|
||||||
<item>
|
<item>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@ -384,14 +442,14 @@ online features (if installed)</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="0">
|
<item row="14" column="0">
|
||||||
<widget class="QLabel" name="label_init_ticks_value">
|
<widget class="QLabel" name="label_init_ticks_value">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Initial System Ticks Override</string>
|
<string>Initial System Ticks Override</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="1">
|
<item row="14" column="1">
|
||||||
<widget class="QLineEdit" name="edit_init_ticks_value">
|
<widget class="QLineEdit" name="edit_init_ticks_value">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||||
@ -404,21 +462,21 @@ online features (if installed)</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="0">
|
<item row="15" column="0">
|
||||||
<widget class="QLabel" name="label_play_coins">
|
<widget class="QLabel" name="label_play_coins">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Play Coins</string>
|
<string>Play Coins</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="1">
|
<item row="15" column="1">
|
||||||
<widget class="QSpinBox" name="spinBox_play_coins">
|
<widget class="QSpinBox" name="spinBox_play_coins">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>300</number>
|
<number>300</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="15" column="0">
|
<item row="16" column="0">
|
||||||
<widget class="QLabel" name="label_steps_per_hour">
|
<widget class="QLabel" name="label_steps_per_hour">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string><html><head/><body><p>Number of steps per hour reported by the pedometer. Range from 0 to 65,535.</p></body></html></string>
|
<string><html><head/><body><p>Number of steps per hour reported by the pedometer. Range from 0 to 65,535.</p></body></html></string>
|
||||||
@ -428,28 +486,28 @@ online features (if installed)</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="15" column="1">
|
<item row="16" column="1">
|
||||||
<widget class="QSpinBox" name="spinBox_steps_per_hour">
|
<widget class="QSpinBox" name="spinBox_steps_per_hour">
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>9999</number>
|
<number>9999</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="16" column="1">
|
<item row="17" column="1">
|
||||||
<widget class="QCheckBox" name="toggle_system_setup">
|
<widget class="QCheckBox" name="toggle_system_setup">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Run System Setup when Home Menu is launched</string>
|
<string>Run System Setup when Home Menu is launched</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="17" column="0">
|
<item row="18" column="0">
|
||||||
<widget class="QLabel" name="label_console_id">
|
<widget class="QLabel" name="label_console_id">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Console ID:</string>
|
<string>Console ID:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="17" column="1">
|
<item row="18" column="1">
|
||||||
<widget class="QPushButton" name="button_regenerate_console_id">
|
<widget class="QPushButton" name="button_regenerate_console_id">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@ -465,14 +523,14 @@ online features (if installed)</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="18" column="0">
|
<item row="19" column="0">
|
||||||
<widget class="QLabel" name="label_mac">
|
<widget class="QLabel" name="label_mac">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>MAC:</string>
|
<string>MAC:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="18" column="1">
|
<item row="19" column="1">
|
||||||
<widget class="QPushButton" name="button_regenerate_mac">
|
<widget class="QPushButton" name="button_regenerate_mac">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||||
@ -488,21 +546,21 @@ online features (if installed)</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="19" column="0">
|
<item row="20" column="0">
|
||||||
<widget class="QLabel" name="label_plugin_loader">
|
<widget class="QLabel" name="label_plugin_loader">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>3GX Plugin Loader:</string>
|
<string>3GX Plugin Loader:</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="19" column="1">
|
<item row="20" column="1">
|
||||||
<widget class="QCheckBox" name="plugin_loader">
|
<widget class="QCheckBox" name="plugin_loader">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable 3GX plugin loader</string>
|
<string>Enable 3GX plugin loader</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="20" column="1">
|
<item row="21" column="1">
|
||||||
<widget class="QCheckBox" name="allow_plugin_loader">
|
<widget class="QCheckBox" name="allow_plugin_loader">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Allow applications to change plugin loader state</string>
|
<string>Allow applications to change plugin loader state</string>
|
||||||
|
|||||||
@ -86,30 +86,227 @@ static constexpr u16 C(const char code[2]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const std::array<u16, 187> country_codes = {{
|
static const std::array<u16, 187> country_codes = {{
|
||||||
0, C("JP"), 0, 0, 0, 0, 0, 0, // 0-7
|
// 0-7 Japan
|
||||||
C("AI"), C("AG"), C("AR"), C("AW"), C("BS"), C("BB"), C("BZ"), C("BO"), // 8-15
|
0,
|
||||||
C("BR"), C("VG"), C("CA"), C("KY"), C("CL"), C("CO"), C("CR"), C("DM"), // 16-23
|
C("JP"),
|
||||||
C("DO"), C("EC"), C("SV"), C("GF"), C("GD"), C("GP"), C("GT"), C("GY"), // 24-31
|
0,
|
||||||
C("HT"), C("HN"), C("JM"), C("MQ"), C("MX"), C("MS"), C("AN"), C("NI"), // 32-39
|
0,
|
||||||
C("PA"), C("PY"), C("PE"), C("KN"), C("LC"), C("VC"), C("SR"), C("TT"), // 40-47
|
0,
|
||||||
C("TC"), C("US"), C("UY"), C("VI"), C("VE"), 0, 0, 0, // 48-55
|
0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, // 56-63
|
0,
|
||||||
C("AL"), C("AU"), C("AT"), C("BE"), C("BA"), C("BW"), C("BG"), C("HR"), // 64-71
|
0,
|
||||||
C("CY"), C("CZ"), C("DK"), C("EE"), C("FI"), C("FR"), C("DE"), C("GR"), // 72-79
|
|
||||||
C("HU"), C("IS"), C("IE"), C("IT"), C("LV"), C("LS"), C("LI"), C("LT"), // 80-87
|
// 8-15 America
|
||||||
C("LU"), C("MK"), C("MT"), C("ME"), C("MZ"), C("NA"), C("NL"), C("NZ"), // 88-95
|
C("AI"),
|
||||||
C("NO"), C("PL"), C("PT"), C("RO"), C("RU"), C("RS"), C("SK"), C("SI"), // 96-103
|
C("AG"),
|
||||||
C("ZA"), C("ES"), C("SZ"), C("SE"), C("CH"), C("TR"), C("GB"), C("ZM"), // 104-111
|
C("AR"),
|
||||||
C("ZW"), C("AZ"), C("MR"), C("ML"), C("NE"), C("TD"), C("SD"), C("ER"), // 112-119
|
C("AW"),
|
||||||
C("DJ"), C("SO"), C("AD"), C("GI"), C("GG"), C("IM"), C("JE"), C("MC"), // 120-127
|
C("BS"),
|
||||||
C("TW"), 0, 0, 0, 0, 0, 0, 0, // 128-135
|
C("BB"),
|
||||||
C("KR"), 0, 0, 0, 0, 0, 0, 0, // 136-143
|
C("BZ"),
|
||||||
C("HK"), C("MO"), 0, 0, 0, 0, 0, 0, // 144-151
|
C("BO"),
|
||||||
C("ID"), C("SG"), C("TH"), C("PH"), C("MY"), 0, 0, 0, // 152-159
|
// 16-23 America
|
||||||
C("CN"), 0, 0, 0, 0, 0, 0, 0, // 160-167
|
C("BR"),
|
||||||
C("AE"), C("IN"), C("EG"), C("OM"), C("QA"), C("KW"), C("SA"), C("SY"), // 168-175
|
C("VG"),
|
||||||
C("BH"), C("JO"), 0, 0, 0, 0, 0, 0, // 176-183
|
C("CA"),
|
||||||
C("SM"), C("VA"), C("BM"), // 184-186
|
C("KY"),
|
||||||
|
C("CL"),
|
||||||
|
C("CO"),
|
||||||
|
C("CR"),
|
||||||
|
C("DM"),
|
||||||
|
// 24-31 America
|
||||||
|
C("DO"),
|
||||||
|
C("EC"),
|
||||||
|
C("SV"),
|
||||||
|
C("GF"),
|
||||||
|
C("GD"),
|
||||||
|
C("GP"),
|
||||||
|
C("GT"),
|
||||||
|
C("GY"),
|
||||||
|
// 32-39 America
|
||||||
|
C("HT"),
|
||||||
|
C("HN"),
|
||||||
|
C("JM"),
|
||||||
|
C("MQ"),
|
||||||
|
C("MX"),
|
||||||
|
C("MS"),
|
||||||
|
C("AN"),
|
||||||
|
C("NI"),
|
||||||
|
// 40-47 America
|
||||||
|
C("PA"),
|
||||||
|
C("PY"),
|
||||||
|
C("PE"),
|
||||||
|
C("KN"),
|
||||||
|
C("LC"),
|
||||||
|
C("VC"),
|
||||||
|
C("SR"),
|
||||||
|
C("TT"),
|
||||||
|
// 48-55 America
|
||||||
|
C("TC"),
|
||||||
|
C("US"),
|
||||||
|
C("UY"),
|
||||||
|
C("VI"),
|
||||||
|
C("VE"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 56-63 Invalid
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 64-71 Europe
|
||||||
|
C("AL"),
|
||||||
|
C("AU"),
|
||||||
|
C("AT"),
|
||||||
|
C("BE"),
|
||||||
|
C("BA"),
|
||||||
|
C("BW"),
|
||||||
|
C("BG"),
|
||||||
|
C("HR"),
|
||||||
|
// 72-79 Europe
|
||||||
|
C("CY"),
|
||||||
|
C("CZ"),
|
||||||
|
C("DK"),
|
||||||
|
C("EE"),
|
||||||
|
C("FI"),
|
||||||
|
C("FR"),
|
||||||
|
C("DE"),
|
||||||
|
C("GR"),
|
||||||
|
// 80-87 Europe
|
||||||
|
C("HU"),
|
||||||
|
C("IS"),
|
||||||
|
C("IE"),
|
||||||
|
C("IT"),
|
||||||
|
C("LV"),
|
||||||
|
C("LS"),
|
||||||
|
C("LI"),
|
||||||
|
C("LT"),
|
||||||
|
// 88-95 Europe
|
||||||
|
C("LU"),
|
||||||
|
C("MK"),
|
||||||
|
C("MT"),
|
||||||
|
C("ME"),
|
||||||
|
C("MZ"),
|
||||||
|
C("NA"),
|
||||||
|
C("NL"),
|
||||||
|
C("NZ"),
|
||||||
|
// 96-103 Europe
|
||||||
|
C("NO"),
|
||||||
|
C("PL"),
|
||||||
|
C("PT"),
|
||||||
|
C("RO"),
|
||||||
|
C("RU"),
|
||||||
|
C("RS"),
|
||||||
|
C("SK"),
|
||||||
|
C("SI"),
|
||||||
|
// 104-111 Europe
|
||||||
|
C("ZA"),
|
||||||
|
C("ES"),
|
||||||
|
C("SZ"),
|
||||||
|
C("SE"),
|
||||||
|
C("CH"),
|
||||||
|
C("TR"),
|
||||||
|
C("GB"),
|
||||||
|
C("ZM"),
|
||||||
|
// 112-119 Europe
|
||||||
|
C("ZW"),
|
||||||
|
C("AZ"),
|
||||||
|
C("MR"),
|
||||||
|
C("ML"),
|
||||||
|
C("NE"),
|
||||||
|
C("TD"),
|
||||||
|
C("SD"),
|
||||||
|
C("ER"),
|
||||||
|
// 120-127 Europe
|
||||||
|
C("DJ"),
|
||||||
|
C("SO"),
|
||||||
|
C("AD"),
|
||||||
|
C("GI"),
|
||||||
|
C("GG"),
|
||||||
|
C("IM"),
|
||||||
|
C("JE"),
|
||||||
|
C("MC"),
|
||||||
|
|
||||||
|
// 128-135 Taiwan
|
||||||
|
C("TW"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 136-143 Korea
|
||||||
|
C("KR"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 144-151 China? (Hong Kong & Macao)
|
||||||
|
C("HK"),
|
||||||
|
C("MO"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 152-159 Southeast Asia
|
||||||
|
C("ID"),
|
||||||
|
C("SG"), // USA
|
||||||
|
C("TH"),
|
||||||
|
C("PH"),
|
||||||
|
C("MY"), // USA
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 160-167 China
|
||||||
|
C("CN"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 168-175 Middle East
|
||||||
|
C("AE"), // USA
|
||||||
|
C("IN"), // EUR
|
||||||
|
C("EG"),
|
||||||
|
C("OM"),
|
||||||
|
C("QA"),
|
||||||
|
C("KW"),
|
||||||
|
C("SA"), // USA
|
||||||
|
C("SY"),
|
||||||
|
// 176-183 Middle East
|
||||||
|
C("BH"),
|
||||||
|
C("JO"),
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
|
||||||
|
// 184-186 European Microstates
|
||||||
|
C("SM"),
|
||||||
|
C("VA"),
|
||||||
|
C("BM"),
|
||||||
}};
|
}};
|
||||||
|
|
||||||
// Based on PKHeX's lists of subregions at
|
// Based on PKHeX's lists of subregions at
|
||||||
@ -218,6 +415,29 @@ u32 Module::GetRegionValue(bool from_secure_info) {
|
|||||||
return Settings::values.region_value.GetValue();
|
return Settings::values.region_value.GetValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Module::IsValidRegionCountry(u32 region, u8 country_code) {
|
||||||
|
switch (region) {
|
||||||
|
case 0: // JPN
|
||||||
|
return country_code == 1;
|
||||||
|
case 1: // USA
|
||||||
|
return (country_code >= 8 && country_code <= 52) || country_code == 153 ||
|
||||||
|
country_code == 156 || country_code == 168 || country_code == 174;
|
||||||
|
case 2: // EUR
|
||||||
|
case 3: // AUS
|
||||||
|
return (country_code >= 64 && country_code <= 127) ||
|
||||||
|
(country_code >= 184 && country_code <= 186) || country_code == 169;
|
||||||
|
case 4: // CHN
|
||||||
|
return country_code == 144 || country_code == 145 || country_code == 160;
|
||||||
|
case 5: // KOR
|
||||||
|
return country_code == 136;
|
||||||
|
case 6: // TWN
|
||||||
|
return country_code == 128;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Module::Interface::GetRegion(Kernel::HLERequestContext& ctx) {
|
void Module::Interface::GetRegion(Kernel::HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp(ctx);
|
IPC::RequestParser rp(ctx);
|
||||||
|
|
||||||
|
|||||||
@ -486,6 +486,8 @@ private:
|
|||||||
public:
|
public:
|
||||||
u32 GetRegionValue(bool from_secure_info);
|
u32 GetRegionValue(bool from_secure_info);
|
||||||
|
|
||||||
|
static bool IsValidRegionCountry(u32 region, u8 country_code);
|
||||||
|
|
||||||
// Utilities for frontend to set config data.
|
// Utilities for frontend to set config data.
|
||||||
// Note: UpdateConfigNANDSavegame should be called after making changes to config data.
|
// Note: UpdateConfigNANDSavegame should be called after making changes to config data.
|
||||||
|
|
||||||
|
|||||||
@ -408,6 +408,7 @@ ResultStatus Apploader_Artic::Load(std::shared_ptr<Kernel::Process>& process) {
|
|||||||
return ResultStatus::ErrorArtic;
|
return ResultStatus::ErrorArtic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto cfg = system.ServiceManager().GetService<Service::CFG::CFG_U>("cfg:u");
|
||||||
// Request console unique data
|
// Request console unique data
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
std::string path;
|
std::string path;
|
||||||
@ -471,7 +472,6 @@ ResultStatus Apploader_Artic::Load(std::shared_ptr<Kernel::Process>& process) {
|
|||||||
memcpy(&console_id, resp_buff->first, sizeof(u64));
|
memcpy(&console_id, resp_buff->first, sizeof(u64));
|
||||||
memcpy(&random_id, reinterpret_cast<u8*>(resp_buff->first) + sizeof(u64),
|
memcpy(&random_id, reinterpret_cast<u8*>(resp_buff->first) + sizeof(u64),
|
||||||
sizeof(u32));
|
sizeof(u32));
|
||||||
auto cfg = system.ServiceManager().GetService<Service::CFG::CFG_U>("cfg:u");
|
|
||||||
if (cfg.get()) {
|
if (cfg.get()) {
|
||||||
auto cfg_module = cfg->GetModule();
|
auto cfg_module = cfg->GetModule();
|
||||||
cfg_module->SetConsoleUniqueId(random_id, console_id);
|
cfg_module->SetConsoleUniqueId(random_id, console_id);
|
||||||
@ -480,7 +480,6 @@ ResultStatus Apploader_Artic::Load(std::shared_ptr<Kernel::Process>& process) {
|
|||||||
} else if (i == 5) {
|
} else if (i == 5) {
|
||||||
std::array<u8, 6> mac;
|
std::array<u8, 6> mac;
|
||||||
memcpy(mac.data(), resp_buff->first, mac.size());
|
memcpy(mac.data(), resp_buff->first, mac.size());
|
||||||
auto cfg = system.ServiceManager().GetService<Service::CFG::CFG_U>("cfg:u");
|
|
||||||
if (cfg.get()) {
|
if (cfg.get()) {
|
||||||
auto cfg_module = cfg->GetModule();
|
auto cfg_module = cfg->GetModule();
|
||||||
cfg_module->GetMacAddress() = Service::CFG::MacToString(mac);
|
cfg_module->GetMacAddress() = Service::CFG::MacToString(mac);
|
||||||
@ -494,10 +493,25 @@ ResultStatus Apploader_Artic::Load(std::shared_ptr<Kernel::Process>& process) {
|
|||||||
if (!HW::UniqueData::GetCTCert().IsValid() || !HW::UniqueData::GetMovableSed().IsValid() ||
|
if (!HW::UniqueData::GetCTCert().IsValid() || !HW::UniqueData::GetMovableSed().IsValid() ||
|
||||||
!HW::UniqueData::GetSecureInfoA().IsValid() ||
|
!HW::UniqueData::GetSecureInfoA().IsValid() ||
|
||||||
!HW::UniqueData::GetLocalFriendCodeSeedB().IsValid()) {
|
!HW::UniqueData::GetLocalFriendCodeSeedB().IsValid()) {
|
||||||
LOG_CRITICAL(Loader, "Some console unique data is invalid, aborting...");
|
client->LogOnServer(Network::ArticBaseCommon::LogOnServerType::LOG_ERROR,
|
||||||
|
"Some console unique data is invalid.\n Aborting...");
|
||||||
return ResultStatus::ErrorArtic;
|
return ResultStatus::ErrorArtic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cfg.get()) {
|
||||||
|
auto cfg_module = cfg->GetModule();
|
||||||
|
if (!Service::CFG::Module::IsValidRegionCountry(cfg_module->GetRegionValue(true),
|
||||||
|
cfg_module->GetCountryCode())) {
|
||||||
|
// Report mismatch to server.
|
||||||
|
client->LogOnServer(
|
||||||
|
Network::ArticBaseCommon::LogOnServerType::LOG_ERROR,
|
||||||
|
"The country configuration does not match\n the console region. "
|
||||||
|
"Please select a valid\n country from the emulation settings.");
|
||||||
|
return ResultStatus::ErrorArtic;
|
||||||
|
}
|
||||||
|
cfg_module->SetSystemSetupNeeded(false);
|
||||||
|
}
|
||||||
|
|
||||||
// Set deliver arg so that System Settings goes to the update screen directly
|
// Set deliver arg so that System Settings goes to the update screen directly
|
||||||
auto apt = Service::APT::GetModule(system);
|
auto apt = Service::APT::GetModule(system);
|
||||||
Service::APT::DeliverArg arg;
|
Service::APT::DeliverArg arg;
|
||||||
|
|||||||
@ -471,6 +471,14 @@ std::optional<Client::Response> Client::Send(Request& request) {
|
|||||||
return std::optional<Client::Response>(std::move(resp.response));
|
return std::optional<Client::Response>(std::move(resp.response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Client::LogOnServer(ArticBaseCommon::LogOnServerType log_type, const std::string& message) {
|
||||||
|
auto req = NewRequest("__log");
|
||||||
|
req.AddParameterS8(static_cast<s8>(log_type));
|
||||||
|
req.AddParameterBuffer(message.data(), message.size());
|
||||||
|
|
||||||
|
Send(req);
|
||||||
|
}
|
||||||
|
|
||||||
void Client::SignalCommunicationError(const std::string& msg) {
|
void Client::SignalCommunicationError(const std::string& msg) {
|
||||||
StopImpl(true);
|
StopImpl(true);
|
||||||
LOG_CRITICAL(Network, "Communication error");
|
LOG_CRITICAL(Network, "Communication error");
|
||||||
|
|||||||
@ -165,6 +165,8 @@ public:
|
|||||||
ping_enabled = enable;
|
ping_enabled = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LogOnServer(ArticBaseCommon::LogOnServerType log_type, const std::string& message);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr const int SERVER_VERSION = 2;
|
static constexpr const int SERVER_VERSION = 2;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
// Copyright 2024 Citra Emulator Project
|
// Copyright Citra Emulator Project / Azahar Emulator Project
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
@ -31,6 +31,12 @@ enum class RequestParameterType : u16 {
|
|||||||
IN_SMALL_BUFFER = 4,
|
IN_SMALL_BUFFER = 4,
|
||||||
IN_BIG_BUFFER = 5,
|
IN_BIG_BUFFER = 5,
|
||||||
};
|
};
|
||||||
|
enum class LogOnServerType : u8 {
|
||||||
|
LOG_DEBUG = 0,
|
||||||
|
LOG_INFO = 1,
|
||||||
|
LOG_WARNING = 2,
|
||||||
|
LOG_ERROR = 3,
|
||||||
|
};
|
||||||
struct RequestParameter {
|
struct RequestParameter {
|
||||||
RequestParameterType type{};
|
RequestParameterType type{};
|
||||||
union {
|
union {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user