Files
bbldrizzyandClaude Sonnet 5.5 d3d4a988eb OpenPrestige
Co-Authored-By: Claude Sonnet 5.5 <[email protected]>
2026-10-21 21:24:22 +01:00

9.6 KiB

TODO_COMPILE - decompiled client source tree (client/src/main/java)

State (2026-10-19 16:45): the regenerated tree compiles with 0 javac errors (543 files, client/work/javac_s3.log), builds with ./gradlew build -PwithClient=true (jar 10.5 MB) and boots under Fabric (client/work/boot_source_modules_renamed.log: bridge: built 121 modules from manifest, failed 0 / bridge bound: 121 modules, toggle test passes, screenshot client/work/boot_source_modules_renamed_on.png). The classpath-jar route (client/work/client-runtime.jar) stays the default (./gradlew build / runClient); the source route is opt-in with -PwithClient=true because it is a lossy reconstruction (see "Known gaps").

How to build

bash client/build_client.sh              # regenerate tree -> client/src/main/{java,resources} -> ./gradlew build -PwithClient=true   (~1.5 min)
bash client/build_client.sh --no-gradle  # stop after installing the tree
bash client/build_client.sh --jar        # only the jar route: tools/build_runtime.sh (indy-fixed, renamed, Yarn) ~1.5 min
bash client/build_client.sh --full       # stage A too (IndyResolve -> FlowClean -> Strip = work/strip1.jar) + both routes (~10+ min)
bash client/tools/boot_test.sh 200 [-PwithClient=true] [-PuiCmd=<cmdfile>]    # dev client, log copied to run/logs/boot_*.log

Dev tool flags: -PclientJar=<yarn jar> (swap the classpath jar), -PdumpClasses=a,b (force class init, see ClinitDump).

Pipeline (all scripts in client/tools, driven by tools/build_source.sh)

  1. stage A (not re-run by default): run_indy.sh -> pipeline_a.sh => work/strip1.jar (obfuscated names, ZKM refs resolved/stripped).
  2. rename.sh: docs/mapping.tsv -> tiny-remapper (+ Widen: package-private -> public, needed because module classes move into module/<category>/) => work/strip.renamed.jar. Same step is used by the jar route (build_runtime.sh) and regenerates src/main/resources/prestige_ui/manifest_live.json (rename_manifest.py).
  3. NoTry (tools/notry.txt): clears the exception table of Prestige.init and aw.a(Object[])JsonObject (Vineflower crashes on them).
  4. pipeline_b.sh: remap to Yarn (+ keyword/case-collision/dedup renames), Vineflower, extract_src.py, fix_sources.py. (Fixed: it now deletes work/remapped.jar/decompiled.jar first - tiny-remapper/Vineflower merge into an existing output file.)
  5. javac-driven fixers (errors 406 -> 98 -> 0): fix_diag.py (raw for-each, record accessors), fix_rethrow.py (ZKM identity rethrow handlers), fix_ctor.py (code before super() hoisted: constant key arithmetic evaluated and inlined, 58 ctors), fix_typed_values.py (covariant Setting.getValue()), fix_reflect.py (rebuilds the lost Method.invoke chains in cU/cW/EventBus: MethodHandles.lookup/privateLookupIn/findVarHandle/unreflect/asSpreader), fix_diag2.py (raw generics casts), manual_edits.py (exact-text repairs, idempotent, fails loudly if upstream changes; resolves module classes through the mapping), fix_bootstrap.py (source equivalent of the bytecode PatchBootstrap: Bootstrap.pre(this) in all 122 module constructors, adds a constructor to modules that had none).
  6. compile.sh = javac against work/mc-yarn-aw.jar + libs; errsummary.py summarises a log.

Naming

docs/mapping.tsv: API surface (Module, Category, Setting + 9 setting types, SettingHolder, ModuleManager, EventBus, MenuModule, Gamemode, Subscribe, ListenerEntry and their key fields/methods) and the 121 module classes (module/<category>/<PascalCaseName>, generated by gen_module_mapping.py from docs/manifest_live.obf.json). Remaining classes keep obfuscated names; case-colliding twins carry a _ suffix (ea vs eA -> ea_) only in the source (Windows file system), the bridge accepts both.

Known gaps (the source route is NOT behaviourally verified; the jar route is the reference)

  • Strip removed 275 "dead unresolved" methods (work/strip1.report.txt, DEADREMOVED: dl 26, cA 18, dB 17, dA 13, H 10, G 10, ..., dU 5 (SettingHolder: addFloat/addInt/addRange/addText/addMulti), bT 5, ...). Their callers were rewritten to throws or no-ops by Strip; bT.a_cF/f are stubs that throw UnsupportedOperationException. Fixing this means making IndyResolve resolve the remaining 1591 REMAIN UNFOLDED sites (work/boot_indy.report.txt) instead of cutting.
  • (2026-10-21: the 5 HUD/runnable bodies below are RECOVERED, see the 2026-10-21 section; only the 5 reconstructed ones remain approximations.)
  • 10 unresolved ZKM reference bodies: reconstructed ge.<init> (vertex offsets/stride = sum(count*bytes)), dc.<init> (fS.a(args)), de.<init> (g = bU.a(key), j = new HashMap), g2.removeEldestEntry (size() > cap), dv.a (glUniform4f(du.g, radii)); no-op with TODO: dE.run, av.run, ca.q, cb.q, b4.q (HUD widget render bodies).
  • Constants lost by Strip (Object var0 = null + ((Object[])var0)[k]): recovered at runtime with tools/java/ClinitDump.java + bridge/DumpHook (instrument <clinit> array loads in the runtime jar, run the dev client with -PclientJar=... -PdumpClasses=..., log client/work/clinit_dump.log): cp (10 shader paths), ap/gB (uniform names), gf (GL types 5126/5121), fQ (49-entry XRay block index table, tools/clinit_tables.json), c9 (quad buffer sizes 4/24 - dumped = guessed). Inferred, not dumped: C ("setRotation", the table is [setPos, setRotation]), W ("getMatrix"), I ("guiProjectionMatrix" vs "itemsProjectionMatrix"), du.g ("roundness"). C and W cannot be initialised in a dump run (ClassTransform TransformerManager remapper is null at that point) - check them in game.
  • Decompiler guesses: Entity/PlayerEntity common types of ?: expressions (aG, cg_, fx_), Optional<Vec3d> (eu_), enum valueOf(String,long) removed (callers pass only the string), da_ ZKM string tables + bootstrap helpers deleted.
  • Not exercised at all: module behaviour (onEnable hooks, event dispatch, rendering), HUD widgets, config download.
  • ClassTransform (net.lenni0451, client/libs/classtransform-bundled.jar) is shaded into the mod jar in the source route. The client's own fabric.mod.json is not copied; the project's one gets entrypoints.main + accessWidener injected by processResources.

Next steps

  1. Make IndyResolve (stage A) resolve all sites so Strip stops dead-removing methods; re-run build_client.sh --full; re-diff the tree.
  2. Verify the inferred constants (C, W, I, du.g) and the 5 no-op HUD bodies against the runtime jar (indy sites there resolve at run time).
  3. Behaviour checks module by module (jar route first), then flip the default to the source route and drop client/work/client-runtime.jar.
  4. Rename the remaining ~420 helper classes / packages with docs/mapping.tsv (same mechanism, re-run both routes + boot test).

2026-10-21 update (agent "verify")

Layout: 543 classes = 21 API classes at the root + client/Prestige + 121 module/<category>/* + 400 helpers in 18 packages (event hud render data type mixin world math combat inventory network reflect gui config util social annotation input). Frozen mapping files: docs/classmap.tsv (400 rows, jar names), docs/classmap_src.tsv (source-tree names, _ case twins); docs/mapping.tsv = API surface; merged by tools/merge_mapping.py -> work/rename.map.tsv. Boot results (logs in client/work/):

  • source route (-PwithClient=true): boot_verify_source_final.log - bridge: built 121 modules, failed 0 / bridge bound: 121 modules, 0 ClassNotFound/NoClassDef/IllegalAccess, Aim Assist toggle ui=true live.a()=true enabledSetting.value=true; HUD smoke (state hudsmoke, DevCmd): all 16 HUD q() + RenderHelper24.run + CobwebPlacerHelper.run ok (boot_verify_source_hudsmoke.png).
  • jar route (tools/build_runtime.sh): boot_verify_jar_final.log - 121 modules bound, toggle on/off round trips; HUD smoke: 15/16 q() ok, the first one fails with the known stateful-key BADREF of g2.removeEldestEntry (AIOOBE index 188911/9; g2 = LRU map used by the shader/text cache) - jar-route-only, source route has the reconstruction. Note the toggle test needs a few attempts: real mouse movement over the game window overrides the simulated cursor (Overlay.pollCursor). Fixes: stale classes in work/boot_yarn.jar (tiny-remapper MERGES into an existing output; old-named fT/fS/.. were loaded by name) -> rm before remap; Widen now also widens private members (nest host/member links are lost by the moves; IllegalAccessError); unresolved reference tables still contain OLD class names -> tools/java/RecoverBodies.java redirects every Class.forName of the client jar to dev.prestige.ui.bridge.OldNames (map src/main/resources/prestige_ui/old_names.tsv, written by tools/old_names.py from rename.sh). No mixin json / fabric.mod.json / Bridge FQN change was needed (the client's mixins are ClassTransform @CTransformer classes applied by the native module, not Fabric mixins; shader/resource paths are string literals and unchanged). Recovered bodies (dE.run=RenderHelper24, av.run=CobwebPlacerHelper, ca.q=ModuleListElement, cb.q=ModuleNotificationsElement, b4.q=HudElement): decoded from the pre-strip jar (out/prestige-deobf-fixed.jar) with tools/recover_refs/ (brute-forces the per-method reference-table key; b4.q found by matching entries of another method: dB.l=MatrixStack.l + Color.WHITE). Source: tools/manual_edits.py (also widens Renderer2D.i/m, CobwebPlacer.E/F/d/o); jar: RecoverBodies. Regeneration (build_source.sh) verified: 0 javac errors, tree identical to client/src/main/java. Remaining: dv.a / g2 / dc / de reconstructions are still inferred; g2 wrong key in the jar route; strings and member names still obfuscated.