From c4dde134f4193d6c9dec771fda09e9ee291efecc Mon Sep 17 00:00:00 2001 From: Moresteck Date: Tue, 15 Oct 2024 23:25:58 +0000 Subject: [PATCH] Impl: 13w16a+ support --- .../legacyfix/LegacyFixLauncher.java | 85 +++++++++++++++++-- .../legacyfix/patch/PatchHelper.java | 6 +- .../legacyfix/patch/impl/ClassicPatch.java | 4 + .../legacyfix/patch/impl/DeAwtPatch.java | 7 -- .../legacyfix/patch/impl/LWJGLFramePatch.java | 67 ++++++++++++++- 5 files changed, 152 insertions(+), 17 deletions(-) diff --git a/src/main/java/uk/betacraft/legacyfix/LegacyFixLauncher.java b/src/main/java/uk/betacraft/legacyfix/LegacyFixLauncher.java index af8a652..a347daa 100644 --- a/src/main/java/uk/betacraft/legacyfix/LegacyFixLauncher.java +++ b/src/main/java/uk/betacraft/legacyfix/LegacyFixLauncher.java @@ -4,32 +4,107 @@ import java.io.File; import java.net.URL; -import java.util.*; +import java.util.LinkedList; +import java.util.List; public class LegacyFixLauncher { public static List arguments = new LinkedList(); public static void main(String[] args) { for (String arg : args) { - if (arguments.contains(arg)) { + if (arguments.contains(arg) && arg.startsWith("--")) { LFLogger.error("LegacyFixLauncher", "Duplicate argument '" + arg + "'!"); } arguments.add(arg); } - String minecraftAppletClassName = getValue("appletClass", "net.minecraft.client.MinecraftApplet"); + URL.setURLStreamHandlerFactory(new LegacyURLStreamHandlerFactory()); + + launch(); + } + private static void launch() { + String minecraftAppletClassName = getValue("appletClass", "net.minecraft.client.MinecraftApplet"); try { Class minecraftAppletClass = ClassLoader.getSystemClassLoader().loadClass(minecraftAppletClassName); Object minecraftApplet = minecraftAppletClass.newInstance(); minecraftAppletClass.getDeclaredMethod("init").invoke(minecraftApplet); + } catch (ClassNotFoundException ignored) { + String mainClassName = getValue("mainClass", "net.minecraft.client.main.Main"); + try { + Class minecraftMainClass = ClassLoader.getSystemClassLoader().loadClass(mainClassName); + minecraftMainClass.getMethod("main", new Class[]{String[].class}).invoke(null, new Object[] {getAcceptableArguments()}); + } catch (ClassNotFoundException ignored2) { + LFLogger.error("Failed to find the main class! Tried \"" + minecraftAppletClassName + "\" and \"" + mainClassName + "\""); + } catch (Throwable t) { + LFLogger.error("Failed to launch Minecraft"); + LFLogger.error("launch", t); + } } catch (Throwable t) { LFLogger.error("Failed to launch Minecraft"); - LFLogger.error("LegacyFixLauncher", t); + LFLogger.error("launch", t); + } + } + + private static String[] getAcceptableArguments() { + List args = new LinkedList(); + + // 13w16a to 13w23a don't allow unrecognized arguments + if (hasKey("limit13w16a")) { + args.addAll(limit(false)); + } else if (hasKey("limit13w23a")) { + args.addAll(limit(true)); + } else { + // 13w23b and later finally allow unrecognized arguments + args.addAll(arguments); } - URL.setURLStreamHandlerFactory(new LegacyURLStreamHandlerFactory()); + return args.toArray(new String[0]); + } + + private static List limit(boolean is13w23a) { + List args = new LinkedList(); + + if (hasKey("demo")) + args.add("--demo"); + + if (hasKey("fullscreen")) + args.add("--fullscreen"); + + if (hasKey("gameDir")) { + args.add("--workDir"); + args.add(getValue("gameDir", ".")); + } + + if (hasKey("server")) { + args.add("--server"); + args.add(getValue("server", "localhost")); + } + + if (hasKey("port")) { + args.add("--port"); + args.add(getValue("port", "25565")); + } + + if (hasKey("username")) { + args.add("--username"); + args.add(getValue("username", "Player")); + } + + if (hasKey("session")) { + args.add("--session"); + args.add(getValue("session", "-")); + } + + if (is13w23a) { + if (hasKey("version")) { + args.add("--version"); + args.add(getValue("version", "unknown")); + } + } + + return args; } public static String getValue(String key, String alt) { diff --git a/src/main/java/uk/betacraft/legacyfix/patch/PatchHelper.java b/src/main/java/uk/betacraft/legacyfix/patch/PatchHelper.java index a671756..34920d2 100644 --- a/src/main/java/uk/betacraft/legacyfix/patch/PatchHelper.java +++ b/src/main/java/uk/betacraft/legacyfix/patch/PatchHelper.java @@ -51,7 +51,7 @@ public static CtClass findMinecraftClass(ClassPool pool) throws NotFoundExceptio minecraftClass = pool.getOrNull("net.minecraft.client.Minecraft"); - if (minecraftClass == null) { + if (minecraftClass == null && minecraftAppletClass != null) { for (CtField field : minecraftAppletClass.getDeclaredFields()) { String className = field.getType().getName(); @@ -132,6 +132,10 @@ public static CtClass findMouseHelperClass(ClassPool pool) throws NotFoundExcept findMinecraftClass(pool); } + if (minecraftClass == null) { + return null; + } + CtField[] minecraftFields = minecraftClass.getDeclaredFields(); for (CtField field : minecraftFields) { CtConstructor[] constructors = field.getType().getConstructors(); diff --git a/src/main/java/uk/betacraft/legacyfix/patch/impl/ClassicPatch.java b/src/main/java/uk/betacraft/legacyfix/patch/impl/ClassicPatch.java index 7b35a5f..b91dfd5 100644 --- a/src/main/java/uk/betacraft/legacyfix/patch/impl/ClassicPatch.java +++ b/src/main/java/uk/betacraft/legacyfix/patch/impl/ClassicPatch.java @@ -11,6 +11,7 @@ import uk.betacraft.legacyfix.LFLogger; import uk.betacraft.legacyfix.LegacyFixAgent; import uk.betacraft.legacyfix.patch.Patch; +import uk.betacraft.legacyfix.patch.PatchException; import uk.betacraft.legacyfix.patch.PatchHelper; /** @@ -24,6 +25,9 @@ public ClassicPatch() { @Override public void apply(Instrumentation inst) throws Exception { CtClass minecraftAppletClass = PatchHelper.findMinecraftAppletClass(pool); + if (minecraftAppletClass == null) + throw new PatchException("No applet class could be found"); + if (minecraftAppletClass.isFrozen()) minecraftAppletClass.defrost(); diff --git a/src/main/java/uk/betacraft/legacyfix/patch/impl/DeAwtPatch.java b/src/main/java/uk/betacraft/legacyfix/patch/impl/DeAwtPatch.java index 28f8e98..a87f4a7 100644 --- a/src/main/java/uk/betacraft/legacyfix/patch/impl/DeAwtPatch.java +++ b/src/main/java/uk/betacraft/legacyfix/patch/impl/DeAwtPatch.java @@ -12,7 +12,6 @@ import uk.betacraft.legacyfix.patch.Patch; import uk.betacraft.legacyfix.patch.PatchException; import uk.betacraft.legacyfix.patch.PatchHelper; -import uk.betacraft.legacyfix.util.IconUtils; public class DeAwtPatch extends Patch { private Exception thrown; @@ -23,12 +22,6 @@ public DeAwtPatch() { @Override public void apply(final Instrumentation inst) throws Exception { - try { - IconUtils.loadIcons((String) LegacyFixAgent.getSettings().get("icon")); - } catch (Exception e) { - LFLogger.error(this, e); - } - CtClass minecraftAppletClass = PatchHelper.findMinecraftAppletClass(pool); if (minecraftAppletClass == null) { throw new PatchException("No applet class could be found"); diff --git a/src/main/java/uk/betacraft/legacyfix/patch/impl/LWJGLFramePatch.java b/src/main/java/uk/betacraft/legacyfix/patch/impl/LWJGLFramePatch.java index 9bd0508..587b4f3 100644 --- a/src/main/java/uk/betacraft/legacyfix/patch/impl/LWJGLFramePatch.java +++ b/src/main/java/uk/betacraft/legacyfix/patch/impl/LWJGLFramePatch.java @@ -1,12 +1,15 @@ package uk.betacraft.legacyfix.patch.impl; -import javassist.CtClass; -import javassist.CtConstructor; -import javassist.CtMethod; +import javassist.*; +import javassist.expr.ExprEditor; +import javassist.expr.NewExpr; +import uk.betacraft.legacyfix.LFLogger; import uk.betacraft.legacyfix.LegacyFixAgent; +import uk.betacraft.legacyfix.LegacyFixLauncher; import uk.betacraft.legacyfix.patch.Patch; import uk.betacraft.legacyfix.patch.PatchException; import uk.betacraft.legacyfix.patch.PatchHelper; +import uk.betacraft.legacyfix.util.IconUtils; import java.lang.instrument.ClassDefinition; import java.lang.instrument.Instrumentation; @@ -18,7 +21,13 @@ public LWJGLFramePatch() { } @Override - public void apply(Instrumentation inst) throws PatchException, Exception { + public void apply(final Instrumentation inst) throws PatchException, Exception { + try { + IconUtils.loadIcons((String) LegacyFixAgent.getSettings().get("icon")); + } catch (Exception e) { + LFLogger.error(this, e); + } + CtClass displayClass = pool.get("org.lwjgl.opengl.Display"); if (displayClass.isFrozen()) displayClass.defrost(); @@ -65,5 +74,55 @@ public void apply(Instrumentation inst) throws PatchException, Exception { // @formatter:on inst.redefineClasses(new ClassDefinition(Class.forName(displayModeClass.getName()), displayModeClass.toBytecode())); + + // Make 13w16a-13w24b honor custom width & height + CtClass minecraftMainClass = pool.getOrNull(LegacyFixLauncher.getValue("mainClass", "net.minecraft.client.main.Main")); + if (minecraftMainClass == null) + return; + + CtMethod mainMethod = minecraftMainClass.getDeclaredMethod("main"); + + mainMethod.instrument(new ExprEditor() { + public void edit(NewExpr m) { + try { + CtConstructor minecraftConstructor = m.getConstructor(); + CtClass[] parameterTypes = minecraftConstructor.getParameterTypes(); + + boolean isMinecraft = false; + for (CtClass proxyClass : parameterTypes) { + // Minecraft class constructor in affected versions takes a Proxy object + if (!"java.net.Proxy".equals(proxyClass.getName())) { + continue; + } + + isMinecraft = true; + } + + if (!isMinecraft) + return; + + for (int i = 0; i < parameterTypes.length; i++) { + CtClass intClass = parameterTypes[i]; + if (!"int".equals(intClass.getName())) { + continue; + } + + // @formatter:off + minecraftConstructor.insertBefore( + "Class legacyfix = ClassLoader.getSystemClassLoader().loadClass(\"uk.betacraft.legacyfix.LegacyFixLauncher\");" + + "$" + (i + 1) + " = ((Integer) legacyfix.getMethod(\"getWidth\", null).invoke(null, null)).intValue();" + + "$" + (i + 2) + " = ((Integer) legacyfix.getMethod(\"getHeight\", null).invoke(null, null)).intValue();" + ); + // @formatter:on + + CtClass minecraftClass = minecraftConstructor.getDeclaringClass(); + inst.redefineClasses(new ClassDefinition(Class.forName(minecraftClass.getName()), minecraftClass.toBytecode())); + break; + } + } catch (Throwable t) { + LFLogger.error("lwjglframepatch", t); + } + } + }); } }