Skip to content

to 2.4.5#260

Merged
patchzyy merged 26 commits into
mainfrom
dev
May 17, 2026
Merged

to 2.4.5#260
patchzyy merged 26 commits into
mainfrom
dev

Conversation

@patchzyy
Copy link
Copy Markdown
Member

@patchzyy patchzyy commented May 17, 2026

Summary by CodeRabbit

  • New Features

    • Added mod archive installation from .zip, .7z, and .rar files with validation and path sanitization.
    • Introduced mod-to-patches conversion system with baseline compatibility analysis.
    • Enhanced mod management interface with rename, reorder, and delete operations.
    • Improved mod launch preparation with file synchronization and progress tracking.
  • Improvements

    • Global exception logging for unhandled errors and unobserved task exceptions.
    • Enhanced error reporting throughout the app with consistent OperationResult handling.
    • Added warning indicators for incompatible mods in the UI.

Review Change Stack

@patchzyy patchzyy merged commit 87eb854 into main May 17, 2026
2 of 3 checks passed
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 48f8d3e7-0a9b-47c2-a30c-5fce4e31b5b5

📥 Commits

Reviewing files that changed from the base of the PR and between 33a59db and 4a20819.

📒 Files selected for processing (63)
  • Flatpak/io.github.TeamWheelWizard.WheelWizard.metainfo.xml
  • WheelWizard/Features/Archives/ArchivesExtensions.cs
  • WheelWizard/Features/Archives/Domain/DecodedArchive.cs
  • WheelWizard/Features/Archives/Domain/U8Node.cs
  • WheelWizard/Features/Archives/ISzsArchiveDecoder.cs
  • WheelWizard/Features/Archives/SzsArchiveDecoder.cs
  • WheelWizard/Features/Archives/U8ArchiveBuilder.cs
  • WheelWizard/Features/GameBanana/Domain/GameBananaModPreview.cs
  • WheelWizard/Features/Mods/ModInstallationService.cs
  • WheelWizard/Features/Mods/ModManager.cs
  • WheelWizard/Features/Mods/ModsExtensions.cs
  • WheelWizard/Features/Mods/ModsLaunchService.cs
  • WheelWizard/Features/Patches/BrsarPatchConverter.cs
  • WheelWizard/Features/Patches/Domain/GameBaselineModels.cs
  • WheelWizard/Features/Patches/GameBaselineStore.cs
  • WheelWizard/Features/Patches/ISzsPatchConverter.cs
  • WheelWizard/Features/Patches/KartSzsAllowList.cs
  • WheelWizard/Features/Patches/LooseBrsarPatchFileName.cs
  • WheelWizard/Features/Patches/ModPatchConversionService.cs
  • WheelWizard/Features/Patches/PatchConversionHelpers.cs
  • WheelWizard/Features/Patches/PatchesExtensions.cs
  • WheelWizard/Features/Patches/Resources/allowed-kart-szs.json
  • WheelWizard/Features/Patches/Resources/game-baseline-data.json
  • WheelWizard/Features/Patches/Resources/game-baseline-index.json
  • WheelWizard/Features/Patches/SzsPatchConverter.cs
  • WheelWizard/Helpers/BigEndianBinaryHelper.cs
  • WheelWizard/Helpers/BinaryStringHelper.cs
  • WheelWizard/Helpers/DownloadHelper.cs
  • WheelWizard/Helpers/FileHelper.cs
  • WheelWizard/Models/Mods/Mod.cs
  • WheelWizard/Program.cs
  • WheelWizard/Resources/Languages/Common.Designer.cs
  • WheelWizard/Resources/Languages/Common.resx
  • WheelWizard/Resources/Languages/Phrases.Designer.cs
  • WheelWizard/Resources/Languages/Phrases.resx
  • WheelWizard/Services/Installation/ModInstallation.cs
  • WheelWizard/Services/Launcher/GoogleLauncher.cs
  • WheelWizard/Services/Launcher/Helpers/ModsLaunchHelper.cs
  • WheelWizard/Services/Launcher/Helpers/RetroRewindLaunchHelper.cs
  • WheelWizard/Services/Launcher/ILauncher.cs
  • WheelWizard/Services/Launcher/RrBetaLauncher.cs
  • WheelWizard/Services/Launcher/RrLauncher.cs
  • WheelWizard/Services/ModManager.cs
  • WheelWizard/Services/ModStorageSystem.cs
  • WheelWizard/Services/PathManager.cs
  • WheelWizard/Services/Storage/CustomFilePickerFileType.cs
  • WheelWizard/SetupExtensions.cs
  • WheelWizard/Shared/MessageTranslations/MessageTranslationHelper.cs
  • WheelWizard/Shared/OperationResult/OperationResult.cs
  • WheelWizard/Views/App.axaml.cs
  • WheelWizard/Views/Layout.axaml
  • WheelWizard/Views/Layout.axaml.cs
  • WheelWizard/Views/Pages/HomePage.axaml.cs
  • WheelWizard/Views/Pages/ModsPage.axaml
  • WheelWizard/Views/Pages/ModsPage.axaml.cs
  • WheelWizard/Views/Pages/TestingPage.axaml.cs
  • WheelWizard/Views/Patterns/GridModPanel.axaml
  • WheelWizard/Views/Patterns/SidebarRadioButton.axaml
  • WheelWizard/Views/Patterns/SidebarRadioButton.axaml.cs
  • WheelWizard/Views/Patterns/VrHistoryGraph.axaml
  • WheelWizard/Views/Patterns/VrHistoryGraph.axaml.cs
  • WheelWizard/Views/Popups/ModManagement/ModContent.axaml.cs
  • WheelWizard/WheelWizard.csproj

📝 Walkthrough

Walkthrough

WheelWizard 2.4.5 introduces a complete mod-to-patch conversion pipeline by refactoring the mod management system from a singleton to a service-based architecture with dependency injection. The PR adds archive decoding/encoding (U8 and Yaz0), baseline-driven patch analysis for SZS and BRSAR formats, mod installation and management services, mod launch preparation, launcher error propagation via OperationResult, and a refreshed ModsPage UI. All launchers now return OperationResult to enable centralized error handling.

Changes

Archive Decoding Infrastructure

Layer / File(s) Summary
Archive codec foundation
WheelWizard/Features/Archives/ISzsArchiveDecoder.cs, WheelWizard/Features/Archives/SzsArchiveDecoder.cs, WheelWizard/Features/Archives/Domain/DecodedArchive.cs, WheelWizard/Features/Archives/Domain/U8Node.cs, WheelWizard/Features/Archives/U8ArchiveBuilder.cs, WheelWizard/Features/Archives/ArchivesExtensions.cs
Yaz0 decompression, U8 directory tree parsing and recursive file extraction, U8 archive construction with node-table metadata and name blob, YAZ0 compression with rolling-hash LZ-style back-reference encoding; DI extension registers SzsArchiveDecoder singleton.

Patch Conversion Infrastructure

Layer / File(s) Summary
Baseline and patch domain models
WheelWizard/Features/Patches/Domain/GameBaselineModels.cs, WheelWizard/Features/Patches/GameBaselineStore.cs, WheelWizard/Features/Patches/PatchConversionHelpers.cs
JSON-serializable baseline index/entry/candidate structures, patch conversion entry and analysis records, embedded baseline resource loading via manifest, JSON element extraction and 64-bit byte hashing helpers.
SZS and BRSAR patch converters
WheelWizard/Features/Patches/ISzsPatchConverter.cs, WheelWizard/Features/Patches/SzsPatchConverter.cs, WheelWizard/Features/Patches/BrsarPatchConverter.cs, WheelWizard/Features/Patches/KartSzsAllowList.cs, WheelWizard/Features/Patches/LooseBrsarPatchFileName.cs, WheelWizard/Features/Patches/Resources/allowed-kart-szs.json
SZS per-member archive analysis with whole-file mode handling; BRSAR end-to-end parsing with embedded sound header detection, group/item resolution, and difference estimation; kart allowlist and loose patch filename validation.
Mod-to-patch conversion orchestration
WheelWizard/Features/Patches/ModPatchConversionService.cs, WheelWizard/Features/Patches/PatchesExtensions.cs
Mod-to-patch workflow: temp-workspace isolation, convertible-file enumeration, baseline selection via difference estimation, archive analysis dispatch, bundle aggregation, YAZ0 writing, directory replacement with rollback, progress UI updates, cancellation support, compatibility refresh; DI extension registers both converters.

Refactored Mod Management Services

Layer / File(s) Summary
Mod installation and management services
WheelWizard/Features/Mods/ModInstallationService.cs, WheelWizard/Features/Mods/ModManager.cs, WheelWizard/Features/Mods/ModsExtensions.cs
IModInstallationService: async load/save mod INI metadata, archive extraction with path sanitization and destination-boundary checks, progress posting. IModManager: observable collection with property-change-driven saving via semaphore-serialized queue, batch-update guards, import/rename/delete/reorder workflows, priority management, compatibility refresh; DI extension registers both services as singletons.
Mod launch preparation
WheelWizard/Features/Mods/ModsLaunchService.cs
IModsLaunchService: builds final file map from enabled mods in priority order, conditionally clears target folder, copies files asynchronously with progress UI, skips unchanged files (size/last-write-time comparison), excludes INI metadata, renames .szs files with mod-priority prefix.

Launcher Result Changes

Layer / File(s) Summary
Launcher interface and all implementations
WheelWizard/Services/Launcher/ILauncher.cs, WheelWizard/Services/Launcher/GoogleLauncher.cs, WheelWizard/Services/Launcher/RrBetaLauncher.cs, WheelWizard/Services/Launcher/RrLauncher.cs, WheelWizard/Services/Launcher/Helpers/RetroRewindLaunchHelper.cs
ILauncher: Launch/Install/Update now return Task<OperationResult>. GoogleLauncher: returns Ok(). RrBetaLauncher: injects IModsLaunchService, Launch validates mods, handles prep failures, wraps exceptions. RrLauncher: injects IModsLaunchService, Launch checks game file, prompts folder clearing, returns OperationResult. RetroRewindLaunchHelper: MyStuffChoice changed from 2 to 0.

ModsPage UI and Views

Layer / File(s) Summary
ModsPage refactoring
WheelWizard/Views/Pages/ModsPage.axaml, WheelWizard/Views/Pages/ModsPage.axaml.cs
XAML: adds patches namespace, removes "Use Patches" checkbox, shifts context menu to per-item, adds "Convert to Patches" action (enabled by HasIncompatibleFiles), adds warning indicator. CS: injects IModManager and IModPatchConversionService, converts all handlers to async, adds patch conversion result message builder, manages async drag finalization.
Related view updates
WheelWizard/Views/Pages/HomePage.axaml.cs, WheelWizard/Views/Pages/TestingPage.axaml.cs, WheelWizard/Views/Popups/ModManagement/ModContent.axaml.cs, WheelWizard/Views/Patterns/GridModPanel.axaml, WheelWizard/Views/Patterns/VrHistoryGraph.axaml.cs
HomePage/TestingPage: await launcher results, show translated errors on failure. ModContent: injects IModManager, refactors install flow with async DownloadAndInstallCurrentModAsync. GridModPanel: adds patches namespace and incompatible warning indicator. VrHistoryGraph: adds UseMatchesAsXAxis property, branching graph label/X-coordinate logic, match-based vs time-based rendering.

Application Infrastructure

Layer / File(s) Summary
Startup, exception logging, and Layout
WheelWizard/Program.cs, WheelWizard/Views/Layout.axaml, WheelWizard/Views/Layout.axaml.cs, WheelWizard/Views/App.axaml.cs
Program: adds global exception logging (AppDomain.UnhandledException, TaskScheduler.UnobservedTaskException). Layout: injects IModManager, subscribes to PropertyChanged, calls async reload on init. App: replaces sync protocol-open with async OpenGameBananaModWindowAsync, logs launcher failures.
Helpers and utilities
WheelWizard/Helpers/FileHelper.cs, WheelWizard/Helpers/BigEndianBinaryHelper.cs, WheelWizard/Helpers/BinaryStringHelper.cs, WheelWizard/Shared/MessageTranslations/MessageTranslationHelper.cs, WheelWizard/Shared/OperationResult/OperationResult.cs
FileHelper: adds FindFilesByExtension, TryDeleteFile, DeleteDirectoryIfExists returning OperationResult; EnsureDirectory now returns OperationResult. BigEndianBinaryHelper: adds BufferToInt32. BinaryStringHelper: ReadAscii, ReadNullTerminatedAscii. MessageTranslationHelper and OperationResult: add Serilog logging.
Service and path updates
WheelWizard/SetupExtensions.cs, WheelWizard/Services/PathManager.cs, WheelWizard/Services/Storage/CustomFilePickerFileType.cs, WheelWizard/Models/Mods/Mod.cs, WheelWizard/Features/GameBanana/Domain/GameBananaModPreview.cs
SetupExtensions: registers AddArchives, AddPatches, AddMods. PathManager: removes ModConfigFilePath, MyStuffFolderPath, RrBetaMyStuffFolderPath. CustomFilePickerFileType: adds All property, removes Mods. Mod: adds HasIncompatibleFiles property. GameBananaModPreview: removes ModStorageSystemHelper, adds inline IsPatchesTag helper.

Localization and Cleanup

Layer / File(s) Summary
Localization resource updates
WheelWizard/Resources/Languages/Common.resx, WheelWizard/Resources/Languages/Common.Designer.cs, WheelWizard/Resources/Languages/Phrases.resx, WheelWizard/Resources/Languages/Phrases.Designer.cs
Common: adds PageTitle_Patches, Attribute_All, Action_ConvertToPatches. Phrases: adds 60+ new strings for patch conversion UI, BRSAR/SZS feedback, progress indicators, warnings, success messages.
Version and removed code
Flatpak/io.github.TeamWheelWizard.WheelWizard.metainfo.xml, WheelWizard/WheelWizard.csproj, WheelWizard/Services/Installation/ModInstallation.cs, WheelWizard/Services/Launcher/Helpers/ModsLaunchHelper.cs, WheelWizard/Services/ModStorageSystem.cs
Version: 2.4.4 → 2.4.5. Removed: old ModInstallation, ModsLaunchHelper, ModStorageSystem enum and helper API. Added: embedded resource configuration for patches JSON files.

🎯 4 (Complex) | ⏱️ ~75 minutes


Possibly Related PRs

  • TeamWheelWizard/WheelWizard#257: This PR directly builds on #257 by fully integrating the archive codec and patch baseline infrastructure, introducing the complete mod-to-patch conversion service and all patch converters (SZS and BRSAR) that depend on the archive decoding foundation.
  • TeamWheelWizard/WheelWizard#254: Related through the GameBananaModPreview changes—this PR removes the ModStorageSystemHelper dependency and reimplements patch-tag detection inline, refining the mod categorization logic previously introduced in #254.
  • TeamWheelWizard/WheelWizard#253: Includes the same VrHistoryGraph feature update (adding UseMatchesAsXAxis mode toggle with match-based vs time-based X-axis rendering) that was developed in #253.

🐰 Patches pulled from mods, archives now decode,
Services inject where singletons once strode,
Baselines guide conversions deep and wide,
While launchers return results with pride!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch dev

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants