From 1968cc7b106159e2bd2166459c3cb04d5f79601f Mon Sep 17 00:00:00 2001 From: german77 Date: Mon, 8 May 2023 22:03:32 -0600 Subject: [PATCH 1/2] service: nfp: Allow to load with a different amiibo id --- src/common/settings.h | 2 ++ src/core/hle/service/nfc/common/device.cpp | 17 ++++++++++---- src/yuzu/configuration/config.cpp | 2 ++ .../configure_input_advanced.cpp | 2 ++ .../configuration/configure_input_advanced.ui | 22 ++++++++++++++++--- src/yuzu_cmd/config.cpp | 1 + 6 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/common/settings.h b/src/common/settings.h index f4eb4e3cde..5f4caaab98 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -535,6 +535,8 @@ struct Values { Setting enable_ir_sensor{false, "enable_ir_sensor"}; Setting ir_sensor_device{"auto", "ir_sensor_device"}; + Setting random_amiibo_id{false, "random_amiibo_id"}; + // Data Storage Setting use_virtual_sd{true, "use_virtual_sd"}; Setting gamecard_inserted{false, "gamecard_inserted"}; diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index e5de65ce01..9b0685bdb2 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -227,11 +227,20 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { return ResultWrongDeviceState; } + UniqueSerialNumber uuid = encrypted_tag_data.uuid.uid; + + // Generate random UUID to bypass amiibo load limits + if (Settings::values.random_amiibo_id) { + Common::TinyMT rng{}; + rng.GenerateRandomBytes(uuid.data(), sizeof(UniqueSerialNumber)); + uuid[3] = 0x88 ^ uuid[0] ^ uuid[1] ^ uuid[2]; + } + if (is_mifare) { tag_info = { - .uuid = encrypted_tag_data.uuid.uid, + .uuid = uuid, .uuid_extension = {}, - .uuid_length = static_cast(encrypted_tag_data.uuid.uid.size()), + .uuid_length = static_cast(uuid.size()), .protocol = NfcProtocol::TypeA, .tag_type = TagType::Type4, }; @@ -240,9 +249,9 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { // Protocol and tag type may change here tag_info = { - .uuid = encrypted_tag_data.uuid.uid, + .uuid = uuid, .uuid_extension = {}, - .uuid_length = static_cast(encrypted_tag_data.uuid.uid.size()), + .uuid_length = static_cast(uuid.size()), .protocol = NfcProtocol::TypeA, .tag_type = TagType::Type2, }; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index a49d122669..b94d368388 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -443,6 +443,7 @@ void Config::ReadControlValues() { ReadBasicSetting(Settings::values.mouse_panning_sensitivity); ReadBasicSetting(Settings::values.enable_joycon_driver); ReadBasicSetting(Settings::values.enable_procon_driver); + ReadBasicSetting(Settings::values.random_amiibo_id); ReadBasicSetting(Settings::values.tas_enable); ReadBasicSetting(Settings::values.tas_loop); @@ -1150,6 +1151,7 @@ void Config::SaveControlValues() { WriteBasicSetting(Settings::values.enable_raw_input); WriteBasicSetting(Settings::values.enable_joycon_driver); WriteBasicSetting(Settings::values.enable_procon_driver); + WriteBasicSetting(Settings::values.random_amiibo_id); WriteBasicSetting(Settings::values.keyboard_enabled); WriteBasicSetting(Settings::values.emulate_analog_keyboard); WriteBasicSetting(Settings::values.mouse_panning_sensitivity); diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp index 8d81322f3a..f131564343 100644 --- a/src/yuzu/configuration/configure_input_advanced.cpp +++ b/src/yuzu/configuration/configure_input_advanced.cpp @@ -140,6 +140,7 @@ void ConfigureInputAdvanced::ApplyConfiguration() { Settings::values.enable_ir_sensor = ui->enable_ir_sensor->isChecked(); Settings::values.enable_joycon_driver = ui->enable_joycon_driver->isChecked(); Settings::values.enable_procon_driver = ui->enable_procon_driver->isChecked(); + Settings::values.random_amiibo_id = ui->random_amiibo_id->isChecked(); } void ConfigureInputAdvanced::LoadConfiguration() { @@ -176,6 +177,7 @@ void ConfigureInputAdvanced::LoadConfiguration() { ui->enable_ir_sensor->setChecked(Settings::values.enable_ir_sensor.GetValue()); ui->enable_joycon_driver->setChecked(Settings::values.enable_joycon_driver.GetValue()); ui->enable_procon_driver->setChecked(Settings::values.enable_procon_driver.GetValue()); + ui->random_amiibo_id->setChecked(Settings::values.random_amiibo_id.GetValue()); UpdateUIEnabled(); } diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui index 0eb2b34bcc..2e8b136600 100644 --- a/src/yuzu/configuration/configure_input_advanced.ui +++ b/src/yuzu/configuration/configure_input_advanced.ui @@ -2728,6 +2728,22 @@ + + + Allows unlimited uses of the same Amiibo in games that would otherwise limit you to one use. + + + + 0 + 23 + + + + Use random Amiibo ID + + + + @@ -2740,7 +2756,7 @@ - + Mouse sensitivity @@ -2762,14 +2778,14 @@ - + Motion / Touch - + Configure diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp index abe7092fcf..dc9a3d68f1 100644 --- a/src/yuzu_cmd/config.cpp +++ b/src/yuzu_cmd/config.cpp @@ -169,6 +169,7 @@ void Config::ReadValues() { ReadSetting("ControlsGeneral", Settings::values.enable_raw_input); ReadSetting("ControlsGeneral", Settings::values.enable_joycon_driver); ReadSetting("ControlsGeneral", Settings::values.enable_procon_driver); + ReadSetting("ControlsGeneral", Settings::values.random_amiibo_id); ReadSetting("ControlsGeneral", Settings::values.emulate_analog_keyboard); ReadSetting("ControlsGeneral", Settings::values.vibration_enabled); ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations); From 42e1db4b0e254d10898f4a2bceb452fbfbaae063 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Tue, 9 May 2023 17:49:56 -0600 Subject: [PATCH 2/2] service: nfc: Seed all random values --- src/core/hle/service/nfc/common/device.cpp | 18 +++++++++++++----- src/core/hle/service/nfc/common/device.h | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index 9b0685bdb2..322bde2ed3 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -48,9 +48,6 @@ NfcDevice::NfcDevice(Core::HID::NpadIdType npad_id_, Core::System& system_, }; is_controller_set = true; callback_key = npad_device->SetCallback(engine_callback); - - auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; - current_posix_time = standard_steady_clock.GetCurrentTimePoint(system).time_point; } NfcDevice::~NfcDevice() { @@ -232,6 +229,7 @@ Result NfcDevice::GetTagInfo(NFP::TagInfo& tag_info, bool is_mifare) const { // Generate random UUID to bypass amiibo load limits if (Settings::values.random_amiibo_id) { Common::TinyMT rng{}; + rng.Initialize(static_cast(GetCurrentPosixTime())); rng.GenerateRandomBytes(uuid.data(), sizeof(UniqueSerialNumber)); uuid[3] = 0x88 ^ uuid[0] ^ uuid[1] ^ uuid[2]; } @@ -415,7 +413,7 @@ Result NfcDevice::Flush() { auto& settings = tag_data.settings; - const auto& current_date = GetAmiiboDate(current_posix_time); + const auto& current_date = GetAmiiboDate(GetCurrentPosixTime()); if (settings.write_date.raw_date != current_date.raw_date) { settings.write_date = current_date; UpdateSettingsCrc(); @@ -534,6 +532,7 @@ Result NfcDevice::GetModelInfo(NFP::ModelInfo& model_info) const { } const auto& model_info_data = encrypted_tag_data.user_memory.model_info; + model_info = { .character_id = model_info_data.character_id, .character_variant = model_info_data.character_variant, @@ -678,6 +677,7 @@ Result NfcDevice::DeleteRegisterInfo() { } Common::TinyMT rng{}; + rng.Initialize(static_cast(GetCurrentPosixTime())); rng.GenerateRandomBytes(&tag_data.owner_mii, sizeof(tag_data.owner_mii)); rng.GenerateRandomBytes(&tag_data.settings.amiibo_name, sizeof(tag_data.settings.amiibo_name)); rng.GenerateRandomBytes(&tag_data.unknown, sizeof(u8)); @@ -710,7 +710,7 @@ Result NfcDevice::SetRegisterInfoPrivate(const NFP::RegisterInfoPrivate& registe auto& settings = tag_data.settings; if (tag_data.settings.settings.amiibo_initialized == 0) { - settings.init_date = GetAmiiboDate(current_posix_time); + settings.init_date = GetAmiiboDate(GetCurrentPosixTime()); settings.write_date.raw_date = 0; } @@ -877,6 +877,7 @@ Result NfcDevice::SetApplicationArea(std::span data) { } Common::TinyMT rng{}; + rng.Initialize(static_cast(GetCurrentPosixTime())); std::memcpy(tag_data.application_area.data(), data.data(), data.size()); // Fill remaining data with random numbers rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), @@ -933,6 +934,7 @@ Result NfcDevice::RecreateApplicationArea(u32 access_id, std::span dat } Common::TinyMT rng{}; + rng.Initialize(static_cast(GetCurrentPosixTime())); std::memcpy(tag_data.application_area.data(), data.data(), data.size()); // Fill remaining data with random numbers rng.GenerateRandomBytes(tag_data.application_area.data() + data.size(), @@ -982,6 +984,7 @@ Result NfcDevice::DeleteApplicationArea() { } Common::TinyMT rng{}; + rng.Initialize(static_cast(GetCurrentPosixTime())); rng.GenerateRandomBytes(tag_data.application_area.data(), sizeof(NFP::ApplicationArea)); rng.GenerateRandomBytes(&tag_data.application_id, sizeof(u64)); rng.GenerateRandomBytes(&tag_data.application_area_id, sizeof(u32)); @@ -1198,6 +1201,11 @@ NFP::AmiiboDate NfcDevice::GetAmiiboDate(s64 posix_time) const { return amiibo_date; } +u64 NfcDevice::GetCurrentPosixTime() const { + auto& standard_steady_clock{system.GetTimeManager().GetStandardSteadyClockCore()}; + return standard_steady_clock.GetCurrentTimePoint(system).time_point; +} + u64 NfcDevice::RemoveVersionByte(u64 application_id) const { return application_id & ~(0xfULL << NFP::application_id_version_offset); } diff --git a/src/core/hle/service/nfc/common/device.h b/src/core/hle/service/nfc/common/device.h index 654eda98e3..98e1945c1f 100644 --- a/src/core/hle/service/nfc/common/device.h +++ b/src/core/hle/service/nfc/common/device.h @@ -105,6 +105,7 @@ private: NFP::AmiiboName GetAmiiboName(const NFP::AmiiboSettings& settings) const; void SetAmiiboName(NFP::AmiiboSettings& settings, const NFP::AmiiboName& amiibo_name); NFP::AmiiboDate GetAmiiboDate(s64 posix_time) const; + u64 GetCurrentPosixTime() const; u64 RemoveVersionByte(u64 application_id) const; void UpdateSettingsCrc(); void UpdateRegisterInfoCrc(); @@ -127,7 +128,6 @@ private: bool is_data_moddified{}; bool is_app_area_open{}; bool is_plain_amiibo{}; - s64 current_posix_time{}; NFP::MountTarget mount_target{NFP::MountTarget::None}; NFP::NTAG215File tag_data{};