[common] autogenerate unique console serial for every install

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2026-02-14 20:12:49 +00:00
parent 19e2dba35a
commit 438c848a25
4 changed files with 69 additions and 25 deletions

View File

@ -620,11 +620,11 @@ struct Values {
"language_index",
Category::System};
SwitchableSetting<Region, true> region_index{linkage, Region::Usa, "region_index", Category::System};
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto,
"time_zone_index", Category::System};
SwitchableSetting<TimeZone, true> time_zone_index{linkage, TimeZone::Auto, "time_zone_index", Category::System};
Setting<u32> serial_battery{linkage, 0, "serial_battery", Category::System};
Setting<u32> serial_unit{linkage, 0, "serial_unit", Category::System};
// Measured in seconds since epoch
SwitchableSetting<bool> custom_rtc_enabled{
linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
SwitchableSetting<bool> custom_rtc_enabled{linkage, false, "custom_rtc_enabled", Category::System, Specialization::Paired, true, true};
SwitchableSetting<s64> custom_rtc{
linkage, 0, "custom_rtc", Category::System, Specialization::Time,
false, true, &custom_rtc_enabled};
@ -794,8 +794,6 @@ struct Values {
true};
// Miscellaneous
Setting<std::string> serial_battery{linkage, std::string(), "serial_battery", Category::Miscellaneous};
Setting<std::string> serial_unit{linkage, std::string(), "serial_unit", Category::Miscellaneous};
Setting<std::string> log_filter{linkage, "*:Info", "log_filter", Category::Miscellaneous};
Setting<bool> log_flush_line{linkage, false, "flush_line", Category::Miscellaneous, Specialization::Default, true, true};
Setting<bool> censor_username{linkage, true, "censor_username", Category::Miscellaneous};

View File

@ -983,22 +983,65 @@ Result ISystemSettingsServer::SetPrimaryAlbumStorage(PrimaryAlbumStorage primary
Result ISystemSettingsServer::GetBatteryLot(Out<BatteryLot> 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());
}
// 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{};
std::array<u8, 10> digits = {
u8((d / 1000000000) % 100),
u8((d / 100000000) % 10),
u8((d / 10000000) % 10),
u8((d / 1000000) % 10),
u8((d / 100000) % 10),
u8((d / 10000) % 10),
u8((d / 1000) % 10),
u8((d / 100) % 10),
u8((d / 10) % 10),
u8(d % 10),
};
// Normalize to retail values
std::array<u8, 4> 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';
u8 sum_odd = 0, sum_even = 0;
for (size_t i = 0; i < sizeof(digits); i += 2) {
sum_odd += digits[i + 0];
sum_even += digits[i + 1];
}
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;
}
Result ISystemSettingsServer::GetSerialNumber(Out<SerialNumber> out_console_serial) {
LOG_INFO(Service_SET, "called");
*out_console_serial = {"YUZ10000000001"};
if (auto const s = ::Settings::values.serial_unit.GetValue(); !s.empty()) {
auto const max_size = out_console_serial->serial_number.size();
auto const end = s.size() > max_size ? s.begin() + max_size : s.end();
std::copy(s.begin(), end, out_console_serial->serial_number.begin());
}
*out_console_serial = GenerateSerialNumber(::Settings::values.serial_unit.GetValue());
R_SUCCEED();
}

View File

@ -11,9 +11,8 @@ namespace FrontendCommon {
void GenerateSettings() {
static std::random_device rd;
// Web Token //
auto &token_setting = Settings::values.eden_token;
if (token_setting.GetValue().empty()) {
// Web Token
if (Settings::values.eden_token.GetValue().empty()) {
static constexpr const size_t token_length = 48;
static constexpr const frozen::string token_set = "abcdefghijklmnopqrstuvwxyz";
static std::uniform_int_distribution<int> token_dist(0, token_set.size() - 1);
@ -23,8 +22,16 @@ void GenerateSettings() {
size_t idx = token_dist(rd);
result += token_set[idx];
}
Settings::values.eden_token.SetValue(result);
}
token_setting.SetValue(result);
// 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<u32> distribution(1, (std::numeric_limits<u32>::max)());
Settings::values.serial_unit.SetValue(distribution(gen));
}
}

View File

@ -57,10 +57,6 @@ void ConfigureDebug::SetConfiguration() {
#endif
// Immutable after starting
ui->serial_battery_edit->setEnabled(runtime_lock);
ui->serial_battery_edit->setText(QString::fromStdString(Settings::values.serial_battery.GetValue()));
ui->serial_board_edit->setEnabled(runtime_lock);
ui->serial_board_edit->setText(QString::fromStdString(Settings::values.serial_unit.GetValue()));
ui->homebrew_args_edit->setEnabled(runtime_lock);
ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args.GetValue()));
ui->toggle_console->setEnabled(runtime_lock);