mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-09-10 17:16:47 -04:00
84 lines
2.3 KiB
C++
84 lines
2.3 KiB
C++
#pragma once
|
|
|
|
#include "nand_path.h"
|
|
#include "nand_settings.h"
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <iomanip>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include <utility>
|
|
|
|
namespace RuntimeConsoleIdentity {
|
|
|
|
struct Identity {
|
|
std::string serial;
|
|
std::string productCode;
|
|
std::string area;
|
|
std::string gameRegion;
|
|
std::array<uint8_t, 6> mac;
|
|
};
|
|
|
|
inline Identity FromSerial(std::string serial) {
|
|
// Keep Nintendo's Wii OUI. The suffix is derived from the NAND serial
|
|
// so every API exposes one coherent, stable virtual-console identity.
|
|
uint32_t hash = 2166136261u;
|
|
for (const unsigned char value : serial) {
|
|
hash ^= value;
|
|
hash *= 16777619u;
|
|
}
|
|
uint32_t suffix = hash & 0x00FFFFFFu;
|
|
if (suffix == 0 || suffix == 0x00FFFFFFu) {
|
|
suffix ^= 0x005A17C3u;
|
|
}
|
|
|
|
return {
|
|
std::move(serial),
|
|
{}, {}, {},
|
|
{
|
|
0x00,
|
|
0x09,
|
|
0xBF,
|
|
static_cast<uint8_t>(suffix >> 16),
|
|
static_cast<uint8_t>(suffix >> 8),
|
|
static_cast<uint8_t>(suffix),
|
|
},
|
|
};
|
|
}
|
|
|
|
inline Identity LoadFromNand() {
|
|
const auto root = RuntimeNandPath::DiscoverNandRootPath();
|
|
const auto settings = RuntimeNandSettings::Read(root);
|
|
if (!settings || !RuntimeNandSettings::HasIdentity(*settings)) {
|
|
RuntimeNandPath::FailNandRoot(
|
|
"NAND setting.txt is missing or has invalid console identity fields (SERNO, CODE, AREA, GAME)",
|
|
root / "title/00000001/00000002/data/setting.txt");
|
|
}
|
|
Identity identity = FromSerial(settings->at("SERNO"));
|
|
identity.productCode = settings->at("CODE");
|
|
identity.area = settings->at("AREA");
|
|
identity.gameRegion = settings->at("GAME");
|
|
return identity;
|
|
}
|
|
|
|
inline const Identity& Current() {
|
|
static const Identity identity = LoadFromNand();
|
|
return identity;
|
|
}
|
|
|
|
inline std::string FormatMac(const std::array<uint8_t, 6>& mac) {
|
|
std::ostringstream output;
|
|
output << std::uppercase << std::hex << std::setfill('0');
|
|
for (size_t index = 0; index < mac.size(); ++index) {
|
|
if (index != 0) {
|
|
output << ':';
|
|
}
|
|
output << std::setw(2) << static_cast<unsigned>(mac[index]);
|
|
}
|
|
return output.str();
|
|
}
|
|
|
|
} // namespace RuntimeConsoleIdentity
|