mirror of
https://github.com/patchzyy/wiicompiled
synced 2026-09-13 09:59:47 -04:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 88b990b060 | |||
| e0e362bd99 |
@@ -281,7 +281,7 @@ foreach ($required in @('ToolkitFingerprint','TranslationFingerprint','NativeToo
|
|||||||
|
|
||||||
$manifest = [ordered]@{
|
$manifest = [ordered]@{
|
||||||
SchemaVersion = 2
|
SchemaVersion = 2
|
||||||
ProductVersion = '0.2.30'
|
ProductVersion = '0.2.31'
|
||||||
ExpectedGameId = $pins.GameId
|
ExpectedGameId = $pins.GameId
|
||||||
ExpectedDolSha256 = $pins.DolSha256
|
ExpectedDolSha256 = $pins.DolSha256
|
||||||
ExpectedRelSha256 = $pins.RelSha256
|
ExpectedRelSha256 = $pins.RelSha256
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>WiiCompiled.Setup.Common.Cli</RootNamespace>
|
<RootNamespace>WiiCompiled.Setup.Common.Cli</RootNamespace>
|
||||||
<AssemblyName>WiiCompiled.Setup.Common.Cli</AssemblyName>
|
<AssemblyName>WiiCompiled.Setup.Common.Cli</AssemblyName>
|
||||||
<Version>0.2.30</Version>
|
<Version>0.2.31</Version>
|
||||||
<Authors>patchzy</Authors>
|
<Authors>patchzy</Authors>
|
||||||
<Product>WiiCompiled</Product>
|
<Product>WiiCompiled</Product>
|
||||||
<Description>Packaging-time helper: resolves (downloading if needed) the nodtool binary bundled by build-appimage.sh and Build-Installer.ps1</Description>
|
<Description>Packaging-time helper: resolves (downloading if needed) the nodtool binary bundled by build-appimage.sh and Build-Installer.ps1</Description>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<RootNamespace>WiiCompiled.Setup.Common</RootNamespace>
|
<RootNamespace>WiiCompiled.Setup.Common</RootNamespace>
|
||||||
<AssemblyName>WiiCompiled.Setup.Common</AssemblyName>
|
<AssemblyName>WiiCompiled.Setup.Common</AssemblyName>
|
||||||
<Version>0.2.30</Version>
|
<Version>0.2.31</Version>
|
||||||
<Authors>patchzy</Authors>
|
<Authors>patchzy</Authors>
|
||||||
<Product>WiiCompiled</Product>
|
<Product>WiiCompiled</Product>
|
||||||
<Description>Shared nodtool/Retro-WFC-payload logic used by both the Windows and Linux installers</Description>
|
<Description>Shared nodtool/Retro-WFC-payload logic used by both the Windows and Linux installers</Description>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ namespace WiiCompiled.Setup.Linux;
|
|||||||
internal static class ProductInfo
|
internal static class ProductInfo
|
||||||
{
|
{
|
||||||
public const string Name = "WiiCompiled";
|
public const string Name = "WiiCompiled";
|
||||||
public const string Version = "0.2.30";
|
public const string Version = "0.2.31";
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>One installed product's record inside install-state.json.</summary>
|
/// <summary>One installed product's record inside install-state.json.</summary>
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<AssemblyName>WiiCompiled.Setup.Linux</AssemblyName>
|
<AssemblyName>WiiCompiled.Setup.Linux</AssemblyName>
|
||||||
<RootNamespace>WiiCompiled.Setup.Linux</RootNamespace>
|
<RootNamespace>WiiCompiled.Setup.Linux</RootNamespace>
|
||||||
<Version>0.2.30</Version>
|
<Version>0.2.31</Version>
|
||||||
<Authors>patchzy</Authors>
|
<Authors>patchzy</Authors>
|
||||||
<Product>WiiCompiled</Product>
|
<Product>WiiCompiled</Product>
|
||||||
<Description>Command-line installer and launcher for WiiCompiled on Linux</Description>
|
<Description>Command-line installer and launcher for WiiCompiled on Linux</Description>
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ internal static class PlatformChecks
|
|||||||
internal static class ProductInfo
|
internal static class ProductInfo
|
||||||
{
|
{
|
||||||
public const string Name = "WiiCompiled";
|
public const string Name = "WiiCompiled";
|
||||||
public const string Version = "0.2.30";
|
public const string Version = "0.2.31";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The setup executable is copied into the installation under this name. It is the launcher and
|
/// The setup executable is copied into the installation under this name. It is the launcher and
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<AssemblyName>WiiCompiled.Setup</AssemblyName>
|
<AssemblyName>WiiCompiled.Setup</AssemblyName>
|
||||||
<RootNamespace>WiiCompiled.Setup.Windows</RootNamespace>
|
<RootNamespace>WiiCompiled.Setup.Windows</RootNamespace>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
<Version>0.2.30</Version>
|
<Version>0.2.31</Version>
|
||||||
<Authors>patchzy</Authors>
|
<Authors>patchzy</Authors>
|
||||||
<Product>WiiCompiled</Product>
|
<Product>WiiCompiled</Product>
|
||||||
<Description>Command-line installer and launcher for WiiCompiled</Description>
|
<Description>Command-line installer and launcher for WiiCompiled</Description>
|
||||||
|
|||||||
@@ -289,6 +289,11 @@ target_include_directories(mkw_nand_settings_tests PRIVATE "${CMAKE_CURRENT_LIST
|
|||||||
target_compile_features(mkw_nand_settings_tests PRIVATE cxx_std_17)
|
target_compile_features(mkw_nand_settings_tests PRIVATE cxx_std_17)
|
||||||
add_test(NAME mkw_nand_settings_tests COMMAND mkw_nand_settings_tests)
|
add_test(NAME mkw_nand_settings_tests COMMAND mkw_nand_settings_tests)
|
||||||
|
|
||||||
|
add_executable(mkw_sc_serial_tests "${CMAKE_CURRENT_LIST_DIR}/tests/sc_serial_tests.cpp")
|
||||||
|
target_include_directories(mkw_sc_serial_tests PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include")
|
||||||
|
target_compile_features(mkw_sc_serial_tests PRIVATE cxx_std_17)
|
||||||
|
add_test(NAME mkw_sc_serial_tests COMMAND mkw_sc_serial_tests)
|
||||||
|
|
||||||
# The input expression engine is self-contained, so it can be exercised without
|
# The input expression engine is self-contained, so it can be exercised without
|
||||||
# linking the runtime or SDL.
|
# linking the runtime or SDL.
|
||||||
add_executable(mkw_input_expr_tests
|
add_executable(mkw_input_expr_tests
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <charconv>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstdint>
|
||||||
|
#include <string_view>
|
||||||
|
#include <system_error>
|
||||||
|
|
||||||
|
namespace RuntimeScSerial {
|
||||||
|
|
||||||
|
// SCGetProductSN's output is a u32, not a character buffer. DWC loads
|
||||||
|
// that word and formats it with the product code to construct csnum.
|
||||||
|
template <typename RangeValidator, typename WordWriter>
|
||||||
|
uint32_t Write(std::string_view serial, uint32_t address,
|
||||||
|
RangeValidator&& contains, WordWriter&& write32) {
|
||||||
|
if (serial.empty() || serial.size() > 9 ||
|
||||||
|
serial.find_first_not_of("0123456789") != std::string_view::npos) return 0;
|
||||||
|
uint32_t number = 0;
|
||||||
|
const auto parsed = std::from_chars(serial.data(), serial.data() + serial.size(), number);
|
||||||
|
if (parsed.ec != std::errc{} || parsed.ptr != serial.data() + serial.size() ||
|
||||||
|
!address || !contains(address, sizeof(uint32_t))) return 0;
|
||||||
|
write32(address, number);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace RuntimeScSerial
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "hle_stubs.h"
|
#include "hle_stubs.h"
|
||||||
|
|
||||||
#include "console_identity.h"
|
#include "console_identity.h"
|
||||||
|
#include "sc_serial_contract.h"
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -97,12 +98,9 @@ PPC_NATIVE_OVERRIDE(801B2424, SCGetProductCode_HLE, uint32_t, (), ());
|
|||||||
extern "C" uint32_t SCGetProductSN_HLE(uint32_t serialAddress)
|
extern "C" uint32_t SCGetProductSN_HLE(uint32_t serialAddress)
|
||||||
{
|
{
|
||||||
const std::string& serial = RuntimeConsoleIdentity::Current().serial;
|
const std::string& serial = RuntimeConsoleIdentity::Current().serial;
|
||||||
if (!serialAddress || !Memory::Contains(serialAddress, serial.size() + 1)) {
|
return RuntimeScSerial::Write(serial, serialAddress,
|
||||||
return 0;
|
[](uint32_t address, size_t size) { return Memory::Contains(address, size); },
|
||||||
}
|
[](uint32_t address, uint32_t value) { Memory::Write32(address, value); });
|
||||||
std::memcpy(Memory::GetPointer(serialAddress, serial.size() + 1),
|
|
||||||
serial.c_str(), serial.size() + 1);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PPC_NATIVE_OVERRIDE(801B2460, SCGetProductSN_HLE, uint32_t, (uint32_t serialAddress), (serialAddress));
|
PPC_NATIVE_OVERRIDE(801B2460, SCGetProductSN_HLE, uint32_t, (uint32_t serialAddress), (serialAddress));
|
||||||
|
|||||||
@@ -0,0 +1,81 @@
|
|||||||
|
#include "sc_serial_contract.h"
|
||||||
|
#include "nand_settings.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
static void Require(bool condition, const char* message) {
|
||||||
|
if (!condition) throw std::runtime_error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint32_t ReadWord(const unsigned char* bytes) {
|
||||||
|
return (uint32_t(bytes[0]) << 24) | (uint32_t(bytes[1]) << 16) |
|
||||||
|
(uint32_t(bytes[2]) << 8) | uint32_t(bytes[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
try {
|
||||||
|
// Feed real generator + SC ABI outputs to the upstream bot decoder.
|
||||||
|
// Usage: mkw_sc_serial_tests --timestamp-vectors <unix-seconds> ...
|
||||||
|
if (argc > 1 && std::string(argv[1]) == "--timestamp-vectors") {
|
||||||
|
for (int i = 2; i < argc; ++i) {
|
||||||
|
const auto timestamp = std::stoll(argv[i]);
|
||||||
|
const auto serial = RuntimeNandSettings::GenerateSerial(static_cast<std::time_t>(timestamp));
|
||||||
|
std::array<unsigned char, 4> output{};
|
||||||
|
Require(RuntimeScSerial::Write(serial, 4,
|
||||||
|
[](uint32_t address, size_t size) { return address == 4 && size == 4; },
|
||||||
|
[&](uint32_t, uint32_t value) {
|
||||||
|
for (unsigned j = 0; j < 4; ++j)
|
||||||
|
output[j] = static_cast<unsigned char>(value >> (24 - 8 * j));
|
||||||
|
}) == 1, "Generated serial must pass SC ABI");
|
||||||
|
std::cout << timestamp << '\t' << serial << "\tLEH"
|
||||||
|
<< std::setfill('0') << std::setw(9) << ReadWord(output.data()) << '\n';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// Reproduce the reported csnums from the old string-writing override.
|
||||||
|
const unsigned char old7886[] = {'7', '8', '8', '6'};
|
||||||
|
const unsigned char old7618[] = {'7', '6', '1', '8'};
|
||||||
|
Require(ReadWord(old7886) == 926431286, "Reproduce shared LEH926431286");
|
||||||
|
Require(ReadWord(old7618) == 926298424, "Reproduce shared LEH926298424");
|
||||||
|
|
||||||
|
std::array<unsigned char, 16> memory;
|
||||||
|
size_t available = 4;
|
||||||
|
unsigned writes = 0;
|
||||||
|
const auto contains = [&](uint32_t address, size_t size) {
|
||||||
|
return address == 4 && size <= available;
|
||||||
|
};
|
||||||
|
const auto write32 = [&](uint32_t address, uint32_t value) {
|
||||||
|
++writes;
|
||||||
|
for (unsigned i = 0; i < 4; ++i)
|
||||||
|
memory[address + i] = static_cast<unsigned char>(value >> (24 - 8 * i));
|
||||||
|
};
|
||||||
|
for (const auto& pair : {std::pair{"788600001", 788600001u}, {"788699999", 788699999u},
|
||||||
|
{"761800001", 761800001u}, {"761899999", 761899999u},
|
||||||
|
{"012345678", 12345678u}, {"000000001", 1u}, {"999999999", 999999999u}}) {
|
||||||
|
memory.fill(0xa5);
|
||||||
|
writes = 0;
|
||||||
|
Require(RuntimeScSerial::Write(pair.first, 4, contains, write32) == 1, "Accept an exactly four-byte output buffer");
|
||||||
|
Require(writes == 1 && ReadWord(memory.data() + 4) == pair.second, "Return full numeric serial, including digits after common prefix");
|
||||||
|
for (size_t i = 0; i < memory.size(); ++i)
|
||||||
|
if (i < 4 || i >= 8) Require(memory[i] == 0xa5, "Do not overwrite adjacent guest stack data");
|
||||||
|
}
|
||||||
|
for (const char* serial : {"", "1234567890", "7886x1234", "-12345678", "+12345678"}) {
|
||||||
|
writes = 0;
|
||||||
|
Require(RuntimeScSerial::Write(serial, 4, contains, write32) == 0 && writes == 0, "Reject malformed serial without a write");
|
||||||
|
}
|
||||||
|
writes = 0;
|
||||||
|
Require(RuntimeScSerial::Write("788600001", 0, contains, write32) == 0 && writes == 0, "Reject null output");
|
||||||
|
available = 3;
|
||||||
|
Require(RuntimeScSerial::Write("788600001", 4, contains, write32) == 0 && writes == 0, "Reject undersized output");
|
||||||
|
std::cout << "SC serial collision reproduction, numeric output and memory-boundary tests passed\n";
|
||||||
|
return 0;
|
||||||
|
} catch (const std::exception& error) {
|
||||||
|
std::cerr << error.what() << '\n';
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user