Skip to content

Commit

Permalink
Impl: 13w16a+ support
Browse files Browse the repository at this point in the history
  • Loading branch information
Moresteck committed Oct 15, 2024
1 parent 78664d5 commit c4dde13
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 17 deletions.
85 changes: 80 additions & 5 deletions src/main/java/uk/betacraft/legacyfix/LegacyFixLauncher.java
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> arguments = new LinkedList<String>();

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<String> args = new LinkedList<String>();

// 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<String> limit(boolean is13w23a) {
List<String> args = new LinkedList<String>();

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) {
Expand Down
6 changes: 5 additions & 1 deletion src/main/java/uk/betacraft/legacyfix/patch/PatchHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -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();

Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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");
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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();
Expand Down Expand Up @@ -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);
}
}
});
}
}

0 comments on commit c4dde13

Please sign in to comment.