文件
Administrator 0da7d49fd6
Build Loader / build (push) Canceled after 0s
Import OpenZen deobfuscated source
2026-09-15 03:14:09 +08:00

4.3 KiB

AGENTS.md

Deobfuscated source of the Zen Minecraft client. Target: MC 1.20.1 + Forge 47.4.20, Java 17. Background (Chinese): README.md.

What this is — critical

  • NOT a Forge mod. Never test by dropping the jar in .minecraft/mods/. It ships as:
    1. a Java agent jar (-javaagent: JVM arg), or
    2. a Windows injector EXE (OpenZenLoader.exe) that maps a DLL into a running javaw.exe.
  • Entrypoints:
    • Agent: asm.patchify.loader.PatchAgent (premain; manifest Premain/Agent-Class) applies ASM patches registered in PatchRegistry.
    • Mod-side: shit.zen.ZenClient@Mod("hey"); mod id is hey, jar is build/libs/hey-1.0.jar.
    • DLL path: shit.zen.dll.DllBootstrap / GameLoaderBridge, loaded by C++ under native/.
  • Layout: asm.patchify.* = agent bootstrap + patch annotations/transformer machinery; shit.zen.** = the client (modules/gui/commands/events/etc.); native/ = CMake C++ (native/dll + native/loader); mapping/zen.mapping = mapping of the ORIGINAL obfuscated Zen jar.
  • Where code goes: vanilla-MC behavior changes live in shit.zen.patch (*Patch.java using @Patch/@Inject/@Overwrite/@WrapInvoke from asm.patchify.annotation, applied to mojmap names); client features go in shit.zen.modules/gui/command etc.

Build-time class-name obfuscation

  • Every build renames all shit.zen.* / asm.patchify.* classes to random 16-char names in one random package (auto-runs after reobfJar; see ext.obfuscateJar in build.gradle).
  • Class names only — method/field names are intentionally preserved (JNI lookups, reflection, GSON @SerializedName). Don't "fix" this.
  • Never hardcode OpenZen class names across a build boundary. The manifest Premain-Class, Class.forName string literals, and the native side (native/dll/src/generated_names.h) are rewritten/propagated by the build automatically — route new bootstrap references through that mechanism.
  • build/rename-mapping.txt is the ONLY way to de-obfuscate runtime stack traces and differs every build. Not to be confused with mapping/zen.mapping (original Zen).
  • native/dll/src/generated_names.h is auto-generated and gitignored — never edit or commit it.
  • Because class names are random, logging relies on fixed message strings (bootstrap.start, bridge.load, agent attached), not logger/class names. Native log: %TEMP%\openzen-<pid>-<ticks>.log — one file per injection attempt (a shared openzen.log was broken: the first injected process held it open forever, so every later injection's log::init hit ERROR_SHARING_VIOLATION and logged nothing).

Commands

  • JDK 17 required; JAVA_HOME must point at it. Run Gradle itself on JDK 17 — the buildscript's ASM 9.6 cannot read class files of newer JDKs (Java 21+).
  • .\gradlew.bat jar — agent jar at build/libs/hey-1.0.jar (reobf + class renaming run automatically).
  • .\gradlew.bat runClient0 — builds the jar and launches a dev MC client with -javaagent wired up. This is the supported way to test in-dev. DevAuth is a runtimeOnly dep (Microsoft login in dev); working dir is run/.
  • .\gradlew.bat dllbuild/dist/OpenZenLoader.exe. Requires MSVC (VS 2019/2022, C++ workload), CMake (auto-found via PATH/vswhere/standard paths), and JAVA_HOME = JDK 17 (jni.h/jvmti.h). Windows-only. upxCompress is optional; it skips with a warning if UPX is absent.
  • .\gradlew.bat clean also wipes native/build/ and native/zen.jar (cleanNative).
  • gradle.properties sets org.gradle.daemon=false and a 3G heap (MC decompilation). First build downloads Forge mappings — expect minutes.
  • No test suite, linter, or formatter exists. Verification = gradlew jar compiling; behavior via gradlew runClient0.

CI (.github/workflows/build-loader.yml)

  • Push to master, path-filtered (src/native/gradle files; docs-only changes skip). windows-2022 runner runs clean dll upxCompress.
  • Commit-message markers: [Release] (case-insensitive) cuts a GitHub Release build-<sha> with exe + jar + mapping; [SKIP CI] skips the run.
  • CI passes the resolved sha as OPENZEN_BUILD_REVISION.

Local run helper

  • launch-mc-agent.ps1 launches MC 1.20.1 Forge with the agent via -javaagent (offline auth). Paths inside are machine-specific hardcodes — edit before use elsewhere.