using System.Text.Json.Serialization;
using WiiCompiled.Setup.Common;
namespace WiiCompiled.Setup.Windows;
internal enum RetroWfcPayloadMode
{
NotApplicable,
Online,
Skipped
}
internal sealed class InstallOptions
{
public required string GamePath { get; init; }
///
/// The canonical Retro Rewind installation Wheel Wizard owns. Its resolved path is recorded as
/// retro_rewind_root; only its compile inputs are ever snapshotted.
///
public string? RetroDirectoryPath { get; init; }
public RetroWfcPayloadMode RetroWfcPayloadMode { get; init; }
public required string InstallDirectory { get; init; }
///
/// Establish a portable installation: the parent of becomes the
/// portable root, gets the portable.txt marker and a UserData directory, and all
/// runtime user state and [paths] settings stay inside it.
///
public bool Portable { get; init; }
public bool HasRetroRewind => RetroDirectoryPath is not null;
}
internal sealed class PayloadManifest
{
public int SchemaVersion { get; set; }
public string ProductVersion { get; set; } = "";
public string ExpectedGameId { get; set; } = "RMCP01";
public string ExpectedDolSha256 { get; set; } = "";
public string ExpectedRelSha256 { get; set; } = "";
public string ToolkitReleaseTag { get; set; } = "";
public string BuildModel { get; set; } = "";
public string RetroWfcPayloadUri { get; set; } = "";
///
/// Content identities computed once at release-build time (Build-Installer.ps1 --emit-payload-identities)
/// so install doesn't re-hash gigabytes per user; compilation alone re-derives the toolkit identity from disk.
///
public string ToolkitFingerprint { get; set; } = "";
public string ToolkitPackageFingerprint { get; set; } = "";
public string RuntimeAssetsFingerprint { get; set; } = "";
public string TranslationFingerprint { get; set; } = "";
public string NativeToolchainFingerprint { get; set; } = "";
}
internal sealed class DiscHeader
{
[JsonPropertyName("game_id")]
public string GameId { get; set; } = "";
[JsonPropertyName("internal_name")]
public string InternalName { get; set; } = "";
[JsonPropertyName("region")]
public string Region { get; set; } = "";
[JsonPropertyName("revision")]
public int Revision { get; set; }
}
internal sealed class InstallState
{
[JsonRequired]
public int SchemaVersion { get; set; } = 1;
///
/// The setup version that produced this installation. This is the field WheelWizard compares
/// against the latest published v* release tag; see docs/WHEELWIZARD_CONTRACT.md.
///
public string SetupVersion { get; set; } = ProductInfo.Version;
public string ProductVersion { get; set; } = ProductInfo.Version;
/// The directory this state describes, so a frontend can confirm what it found.
public string InstallDir { get; set; } = "";
public DateTime InstalledUtc { get; set; } = DateTime.UtcNow;
public bool RetroRewindInstalled { get; set; }
public string ToolkitReleaseTag { get; set; } = "";
public string DolSha256 { get; set; } = "";
public string RelSha256 { get; set; } = "";
public string RetroRewindCodePulSha256 { get; set; } = "";
public string RetroRewindCompileInputsSha256 { get; set; } = "";
public string RetroWfcPayloadMode { get; set; } = "";
public string RetroWfcPayloadSha256 { get; set; } = "";
public long RetroWfcPayloadLength { get; set; }
///
/// The RetroRewind6 directory this installation was pointed at. The runtime's actual copy is
/// [paths] retro_rewind_root; this mirror lets uninstall drop only the setting it owns.
///
public string RetroRewindRoot { get; set; } = "";
}
///
/// Written next to every locally produced product (Base, RetroRewind): the exact inputs
/// it was built from, so launch/update can decide without re-running anything whether it's still correct.
///
internal sealed class ProductFingerprint
{
[JsonRequired]
public int SchemaVersion { get; set; } = 1;
public string Profile { get; set; } = "";
public string SetupVersion { get; set; } = ProductInfo.Version;
public string ToolkitFingerprint { get; set; } = "";
public string DolSha256 { get; set; } = "";
public string RelSha256 { get; set; } = "";
///
/// Identity of the exact executable produced by this build. A valid input provenance is not
/// enough if a partial copy, third-party replacement, or disk corruption changed the product
/// after it was built.
///
public string ExecutableSha256 { get; set; } = "";
public string CodePulSha256 { get; set; } = "";
///
/// Identity of every translator-consumed Retro Rewind input this product was built from. An
/// asset-only change to the canonical installation does not alter it, which is exactly why an
/// asset-only Retro Rewind update needs no backend work at all.
///
public string RetroRewindCompileInputsSha256 { get; set; } = "";
public string RetroWfcPayloadMode { get; set; } = "";
public string RetroWfcPayloadSha256 { get; set; } = "";
public long RetroWfcPayloadLength { get; set; }
public DateTimeOffset BuiltUtc { get; set; } = DateTimeOffset.UtcNow;
public const string FileName = "build-fingerprint.json";
}
///
/// Written whenever the toolkit (translator + build workspace + compiler) is installed or replaced;
/// records compile, packaged-tool, and copied-runtime identities. Launch checks compare the compile
/// identity against each product's in O(1).
///
internal sealed class ToolkitState
{
[JsonRequired]
public int SchemaVersion { get; set; } = 2;
public string ToolkitFingerprint { get; set; } = "";
public string ToolkitPackageFingerprint { get; set; } = "";
/// Identity of the runtime assets copied verbatim beside each product.
public string RuntimeAssetsFingerprint { get; set; } = "";
public string TranslationFingerprint { get; set; } = "";
public string NativeToolchainFingerprint { get; set; } = "";
public string ToolkitReleaseTag { get; set; } = "";
public string SetupVersion { get; set; } = ProductInfo.Version;
public DateTimeOffset UpdatedUtc { get; set; } = DateTimeOffset.UtcNow;
public const string FileName = "toolkit-state.json";
}