From 953dda9cc137895958b0350ca5dfc69fe96d1ab5 Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 14 Feb 2026 21:49:30 +0000 Subject: [PATCH] generate battery serial as well --- docs/user/Native.md | 5 +- .../service/set/system_settings_server.cpp | 80 +++++++++++-------- src/frontend_common/settings_generator.cpp | 11 +-- 3 files changed, 54 insertions(+), 42 deletions(-) diff --git a/docs/user/Native.md b/docs/user/Native.md index ec1cd02253..0d8ee81a7a 100644 --- a/docs/user/Native.md +++ b/docs/user/Native.md @@ -6,7 +6,4 @@ Debugging on physical hardware can get tedious and time consuming. Users are emp **Standard key prefix**: Allows to redirect the key manager to a file other than `prod.keys` (for example `other` would redirect to `other.keys`). This is useful for testing multiple keysets. Default is `prod`. -**Changing serial**: Very basic way to set debug values for the serial (and battery number). Developers do not need to write the full serial as it will be writen in-place (that is, it will be filled with the default serial and then overwrite the serial from the beginning). -- Battery serial: `YUZU0EMULATOR14022024` -- Board serial: `YUZ10000000001` -If the user were to set their board serial as `ABC`, then it will be written in-place and the resulting serial would be `ABC10000000001`. There are no underlying checks to ensure correctness of serials other than a hard limit of 16-characters for both. +**Changing serial**: Very basic way to set debug values for the serial (and battery number). Developers do not need to write the full serial as only the first digits (excluding the last) will be accoutned for. Region settings will affect the generated serial. The serial corresponds to a non-OLED/Lite console. diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 31bca55d5b..e0dbe7f3a5 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -980,19 +980,7 @@ Result ISystemSettingsServer::SetPrimaryAlbumStorage(PrimaryAlbumStorage primary R_SUCCEED(); } -Result ISystemSettingsServer::GetBatteryLot(Out out_battery_lot) { - LOG_INFO(Service_SET, "called"); - *out_battery_lot = {"YUZU0EMULATOR14022024"}; - // if (auto const s = ::Settings::values.serial_battery.GetValue(); !s.empty()) { - // auto const max_size = out_battery_lot->lot_number.size(); - // auto const end = s.size() > max_size ? s.begin() + max_size : s.end(); - // std::copy(s.begin(), end, out_battery_lot->lot_number.begin()); - // } - R_SUCCEED(); -} - -static SerialNumber GenerateSerialNumber(u32 d) { - SerialNumber c{}; +void Fill3DS_CRC(u32 d, char* data) { std::array digits = { u8((d / 1000000000) % 100), u8((d / 100000000) % 10), @@ -1009,24 +997,9 @@ static SerialNumber GenerateSerialNumber(u32 d) { std::array retail_digits = { 1, 4, 5, 7 }; digits[0] = retail_digits[(d % 10) % 4]; digits[1] = 0; - - c.serial_number[0] = 'X'; - c.serial_number[1] = 'A'; - c.serial_number[2] = [] { - // Adding another setting would be tedious so... let's just reuse region_index :) - switch (::Settings::values.region_index.GetValue()) { - case ::Settings::Region::Japan: return 'J'; - case ::Settings::Region::Usa: return 'W'; - case ::Settings::Region::Europe: return 'E'; - case ::Settings::Region::Australia: return 'M'; //pretend its Malaysia - case ::Settings::Region::China: - case ::Settings::Region::Taiwan: return 'C'; - case ::Settings::Region::Korea: return 'K'; - default: return 'W'; - } - }(); + // for (size_t i = 0; i < sizeof(digits); ++i) - c.serial_number[3 + i] = digits[i] + '0'; + data[i] = digits[i] + '0'; u8 sum_odd = 0, sum_even = 0; for (size_t i = 0; i < sizeof(digits); i += 2) { sum_odd += digits[i + 0]; @@ -1035,13 +1008,54 @@ static SerialNumber GenerateSerialNumber(u32 d) { u8 sum_digit = ((sum_even * 3) + sum_odd) % 10; if (sum_digit != 0) sum_digit = 10 - sum_digit; - c.serial_number[3 + sizeof(digits)] = sum_digit + '0'; - return c; + data[sizeof(digits)] = sum_digit + '0'; +} + +Result ISystemSettingsServer::GetBatteryLot(Out out_battery_lot) { + LOG_INFO(Service_SET, "called"); + *out_battery_lot = []{ + u32 d = ::Settings::values.serial_battery.GetValue(); + BatteryLot c{}; + c.lot_number[0] = 'B'; + c.lot_number[1] = 'H'; + c.lot_number[2] = 'A'; + c.lot_number[3] = 'C'; + // TODO: I have no fucking idea what the letters mean + c.lot_number[4] = 'H'; + c.lot_number[5] = 'Z'; + c.lot_number[6] = 'Z'; + c.lot_number[7] = 'A'; + c.lot_number[8] = 'D'; + c.lot_number[9] = u8((d / 100000) % 26) + 'A'; + Fill3DS_CRC(d, c.lot_number.data() + 10); + return c; + }(); + R_SUCCEED(); } Result ISystemSettingsServer::GetSerialNumber(Out out_console_serial) { LOG_INFO(Service_SET, "called"); - *out_console_serial = GenerateSerialNumber(::Settings::values.serial_unit.GetValue()); + *out_console_serial = []{ + u32 d = ::Settings::values.serial_unit.GetValue(); + SerialNumber c{}; + c.serial_number[0] = 'X'; + c.serial_number[1] = 'A'; + c.serial_number[2] = [] { + // Adding another setting would be tedious so... let's just reuse region_index :) + switch (::Settings::values.region_index.GetValue()) { + case ::Settings::Region::Japan: return 'J'; + case ::Settings::Region::Usa: return 'W'; + case ::Settings::Region::Europe: return 'E'; + case ::Settings::Region::Australia: return 'M'; //pretend its Malaysia + case ::Settings::Region::China: + case ::Settings::Region::Taiwan: return 'C'; + case ::Settings::Region::Korea: return 'K'; + default: return 'W'; + } + }(); + Fill3DS_CRC(d, c.serial_number.data() + 3); + return c; + }(); R_SUCCEED(); } diff --git a/src/frontend_common/settings_generator.cpp b/src/frontend_common/settings_generator.cpp index c3d4750649..46625656b1 100644 --- a/src/frontend_common/settings_generator.cpp +++ b/src/frontend_common/settings_generator.cpp @@ -27,12 +27,13 @@ void GenerateSettings() { // Randomly generated number because, well, we fill the rest automagically ;) // Other serial parts are filled by Region_Index - if (Settings::values.serial_unit.GetValue() == 0) { - std::random_device device; - std::mt19937 gen(device()); - std::uniform_int_distribution distribution(1, (std::numeric_limits::max)()); + std::random_device device; + std::mt19937 gen(device()); + std::uniform_int_distribution distribution(1, (std::numeric_limits::max)()); + if (Settings::values.serial_unit.GetValue() == 0) Settings::values.serial_unit.SetValue(distribution(gen)); - } + if (Settings::values.serial_battery.GetValue() == 0) + Settings::values.serial_battery.SetValue(distribution(gen)); } }