Skip to content

Latest commit

 

History

History
89 lines (70 loc) · 5.55 KB

File metadata and controls

89 lines (70 loc) · 5.55 KB

The reproducible patch system

One pipeline turns the user's own copy of the disc into the fully-patched English app tree, and tracks every file we touch in one auditable place. It is the foundation for the end deliverable: an English installer re-wrapped from the user's own setup.exe.

Hard rule it respects

We never ship a SYGNAS byte. Git holds only the recipe — patch/manifest.toml, the engine tools/build_patch.py, and the patch sources under patch/. The user runs the build against their own originals/ (gitignored); the output out/ (gitignored) is derived-from-originals and also never redistributed. What we eventually hand a user is the tooling + the delta, which they apply to their own disc.

Pieces

Path Role
patch/manifest.toml What we patch — one declarative entry per file + op + a note. The single source of truth.
tools/build_patch.py How — mirrors originals/installed/ → out/patched/, applies each op, writes the audit. Stdlib only (py3.11+ for tomllib).
out/patched/ The full patched English tree (passthrough files copied verbatim, patched files transformed). Gitignored.
out/patched/PATCH-LOG.txt Generated audit — every op applied + everything deferred.
patch/launcher/*.ini Launcher speech sources (cp932), generated by tools/build_launcher_en.py; repacked by the xvi op.
patch/text/* Tracked EN replacements (readme, …), authored UTF-8 and transcoded on build.

Run it (in nix develop): python tools/build_patch.py → out/patched/ + PATCH-LOG.txt. The build is reproducible (two runs hash-identical) and idempotent (wipes+rebuilds out/).

Op vocabulary

Applied in this fixed order (rename always last). Any op may set active = false to record intent without applying — logged as DEFERRED. String fields template {install_root_jp} / {install_root_en} from [meta].

Op Does Used for
xvi repack a translated cp932 Ini into each .Xvi (via sygnas_repack.py) the 22 launcher characters
text_keys replace INI KEY= values, preserve everything else Launch.ini menu titles
text_subst literal find→replace pairs in a text file wallpaper UI text; (deferred) install-root path rewrite
text_file replace a whole file with a tracked EN version (encoding/crlf transcode) the readme
binpatch replace whole NUL-terminated (wide/narrow) strings, NUL-padded in place gcalcore.dll/gcal.exe host→localhost
rename rename a file in the patched tree (deferred) .mink/.scr/install root

binpatch matches a complete NUL-terminated string (old + terminator), so the bare host www.google.com and the host inside a longer URL are disambiguated; the replacement is written in place and the freed tail is zeroed (the new string stays shorter and NUL-terminated), so the file size never changes and the PE stays valid.

Locale-safety (project goal #2: run on a non-JP-locale box, no AppLocale)

The app reads text via ANSI APIs (GetPrivateProfileStringA, DrawTextA), so any non-ASCII byte mojibakes on a non-JP system. Rules baked into the manifest:

  • App-read text → pure ASCII. Launch.ini titles use "Lucky Star", not "Lucky☆Star". (The .Xvi serifs are drawn with DrawTextA too; a few still carry ☆ → an ASCII pass is a follow-up.)
  • Notepad-only text → UTF-8 + BOM (utf-8-sig). XP Notepad honours the BOM on any locale, so the readme keeps ☆ × ■ ○.
  • HTML → UTF-8 (its <meta charset> drives the browser); anything renders.
  • File paths → ASCII (the らき☆マス install root, the JP .mink/.scr names). This is the bulk of the locale fix and is tracked as deferred rename + text_subst entries — it needs the install to actually live at the ASCII path, which the installer stage pins.

Calendar redirect (host → localhost)

So the mascots' calendar works offline and the XP box keeps real internet (no hosts blackhole): binpatch rewrites the wide host string in both gcalcore.dll and gcal.exe (www.google.com → localhost; also the allcalendars URL and gcal.exe's add-event deep-link). The server side matches: gcalsrv.lua returns a localhost event-feed link, and the embedded cert is regenerated CN=localhost (tools/gcal-emu/make-xp-cert.sh, SAN also lists the google names so the legacy hosts-redirect still validates). After applying, remove the XP hosts line. Validate with tools/gcal-xp/test/clientlogin.vbs (defaults to https://localhost/...).

The deferred surface

Everything not yet safe to apply is recorded in the manifest as active = false (so nothing is lost and the audit shows it): the install-root path rewrite, the .mink (10) / .scr (4) / wallpaper-JPG renames, plus prose TODOs for the MinkIt copy-engine path config (no INI ships → RE where it reads its folder), autorun.inf (installer regenerates it), and the PE-resource UI strings (lang 1041) in the 4 exes + 4 .scr (a future pe-res op). Flip active = true once the gating RE / installer work lands.

The end goal — English installer (re-wrap)

The next major stage consumes out/patched/: extract the user's own setup.exe (innoextract), drop in the patched tree, translate the Inno script/UI ([Languages] + custom messages) and pin an English {app} install path, recompile with ISCC under wine → an English setup.exe the user builds from their own disc. (Distribution as an xdelta3/IPS delta off out/patched/ is the lighter alternative.)