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:
PabloMK7
2025-03-29 22:50:00 +01:00
committed by GitHub
parent eda2d6f9fa
commit 5c7622100b
16 changed files with 528 additions and 177 deletions

View File

@@ -73,7 +73,7 @@ import kotlin.math.roundToInt
class SettingsAdapter(
private val fragmentView: SettingsFragmentView,
private val context: Context
public val context: Context
) : RecyclerView.Adapter<SettingViewHolder?>(), DialogInterface.OnClickListener {
private var settings: ArrayList<SettingsItem>? = null
private var clickedItem: SettingsItem? = null

View File

@@ -13,6 +13,7 @@ import android.hardware.camera2.CameraManager
import android.os.Build
import android.text.TextUtils
import androidx.preference.PreferenceManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlin.math.min
import org.citra.citra_emu.CitraApplication
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)
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
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(
StringInputSetting(
usernameSetting,
R.string.username,
0,
"AZAHAR",
10
)
)
val regionSetting = object : AbstractIntSetting {
override var int: Int
get() {
val ret = IntSetting.EMULATED_REGION.int
checkCountryCompatibility()
return ret
}
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(
SingleChoiceSetting(
IntSetting.EMULATED_REGION,
regionSetting,
R.string.emulated_region,
0,
R.array.regionNames,
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 {
override var short: Short
get() = SystemSaveGame.getCountryCode()
set(value) = SystemSaveGame.setCountryCode(value)
get() {
val ret = SystemSaveGame.getCountryCode()
checkCountryCompatibility()
return ret;
}
set(value) {
SystemSaveGame.setCountryCode(value)
countryCompatibilityChanged = true
checkCountryCompatibility()
}
override val key = null
override val section = null
override val isRuntimeEditable = false
@@ -348,7 +367,34 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
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 {
override var int: Int
get() = SystemSaveGame.getPlayCoins()

View File

@@ -48,6 +48,8 @@ object SystemSaveGame {
external fun getMac(): String
external fun regenerateMac()
external fun getCountryCompatibility(region: Int): Int
}
enum class BirthdayMonth(val code: Int, val days: Int) {

View File

@@ -6,6 +6,7 @@
#include <core/core.h>
#include <core/hle/service/cfg/cfg.h>
#include <core/hle/service/ptm/ptm.h>
#include <core/hw/unique_data.h>
#include "android_common/android_common.h"
static bool changes_pending = false;
@@ -138,4 +139,21 @@ void Java_org_citra_citra_1emu_utils_SystemSaveGame_regenerateMac(JNIEnv* env,
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"

View File

@@ -200,6 +200,9 @@
<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_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 -->
<string name="inner_camera">Inner Camera</string>