Przeglądaj źródła

Create a random console_unique_id (#2668)

* Create a random console_id when config save_file is created

Added button in system config to refresh the console unique id

* Moved the connect for the button from .ui file to constructor of ConfigureSystem

* Added warning and info dialog
Fixup: Make use of qt5 style connects,
  renamed the refresh button,
  removed some duplicate code,
  changed random device and moved all to the generate function

* Changed the random generator to reflect what a real 3DS stores as console unique id
Fixup: Changed the warning message

* Fixup: Set and Create

* Fixup: Added console id label, therfore removed second message box

* Fixup: fixed the endianess

* Fixup: more endianness fixes

* Fixup: Endianness the 3rd
B3n30 9 lat temu
rodzic
commit
8bee016145

+ 28 - 2
src/citra_qt/configuration/configure_system.cpp

@@ -2,6 +2,7 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <QMessageBox>
 #include "citra_qt/configuration/configure_system.h"
 #include "citra_qt/ui_settings.h"
 #include "core/core.h"
@@ -15,8 +16,11 @@ static const std::array<int, 12> days_in_month = {{
 
 ConfigureSystem::ConfigureSystem(QWidget* parent) : QWidget(parent), ui(new Ui::ConfigureSystem) {
     ui->setupUi(this);
-    connect(ui->combo_birthmonth, SIGNAL(currentIndexChanged(int)),
-            SLOT(updateBirthdayComboBox(int)));
+    connect(ui->combo_birthmonth,
+            static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+            &ConfigureSystem::updateBirthdayComboBox);
+    connect(ui->button_regenerate_console_id, &QPushButton::clicked, this,
+            &ConfigureSystem::refreshConsoleID);
 
     this->setConfiguration();
 }
@@ -71,6 +75,10 @@ void ConfigureSystem::ReadSystemSettings() {
     // set sound output mode
     sound_index = Service::CFG::GetSoundOutputMode();
     ui->combo_sound->setCurrentIndex(sound_index);
+
+    // set the console id
+    u64 console_id = Service::CFG::GetConsoleUniqueId();
+    ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper());
 }
 
 void ConfigureSystem::applyConfiguration() {
@@ -140,3 +148,21 @@ void ConfigureSystem::updateBirthdayComboBox(int birthmonth_index) {
     // restore the day selection
     ui->combo_birthday->setCurrentIndex(birthday_index);
 }
+
+void ConfigureSystem::refreshConsoleID() {
+    QMessageBox::StandardButton reply;
+    QString warning_text = tr("This will replace your current virtual 3DS with a new one. "
+                              "Your current virtual 3DS will not be recoverable. "
+                              "This might have unexpected effects in games. This might fail, "
+                              "if you use an outdated config savegame. Continue?");
+    reply = QMessageBox::critical(this, tr("Warning"), warning_text,
+                                  QMessageBox::No | QMessageBox::Yes);
+    if (reply == QMessageBox::No)
+        return;
+    u32 random_number;
+    u64 console_id;
+    Service::CFG::GenerateConsoleUniqueId(random_number, console_id);
+    Service::CFG::SetConsoleUniqueId(random_number, console_id);
+    Service::CFG::UpdateConfigNANDSavegame();
+    ui->label_console_id->setText("Console ID: 0x" + QString::number(console_id, 16).toUpper());
+}

+ 1 - 0
src/citra_qt/configuration/configure_system.h

@@ -23,6 +23,7 @@ public:
 
 public slots:
     void updateBirthdayComboBox(int birthmonth_index);
+    void refreshConsoleID();
 
 private:
     void ReadSystemSettings();

+ 23 - 0
src/citra_qt/configuration/configure_system.ui

@@ -220,6 +220,29 @@
           </item>
          </widget>
         </item>
+        <item row="4" column="0">
+         <widget class="QLabel" name="label_console_id">
+          <property name="text">
+           <string>Console ID:</string>
+          </property>
+         </widget>
+        </item>
+        <item row="4" column="1">
+         <widget class="QPushButton" name="button_regenerate_console_id">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="layoutDirection">
+           <enum>Qt::RightToLeft</enum>
+          </property>
+          <property name="text">
+           <string>Regenerate</string>
+          </property>
+         </widget>
+        </item>
        </layout>
       </widget>
      </item>

+ 50 - 5
src/core/hle/service/cfg/cfg.cpp

@@ -4,6 +4,7 @@
 
 #include <algorithm>
 #include <array>
+#include <cryptopp/osrng.h>
 #include <cryptopp/sha.h>
 #include "common/file_util.h"
 #include "common/logging/log.h"
@@ -50,6 +51,7 @@ enum ConfigBlockID {
     SoundOutputModeBlockID = 0x00070001,
     ConsoleUniqueID1BlockID = 0x00090000,
     ConsoleUniqueID2BlockID = 0x00090001,
+    ConsoleUniqueID3BlockID = 0x00090002,
     UsernameBlockID = 0x000A0000,
     BirthdayBlockID = 0x000A0001,
     LanguageBlockID = 0x000A0002,
@@ -86,7 +88,6 @@ struct ConsoleCountryInfo {
 static_assert(sizeof(ConsoleCountryInfo) == 4, "ConsoleCountryInfo must be exactly 4 bytes");
 }
 
-static const u64 CONSOLE_UNIQUE_ID = 0xDEADC0DE;
 static const ConsoleModelInfo CONSOLE_MODEL = {NINTENDO_3DS_XL, {0, 0, 0}};
 static const u8 CONSOLE_LANGUAGE = LANGUAGE_EN;
 static const UsernameBlock CONSOLE_USERNAME_BLOCK = {u"CITRA", 0, 0};
@@ -438,13 +439,22 @@ ResultCode FormatConfig() {
     if (!res.IsSuccess())
         return res;
 
-    res = CreateConfigInfoBlk(ConsoleUniqueID1BlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE,
-                              &CONSOLE_UNIQUE_ID);
+    u32 random_number;
+    u64 console_id;
+    GenerateConsoleUniqueId(random_number, console_id);
+
+    u64_le console_id_le = console_id;
+    res = CreateConfigInfoBlk(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le);
     if (!res.IsSuccess())
         return res;
 
-    res = CreateConfigInfoBlk(ConsoleUniqueID2BlockID, sizeof(CONSOLE_UNIQUE_ID), 0xE,
-                              &CONSOLE_UNIQUE_ID);
+    res = CreateConfigInfoBlk(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le);
+    if (!res.IsSuccess())
+        return res;
+
+    u32_le random_number_le = random_number;
+    res = CreateConfigInfoBlk(ConsoleUniqueID3BlockID, sizeof(random_number_le), 0xE,
+                              &random_number_le);
     if (!res.IsSuccess())
         return res;
 
@@ -663,5 +673,40 @@ SoundOutputMode GetSoundOutputMode() {
     return static_cast<SoundOutputMode>(block);
 }
 
+void GenerateConsoleUniqueId(u32& random_number, u64& console_id) {
+    CryptoPP::AutoSeededRandomPool rng;
+    random_number = rng.GenerateWord32(0, 0xFFFF);
+    u64_le local_friend_code_seed;
+    rng.GenerateBlock(reinterpret_cast<byte*>(&local_friend_code_seed),
+                      sizeof(local_friend_code_seed));
+    console_id = (local_friend_code_seed & 0x3FFFFFFFF) | (static_cast<u64>(random_number) << 48);
+}
+
+ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id) {
+    u64_le console_id_le = console_id;
+    ResultCode res =
+        SetConfigInfoBlock(ConsoleUniqueID1BlockID, sizeof(console_id_le), 0xE, &console_id_le);
+    if (!res.IsSuccess())
+        return res;
+
+    res = SetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le);
+    if (!res.IsSuccess())
+        return res;
+
+    u32_le random_number_le = random_number;
+    res = SetConfigInfoBlock(ConsoleUniqueID3BlockID, sizeof(random_number_le), 0xE,
+                             &random_number_le);
+    if (!res.IsSuccess())
+        return res;
+
+    return RESULT_SUCCESS;
+}
+
+u64 GetConsoleUniqueId() {
+    u64_le console_id_le;
+    GetConfigInfoBlock(ConsoleUniqueID2BlockID, sizeof(console_id_le), 0xE, &console_id_le);
+    return console_id_le;
+}
+
 } // namespace CFG
 } // namespace Service

+ 21 - 0
src/core/hle/service/cfg/cfg.h

@@ -342,5 +342,26 @@ void SetSoundOutputMode(SoundOutputMode mode);
  */
 SoundOutputMode GetSoundOutputMode();
 
+/**
+ * Generates a new random console unique id.
+ * @param random_number a random generated 16bit number stored at 0x90002, used for generating the
+ * console_id
+ * @param console_id the randomly created console id
+ */
+void GenerateConsoleUniqueId(u32& random_number, u64& console_id);
+
+/**
+ * Sets the random_number and the  console unique id in the config savegame.
+ * @param random_number the random_number to set
+ * @param console_id the console id to set
+ */
+ResultCode SetConsoleUniqueId(u32 random_number, u64 console_id);
+
+/**
+ * Gets the console unique id from config savegame.
+ * @returns the console unique id
+ */
+u64 GetConsoleUniqueId();
+
 } // namespace CFG
 } // namespace Service