Skip to content

Commit

Permalink
Move forge injection to corresponding bootstrap class
Browse files Browse the repository at this point in the history
  • Loading branch information
InitAuther97 committed Feb 18, 2025
1 parent f8b5d98 commit 0ed3242
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
import net.minecraftforge.securemodules.SecureModuleFinder;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.MarkerManager;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;

import java.io.File;
import java.io.InputStream;
Expand Down Expand Up @@ -82,6 +86,55 @@ private void inject() throws Throwable {
injectLaunchPlugin();
}

@Override
public void dirtyHacks() throws Exception {
AbstractBootstrap.super.dirtyHacks();
try (var in = getClass().getClassLoader().getResourceAsStream("net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.class")) {
var clazz = new ClassNode();
new ClassReader(in).accept(clazz, 0);
final var mdName = "net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer";
final var mdSig = "L" + mdName + ";";
{
MethodNode constructor = null;
for (var method: clazz.methods) {
if ("<init>".equals(method.name)) {
constructor = method;
}
}
if (constructor == null) {
throw new RuntimeException("Cannot transform ModDiscoverer: <init> not found");
}

FrameNode lastFrame = null;
for (var insn: constructor.instructions) {
if (insn instanceof FrameNode frame) {
lastFrame = frame;
}
}
if (lastFrame == null) {
throw new RuntimeException("Cannot transform ModDiscoverer: <init> return not found");
}

var aloadThis = new VarInsnNode(Opcodes.ALOAD, 0);
var putField = new FieldInsnNode(Opcodes.PUTSTATIC, mdName, "arclight$INSTANCE", mdSig);
constructor.instructions.insertBefore(lastFrame, aloadThis);
constructor.instructions.insert(aloadThis, putField);
constructor.instructions.insert(putField, new InsnNode(Opcodes.RETURN));
constructor.instructions.remove(lastFrame);
}
{
clazz.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "arclight$INSTANCE", mdSig, mdSig, null);
}
var cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
clazz.accept(cw);
byte[] bytes = cw.toByteArray();
Unsafe.defineClass(mdName.replace('/', '.'), bytes, 0, bytes.length, getClass().getClassLoader() /* MC-BOOTSTRAP */, getClass().getProtectionDomain());
System.out.println("Redefined ModDiscoverer in cl:" +getClass().getClassLoader());
} catch (Throwable t) {
t.printStackTrace();
}
}

private void injectClassPath() throws Throwable {
var platform = ClassLoader.getPlatformClassLoader();
var ucpField = platform.getClass().getSuperclass().getDeclaredField("ucp");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
import io.izzel.arclight.i18n.ArclightConfig;
import io.izzel.arclight.i18n.ArclightLocale;
import net.minecraftforge.bootstrap.api.BootstrapEntryPoint;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.tree.*;

import java.util.Arrays;
import java.util.ServiceLoader;
Expand Down Expand Up @@ -49,4 +53,52 @@ public void main(String[] args) {
System.err.println("Fail to launch Arclight.");
}
}

@Override
public void dirtyHacks() throws Exception {
try (var in = getClass().getClassLoader().getResourceAsStream("net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.class")) {
var clazz = new ClassNode();
new ClassReader(in).accept(clazz, 0);
final var mdName = "net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer";
final var mdSig = "L" + mdName + ";";
{
MethodNode constructor = null;
for (var method: clazz.methods) {
if ("<init>".equals(method.name)) {
constructor = method;
}
}
if (constructor == null) {
throw new RuntimeException("Cannot transform ModDiscoverer: <init> not found");
}

FrameNode lastFrame = null;
for (var insn: constructor.instructions) {
if (insn instanceof FrameNode frame) {
lastFrame = frame;
}
}
if (lastFrame == null) {
throw new RuntimeException("Cannot transform ModDiscoverer: <init> return not found");
}

var aloadThis = new VarInsnNode(Opcodes.ALOAD, 0);
var putField = new FieldInsnNode(Opcodes.PUTSTATIC, mdName, "arclight$INSTANCE", mdSig);
constructor.instructions.insertBefore(lastFrame, aloadThis);
constructor.instructions.insert(aloadThis, putField);
constructor.instructions.insert(putField, new InsnNode(Opcodes.RETURN));
constructor.instructions.remove(lastFrame);
}
{
clazz.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "arclight$INSTANCE", mdSig, mdSig, null);
}
var cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
clazz.accept(cw);
byte[] bytes = cw.toByteArray();
Unsafe.defineClass(mdName.replace('/', '.'), bytes, 0, bytes.length, getClass().getClassLoader() /* MC-BOOTSTRAP */, getClass().getProtectionDomain());
System.out.println("Redefined ModDiscoverer in cl:" +getClass().getClassLoader());
} catch (Throwable t) {
t.printStackTrace();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,50 +80,6 @@ default void dirtyHacks() throws Exception {
byte[] bytes = cw.toByteArray();
Unsafe.defineClass("com.mojang.brigadier.tree.CommandNode", bytes, 0, bytes.length, getClass().getClassLoader() /* MC-BOOTSTRAP */, getClass().getProtectionDomain());
}
try (var in = getClass().getClassLoader().getResourceAsStream("net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer.class")) {
var clazz = new ClassNode();
new ClassReader(in).accept(clazz, 0);
final var mdName = "net/minecraftforge/fml/loading/moddiscovery/ModDiscoverer";
final var mdSig = "L" + mdName + ";";
{
MethodNode constructor = null;
for (var method: clazz.methods) {
if ("<init>".equals(method.name)) {
constructor = method;
}
}
if (constructor == null) {
throw new RuntimeException("Cannot transform ModDiscoverer: <init> not found");
}

FrameNode lastFrame = null;
for (var insn: constructor.instructions) {
if (insn instanceof FrameNode frame) {
lastFrame = frame;
}
}
if (lastFrame == null) {
throw new RuntimeException("Cannot transform ModDiscoverer: <init> return not found");
}

var aloadThis = new VarInsnNode(Opcodes.ALOAD, 0);
var putField = new FieldInsnNode(Opcodes.PUTSTATIC, mdName, "arclight$INSTANCE", mdSig);
constructor.instructions.insertBefore(lastFrame, aloadThis);
constructor.instructions.insert(aloadThis, putField);
constructor.instructions.insert(putField, new InsnNode(Opcodes.RETURN));
constructor.instructions.remove(lastFrame);
}
{
clazz.visitField(Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC, "arclight$INSTANCE", mdSig, mdSig, null);
}
var cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
clazz.accept(cw);
byte[] bytes = cw.toByteArray();
Unsafe.defineClass(mdName.replace('/', '.'), bytes, 0, bytes.length, getClass().getClassLoader() /* MC-BOOTSTRAP */, getClass().getProtectionDomain());
System.out.println("Redefined ModDiscoverer in cl:" +getClass().getClassLoader());
} catch (Throwable t) {
t.printStackTrace();
}
}

default void setupMod(ArclightPlatform platform) throws Exception {
Expand Down

0 comments on commit 0ed3242

Please sign in to comment.