Added support for old Alpha versions
This commit is contained in:
parent
326d47f0ce
commit
bb61fb3f6d
6 changed files with 231 additions and 21 deletions
|
@ -10,7 +10,7 @@ repositories {
|
|||
|
||||
group = 'net.minecraft'
|
||||
archivesBaseName = 'launchwrapper'
|
||||
version = '1.4'
|
||||
version = '1.5'
|
||||
|
||||
dependencies {
|
||||
compile 'net.sf.jopt-simple:jopt-simple:4.5'
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
package net.minecraft.launchwrapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
public class AlphaVanillaTweaker implements ITweaker {
|
||||
public static File gameDir;
|
||||
public static File assetsDir;
|
||||
|
||||
private List<String> args;
|
||||
|
||||
@Override
|
||||
public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
|
||||
this.args = args;
|
||||
AlphaVanillaTweaker.gameDir = gameDir;
|
||||
AlphaVanillaTweaker.assetsDir = assetsDir;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectIntoClassLoader(LaunchClassLoader classLoader) {
|
||||
classLoader.registerTransformer("net.minecraft.launchwrapper.injector.AlphaVanillaTweakInjector");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLaunchTarget() {
|
||||
return "net.minecraft.launchwrapper.injector.AlphaVanillaTweakInjector";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getLaunchArguments() {
|
||||
return args.toArray(new String[args.size()]);
|
||||
}
|
||||
}
|
|
@ -18,7 +18,7 @@ public class Launch {
|
|||
new Launch().launch(args);
|
||||
}
|
||||
|
||||
private final LaunchClassLoader classLoader;
|
||||
public static LaunchClassLoader classLoader;
|
||||
|
||||
private Launch() {
|
||||
final URLClassLoader ucl = (URLClassLoader) getClass().getClassLoader();
|
||||
|
|
|
@ -35,8 +35,8 @@ public class LaunchClassLoader extends URLClassLoader {
|
|||
|
||||
private static final String[] RESERVED_NAMES = {"CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9"};
|
||||
|
||||
private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("legacy.debugClassLoading", "false"));
|
||||
private static final boolean DEBUG_FINER = DEBUG && Boolean.parseBoolean(System.getProperty("legacy.debugClassLoadingFiner", "false"));
|
||||
private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("legacy.debugClassLoading", "false")) || true;
|
||||
private static final boolean DEBUG_FINER = DEBUG && Boolean.parseBoolean(System.getProperty("legacy.debugClassLoadingFiner", "false")) || true;
|
||||
private static final boolean DEBUG_SAVE = DEBUG && Boolean.parseBoolean(System.getProperty("legacy.debugClassLoadingSave", "false"));
|
||||
private static File tempFolder = null;
|
||||
|
||||
|
|
|
@ -0,0 +1,178 @@
|
|||
package net.minecraft.launchwrapper.injector;
|
||||
|
||||
import net.minecraft.launchwrapper.IClassTransformer;
|
||||
import net.minecraft.launchwrapper.Launch;
|
||||
import net.minecraft.launchwrapper.VanillaTweaker;
|
||||
import org.lwjgl.opengl.Display;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.ClassWriter;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.objectweb.asm.tree.AbstractInsnNode;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.FieldNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.applet.Applet;
|
||||
import java.applet.AppletStub;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.*;
|
||||
import java.util.List;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
|
||||
public class AlphaVanillaTweakInjector implements IClassTransformer {
|
||||
private static String minecraftClass;
|
||||
private static String minecraftField;
|
||||
|
||||
public AlphaVanillaTweakInjector() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] transform(final String name, final String transformedName, final byte[] bytes) {
|
||||
return bytes;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
|
||||
Class clazz = getaClass("net.minecraft.client.MinecraftApplet");
|
||||
System.out.println("AlphaVanillaTweakInjector.class.getClassLoader() = " + AlphaVanillaTweakInjector.class.getClassLoader());
|
||||
Constructor constructor = clazz.getConstructor();
|
||||
Object object = constructor.newInstance();
|
||||
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
String name = field.getType().getName();
|
||||
|
||||
if (!name.contains(".")) {
|
||||
System.out.println("Found likely Minecraft candidate: " + field);
|
||||
|
||||
Field fileField = getWorkingDirField(name);
|
||||
if (fileField != null) {
|
||||
System.out.println("Found File, changing to " + Launch.minecraftHome);
|
||||
fileField.setAccessible(true);
|
||||
fileField.set(null, Launch.minecraftHome);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
startMinecraft((Applet) object, args);
|
||||
}
|
||||
|
||||
private static void startMinecraft(final Applet applet, String[] args) {
|
||||
final Map<String, String> params = new HashMap<String, String>();
|
||||
|
||||
// Extract params
|
||||
String name = "Player" + System.currentTimeMillis() % 1000;
|
||||
if (args.length > 0) name = args[0];
|
||||
|
||||
String sessionId = "-";
|
||||
if (args.length > 1) sessionId = args[1];
|
||||
|
||||
params.put("username", name);
|
||||
params.put("sessionid", sessionId);
|
||||
|
||||
final Frame launcherFrameFake = new Frame();
|
||||
launcherFrameFake.setTitle("Minecraft");
|
||||
launcherFrameFake.setBackground(Color.BLACK);
|
||||
|
||||
final JPanel panel = new JPanel();
|
||||
launcherFrameFake.setLayout(new BorderLayout());
|
||||
panel.setPreferredSize(new Dimension(854, 480));
|
||||
launcherFrameFake.add(panel, BorderLayout.CENTER);
|
||||
launcherFrameFake.pack();
|
||||
|
||||
launcherFrameFake.setLocationRelativeTo(null);
|
||||
launcherFrameFake.setVisible(true);
|
||||
|
||||
launcherFrameFake.addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
System.exit(1);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
class LauncherFake extends Applet implements AppletStub {
|
||||
public void appletResize(int width, int height) {
|
||||
// Actually empty as well
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isActive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getDocumentBase() {
|
||||
try {
|
||||
return new URL("http://www.minecraft.net/game/");
|
||||
} catch (MalformedURLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParameter(String paramName) {
|
||||
if (params.containsKey(paramName)) {
|
||||
return params.get(paramName);
|
||||
}
|
||||
System.err.println("Client asked for parameter: " + paramName);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
final LauncherFake fakeLauncher = new LauncherFake();
|
||||
applet.setStub(fakeLauncher);
|
||||
|
||||
fakeLauncher.setLayout(new BorderLayout());
|
||||
fakeLauncher.add(applet, BorderLayout.CENTER);
|
||||
fakeLauncher.validate();
|
||||
|
||||
launcherFrameFake.removeAll();
|
||||
launcherFrameFake.setLayout(new BorderLayout());
|
||||
launcherFrameFake.add(fakeLauncher, BorderLayout.CENTER);
|
||||
launcherFrameFake.validate();
|
||||
|
||||
applet.init();
|
||||
applet.start();
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
public void run() {
|
||||
applet.stop();
|
||||
}
|
||||
});
|
||||
|
||||
VanillaTweakInjector.loadIconsOnFrames();
|
||||
}
|
||||
|
||||
private static Class<?> getaClass(String name) throws ClassNotFoundException {
|
||||
return Launch.classLoader.findClass(name);
|
||||
}
|
||||
|
||||
private static Field getWorkingDirField(String name) throws ClassNotFoundException {
|
||||
Class<?> clazz = getaClass(name);
|
||||
|
||||
for (Field field : clazz.getDeclaredFields()) {
|
||||
if (Modifier.isStatic(field.getModifiers()) && field.getType().getName().equals("java.io.File")) {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -10,7 +10,6 @@ import org.objectweb.asm.Type;
|
|||
import org.objectweb.asm.tree.*;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.File;
|
||||
|
@ -64,25 +63,21 @@ public class VanillaTweakInjector implements IClassTransformer {
|
|||
}
|
||||
|
||||
// Prepare our injection code
|
||||
final MethodNode methodNode = new MethodNode();
|
||||
final MethodNode injectedMethod = new MethodNode();
|
||||
final Label label = new Label();
|
||||
methodNode.visitLabel(label);
|
||||
methodNode.visitLineNumber(9001, label); // Linenumber which shows up in the stacktrace
|
||||
injectedMethod.visitLabel(label);
|
||||
injectedMethod.visitLineNumber(9001, label); // Linenumber which shows up in the stacktrace
|
||||
// Call the method below
|
||||
methodNode.visitMethodInsn(INVOKESTATIC, "net/minecraft/launchwrapper/injector/VanillaTweakInjector", "inject", "()Ljava/io/File;");
|
||||
injectedMethod.visitMethodInsn(INVOKESTATIC, "net/minecraft/launchwrapper/injector/VanillaTweakInjector", "inject", "()Ljava/io/File;");
|
||||
// Store the result in the workDir variable.
|
||||
methodNode.visitFieldInsn(PUTSTATIC, "net/minecraft/client/Minecraft", workDirNode.name, "Ljava/io/File;");
|
||||
injectedMethod.visitFieldInsn(PUTSTATIC, "net/minecraft/client/Minecraft", workDirNode.name, "Ljava/io/File;");
|
||||
|
||||
// Find the injection point and insert our code
|
||||
final ListIterator<AbstractInsnNode> iterator = mainMethod.instructions.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final AbstractInsnNode insn = iterator.next();
|
||||
if (insn.getOpcode() == INVOKEVIRTUAL) {
|
||||
final MethodInsnNode mins = (MethodInsnNode) insn;
|
||||
if (mins.owner.equals("java/awt/Frame") && mins.name.equals("validate")) {
|
||||
mainMethod.instructions.insert(insn, methodNode.instructions);
|
||||
break;
|
||||
}
|
||||
if (insn.getOpcode() == RETURN) {
|
||||
mainMethod.instructions.insertBefore(insn, injectedMethod.instructions);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -96,8 +91,16 @@ public class VanillaTweakInjector implements IClassTransformer {
|
|||
System.out.println("Turning of ImageIO disk-caching");
|
||||
ImageIO.setUseCache(false);
|
||||
|
||||
// Load icon from disk
|
||||
loadIconsOnFrames();
|
||||
|
||||
// Set the workdir, return value will get assigned
|
||||
System.out.println("Setting gameDir to:" + VanillaTweaker.gameDir);
|
||||
return VanillaTweaker.gameDir;
|
||||
}
|
||||
|
||||
public static void loadIconsOnFrames() {
|
||||
try {
|
||||
// Load icon from disk
|
||||
final File smallIcon = new File(VanillaTweaker.assetsDir, "icons/icon_16x16.png");
|
||||
final File bigIcon = new File(VanillaTweaker.assetsDir, "icons/icon_32x32.png");
|
||||
System.out.println("Loading current icons for window from: " + smallIcon + " and " + bigIcon);
|
||||
|
@ -121,10 +124,6 @@ public class VanillaTweakInjector implements IClassTransformer {
|
|||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
// Set the workdir, return value will get assigned
|
||||
System.out.println("Setting gameDir to:" + VanillaTweaker.gameDir);
|
||||
return VanillaTweaker.gameDir;
|
||||
}
|
||||
|
||||
private static ByteBuffer loadIcon(final File iconFile) throws IOException {
|
||||
|
|
Loading…
Add table
Reference in a new issue