Add a cross-platform web-based editor (Linux/macOS/Windows)#88
Open
VasilyPolyuhovich wants to merge 3 commits into
Open
Add a cross-platform web-based editor (Linux/macOS/Windows)#88VasilyPolyuhovich wants to merge 3 commits into
VasilyPolyuhovich wants to merge 3 commits into
Conversation
The original tool is a Windows-only WPF/.NET Framework 4.8 app. This adds a cross-platform port that builds and runs on Linux/macOS/Windows. - TldSaveEditor.Core (net10.0): portable save logic extracted from the WPF project (serialization, game-data model, CLZF, item/map dictionaries) plus a UI-agnostic SaveEditorService facade and DTOs. GetLocalPath now resolves the save folder on Windows, macOS and Linux (Steam Proton prefix, libraryfolders). - TldSaveEditor.Server (net10.0): local-only ASP.NET minimal API over the service, serving a zero-build web UI from wwwroot. - Web UI tabs: Player, Skills, Inventory, Afflictions, Map (with player-position marker), Profile. Per-item condition/quantity/litres/rounds editing, experience mode, custom mode, carry-weight limit, backups + restore. - run.sh launcher (builds, runs, opens the browser). Save-integrity fixes carried into Core: - Liquid fixed-point bug (issues FINDarkside#85/FINDarkside#87/FINDarkside#74): water/fuel/volume are Int64 (1 L = 1e9), not float; added long fields + Liters helpers + fixed item dictionary defaults. - JsonConvert.DefaultSettings (FloatFormatHandling.Symbol + ByteArrayConverter) is required on write, otherwise Infinity/NaN and byte arrays corrupt the save. Verified: all real saves load/edit/save round-trip cleanly on Linux.
- Single-source JsonConvert.DefaultSettings in GameSave's static ctor (was duplicated in MainWindow and SaveEditorService); load-bearing for save integrity, now defined once for both the WPF app and the web server. - Reuse GameSave.Backup() (made public) for the restore snapshot instead of a private copy in the service — restores now also prune to MAX_BACKUPS. - Serialize all SaveEditorService methods behind a lock: it is registered as a singleton and the parser's static caches / the in-memory graph are not thread-safe under concurrent requests. - Map server errors to status codes (404 not-found, 409 no-save-loaded, 400 bad-arg) and stop echoing raw exception text for unexpected errors. - Validate /load and /restore paths resolve under SavesFolder (defence-in-depth on top of loopback-only binding). - UpdateItem takes UpdateItemRequest instead of five positional args. - Batch inventory rows via DocumentFragment; align launchSettings to the real port; remove dead Util.IsDebug field. Verified: all 15 real saves still round-trip cleanly; restore/item-edit/path rejection behave as expected.
The server is plain cross-platform ASP.NET (net10.0) and already handles Windows specifics (LOCALAPPDATA save path, browser auto-open), so it runs on Windows as-is — it just lacked a convenience launcher. run.cmd mirrors run.sh. README now documents the .NET 10 requirement and how to run on each OS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Thanks for this tool — it's been genuinely useful.
Since the editor is Windows-only (WPF / .NET Framework), I put together a cross-platform version that runs in the browser, so it works on Linux and macOS too. It lives under a new
src/folder and is almost entirely additive — the existing WPF app behaves the same. Totally fine to take it or leave it.What's in it
src/TldSaveEditor.Core— the existing save logic moved into a small .NET 10 class library (serialization, game-data model, item/map dictionaries). Most files here are your code unchanged; the only genuinely new pieces areServices/SaveEditorService.csandServices/Dtos.cs(a thin UI-agnostic facade).src/TldSaveEditor.Server— a tiny local-only ASP.NET app that serves a plain HTML/JS UI (no front-end build step) over a localhost API.Util.GetLocalPath()now resolves the save folder on Windows, macOS and Linux (Steam/Proton prefix) instead of the Windows-only shell call.The only change to the existing app: the shared
JsonConvert.DefaultSettings(float/byte handling) moved fromMainWindowintoGameSaveso the app and the server use one definition.Running it
Needs the .NET 10 SDK.
./run.shrun.cmddotnet run --project src/TldSaveEditor.Server -c ReleaseServes
http://127.0.0.1:5173(loopback only) and covers the Player, Skills, Inventory, Afflictions, Map and Profile tabs. Every save still writes a timestamped backup, and the UI can restore one.Two fixes carried into the core
2E+09and corrupted saves on write. This addresses Water amount broken on some systems #85, Incorrect Scientific Notation Conversion When Parsing Floating-Point Numbers #87 and the Storm Lantern part of Save corrupts when adding certain items #74.FloatFormatHandling.Symbol+ the byte-array converter to avoid turningInfinity/byte arrays into malformed JSON (the WPF app already set this; now it's shared).I tested load → edit → save → reload across a range of my own sandbox saves and it round-trips cleanly. Happy to adjust or split this up if that makes review easier.