Files
OpenZen/src/main/java/shit/zen/dll/DllBootstrap.java
T
Shirona1337 91fb65c22f feat(build): randomized build-time class-name obfuscation + pin Qt 6.10.2
Rename every shit.zen.* / asm.patchify.* class to a fresh random 16-char name in one random 16-char package on each build, via an ASM ClassRemapper pass (build.gradle ext.obfuscateJar, run after ForgeGradle reobfJar). Class names only; methods/fields preserved. Manifest Premain/Agent-Class, the DllBootstrap Class.forName string, and the native bridge name (generated_names.h OZ_BRIDGE_FQCN) are wired to the generated names. Residual original-name strings (loggers, log text, the asm.patchify.* property keys) scrubbed. Emits build/rename-mapping.txt.

Pin Qt to 6.10.2 (vcpkg builtin-baseline + CI tag 2026.04.27): MSVC 14.44 crashes building Qt 6.11.0. Build Qt single-threaded locally (VCPKG_MAX_CONCURRENCY=1, loader --parallel 1, gated off GitHub Actions) to dodge parallel-compilation compiler crashes on that toolset.

CI uploads rename-mapping.txt as an artifact and attaches it to the Release; the Release body warns that prebuilt artifacts share one fixed (blacklist-able) mapping and users should self-compile. README documents the obfuscation + the self-compile warning.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-01 14:09:28 +08:00

62 lines
2.6 KiB
Java

package shit.zen.dll;
import asm.patchify.loader.PatchAgent;
import net.minecraft.client.Minecraft;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import shit.zen.ZenClient;
import shit.zen.asm.Bootstrap;
/**
* Final hand-off step on the DLL injection path. By the time {@link #start} is
* invoked, {@code GameLoaderBridge} has already re-defined every class in the
* jar onto the Forge GameClassLoader, so {@link ZenClient} and all 21 patch
* handler classes share Minecraft's class loader.
*
* <p>This entry point intentionally does <b>not</b> construct {@link ZenClient}.
* Once {@link PatchAgent#installPatchesAndRetransform()} returns, the
* retransformed {@code Minecraft.tick()} contains the injected
* {@code MinecraftPatch.onTick} prologue that lazily constructs {@link
* ZenClient} on the next tick. Letting the existing tick-driven lazy-init run
* keeps the DLL path and the mod path identical from {@code ZenClient.init}
* onwards.</p>
*/
public final class DllBootstrap {
private static final Logger LOGGER = LogManager.getLogger(DllBootstrap.class);
private static volatile boolean started = false;
private DllBootstrap() {
}
public static synchronized void start(String extractedJarPath) {
if (started) {
LOGGER.info("bootstrap.start ignored (already started)");
return;
}
started = true;
try {
LOGGER.info("bootstrap.start jar={}", extractedJarPath);
LOGGER.info("bootstrap loader = {}", DllBootstrap.class.getClassLoader());
LOGGER.info("client loader = {}", ZenClient.class.getClassLoader());
LOGGER.info("Minecraft loader = {}", Minecraft.class.getClassLoader());
LOGGER.info("agent inst = {}", PatchAgent.getInstrumentation());
// Load mojmap → SRG mappings before we attempt any retransform.
Bootstrap.init();
// Register the 21 patch classes and trigger retransform of the
// already-loaded Minecraft targets. After this returns,
// Minecraft.tick / LocalPlayer.tick / etc. carry the injected
// prologues; the next tick will invoke MinecraftPatch.onTick which
// performs the real ZenClient construction via its existing
// lazy-init path.
ZenClient.registerPatches();
PatchAgent.installPatchesAndRetransform();
LOGGER.info("bootstrap done. client will be constructed on the next tick.");
} catch (Throwable t) {
LOGGER.error("bootstrap.start failed", t);
}
}
}