Skip to content

Commit

Permalink
Fix FML. Move to glass maven
Browse files Browse the repository at this point in the history
  • Loading branch information
Lassebq committed Sep 12, 2024
1 parent 2b7c072 commit 20b4432
Show file tree
Hide file tree
Showing 9 changed files with 158 additions and 74 deletions.
6 changes: 1 addition & 5 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies {
implementation "org.ow2.asm:asm:${project.asm_version}"
implementation "org.ow2.asm:asm-util:${project.asm_version}"
implementation "org.ow2.asm:asm-tree:${project.asm_version}"
implementation "org.json:json:20230311"
implementation "org.json:json:20240303"
// I'll bring discord RPC support later, when I have an environment to compile natives

testRuntimeOnly('org.junit.platform:junit-platform-launcher:1.5.2')
Expand All @@ -41,16 +41,12 @@ allprojects {
}

repositories {
mavenLocal()
maven {
url "https://libraries.minecraft.net/"
}
maven {
url "https://maven.glass-launcher.net/releases"
}
maven {
url "https://mcphackers.github.io/libraries/"
}
mavenCentral()
}

Expand Down
16 changes: 13 additions & 3 deletions src/main/java/org/mcphackers/launchwrapper/Launch.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.mcphackers.launchwrapper;

import org.mcphackers.launchwrapper.loader.LaunchClassLoader;
import org.mcphackers.launchwrapper.target.LaunchTarget;
import org.mcphackers.launchwrapper.tweak.Tweak;

public class Launch {
Expand Down Expand Up @@ -35,7 +36,7 @@ public void launch() {
LaunchClassLoader loader = getLoader();
Tweak mainTweak = getTweak();
if(mainTweak == null) {
System.err.println("Could not find launch target");
LOGGER.logErr("No suitable tweak found. Is Minecraft on classpath?");
return;
}
mainTweak.prepare(loader);
Expand All @@ -45,9 +46,14 @@ public void launch() {
setupDiscordRPC();
}
loader.setLoaderTweak(mainTweak.getLoaderTweak());
mainTweak.getLaunchTarget().launch(loader);
LaunchTarget target = mainTweak.getLaunchTarget();
if(target != null) {
target.launch(loader);
} else {
LOGGER.logErr("Could not find launch target");
}
} else {
System.err.println("Tweak could not be applied");
LOGGER.logErr("Tweak could not be applied");
}
}

Expand Down Expand Up @@ -78,6 +84,10 @@ public void log(String format, Object... args) {
System.out.println("[LaunchWrapper] " + String.format(format, args));
}

public void logErr(String format, Object... args) {
System.err.println("[LaunchWrapper] " + String.format(format, args));
}

public void logDebug(String format, Object... args) {
if(!DEBUG) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,15 @@ private URL getOverridenResourceURL(String name) {
return null;
}

@Override
public URL[] getURLs() {
if(parent instanceof URLClassLoader) {
return ((URLClassLoader)parent).getURLs();
}
//TODO get classpath list on modern java
return super.getURLs();
}

public Enumeration<URL> findResources(String name) throws IOException {
return parent.getResources(name);
}
Expand Down
40 changes: 40 additions & 0 deletions src/main/java/org/mcphackers/launchwrapper/tweak/ForgeTweak.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package org.mcphackers.launchwrapper.tweak;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.mcphackers.launchwrapper.LaunchConfig;
import org.mcphackers.launchwrapper.loader.LaunchClassLoader;
import org.mcphackers.launchwrapper.tweak.injection.Injection;
import org.mcphackers.launchwrapper.tweak.injection.legacy.AddMain;
import org.mcphackers.launchwrapper.tweak.injection.legacy.ClassicCrashScreen;
import org.mcphackers.launchwrapper.tweak.injection.legacy.FixClassicSession;
import org.mcphackers.launchwrapper.tweak.injection.legacy.FixGrayScreen;
import org.mcphackers.launchwrapper.tweak.injection.legacy.FixShutdown;
import org.mcphackers.launchwrapper.tweak.injection.legacy.FixSplashScreen;
import org.mcphackers.launchwrapper.tweak.injection.legacy.ForgeVersionCheck;
import org.mcphackers.launchwrapper.tweak.injection.legacy.IndevSaving;
import org.mcphackers.launchwrapper.tweak.injection.legacy.LWJGLPatch;
import org.mcphackers.launchwrapper.tweak.injection.legacy.LegacyInit;
import org.mcphackers.launchwrapper.tweak.injection.legacy.OptionsLoadFix;
import org.mcphackers.launchwrapper.tweak.injection.legacy.ReplaceGameDir;
import org.mcphackers.launchwrapper.tweak.injection.legacy.UnlicensedCopyText;
import org.mcphackers.launchwrapper.tweak.injection.vanilla.ChangeBrand;

public class ForgeTweak extends LegacyTweak {

public ForgeTweak(LaunchConfig config) {
super(config);
}

public List<Injection> getInjections() {
List<Injection> list = new ArrayList<Injection>();
list.addAll(super.getInjections());
list.add(new ForgeVersionCheck());
return list;
}

}
37 changes: 20 additions & 17 deletions src/main/java/org/mcphackers/launchwrapper/tweak/Tweak.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,26 +62,29 @@ public final boolean transform(ClassNodeSource source) {
public abstract ClassLoaderTweak getLoaderTweak();

public abstract LaunchTarget getLaunchTarget();

public static Tweak forClass(ClassNodeSource source, LaunchConfig launch, String clazz) {
try {
try {
return (Tweak)Class.forName(clazz)
.getConstructor(LaunchConfig.class, Tweak.class)
.newInstance(launch, getDefault(source, launch));
} catch (NoSuchMethodException e) {
return (Tweak)Class.forName(clazz)
.getConstructor(LaunchConfig.class)
.newInstance(launch);
}
} catch (ClassNotFoundException e) {
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

public static Tweak get(ClassNodeSource classLoader, LaunchConfig launch) {
if(launch.tweakClass.get() != null) {
try {
try {
// Instantiate custom tweak if it's present on classpath;
return (Tweak)Class.forName(launch.tweakClass.get())
.getConstructor(LaunchConfig.class, Tweak.class)
.newInstance(launch, getDefault(classLoader, launch));
} catch (NoSuchMethodException e) {
return (Tweak)Class.forName(launch.tweakClass.get())
.getConstructor(LaunchConfig.class)
.newInstance(launch);
}
} catch (ClassNotFoundException e) {
return null;
} catch (Exception e) {
e.printStackTrace();
return null;
}
return forClass(classLoader, launch, launch.tweakClass.get());
}
return getDefault(classLoader, launch);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public boolean required() {

@Override
public boolean apply(ClassNodeSource source, LaunchConfig config) {
if (context.run == null) {
if(context.run == null) {
return false;
}
AbstractInsnNode insn1 = context.run.instructions.getFirst();
Expand All @@ -58,73 +58,70 @@ public boolean apply(ClassNodeSource source, LaunchConfig config) {
LabelNode start = null;
AbstractInsnNode end = null;
TryCatchBlockNode afterCatch = null;
while (insn1 != null) {
while(insn1 != null) {
AbstractInsnNode[] insns1 = fill(insn1, 6);
if (compareInsn(insns1[0], ALOAD, 0)
&& compareInsn(insns1[1], GETFIELD, context.minecraft.name, context.running.name,
context.running.desc)
&& compareInsn(insns1[2], IFEQ)
&& compareInsn(insns1[3], ALOAD, 0)
&& compareInsn(insns1[4], GETFIELD, context.minecraft.name, null,
"L" + context.minecraftApplet.name + ";")
&& compareInsn(insns1[5], IFNULL)) {
if(compareInsn(insns1[0], ALOAD, 0)
&& compareInsn(insns1[1], GETFIELD, context.minecraft.name, context.running.name, context.running.desc)
&& compareInsn(insns1[2], IFEQ)
&& compareInsn(insns1[3], ALOAD, 0)
&& compareInsn(insns1[4], GETFIELD, context.minecraft.name, null, "L" + context.minecraftApplet.name + ";")
&& compareInsn(insns1[5], IFNULL)) {
start = new LabelNode();
context.run.instructions.insertBefore(insn1, start);
JumpInsnNode jmp = (JumpInsnNode) insns1[2];
end = previousInsn(jmp.label); // GOTO outside of loop
// end = previousInsn(end); // GOTO to the beggining of loop
for (TryCatchBlockNode tryCatch : context.run.tryCatchBlocks) {
if (afterCatch == null && tryCatch.type != null && !tryCatch.type.startsWith("java/lang/")) {
for(TryCatchBlockNode tryCatch : context.run.tryCatchBlocks) {
if(afterCatch == null && tryCatch.type != null && !tryCatch.type.startsWith("java/lang/")) {
afterCatch = tryCatch;
}
// if ("java/lang/Throwable".equals(tryCatch.type)) {
AbstractInsnNode testInsn = nextInsn(tryCatch.handler);
while (tryCatch.end != testInsn && testInsn != null) {
while(tryCatch.end != testInsn && testInsn != null) {
testInsn = nextInsn(testInsn);
if (compareInsn(testInsn, ACONST_NULL) && compareInsn(nextInsn(testInsn), PUTFIELD)) {
if(compareInsn(testInsn, ACONST_NULL)
&& compareInsn(nextInsn(testInsn), PUTFIELD)) {
FieldInsnNode putfield = (FieldInsnNode) nextInsn(testInsn);
fieldName = putfield.name;
fieldDesc = putfield.desc;
}
}
// }
}
}
insn1 = nextInsn(insn1);
}
if (start == null || end == null) {
if(start == null || end == null) {
return false;
}
if (fieldDesc == null || fieldName == null) {
if(fieldDesc == null || fieldName == null) {
return false;
}
MethodNode setWorld = null;
for (MethodNode m : context.minecraft.methods) {
if (m.desc.equals("(" + fieldDesc + ")V")) {
for(MethodNode m : context.minecraft.methods) {
if(m.desc.equals("(" + fieldDesc + ")V")) {
setWorld = m;
break;
}
}
if (setWorld == null) {
if(setWorld == null) {
return false;
}
ClassNode errScreen = null;
MethodNode openScreen = null;
for (MethodNode m : context.minecraft.methods) {
if (m.desc.equals("()V")) {
for(MethodNode m : context.minecraft.methods) {
if(m.desc.equals("()V")) {
AbstractInsnNode insn = m.instructions.getFirst();
if (insn != null && insn.getOpcode() == -1) {
if(insn != null && insn.getOpcode() == -1) {
insn = nextInsn(insn);
}
if (!compareInsn(insn, INVOKESTATIC, "org/lwjgl/opengl/Display", "isActive", "()Z")) {
if(!compareInsn(insn, INVOKESTATIC, "org/lwjgl/opengl/Display", "isActive", "()Z")) {
continue;
}
AbstractInsnNode insn2 = insn;
while (insn2 != null) {
while(insn2 != null) {
AbstractInsnNode[] insns2 = fill(insn2, 3);
if (compareInsn(insns2[0], ALOAD, 0)
&& compareInsn(insns2[1], ACONST_NULL)
&& compareInsn(insns2[2], INVOKEVIRTUAL, context.minecraft.name, null, null)) {
if(compareInsn(insns2[0], ALOAD, 0)
&& compareInsn(insns2[1], ACONST_NULL)
&& compareInsn(insns2[2], INVOKEVIRTUAL, context.minecraft.name, null, null)) {
MethodInsnNode invoke = (MethodInsnNode) insns2[2];
openScreen = NodeHelper.getMethod(context.minecraft, invoke.name, invoke.desc);
break;
Expand All @@ -134,40 +131,40 @@ && compareInsn(insns2[2], INVOKEVIRTUAL, context.minecraft.name, null, null)) {
break;
}
}
if (openScreen == null) {
if(openScreen == null) {
return false;
}
AbstractInsnNode insn = openScreen.instructions.getFirst();
while (insn != null) {
if (insn.getOpcode() == INSTANCEOF) {
while(insn != null) {
if(insn.getOpcode() == INSTANCEOF) {
break;
}
insn = nextInsn(insn);
}
if (insn == null) {
if(insn == null) {
return false;
}
errScreen = source.getClass(((TypeInsnNode) insn).desc);

if (errScreen == null) {
if(errScreen == null) {
return false;
}
MethodNode init = NodeHelper.getMethod(errScreen, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V");
if (init == null) {
if(init == null) {
MethodNode newInit = new MethodNode(ACC_PUBLIC, "<init>", "(Ljava/lang/String;Ljava/lang/String;)V", null,
null);
InsnList insnList = newInit.instructions;
insnList.add(new VarInsnNode(ALOAD, 0));
insnList.add(new MethodInsnNode(INVOKESPECIAL, errScreen.superName, "<init>", "()V"));
int c = 1;
for (FieldNode f : errScreen.fields) {
if (!f.desc.equals("Ljava/lang/String;")) {
for(FieldNode f : errScreen.fields) {
if(!f.desc.equals("Ljava/lang/String;")) {
continue;
}
insnList.add(new VarInsnNode(ALOAD, 0));
insnList.add(new VarInsnNode(ALOAD, c));
insnList.add(new FieldInsnNode(PUTFIELD, errScreen.name, f.name, f.desc));
if (c == 2) {
if(c == 2) {
break;
}
c++;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,11 @@
import org.mcphackers.rdi.util.NodeHelper;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.FieldInsnNode;
import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.InsnList;
import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import org.objectweb.asm.tree.LdcInsnNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.VarInsnNode;

public class FixShutdown extends InjectionWithContext<LegacyTweakContext> {
Expand Down Expand Up @@ -94,7 +87,6 @@ && compareInsn(insns2[1], INVOKESTATIC, "java/lang/System", "exit", "(I)V")) {
insert.add(new MethodInsnNode(INVOKESTATIC, "java/lang/System", "exit", "(I)V"));
destroy.instructions.insert(insn1, insert);
b = true;
// tweakInfo("Shutdown patch");
}
}
}
Expand Down Expand Up @@ -126,7 +118,6 @@ && compareInsn(insns2[2], INVOKEVIRTUAL, context.minecraft.name, null, null)) {
if(Type.getReturnType(invoke.desc).getSort() == Type.VOID) {
addTryCatch(destroy, insns2[0], insns2[2], "java/lang/Throwable");
b = true;
// tweakInfo("SoundManager shutdown");
break;
}
}
Expand Down
Loading

0 comments on commit 20b4432

Please sign in to comment.