Ship a self-contained OpenZenLoader.exe (OpenZen.dll embedded as
RCDATA) that injects into a running Minecraft 1.20.1 Forge
javaw.exe and brings up the Zen client without -javaagent or a
mods/ entry. The existing Forge mod path stays intact.
Native (native/):
- DLL: JNI_GetCreatedJavaVMs + JVMTI late-attach via the JDK's
instrument.dll Agent_OnAttach to obtain a real Instrumentation;
URLClassLoader on the game loader loads a single bridge class.
- Loader EXE: Win32 listview of javaw.exe/java.exe processes
with window titles, CreateRemoteThread+LoadLibraryW injection,
embedded DLL extracted to %TEMP%\OpenZenLoader at runtime.
Java:
- shit.zen.dll.GameLoaderBridge re-defines every jar class onto
the Forge GameClassLoader (fixed-point retry for super-class
deps) and extracts non-class resources to
%TEMP%\openzen-resources-<pid>, exposed via the
openzen.resources system property.
- shit.zen.dll.DllBootstrap only runs Bootstrap.init +
registerPatches + installPatchesAndRetransform; ZenClient
construction stays on MinecraftPatch.onTick lazy-init.
- shit.zen.asm.Bootstrap parses mapping.srg, detects SRG vs
mojmap runtime via Minecraft.tick reflection, exposes
remapMethod/remapField used at 5 PatchTransformer match
points and from ReflectionUtil.
- ReflectionUtil.resolveField walks the superclass chain trying
SRG then mojmap on each level so e.g. activeEffects on
LocalPlayer resolves on LivingEntity.
- shit.zen.utils.misc.Assets unifies resource lookup with a
fallback to openzen.resources; fonts, cloud assets and WebUI
static files route through it.
- PatchAgent.installPatchesAndRetransform is now idempotent so
DllBootstrap and ZenClient.init can both call it safely.
Build:
- ./gradlew jar forge mod jar (unchanged)
- ./gradlew dll single-file Loader EXE in build/dist
- CMake auto-located via vswhere when VS 2022 ships it.
- README documents both paths and required toolchain.
Co-Authored-By: Claude Opus 4.7 <[email protected]>
46 lines
1.3 KiB
CMake
46 lines
1.3 KiB
CMake
set(JAR_SOURCE "${CMAKE_SOURCE_DIR}/zen.jar")
|
|
set(JAR_STAGED "${CMAKE_CURRENT_BINARY_DIR}/zen.jar")
|
|
|
|
if(NOT EXISTS ${JAR_SOURCE})
|
|
message(WARNING
|
|
"zen.jar not found at ${JAR_SOURCE}; "
|
|
"did you run the Gradle 'stageNativeJar' task first? "
|
|
"The DLL will be built but the embedded jar resource will be empty.")
|
|
file(WRITE ${JAR_STAGED} "")
|
|
else()
|
|
configure_file(${JAR_SOURCE} ${JAR_STAGED} COPYONLY)
|
|
endif()
|
|
|
|
add_library(OpenZen SHARED
|
|
src/main.cpp
|
|
src/jvm_attach.cpp
|
|
src/jar_extract.cpp
|
|
src/class_loader.cpp
|
|
src/diagnostics.cpp
|
|
res/openzen.rc
|
|
)
|
|
|
|
target_include_directories(OpenZen PRIVATE
|
|
${CMAKE_CURRENT_SOURCE_DIR}/src
|
|
${CMAKE_CURRENT_SOURCE_DIR}/res
|
|
)
|
|
|
|
# rc.exe needs to find zen.jar (staged into CMAKE_CURRENT_BINARY_DIR by the
|
|
# configure_file above) when assembling RCDATA from openzen.rc.
|
|
set_source_files_properties(res/openzen.rc PROPERTIES
|
|
COMPILE_FLAGS "/I\"${CMAKE_CURRENT_BINARY_DIR}\""
|
|
)
|
|
|
|
target_compile_definitions(OpenZen PRIVATE
|
|
OPENZEN_DLL_EXPORTS
|
|
)
|
|
|
|
set_target_properties(OpenZen PROPERTIES
|
|
OUTPUT_NAME "OpenZen"
|
|
PREFIX ""
|
|
)
|
|
|
|
# We do not link jvm.dll: jvm.dll is already loaded in the host process when the
|
|
# DLL is injected, and JNI_GetCreatedJavaVMs is provided by it. We only need
|
|
# the JNI headers at compile time.
|