Merge pull request #10207 from german77/amiibo_cheater
service: nfp: Allow to load with a different amiibo id
This commit is contained in:
		@@ -535,6 +535,8 @@ struct Values {
 | 
			
		||||
    Setting<bool> enable_ir_sensor{false, "enable_ir_sensor"};
 | 
			
		||||
    Setting<std::string> ir_sensor_device{"auto", "ir_sensor_device"};
 | 
			
		||||
 | 
			
		||||
    Setting<bool> random_amiibo_id{false, "random_amiibo_id"};
 | 
			
		||||
 | 
			
		||||
    // Data Storage
 | 
			
		||||
    Setting<bool> use_virtual_sd{true, "use_virtual_sd"};
 | 
			
		||||
    Setting<bool> gamecard_inserted{false, "gamecard_inserted"};
 | 
			
		||||
 
 | 
			
		||||
@@ -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() {
 | 
			
		||||
@@ -227,11 +224,21 @@ 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.Initialize(static_cast<u32>(GetCurrentPosixTime()));
 | 
			
		||||
        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<u8>(encrypted_tag_data.uuid.uid.size()),
 | 
			
		||||
            .uuid_length = static_cast<u8>(uuid.size()),
 | 
			
		||||
            .protocol = NfcProtocol::TypeA,
 | 
			
		||||
            .tag_type = TagType::Type4,
 | 
			
		||||
        };
 | 
			
		||||
@@ -240,9 +247,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<u8>(encrypted_tag_data.uuid.uid.size()),
 | 
			
		||||
        .uuid_length = static_cast<u8>(uuid.size()),
 | 
			
		||||
        .protocol = NfcProtocol::TypeA,
 | 
			
		||||
        .tag_type = TagType::Type2,
 | 
			
		||||
    };
 | 
			
		||||
@@ -406,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();
 | 
			
		||||
@@ -525,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,
 | 
			
		||||
@@ -669,6 +677,7 @@ Result NfcDevice::DeleteRegisterInfo() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Common::TinyMT rng{};
 | 
			
		||||
    rng.Initialize(static_cast<u32>(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));
 | 
			
		||||
@@ -701,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;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -868,6 +877,7 @@ Result NfcDevice::SetApplicationArea(std::span<const u8> data) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Common::TinyMT rng{};
 | 
			
		||||
    rng.Initialize(static_cast<u32>(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(),
 | 
			
		||||
@@ -924,6 +934,7 @@ Result NfcDevice::RecreateApplicationArea(u32 access_id, std::span<const u8> dat
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Common::TinyMT rng{};
 | 
			
		||||
    rng.Initialize(static_cast<u32>(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(),
 | 
			
		||||
@@ -973,6 +984,7 @@ Result NfcDevice::DeleteApplicationArea() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Common::TinyMT rng{};
 | 
			
		||||
    rng.Initialize(static_cast<u32>(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));
 | 
			
		||||
@@ -1189,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);
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -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{};
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -2728,6 +2728,22 @@
 | 
			
		||||
                     </widget>
 | 
			
		||||
                   </item>
 | 
			
		||||
                   <item row="7" column="0">
 | 
			
		||||
                     <widget class="QCheckBox" name="random_amiibo_id">
 | 
			
		||||
                       <property name="toolTip">
 | 
			
		||||
                         <string>Allows unlimited uses of the same Amiibo in games that would otherwise limit you to one use.</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="minimumSize">
 | 
			
		||||
                         <size>
 | 
			
		||||
                           <width>0</width>
 | 
			
		||||
                           <height>23</height>
 | 
			
		||||
                         </size>
 | 
			
		||||
                       </property>
 | 
			
		||||
                       <property name="text">
 | 
			
		||||
                         <string>Use random Amiibo ID</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                     </widget>
 | 
			
		||||
                   </item>
 | 
			
		||||
                   <item row="8" column="0">
 | 
			
		||||
                     <widget class="QCheckBox" name="mouse_panning">
 | 
			
		||||
                       <property name="minimumSize">
 | 
			
		||||
                         <size>
 | 
			
		||||
@@ -2740,7 +2756,7 @@
 | 
			
		||||
                       </property>
 | 
			
		||||
                     </widget>
 | 
			
		||||
                   </item>
 | 
			
		||||
                   <item row="7" column="2">
 | 
			
		||||
                   <item row="8" column="2">
 | 
			
		||||
                     <widget class="QSpinBox" name="mouse_panning_sensitivity">
 | 
			
		||||
                       <property name="toolTip">
 | 
			
		||||
                         <string>Mouse sensitivity</string>
 | 
			
		||||
@@ -2762,14 +2778,14 @@
 | 
			
		||||
                       </property>
 | 
			
		||||
                     </widget>
 | 
			
		||||
                   </item>
 | 
			
		||||
                   <item row="8" column="0">
 | 
			
		||||
                   <item row="9" column="0">
 | 
			
		||||
                     <widget class="QLabel" name="motion_touch">
 | 
			
		||||
                       <property name="text">
 | 
			
		||||
                         <string>Motion / Touch</string>
 | 
			
		||||
                       </property>
 | 
			
		||||
                     </widget>
 | 
			
		||||
                   </item>
 | 
			
		||||
                   <item row="8" column="2">
 | 
			
		||||
                   <item row="9" column="2">
 | 
			
		||||
                     <widget class="QPushButton" name="buttonMotionTouch">
 | 
			
		||||
                       <property name="text">
 | 
			
		||||
                         <string>Configure</string>
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user