Format source and add README

This commit is contained in:
Lassebq 2023-03-13 00:50:07 +02:00
parent d18a02a90c
commit ee061a6204
No known key found for this signature in database
GPG key ID: DE0866BB0C980B6E
33 changed files with 3266 additions and 3439 deletions

51
README.md Normal file
View file

@ -0,0 +1,51 @@
# LaunchWrapper
**LaunchWrapper** is a wrapper for legacy Minecraft which provides fixes for certain game features and also improves compatibility with launchers.
LaunchWrapper is bundled in [BetterJSONs](https://github.com/MCPHackers/BetterJSONs) which are meant for official Minecraft Launcher.
# Features
- Strips game window from Java **AWT** (**Abstract Window Toolkit**) and lets the game use internal **LWJGL** frame
- Allows changing assets directory in 1.6 snapshots (the game didn't have a parameter to do that yet)
- Allows changing game directory in versions before 1.6
- Replaces mouse input code with **LWJGL** calls
- Fixes TimSort crash when using java 8+
- Adds ability to customize built-in **LWJGL** frame
- Changing display title
- Setting icon
- Proxies all requests from old skin servers to the current skin API and converts skins to required format
- Uses Betacraft proxy to download sounds for versions before 1.6
- Adds ability to launch classic and pre-classic at custom resolution and fullscreen
- Makes save slots in classic and indev functional and saves to `.minecraft/levels` directory
- A launcher for isometric level viewer (IsomPreviewApplet)
- A VSync toggle (Used to prevent extreme framerate in early versions which causes **coil whine**)
- Does not depend on any hard-coded obfuscated names and is mostly compatible with every Minecraft version
- This also includes modded versions
- A parameter to download `minecraft_server.jar` for snapshots which require it: `12w18a`, `12w19a`, `12w21a`
- The wrapper is fully compatible with java 5+ if the game is vanilla
# How to use
*This is a more in-depth guide for people experienced in Java*
Make sure all minecraft and wrapper libraries are on classpath<br>
Use `java -cp <classpath> org.mcphackers.launchwrapper.Launch <arguments>` to launch the game
Arguments are formatted the same way as in Mojang launch wrapper. <br>
For example: `--username DemoUser --width 1280 --height 720 --title "Minecraft Demo" --demo`
Arguments may be as follows:
- `awtFrame` - disable AWT patches (Does not work at that moment)
- `isom` - Launch IsomPreviewApplet
- `forceVsync` - Launch the game with VSync enabled
- `forceResizable` - Early Indev and Classic are don't properly update viewport, so the wrapper disables frame resizing. To enable it anyway use this argument
- `skinProxy` - **classic** / **pre-b1.9-pre4** / **pre-1.8** / **default** - convert the skin to one of these specified formats
- **classic** - flatten all skin layers, flip bottom textures and crop to 64x32
- **pre-b1.9-pre4** - flip bottom textures and crop to 64x32
- **pre-1.8** - crop to 64x32
- **default** - do nothing with requested skin
- `resourcesProxyPort` - Betacraft proxy port for sound resources
- `serverSHA1` - Compare minecraft_server.jar in .minecraft/server against this hash
- `serverURL` - URL to download the server from if the hash is mismatched or the jar is missing
- `icon` - List of path of icon graphics separated by `;`
- `title` - The display title
- \+ any Minecraft launch argument or applet parameter

View file

@ -21,7 +21,7 @@ dependencies {
implementation 'org.lwjgl.lwjgl:lwjgl_util:2.9.4'
implementation 'org.ow2.asm:asm:9.3'
implementation 'org.ow2.asm:asm-tree:9.3'
implementation 'org.json:json:20220924'
implementation 'org.json:json:20230311'
}
task sourcesJar(type: Jar) {

View file

@ -18,16 +18,16 @@ public class AppletLaunchTarget extends LaunchTarget {
targetClass = classTarget;
title = classTarget;
}
public void setTitle(String title) {
this.title = title;
}
public void setResolution(int w, int h) {
width = w;
height = h;
}
public void setIcon(Image img) {
icon = img;
}

View file

@ -10,9 +10,9 @@ public class Launch {
private static final LaunchClassLoader CLASS_LOADER = LaunchClassLoader.instantiate();
public static Launch INSTANCE;
public final LaunchConfig config;
private Launch(LaunchConfig config) {
this.config = config;
}
@ -34,11 +34,11 @@ public class Launch {
mainTweak.getLaunchTarget(CLASS_LOADER).launch();
}
}
public void setClassPath(URL[] urls) {
CLASS_LOADER.setClassPath(urls);
}
public static Launch create(LaunchConfig config) {
return INSTANCE = new Launch(config);
}

View file

@ -9,6 +9,7 @@ import java.util.Map;
public class LaunchConfig {
private Map<String, LaunchParameter<?>> parameters = new HashMap<String, LaunchParameter<?>>();
public LaunchParameterSwitch demo = new LaunchParameterSwitch("demo", false);
public LaunchParameterSwitch fullscreen = new LaunchParameterSwitch("fullscreen", false);
public LaunchParameterSwitch checkGlErrors = new LaunchParameterSwitch("checkGlErrors", false);
@ -41,7 +42,7 @@ public class LaunchConfig {
public LaunchParameterString loadmap_user = new LaunchParameterString("loadmap_user");
public LaunchParameterNumber loadmap_id = new LaunchParameterNumber("loadmap_id");
public LaunchParameterString mppass = new LaunchParameterString("mppass", "");
public LaunchParameterSwitch lwjglFrame = new LaunchParameterSwitch("lwjglFrame", true, true);
public LaunchParameterSwitch lwjglFrame = new LaunchParameterSwitch("awtFrame", true, true);
public LaunchParameterSwitch isom = new LaunchParameterSwitch("isom", false, true);
public LaunchParameterSwitch forceVsync = new LaunchParameterSwitch("forceVsync", false, true);
public LaunchParameterSwitch forceResizable = new LaunchParameterSwitch("forceResizable", false, true);
@ -53,40 +54,36 @@ public class LaunchConfig {
public LaunchParameterString title = new LaunchParameterString("title", null, true);
public LaunchConfig(String[] args) {
int i = 0;
while(i < args.length) {
for(int i = 0; i < args.length; i++) {
if(args[i].startsWith("--")) {
String paramName = args[i].substring(2);
LaunchParameter<?> param = parameters.get(paramName.toLowerCase(Locale.ENGLISH));
if(paramName.equalsIgnoreCase("awtFrame")) {
lwjglFrame.set(false);
if(param == null) {
continue;
}
else if(param != null) {
if(param.isSwitch()) {
((LaunchParameterSwitch)param).set(true);
}
else if(i + 1 < args.length) {
try {
//TODO better handling for alternative parameter names
if(param.equals(session)) {
sessionid.set(args[i + 1]);
}
if(param.equals(sessionid)) {
session.set(args[i + 1]);
}
if(param.equals(gameDir)) {
workDir.set(new File(args[i + 1]));
}
if(param.equals(workDir)) {
gameDir.set(new File(args[i + 1]));
}
param.setString(args[i + 1]);
i++;
} catch (IllegalArgumentException e) {}
if(param.isSwitch()) {
((LaunchParameterSwitch) param).setFlag();
} else if(i + 1 < args.length) {
try {
// TODO better handling for alternative parameter names
if(param.equals(session)) {
sessionid.set(args[i + 1]);
}
if(param.equals(sessionid)) {
session.set(args[i + 1]);
}
if(param.equals(gameDir)) {
workDir.set(new File(args[i + 1]));
}
if(param.equals(workDir)) {
gameDir.set(new File(args[i + 1]));
}
param.setString(args[i + 1]);
i++;
} catch (IllegalArgumentException e) {
}
}
}
i++;
}
}
@ -109,7 +106,7 @@ public class LaunchConfig {
}
return map;
}
public String[] getArgs() {
List<String> list = new ArrayList<String>();
for(LaunchParameter<?> param : parameters.values()) {
@ -126,46 +123,46 @@ public class LaunchConfig {
String[] arr = new String[list.size()];
return list.toArray(arr);
}
public abstract class LaunchParameter<T> {
public final String name;
public final boolean wrapperOnly;
protected LaunchParameter(String name) {
this(name, false);
}
protected LaunchParameter(String name, boolean wrapper) {
this.name = name;
this.wrapperOnly = wrapper;
parameters.put(name.toLowerCase(Locale.ENGLISH), this);
}
public boolean isSwitch() {
return false;
}
public abstract String getString();
public abstract void setString(String argument);
public abstract Object get();
public abstract void set(T value);
}
public class LaunchParameterFile extends LaunchParameter<File> {
private File value;
public LaunchParameterFile(String name) {
super(name);
}
public LaunchParameterFile(String name, File defaultValue) {
super(name);
value = defaultValue;
}
public LaunchParameterFile(String name, File defaultValue, boolean wrapper) {
super(name, wrapper);
value = defaultValue;
@ -173,7 +170,8 @@ public class LaunchConfig {
@Override
public String getString() {
if(value == null) return null;
if(value == null)
return null;
return this.value.getAbsolutePath();
}
@ -186,25 +184,25 @@ public class LaunchConfig {
public File get() {
return this.value;
}
@Override
public void set(File value) {
this.value = value;
}
}
public class LaunchParameterFileList extends LaunchParameter<File[]> {
private File[] value;
public LaunchParameterFileList(String name) {
super(name);
}
public LaunchParameterFileList(String name, File[] defaultValue) {
super(name);
value = defaultValue;
}
public LaunchParameterFileList(String name, File[] defaultValue, boolean wrapper) {
super(name, wrapper);
value = defaultValue;
@ -212,7 +210,8 @@ public class LaunchConfig {
@Override
public String getString() {
if(value == null) return null;
if(value == null)
return null;
String s = "";
for(int i = 0; i < value.length; i++) {
if(i != 0) {
@ -237,30 +236,33 @@ public class LaunchConfig {
public File[] get() {
return this.value;
}
@Override
public void set(File[] value) {
this.value = value;
}
}
public class LaunchParameterSwitch extends LaunchParameter<Boolean> {
private boolean value;
private boolean defaultValue;
public LaunchParameterSwitch(String name) {
super(name);
}
public LaunchParameterSwitch(String name, Boolean defaultValue) {
public LaunchParameterSwitch(String name, Boolean defaultVal) {
super(name);
value = defaultValue;
defaultValue = defaultVal;
value = defaultVal;
}
public LaunchParameterSwitch(String name, Boolean defaultValue, boolean wrapper) {
public LaunchParameterSwitch(String name, Boolean defaultVal, boolean wrapper) {
super(name, wrapper);
value = defaultValue;
defaultValue = defaultVal;
value = defaultVal;
}
public boolean isSwitch() {
return true;
}
@ -279,25 +281,33 @@ public class LaunchConfig {
public Boolean get() {
return this.value;
}
@Override
public void set(Boolean value) {
this.value = value == null ? false : value;
}
public void setFlag() {
this.value = !defaultValue;
}
public void toggle() {
this.value = !value;
}
}
public class LaunchParameterString extends LaunchParameter<String> {
private String value;
public LaunchParameterString(String name) {
super(name);
}
public LaunchParameterString(String name, String defaultValue) {
super(name);
value = defaultValue;
}
public LaunchParameterString(String name, String defaultValue, boolean wrapper) {
super(name, wrapper);
value = defaultValue;
@ -317,25 +327,25 @@ public class LaunchConfig {
public String get() {
return this.value;
}
@Override
public void set(String value) {
this.value = value;
}
}
public class LaunchParameterNumber extends LaunchParameter<Integer> {
private Integer value;
public LaunchParameterNumber(String name) {
super(name);
}
public LaunchParameterNumber(String name, Integer defaultValue) {
super(name);
value = defaultValue;
}
public LaunchParameterNumber(String name, Integer defaultValue, boolean wrapper) {
super(name, wrapper);
value = defaultValue;
@ -355,7 +365,7 @@ public class LaunchConfig {
public Integer get() {
return this.value;
}
@Override
public void set(Integer value) {
this.value = value;

View file

@ -3,9 +3,9 @@ package org.mcphackers.launchwrapper;
import org.mcphackers.launchwrapper.loader.LaunchClassLoader;
public abstract class LaunchTarget {
protected final LaunchClassLoader classLoader;
public LaunchTarget(LaunchClassLoader classLoader) {
this.classLoader = classLoader;
}

View file

@ -3,15 +3,15 @@ package org.mcphackers.launchwrapper;
import org.mcphackers.launchwrapper.loader.LaunchClassLoader;
public class MainLaunchTarget extends LaunchTarget {
public String targetClass;
public String[] args;
public MainLaunchTarget(LaunchClassLoader classLoader, String classTarget) {
super(classLoader);
targetClass = classTarget;
}
public void launch() {
classLoader.invokeMain(targetClass, args);
}

View file

@ -5,13 +5,13 @@ import org.objectweb.asm.tree.FieldNode;
import org.objectweb.asm.tree.MethodNode;
public interface ClassNodeSource {
ClassNode getClass(String name);
FieldNode getField(String owner, String name, String desc);
MethodNode getMethod(String owner, String name, String desc);
void overrideClass(ClassNode node);
}

View file

@ -18,26 +18,26 @@ import org.mcphackers.launchwrapper.tweak.AppletWrapper;
import org.mcphackers.launchwrapper.util.Util;
public class Inject {
private static final Launch LAUNCH = Launch.INSTANCE;
private static final BufferedImage DEFAULT_ICON = getIcon();
public static AppletWrapper getApplet() {
return new AppletWrapper(LAUNCH.config.getArgsAsMap());
}
/**
* Indev load level injection
*/
public static File getLevelFile(int index) {
return new File(LAUNCH.config.gameDir.get(), "levels/level" + index + ".dat");
}
public static AppletWrapper getApplet() {
return new AppletWrapper(LAUNCH.config.getArgsAsMap());
}
/**
* Indev save level injection
*/
public static File saveLevel(int index, String levelName) {
final int maxLevels = 5;
/**
* Indev load level injection
*/
public static File getLevelFile(int index) {
return new File(LAUNCH.config.gameDir.get(), "levels/level" + index + ".dat");
}
/**
* Indev save level injection
*/
public static File saveLevel(int index, String levelName) {
final int maxLevels = 5;
File levels = new File(LAUNCH.config.gameDir.get(), "levels");
File level = new File(levels, "level" + index + ".dat");
File levelNames = new File(levels, "levels.txt");
@ -77,33 +77,30 @@ public class Inject {
return null;
}
return level;
}
}
public static ByteBuffer loadIcon(BufferedImage icon) {
final int[] rgb = icon.getRGB(0, 0, icon.getWidth(), icon.getHeight(), null, 0, icon.getWidth());
public static ByteBuffer loadIcon(BufferedImage icon) {
final int[] rgb = icon.getRGB(0, 0, icon.getWidth(), icon.getHeight(), null, 0, icon.getWidth());
final ByteBuffer buffer = ByteBuffer.allocate(4 * rgb.length);
for (int color : rgb) {
buffer.putInt(color << 8 | ((color >> 24) & 0xFF));
}
buffer.flip();
return buffer;
}
final ByteBuffer buffer = ByteBuffer.allocate(4 * rgb.length);
for(int color : rgb) {
buffer.putInt(color << 8 | ((color >> 24) & 0xFF));
}
buffer.flip();
return buffer;
}
public static ByteBuffer[] loadDefaultIcon(boolean grassBlock) {
if(!grassBlock) {
try {
return new ByteBuffer[] { loadIcon("/icon_16x16.png"), loadIcon("/icon_32x32.png") };
} catch (IOException e) {
e.printStackTrace();
}
}
return new ByteBuffer[] { loadIcon(DEFAULT_ICON) };
}
public static ByteBuffer[] loadDefaultIcon(boolean grassBlock) {
if(!grassBlock) {
try {
return new ByteBuffer[] {
loadIcon("/icon_16x16.png"),
loadIcon("/icon_32x32.png")
};
} catch (IOException e) {
e.printStackTrace();
}
}
return new ByteBuffer[] { loadIcon(DEFAULT_ICON) };
}
public static ByteBuffer[] loadIcons() {
List<ByteBuffer> processedIcons = new ArrayList<ByteBuffer>();
for(File icon : LAUNCH.config.icon.get()) {
@ -118,7 +115,7 @@ public class Inject {
}
return processedIcons.toArray(new ByteBuffer[0]);
}
public static ByteBuffer[] loadIcon(File icon) {
try {
return new ByteBuffer[] { loadIcon(ImageIO.read(icon)) };
@ -126,11 +123,11 @@ public class Inject {
return null;
}
}
private static ByteBuffer loadIcon(String icon) throws IOException {
return loadIcon(ImageIO.read(Inject.class.getResourceAsStream(icon)));
}
public static BufferedImage getIcon() {
if(DEFAULT_ICON != null) {
return DEFAULT_ICON;

View file

@ -15,11 +15,11 @@ public class InjectUtils {
PRIVATE, DEFAULT, PROTECTED, PUBLIC;
public static Access getFromBytecode(int acc) {
if ((acc & ACC_PRIVATE) == ACC_PRIVATE)
if((acc & ACC_PRIVATE) == ACC_PRIVATE)
return PRIVATE;
if ((acc & ACC_PROTECTED) == ACC_PROTECTED)
if((acc & ACC_PROTECTED) == ACC_PROTECTED)
return PROTECTED;
if ((acc & ACC_PUBLIC) == ACC_PUBLIC)
if((acc & ACC_PUBLIC) == ACC_PUBLIC)
return PUBLIC;
return DEFAULT;
}
@ -32,25 +32,25 @@ public class InjectUtils {
return acc;
}
}
public static FieldNode getField(ClassNode node, String name, String desc) {
for(FieldNode field : node.fields) {
if(field.name.equals(name) && field.desc.equals(desc)) {
return field;
}
}
return null;
for(FieldNode field : node.fields) {
if(field.name.equals(name) && field.desc.equals(desc)) {
return field;
}
}
return null;
}
public static MethodNode getMethod(ClassNode node, String name, String desc) {
for(MethodNode method : node.methods) {
if(method.name.equals(name) && method.desc.equals(desc)) {
return method;
}
}
return null;
for(MethodNode method : node.methods) {
if(method.name.equals(name) && method.desc.equals(desc)) {
return method;
}
}
return null;
}
public static List<MethodNode> getConstructors(ClassNode node) {
List<MethodNode> constructors = new ArrayList<MethodNode>();
for(MethodNode method : node.methods) {
@ -60,15 +60,15 @@ public class InjectUtils {
}
return constructors;
}
public static boolean isAbstract(MethodNode method) {
return (method.access & ACC_ABSTRACT) != 0;
}
public static boolean isStatic(MethodNode method) {
return (method.access & ACC_STATIC) != 0;
}
public static boolean isStatic(FieldNode field) {
return (field.access & ACC_STATIC) != 0;
}

View file

@ -30,9 +30,9 @@ public class InsnHelper {
}
public static InsnList copyInsns(InsnList insnList) {
MethodNode mv = new MethodNode();
insnList.accept(mv);
return mv.instructions;
MethodNode mv = new MethodNode();
insnList.accept(mv);
return mv.instructions;
}
public static void removeRange(InsnList insns, AbstractInsnNode first, AbstractInsnNode last) {
@ -56,25 +56,25 @@ public class InsnHelper {
public static AbstractInsnNode intInsn(int value) {
switch(value) {
case -1:
return new InsnNode(ICONST_M1);
case 0:
return new InsnNode(ICONST_0);
case 1:
return new InsnNode(ICONST_1);
case 2:
return new InsnNode(ICONST_2);
case 3:
return new InsnNode(ICONST_3);
case 4:
return new InsnNode(ICONST_4);
case 5:
return new InsnNode(ICONST_5);
default:
if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
return new IntInsnNode(SIPUSH, value);
}
return new LdcInsnNode(value);
case -1:
return new InsnNode(ICONST_M1);
case 0:
return new InsnNode(ICONST_0);
case 1:
return new InsnNode(ICONST_1);
case 2:
return new InsnNode(ICONST_2);
case 3:
return new InsnNode(ICONST_3);
case 4:
return new InsnNode(ICONST_4);
case 5:
return new InsnNode(ICONST_5);
default:
if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
return new IntInsnNode(SIPUSH, value);
}
return new LdcInsnNode(value);
}
}
@ -85,14 +85,11 @@ public class InsnHelper {
public static AbstractInsnNode floatInsn(float value) {
if(value == 0F) {
return new InsnNode(FCONST_0);
}
else if(value == 1F) {
} else if(value == 1F) {
return new InsnNode(FCONST_1);
}
else if(value == 2F) {
} else if(value == 2F) {
return new InsnNode(FCONST_2);
}
else {
} else {
return new LdcInsnNode(value);
}
}
@ -100,11 +97,9 @@ public class InsnHelper {
public static AbstractInsnNode doubleInsn(double value) {
if(value == 0D) {
return new InsnNode(DCONST_0);
}
else if(value == 1D) {
} else if(value == 1D) {
return new InsnNode(DCONST_1);
}
else {
} else {
return new LdcInsnNode(value);
}
}
@ -117,7 +112,7 @@ public class InsnHelper {
current = current.getPrevious();
}
if(current.getType() == LABEL) {
return (LabelNode)current;
return (LabelNode) current;
}
return null;
}
@ -136,8 +131,7 @@ public class InsnHelper {
AbstractInsnNode insn = first;
while(insn != null) {
AbstractInsnNode prev = insn.getPrevious();
if(prev != null && prev.getOpcode() == ALOAD && ((VarInsnNode)prev).var == 0
&& insn.getOpcode() == INVOKESPECIAL && ((MethodInsnNode)insn).name.equals("<init>")) {
if(prev != null && prev.getOpcode() == ALOAD && ((VarInsnNode) prev).var == 0 && insn.getOpcode() == INVOKESPECIAL && ((MethodInsnNode) insn).name.equals("<init>")) {
break;
}
insn = insn.getNext();
@ -157,19 +151,13 @@ public class InsnHelper {
}
public static boolean isReturn(int opcode) {
return
opcode == RETURN ||
opcode == IRETURN ||
opcode == LRETURN ||
opcode == FRETURN ||
opcode == DRETURN ||
opcode == ARETURN;
return opcode == RETURN || opcode == IRETURN || opcode == LRETURN || opcode == FRETURN || opcode == DRETURN || opcode == ARETURN;
}
public static boolean containsInvoke(InsnList insns, MethodInsnNode invoke) {
for(AbstractInsnNode insn : insns) {
if(insn.getType() == METHOD_INSN) {
MethodInsnNode invoke2 = (MethodInsnNode)insn;
MethodInsnNode invoke2 = (MethodInsnNode) insn;
if(invoke2.getOpcode() == invoke.getOpcode() && invoke2.owner.equals(invoke.owner) && invoke2.name.equals(invoke.name) && invoke2.desc.equals(invoke.desc)) {
return true;
}
@ -212,7 +200,7 @@ public class InsnHelper {
AbstractInsnNode insn = instructions.getFirst();
while(insn != null) {
if(insn.getType() == VAR_INSN) {
VarInsnNode var = (VarInsnNode)insn;
VarInsnNode var = (VarInsnNode) insn;
lastFree = Math.max(lastFree, var.var + 1);
}
insn = insn.getNext();
@ -220,42 +208,42 @@ public class InsnHelper {
return lastFree;
}
@SuppressWarnings("unused")
public static boolean compareInsn(AbstractInsnNode insn, int opcode, Object... compare) {
if(insn == null) {
return false;
}
boolean opcodeEqual = opcode == insn.getOpcode() || opcode == -1;
if(!opcodeEqual) return false;
if(!opcodeEqual)
return false;
if(compare.length == 0 && opcodeEqual) {
return true;
}
boolean matches = true;
switch(insn.getType()) {
case INSN:
InsnNode insn1 = (InsnNode)insn;
InsnNode insn1 = (InsnNode) insn;
// Nothing to compare
return matches;
case INT_INSN:
IntInsnNode insn2 = (IntInsnNode)insn;
IntInsnNode insn2 = (IntInsnNode) insn;
if(compare.length > 0) {
matches &= insn2.operand == (Integer)compare[0];
matches &= insn2.operand == (Integer) compare[0];
}
return matches;
case VAR_INSN:
VarInsnNode insn3 = (VarInsnNode)insn;
VarInsnNode insn3 = (VarInsnNode) insn;
if(compare.length > 0) {
matches &= insn3.var == (Integer)compare[0];
matches &= insn3.var == (Integer) compare[0];
}
return matches;
case TYPE_INSN:
TypeInsnNode insn4 = (TypeInsnNode)insn;
TypeInsnNode insn4 = (TypeInsnNode) insn;
if(compare.length > 0) {
matches &= insn4.desc.equals(compare[0]);
}
return matches;
case FIELD_INSN:
FieldInsnNode insn5 = (FieldInsnNode)insn;
FieldInsnNode insn5 = (FieldInsnNode) insn;
if(compare.length > 0) {
matches &= compare[0] == null || insn5.owner.equals(compare[0]);
}
@ -267,7 +255,7 @@ public class InsnHelper {
}
return matches;
case METHOD_INSN:
MethodInsnNode insn6 = (MethodInsnNode)insn;
MethodInsnNode insn6 = (MethodInsnNode) insn;
if(compare.length > 0) {
matches &= compare[0] == null || insn6.owner.equals(compare[0]);
}
@ -279,9 +267,9 @@ public class InsnHelper {
}
return matches;
case INVOKE_DYNAMIC_INSN:
InvokeDynamicInsnNode insn7 = (InvokeDynamicInsnNode)insn;
InvokeDynamicInsnNode insn7 = (InvokeDynamicInsnNode) insn;
if(compare.length > 0) {
matches &= compare[0] == null || insn7.bsm.equals(compare[0]); //TODO ?
matches &= compare[0] == null || insn7.bsm.equals(compare[0]); // TODO ?
}
if(compare.length > 1) {
matches &= compare[1] == null || insn7.name.equals(compare[1]);
@ -291,63 +279,63 @@ public class InsnHelper {
}
return matches;
case JUMP_INSN:
JumpInsnNode insn8 = (JumpInsnNode)insn;
JumpInsnNode insn8 = (JumpInsnNode) insn;
if(compare.length > 0) {
LabelNode label = (LabelNode)compare[0];
LabelNode label = (LabelNode) compare[0];
matches &= label == insn8.label;
}
return matches;
case LABEL:
LabelNode insn9 = (LabelNode)insn;
//TODO
LabelNode insn9 = (LabelNode) insn;
// TODO
return matches;
case LDC_INSN:
LdcInsnNode insn10 = (LdcInsnNode)insn;
LdcInsnNode insn10 = (LdcInsnNode) insn;
if(compare.length > 0) {
Object o = compare[0];
matches &= o == null && insn10.cst == null || o != null && o.equals(insn10.cst);
}
return matches;
case IINC_INSN:
IincInsnNode insn11 = (IincInsnNode)insn;
IincInsnNode insn11 = (IincInsnNode) insn;
if(compare.length > 0) {
Integer i = (Integer)compare[0];
Integer i = (Integer) compare[0];
matches &= i == null || insn11.var == i;
}
if(compare.length > 1) {
Integer i = (Integer)compare[1];
Integer i = (Integer) compare[1];
matches &= i == null || insn11.incr == i;
}
return matches;
case TABLESWITCH_INSN:
TableSwitchInsnNode insn12 = (TableSwitchInsnNode)insn;
TableSwitchInsnNode insn12 = (TableSwitchInsnNode) insn;
// TODO
return matches;
case LOOKUPSWITCH_INSN:
LookupSwitchInsnNode insn13 = (LookupSwitchInsnNode)insn;
LookupSwitchInsnNode insn13 = (LookupSwitchInsnNode) insn;
// TODO
return matches;
case MULTIANEWARRAY_INSN:
MultiANewArrayInsnNode insn14 = (MultiANewArrayInsnNode)insn;
MultiANewArrayInsnNode insn14 = (MultiANewArrayInsnNode) insn;
if(compare.length > 0) {
matches &= compare[0] == null || insn14.desc.equals(compare[0]);
}
if(compare.length > 1) {
Integer i = (Integer)compare[0];
Integer i = (Integer) compare[0];
matches &= i == null || insn14.dims == i;
}
return matches;
case FRAME:
FrameNode insn15 = (FrameNode)insn;
FrameNode insn15 = (FrameNode) insn;
// TODO
return matches;
case LINE:
LineNumberNode insn16 = (LineNumberNode)insn;
LineNumberNode insn16 = (LineNumberNode) insn;
if(compare.length > 0) {
matches &= insn16.line == (Integer)compare[0];
matches &= insn16.line == (Integer) compare[0];
}
return matches;
}
return false;
}

View file

@ -65,13 +65,13 @@ public class LaunchClassLoader extends ClassLoader implements ClassNodeSource {
name = className(name);
Class<?> cls = exceptions.get(name);
if(cls != null) {
return cls;
return cls;
}
cls = transformedClass(name);
if(cls != null) {
return cls;
return cls;
}
throw new ClassNotFoundException(name);
throw new ClassNotFoundException(name);
}
public void invokeMain(String launchTarget, String... args) {
@ -89,36 +89,41 @@ public class LaunchClassLoader extends ClassLoader implements ClassNodeSource {
protected Class<?> redefineClass(String name) {
byte[] classData = getClassAsBytes(name);
if(classData == null) return null;
if(classData == null)
return null;
System.out.println(name);
Class<?> definedClass = defineClass(name, classData, 0, classData.length, getProtectionDomain(name));
classes.put(name, definedClass);
return definedClass;
}
private ProtectionDomain getProtectionDomain(String name) {
final URL resource = parent.getResource(classResourceName(name));
if (resource == null) {
return null;
}
URLConnection urlConnection;
final URL resource = parent.getResource(classResourceName(name));
if(resource == null) {
return null;
}
URLConnection urlConnection;
try {
urlConnection = resource.openConnection();
} catch (IOException e) {
e.printStackTrace();
return null;
}
CodeSource codeSource = urlConnection == null ? null : new CodeSource(urlConnection.getURL(), new Certificate[0]);
CodeSource codeSource = urlConnection == null ? null : new CodeSource(urlConnection.getURL(), new Certificate[0]);
return new ProtectionDomain(codeSource, null);
}
public void overrideClass(ClassNode node) {
if(node == null) return;
if(node == null)
return;
overridenClasses.put(className(node.name), node);
classNodeCache.put(node.name, node);
}
/**
* @param name can be specified either as net.minecraft.client.Minecraft or as net/minecraft/client/Minecraft
* @param name
* can be specified either as net.minecraft.client.Minecraft or as
* net/minecraft/client/Minecraft
* @return parsed ClassNode
*/
public ClassNode getClass(String name) {
@ -127,20 +132,21 @@ public class LaunchClassLoader extends ClassLoader implements ClassNodeSource {
return node;
}
byte[] classData = getClassAsBytes(name);
if(classData == null) return null;
if(classData == null)
return null;
ClassNode classNode = new ClassNode();
ClassReader classReader = new ClassReader(classData);
classReader.accept(classNode, 0);
classNodeCache.put(classNode.name, classNode);
return classNode;
ClassReader classReader = new ClassReader(classData);
classReader.accept(classNode, 0);
classNodeCache.put(classNode.name, classNode);
return classNode;
}
public FieldNode getField(String owner, String name, String desc) {
return InjectUtils.getField(getClass(owner), name, desc);
return InjectUtils.getField(getClass(owner), name, desc);
}
public MethodNode getMethod(String owner, String name, String desc) {
return InjectUtils.getMethod(getClass(owner), name, desc);
return InjectUtils.getMethod(getClass(owner), name, desc);
}
private Class<?> redefineClass(ClassNode node) {
@ -168,17 +174,18 @@ public class LaunchClassLoader extends ClassLoader implements ClassNodeSource {
}
private byte[] getClassAsBytes(String name) {
InputStream is = parent.getResourceAsStream(classResourceName(name));
if(is == null) return null;
byte[] classData;
InputStream is = parent.getResourceAsStream(classResourceName(name));
if(is == null)
return null;
byte[] classData;
try {
classData = Util.readStream(is);
} catch (IOException e) {
Util.closeSilently(is);
Util.closeSilently(is);
return null;
}
Util.closeSilently(is);
return classData;
Util.closeSilently(is);
return classData;
}
private Class<?> transformedClass(String name) {
@ -188,11 +195,11 @@ public class LaunchClassLoader extends ClassLoader implements ClassNodeSource {
}
ClassNode transformed = overridenClasses.get(name);
if(transformed != null) {
return redefineClass(transformed);
return redefineClass(transformed);
}
return redefineClass(name);
return redefineClass(name);
}
public void addException(Class<?> cls) {
exceptions.put(cls.getName(), cls);
}

View file

@ -5,11 +5,11 @@ import org.objectweb.asm.ClassWriter;
public class SafeClassWriter extends ClassWriter {
private final ClassLoader classLoader;
public SafeClassWriter(final int flags) {
this(null, flags);
}
public SafeClassWriter(ClassLoader parent, int flags) {
this(parent, null, flags);
}
@ -18,6 +18,7 @@ public class SafeClassWriter extends ClassWriter {
super(classReader, flags);
classLoader = parent == null ? ClassLoader.getSystemClassLoader() : parent;
}
protected ClassLoader getClassLoader() {
return classLoader;
}

View file

@ -21,10 +21,12 @@ public class BasicResponseURLConnection extends HttpURLConnection {
}
@Override
public void connect() throws IOException {}
public void connect() throws IOException {
}
@Override
public void disconnect() {}
public void disconnect() {
}
@Override
public boolean usingProxy() {
@ -35,8 +37,8 @@ public class BasicResponseURLConnection extends HttpURLConnection {
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(responseMessage.getBytes());
}
public int getResponseCode() {
return responseCode;
}
}
}

View file

@ -5,10 +5,10 @@ import java.net.URL;
import java.net.URLConnection;
public class LegacyURLStreamHandler extends URLStreamHandlerProxy {
private SkinType skins;
private int port;
public LegacyURLStreamHandler(SkinType skins, int port) {
this.skins = skins;
this.port = port;
@ -19,47 +19,46 @@ public class LegacyURLStreamHandler extends URLStreamHandlerProxy {
String host = url.getHost();
String path = url.getPath();
if(host.endsWith(".minecraft.net") || host.equals("s3.amazonaws.com")) {
if (path.equals("/game/joinserver.jsp"))
if(path.equals("/game/joinserver.jsp"))
return new BasicResponseURLConnection(url, "ok");
else if (path.equals("/login/session.jsp"))
else if(path.equals("/login/session.jsp"))
return new BasicResponseURLConnection(url, "ok");
else if (host.equals("login.minecraft.net") && path.equals("/session"))
else if(host.equals("login.minecraft.net") && path.equals("/session"))
return new BasicResponseURLConnection(url, "ok");
else if (path.equals("/game/"))
else if(path.equals("/game/"))
return new BasicResponseURLConnection(url, "42069");
else if (path.equals("/haspaid.jsp"))
else if(path.equals("/haspaid.jsp"))
return new BasicResponseURLConnection(url, "true");
else if (path.contains("/level/save.html"))
else if(path.contains("/level/save.html"))
return new SaveLevelURLConnection(url);
else if (path.contains("/level/load.html"))
else if(path.contains("/level/load.html"))
return new LoadLevelURLConnection(url);
else if (path.equals("/listmaps.jsp"))
else if(path.equals("/listmaps.jsp"))
return new ListLevelsURLConnection(url);
else if (path.startsWith("/MinecraftResources/") || path.startsWith("/resources/"))
else if(path.startsWith("/MinecraftResources/") || path.startsWith("/resources/"))
return new ResourceIndexURLConnection(url, port);
else if (path.startsWith("/MinecraftSkins/") || path.startsWith("/skin/")
|| path.startsWith("/MinecraftCloaks/") || path.startsWith("/cloak/"))
else if(path.startsWith("/MinecraftSkins/") || path.startsWith("/skin/") || path.startsWith("/MinecraftCloaks/") || path.startsWith("/cloak/"))
return new SkinURLConnection(url, skins);
else if(host.equals("assets.minecraft.net") && path.equals("/1_6_has_been_released.flag")) {
return new BasicResponseURLConnection(url, "");
//return new BasicResponseURLConnection(url, "https://web.archive.org/web/20130702232237if_/https://mojang.com/2013/07/minecraft-the-horse-update/");
// return new BasicResponseURLConnection(url, "https://web.archive.org/web/20130702232237if_/https://mojang.com/2013/07/minecraft-the-horse-update/");
}
}
return super.openConnection(url);
}
public enum SkinType {
CLASSIC("classic"),
PRE_B1_9("pre-b1.9-pre4"),
PRE_1_8("pre-1.8"),
DEFAULT("default");
private String name;
private SkinType(String name) {
this.name = name;
}
public static SkinType get(String name) {
for(SkinType skinType : values()) {
if(skinType.name.equals(name)) {
@ -69,7 +68,7 @@ public class LegacyURLStreamHandler extends URLStreamHandlerProxy {
return null;
}
}
public enum ResourceIndex {
}
}
}

View file

@ -13,15 +13,16 @@ import org.mcphackers.launchwrapper.Launch;
import org.mcphackers.launchwrapper.util.Util;
public class ListLevelsURLConnection extends URLConnection {
public static final String EMPTY_LEVEL = "-";
public ListLevelsURLConnection(URL url) {
super(url);
}
@Override
public void connect() throws IOException {}
public void connect() throws IOException {
}
public InputStream getInputStream() throws IOException {
File levels = new File(Launch.INSTANCE.config.gameDir.get(), "levels");

View file

@ -26,7 +26,8 @@ public class LoadLevelURLConnection extends HttpURLConnection {
}
@Override
public void connect() throws IOException {}
public void connect() throws IOException {
}
@Override
public void disconnect() {

View file

@ -9,18 +9,19 @@ import org.mcphackers.launchwrapper.protocol.LegacyURLStreamHandler.ResourceInde
import org.mcphackers.launchwrapper.util.Util;
public class ResourceIndexURLConnection extends URLConnection {
private static final String[] RESOURCES = new String[] {"/resources/", "/MinecraftResources/"};
private static final String[] RESOURCES = new String[] { "/resources/", "/MinecraftResources/" };
ResourceIndex index = null;
int port = -1;
public ResourceIndexURLConnection(URL url, int port) {
super(url);
this.port = port;
}
@Override
public void connect() throws IOException {}
public void connect() throws IOException {
}
@Override
public InputStream getInputStream() throws IOException {
@ -32,7 +33,7 @@ public class ResourceIndexURLConnection extends URLConnection {
}
return url.openStream();
}
protected int getPort() {
return port;
}

View file

@ -21,7 +21,7 @@ public class SaveLevelURLConnection extends HttpURLConnection {
ByteArrayOutputStream levelOutput = new ByteArrayOutputStream();
Exception exception;
public SaveLevelURLConnection(URL url) {
super(url);
}
@ -39,7 +39,6 @@ public class SaveLevelURLConnection extends HttpURLConnection {
return false;
}
@SuppressWarnings("unused")
@Override
public InputStream getInputStream() throws IOException {
try {
@ -70,12 +69,11 @@ public class SaveLevelURLConnection extends HttpURLConnection {
if(levelName.equals("---")) {
level.delete();
lvlNames[levelId] = EMPTY_LEVEL;
}
else {
} else {
if(!levels.exists()) {
levels.mkdirs();
}
OutputStream fileOutput = new FileOutputStream(level);
OutputStream fileOutput = new FileOutputStream(level);
fileOutput.write(levelData);
fileOutput.close();
}

View file

@ -2,7 +2,6 @@ package org.mcphackers.launchwrapper.protocol;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
@ -19,11 +18,11 @@ public class SkinRequests {
public static String getUUIDfromName(String username) {
String cachedUUID = nameToUUID.get(username);
if (cachedUUID != null) {
if(cachedUUID != null) {
return cachedUUID;
} else {
JSONObject obj = requestUUIDfromName(username);
if (obj != null) {
if(obj != null) {
String uuid = obj.optString("id");
nameToUUID.put(username, uuid);
@ -38,7 +37,7 @@ public class SkinRequests {
try {
URL profileURL = new URL("https://api.mojang.com/users/profiles/minecraft/" + name);
InputStream connStream = profileURL.openConnection().getInputStream();
JSONObject uuidJson = new JSONObject(new String(Util.readStream(connStream), "UTF-8"));
JSONObject uuidJson = new JSONObject(new String(Util.readStream(connStream), "UTF-8"));
return uuidJson;
} catch (Throwable t) {
@ -49,24 +48,24 @@ public class SkinRequests {
public static SkinData fetchSkin(String uuid) {
try {
URL uuidtoprofileURL = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid);
URL uuidtoprofileURL = new URL("https://sessionserver.mojang.com/session/minecraft/profile/" + uuid);
JSONObject profilejson = new JSONObject(new String(Util.readStream(uuidtoprofileURL.openStream()), "UTF-8"));
String base64tex = profilejson.getJSONArray("properties").getJSONObject(0).optString("value");
String texjsonstr = new String(Base64.decode(base64tex), "UTF-8");
JSONObject profilejson = new JSONObject(new String(Util.readStream(uuidtoprofileURL.openStream()), "UTF-8"));
String base64tex = profilejson.getJSONArray("properties").getJSONObject(0).optString("value");
String texjsonstr = new String(Base64.decode(base64tex), "UTF-8");
JSONObject texjson = new JSONObject(texjsonstr);
JSONObject txts = texjson.optJSONObject("textures");
JSONObject skinjson = txts.optJSONObject("SKIN");
String skinURLstr = skinjson.optString("url");
JSONObject texjson = new JSONObject(texjsonstr);
JSONObject txts = texjson.optJSONObject("textures");
JSONObject skinjson = txts.optJSONObject("SKIN");
String skinURLstr = skinjson.optString("url");
byte[] officialCape = null;
byte[] officialSkin = null;
JSONObject capejson = txts.optJSONObject("CAPE");
if (capejson != null) {
String capeURLstr = capejson.optString("url");
URL capeURL = new URL(capeURLstr);
if(capejson != null) {
String capeURLstr = capejson.optString("url");
URL capeURL = new URL(capeURLstr);
officialCape = Util.readStream(capeURL.openStream());
}
@ -108,20 +107,20 @@ public class SkinRequests {
byte[] cape = null;
try {
if (skindata.cape != null) {
if(skindata.cape != null) {
switch(skinType) {
case CLASSIC:
case PRE_B1_9:
case PRE_1_8:
ByteArrayInputStream bis = new ByteArrayInputStream(skindata.cape);
ImageUtils imgu = new ImageUtils(bis);
imgu = imgu.crop(0, 0, 64, 32);
cape = imgu.getInByteForm();
break;
case DEFAULT:
return skindata.cape;
case CLASSIC:
case PRE_B1_9:
case PRE_1_8:
ByteArrayInputStream bis = new ByteArrayInputStream(skindata.cape);
ImageUtils imgu = new ImageUtils(bis);
imgu = imgu.crop(0, 0, 64, 32);
cape = imgu.getInByteForm();
break;
case DEFAULT:
return skindata.cape;
}
}
} catch (Throwable t) {
@ -139,23 +138,23 @@ public class SkinRequests {
byte[] skin = null;
try {
if (skindata.skin != null) {
if(skindata.skin != null) {
ByteArrayInputStream bis = new ByteArrayInputStream(skindata.skin);
ImageUtils imgu = new ImageUtils(bis);
switch(skinType) {
case CLASSIC:
overlayHeadLayer(imgu);
case PRE_B1_9:
rotateBottomTX(imgu);
case PRE_1_8:
if(imgu.getImage().getHeight() == 64)
overlay64to32(imgu);
if(skindata.slim)
alexToSteve(imgu);
imgu = imgu.crop(0, 0, 64, 32);
case DEFAULT:
break;
case CLASSIC:
overlayHeadLayer(imgu);
case PRE_B1_9:
rotateBottomTX(imgu);
case PRE_1_8:
if(imgu.getImage().getHeight() == 64)
overlay64to32(imgu);
if(skindata.slim)
alexToSteve(imgu);
imgu = imgu.crop(0, 0, 64, 32);
case DEFAULT:
break;
}
skin = imgu.getInByteForm();
}

View file

@ -11,13 +11,13 @@ import org.mcphackers.launchwrapper.protocol.LegacyURLStreamHandler.SkinType;
import org.mcphackers.launchwrapper.util.Util;
public class SkinURLConnection extends HttpURLConnection {
private static final String[] CLOAKS = {"/cloak/", "/MinecraftCloaks/"};
private static final String[] SKINS = {"/skin/", "/MinecraftSkins/"};
private static final String[] CLOAKS = { "/cloak/", "/MinecraftCloaks/" };
private static final String[] SKINS = { "/skin/", "/MinecraftSkins/" };
protected SkinType skinType;
protected InputStream inputStream;
public SkinURLConnection(URL url, SkinType skin) {
super(url);
responseCode = 200;
@ -25,7 +25,8 @@ public class SkinURLConnection extends HttpURLConnection {
}
@Override
public void disconnect() {}
public void disconnect() {
}
@Override
public boolean usingProxy() {
@ -38,8 +39,8 @@ public class SkinURLConnection extends HttpURLConnection {
String username = queryMap.get("user");
String path = url.getPath();
for (String template : CLOAKS) {
if (path.startsWith(template)) {
for(String template : CLOAKS) {
if(path.startsWith(template)) {
if(username == null)
username = path.substring(template.length()).replace(".png", "");
byte[] skinData = SkinRequests.getCape(username, skinType);
@ -50,8 +51,8 @@ public class SkinURLConnection extends HttpURLConnection {
}
}
for (String template : SKINS) {
if (path.startsWith(template)) {
for(String template : SKINS) {
if(path.startsWith(template)) {
if(username == null)
username = path.substring(template.length()).replace(".png", "");
byte[] skinData = SkinRequests.getSkin(username, skinType);
@ -68,4 +69,4 @@ public class SkinURLConnection extends HttpURLConnection {
public InputStream getInputStream() throws IOException {
return inputStream;
}
}
}

View file

@ -14,14 +14,14 @@ import org.mcphackers.launchwrapper.util.Util;
public abstract class URLStreamHandlerProxy extends URLStreamHandler {
private static final Map<String, URLStreamHandler> DEFAULT_HANDLERS = new HashMap<String, URLStreamHandler>();
protected URLStreamHandler parent;
@Override
protected final URLConnection openConnection(URL url, Proxy p) throws IOException {
return openConnection(url);
}
protected URLConnection openConnection(URL url) throws IOException {
if(parent == null) {
return null;
@ -34,27 +34,27 @@ public abstract class URLStreamHandlerProxy extends URLStreamHandler {
handler.parent = getURLStreamHandler(protocol);
try {
Field handlersField = URL.class.getDeclaredField("handlers");
Hashtable handlers = (Hashtable)Util.getStaticObjectUnsafe(handlersField);
Hashtable handlers = (Hashtable) Util.getStaticObjectUnsafe(handlersField);
handlers.put(protocol, handler);
} catch (Exception e) {
e.printStackTrace();
}
}
public static URLStreamHandler getURLStreamHandler(String protocol) {
URLStreamHandler handler = DEFAULT_HANDLERS.get(protocol);
if(handler != null) {
return handler;
}
try {
URL url = new URL(protocol + ":");
Field handlerField = URL.class.getDeclaredField("handler");
handler = (URLStreamHandler)Util.getObjectUnsafe(url, handlerField);
DEFAULT_HANDLERS.put(protocol, handler);
return handler;
} catch (Exception e) {
e.printStackTrace();
return null;
}
try {
URL url = new URL(protocol + ":");
Field handlerField = URL.class.getDeclaredField("handler");
handler = (URLStreamHandler) Util.getObjectUnsafe(url, handlerField);
DEFAULT_HANDLERS.put(protocol, handler);
return handler;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}

View file

@ -15,53 +15,53 @@ import java.util.Collections;
import java.util.Map;
public class AppletWrapper extends Applet implements AppletStub {
private static final long serialVersionUID = 1L;
private Map<String, String> args;
private static final long serialVersionUID = 1L;
public AppletWrapper(Map<String, String> argsAsMap) {
args = argsAsMap;
private Map<String, String> args;
public AppletWrapper(Map<String, String> argsAsMap) {
args = argsAsMap;
}
public void appletResize(int width, int height) {
}
}
@Override
public boolean isActive() {
return true;
}
@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 URL getDocumentBase() {
try {
return new URL("http://www.minecraft.net/game/");
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
@Override
public URL getCodeBase() {
try {
return new URL("http://www.minecraft.net/game/");
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
@Override
public URL getCodeBase() {
try {
return new URL("http://www.minecraft.net/game/");
} catch (MalformedURLException e) {
e.printStackTrace();
}
return null;
}
@Override
public String getParameter(String paramName) {
return args.get(paramName);
}
public static void startApplet(Class<? extends Applet> appletClass, int width, int height, String title) {
startApplet(appletClass, width, height, title, null);
}
public static void startApplet(Class<? extends Applet> appletClass, int width, int height, String title, Image icon) {
try {
@Override
public String getParameter(String paramName) {
return args.get(paramName);
}
public static void startApplet(Class<? extends Applet> appletClass, int width, int height, String title) {
startApplet(appletClass, width, height, title, null);
}
public static void startApplet(Class<? extends Applet> appletClass, int width, int height, String title, Image icon) {
try {
final Applet applet = appletClass.newInstance();
if(applet != null) {
applet.setStub(new AppletWrapper(Collections.<String, String>emptyMap()));
@ -82,8 +82,8 @@ public class AppletWrapper extends Applet implements AppletStub {
}
});
applet.start();
} catch (Exception e) {
e.printStackTrace();
};
}
} catch (Exception e) {
e.printStackTrace();
} ;
}
}

View file

@ -30,7 +30,7 @@ public class IsomTweak extends LegacyTweak {
public IsomTweak(ClassNodeSource source, LaunchConfig launch) {
super(source, launch);
}
protected void init() {
super.init();
isomApplet = source.getClass(MAIN_ISOM);
@ -70,7 +70,7 @@ public class IsomTweak extends LegacyTweak {
source.overrideClass(isomCanvas);
return true;
}
public LaunchTarget getLaunchTarget(LaunchClassLoader loader) {
if(isomApplet != null) {
AppletLaunchTarget launchTarget = new AppletLaunchTarget(loader, isomApplet.name);

View file

@ -8,15 +8,15 @@ import org.mcphackers.launchwrapper.loader.LaunchClassLoader;
public abstract class Tweak {
private static final boolean DEBUG = true;
protected ClassNodeSource source;
public Tweak(ClassNodeSource source) {
this.source = source;
}
public abstract boolean transform();
public abstract LaunchTarget getLaunchTarget(LaunchClassLoader loader);
public static Tweak get(LaunchClassLoader classLoader, LaunchConfig launch) {
@ -38,7 +38,7 @@ public abstract class Tweak {
}
return null; // Tweak not found
}
protected void debugInfo(String msg) {
if(DEBUG)
System.out.println("TWEAK: " + msg);

View file

@ -22,7 +22,7 @@ import org.objectweb.asm.tree.*;
public class VanillaTweak extends Tweak {
public static final String MAIN_CLASS = "net/minecraft/client/main/Main";
protected LaunchConfig launch;
protected ClassNode minecraftMain;
protected ClassNode minecraft;
@ -37,12 +37,13 @@ public class VanillaTweak extends Tweak {
public boolean transform() {
minecraftMain = source.getClass(MAIN_CLASS);
MethodNode main = InjectUtils.getMethod(minecraftMain, "main", "([Ljava/lang/String;)V");
if(main == null) return false;
if(main == null)
return false;
AbstractInsnNode insn = main.instructions.getLast();
while(insn != null) {
// Last call inside of main is minecraft.run();
if(insn.getOpcode() == INVOKEVIRTUAL) {
MethodInsnNode invoke = (MethodInsnNode)insn;
MethodInsnNode invoke = (MethodInsnNode) insn;
minecraft = source.getClass(invoke.owner);
run = InjectUtils.getMethod(minecraft, invoke.name, invoke.desc);
debugInfo(minecraft.name + "." + invoke.name + invoke.desc + " is Minecraft.run()");
@ -53,9 +54,9 @@ public class VanillaTweak extends Tweak {
for(AbstractInsnNode insn2 = main.instructions.getFirst(); insn2 != null; insn2 = nextInsn(insn2)) {
if(compareInsn(insn2, INVOKEVIRTUAL, "joptsimple/OptionParser", "accepts", "(Ljava/lang/String;)Ljoptsimple/OptionSpecBuilder;")) {
if(insn2.getPrevious() != null && insn2.getPrevious().getType() == AbstractInsnNode.LDC_INSN) {
LdcInsnNode ldc = (LdcInsnNode)insn2.getPrevious();
LdcInsnNode ldc = (LdcInsnNode) insn2.getPrevious();
if(ldc.cst instanceof String) {
availableParameters.add((String)ldc.cst);
availableParameters.add((String) ldc.cst);
}
}
}
@ -75,60 +76,58 @@ public class VanillaTweak extends Tweak {
MethodNode init = getInit(run);
boolean fixedTitle = replaceTitle(init);
boolean fixedIcon = replaceIcon(init);
for(MethodNode m : minecraft.methods) {
if(!fixedTitle) {
fixedTitle = replaceTitle(m);
}
if(!fixedIcon) {
fixedIcon = replaceIcon(m);
}
if(fixedTitle && fixedIcon) {
break;
}
for(MethodNode m : minecraft.methods) {
if(!fixedTitle) {
fixedTitle = replaceTitle(m);
}
if(!fixedIcon) {
fixedIcon = replaceIcon(m);
}
if(fixedTitle && fixedIcon) {
break;
}
}
source.overrideClass(minecraft);
return true;
}
private boolean replaceTitle(MethodNode m) {
AbstractInsnNode insn = m.instructions.getFirst();
while(insn != null) {
AbstractInsnNode[] insns = fill(insn, 2);
if(compareInsn(insns[0], LDC)
&& compareInsn(insns[1], INVOKESTATIC, "org/lwjgl/opengl/Display", "setTitle", "(Ljava/lang/String;)V")) {
LdcInsnNode ldc = (LdcInsnNode)insn;
if(ldc.cst instanceof String) {
if(launch.title.get() != null) {
debugInfo("Replaced title");
ldc.cst = launch.title.get();
return true;
}
}
}
if(compareInsn(insns[0], LDC) && compareInsn(insns[1], INVOKESTATIC, "org/lwjgl/opengl/Display", "setTitle", "(Ljava/lang/String;)V")) {
LdcInsnNode ldc = (LdcInsnNode) insn;
if(ldc.cst instanceof String) {
if(launch.title.get() != null) {
debugInfo("Replaced title");
ldc.cst = launch.title.get();
return true;
}
}
}
insn = nextInsn(insn);
}
return false;
}
private boolean replaceIcon(MethodNode m) {
AbstractInsnNode insn = m.instructions.getFirst();
while(insn != null) {
if(launch.icon.get() != null && hasIcon(launch.icon.get())
&& compareInsn(insn, INVOKESTATIC, "org/lwjgl/opengl/Display", "setIcon", "([Ljava/nio/ByteBuffer;)I")) {
IdentifyCall call = new IdentifyCall((MethodInsnNode)insn);
for(AbstractInsnNode[] arg : call.getArguments()) {
remove(m.instructions, arg);
}
MethodInsnNode insert = new MethodInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "loadIcons", "()[Ljava/nio/ByteBuffer;");
m.instructions.insertBefore(insn, insert);
debugInfo("Replaced icon");
if(launch.icon.get() != null && hasIcon(launch.icon.get()) && compareInsn(insn, INVOKESTATIC, "org/lwjgl/opengl/Display", "setIcon", "([Ljava/nio/ByteBuffer;)I")) {
IdentifyCall call = new IdentifyCall((MethodInsnNode) insn);
for(AbstractInsnNode[] arg : call.getArguments()) {
remove(m.instructions, arg);
}
MethodInsnNode insert = new MethodInsnNode(INVOKESTATIC, "org/mcphackers/launchwrapper/inject/Inject", "loadIcons", "()[Ljava/nio/ByteBuffer;");
m.instructions.insertBefore(insn, insert);
debugInfo("Replaced icon");
return true;
}
}
insn = nextInsn(insn);
}
return false;
}
private boolean hasIcon(File[] icons) {
for(File f : icons) {
if(f.exists()) {
@ -141,7 +140,7 @@ public class VanillaTweak extends Tweak {
private MethodNode getInit(MethodNode run) {
for(AbstractInsnNode insn : run.instructions) {
if(insn.getType() == AbstractInsnNode.METHOD_INSN) {
MethodInsnNode invoke = (MethodInsnNode)insn;
MethodInsnNode invoke = (MethodInsnNode) insn;
if(invoke.owner.equals(minecraft.name)) {
return InjectUtils.getMethod(minecraft, invoke.name, invoke.desc);
}
@ -155,14 +154,9 @@ public class VanillaTweak extends Tweak {
AbstractInsnNode insn = m.instructions.getFirst();
while(insn != null) {
AbstractInsnNode[] insns = fill(insn, 6);
if(compareInsn(insns[0], NEW, "java/io/File")
&& compareInsn(insns[1], DUP)
&& compareInsn(insns[2], ALOAD, 0)
&& compareInsn(insns[3], GETFIELD, minecraft.name, null, "Ljava/io/File;")
&& compareInsn(insns[4], LDC)
&& compareInsn(insns[5], INVOKESPECIAL, "java/io/File", "<init>", "(Ljava/io/File;Ljava/lang/String;)V")) {
LdcInsnNode ldc = (LdcInsnNode)insns[4];
String s = (String)ldc.cst;
if(compareInsn(insns[0], NEW, "java/io/File") && compareInsn(insns[1], DUP) && compareInsn(insns[2], ALOAD, 0) && compareInsn(insns[3], GETFIELD, minecraft.name, null, "Ljava/io/File;") && compareInsn(insns[4], LDC) && compareInsn(insns[5], INVOKESPECIAL, "java/io/File", "<init>", "(Ljava/io/File;Ljava/lang/String;)V")) {
LdcInsnNode ldc = (LdcInsnNode) insns[4];
String s = (String) ldc.cst;
if(s.startsWith("assets/")) {
ldc.cst = s.substring(6);
InsnList insert = new InsnList();
@ -173,7 +167,7 @@ public class VanillaTweak extends Tweak {
m.instructions.remove(insns[2]);
m.instructions.remove(insns[3]);
m.instructions.insert(insns[1], insert);
} else if (s.equals("assets")) {
} else if(s.equals("assets")) {
ldc.cst = assets;
m.instructions.remove(insns[2]);
m.instructions.remove(insns[3]);

File diff suppressed because it is too large Load diff

View file

@ -9,6 +9,7 @@ import javax.imageio.ImageIO;
/**
* use this for whatever you want
*
* @author Moresteck
*/
public class ImageUtils {
@ -28,10 +29,10 @@ public class ImageUtils {
int bufHeight = this.bufImg.getHeight();
BufferedImage img = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
for (int i = 0; i < bufWidth; i++) {
for (int j = 0; j < bufHeight; j++) {
if (j >= y && j < y+height && i >= x && i < x+width) {
img.setRGB(i-x, j-y, pixels[i][j]);
for(int i = 0; i < bufWidth; i++) {
for(int j = 0; j < bufHeight; j++) {
if(j >= y && j < y + height && i >= x && i < x + width) {
img.setRGB(i - x, j - y, pixels[i][j]);
}
}
}
@ -47,13 +48,13 @@ public class ImageUtils {
int height = this.bufImg.getHeight();
int[][] pixels = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
int pixel = this.bufImg.getRGB(i, j);
if (j >= y && j < y+img.getHeight() && i >= x && i < x+img.getWidth()) {
int toset = img.getRGB(i-x, j-y);
if (!forceTransparent) {
if ((toset>>24) != 0x00) {
if(j >= y && j < y + img.getHeight() && i >= x && i < x + img.getWidth()) {
int toset = img.getRGB(i - x, j - y);
if(!forceTransparent) {
if((toset >> 24) != 0x00) {
pixel = toset;
}
} else {
@ -64,8 +65,8 @@ public class ImageUtils {
}
}
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
this.bufImg.setRGB(i, j, pixels[i][j]);
}
@ -78,9 +79,9 @@ public class ImageUtils {
int width = this.bufImg.getWidth();
int height = this.bufImg.getHeight();
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
this.bufImg.setRGB(flipX ? width-1-i : i, flipY ? height-1-j : j, pixels[i][j]);
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
this.bufImg.setRGB(flipX ? width - 1 - i : i, flipY ? height - 1 - j : j, pixels[i][j]);
}
}
return this;
@ -91,8 +92,8 @@ public class ImageUtils {
int height = this.bufImg.getHeight();
int[][] pixels = new int[width][height];
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
for(int i = 0; i < width; i++) {
for(int j = 0; j < height; j++) {
pixels[i][j] = this.bufImg.getRGB(i, j);
}
}

View file

@ -12,16 +12,15 @@ import java.util.Map;
import sun.misc.Unsafe;
@SuppressWarnings("restriction")
public final class Util {
private static final Unsafe theUnsafe = getUnsafe();
private static Unsafe getUnsafe() {
try {
final Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
unsafeField.setAccessible(true);
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
unsafeField.setAccessible(true);
final Unsafe unsafe = (Unsafe) unsafeField.get(null);
return unsafe;
} catch (Exception e) {
e.printStackTrace();
@ -30,49 +29,49 @@ public final class Util {
}
public static void setStaticBooleanUnsafe(final Field field, boolean value) {
final Object staticFieldBase = theUnsafe.staticFieldBase(field);
final long staticFieldOffset = theUnsafe.staticFieldOffset(field);
theUnsafe.putBoolean(staticFieldBase, staticFieldOffset, value);
final Object staticFieldBase = theUnsafe.staticFieldBase(field);
final long staticFieldOffset = theUnsafe.staticFieldOffset(field);
theUnsafe.putBoolean(staticFieldBase, staticFieldOffset, value);
}
public static void setStaticObjectUnsafe(final Field field, Object value) {
final Object staticFieldBase = theUnsafe.staticFieldBase(field);
final long staticFieldOffset = theUnsafe.staticFieldOffset(field);
theUnsafe.putObject(staticFieldBase, staticFieldOffset, value);
final Object staticFieldBase = theUnsafe.staticFieldBase(field);
final long staticFieldOffset = theUnsafe.staticFieldOffset(field);
theUnsafe.putObject(staticFieldBase, staticFieldOffset, value);
}
public static Object getStaticObjectUnsafe(final Field field) {
final Object staticFieldBase = theUnsafe.staticFieldBase(field);
final long staticFieldOffset = theUnsafe.staticFieldOffset(field);
return theUnsafe.getObject(staticFieldBase, staticFieldOffset);
final Object staticFieldBase = theUnsafe.staticFieldBase(field);
final long staticFieldOffset = theUnsafe.staticFieldOffset(field);
return theUnsafe.getObject(staticFieldBase, staticFieldOffset);
}
public static Object getObjectUnsafe(final Object base, final Field field) {
final long fieldOffset = theUnsafe.objectFieldOffset(field);
return theUnsafe.getObject(base, fieldOffset);
final long fieldOffset = theUnsafe.objectFieldOffset(field);
return theUnsafe.getObject(base, fieldOffset);
}
public static void closeSilently(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
} catch (IOException ignored) {
}
}
}
public static void closeSilently(Closeable closeable) {
if(closeable != null) {
try {
closeable.close();
} catch (IOException ignored) {
}
}
}
public static byte[] readStream(InputStream stream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
public static byte[] readStream(InputStream stream) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[16384];
int nRead;
byte[] data = new byte[16384];
while ((nRead = stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
while((nRead = stream.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
return buffer.toByteArray();
}
return buffer.toByteArray();
}
public static URL replaceHost(URL url, String hostName, int port) {
try {
@ -94,13 +93,13 @@ public final class Util {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = bs.read(buffer, 0, buffer.length)) != -1) {
while((bytesRead = bs.read(buffer, 0, buffer.length)) != -1) {
md.update(buffer, 0, bytesRead);
}
byte[] digest = md.digest();
StringBuilder sb = new StringBuilder();
for (byte bite : digest) {
for(byte bite : digest) {
sb.append(Integer.toString((bite & 255) + 256, 16).substring(1).toLowerCase());
}
bs.close();
@ -112,7 +111,7 @@ public final class Util {
String query = url.getQuery();
if(query != null) {
String[] pairs = query.split("&");
for (String pair : pairs) {
for(String pair : pairs) {
final int idx = pair.indexOf("=");
final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;

View file

@ -16,12 +16,12 @@ import org.objectweb.asm.tree.MethodInsnNode;
public class IdentifyCall {
protected MethodInsnNode invokeInsn;
protected List<AbstractInsnNode[]> arguments;
public IdentifyCall(MethodInsnNode invoke) {
invokeInsn = invoke;
arguments = initArguments();
}
private List<AbstractInsnNode[]> initArguments() {
boolean isStatic = invokeInsn.getOpcode() == Opcodes.INVOKESTATIC;
Type[] argTypes = Type.getArgumentTypes(invokeInsn.desc);
@ -63,10 +63,11 @@ public class IdentifyCall {
}
return args;
}
/**
* Returns a collection of insn node arrays with each argument
* Non-static methods include the owner of a call at index 0
* Returns a collection of insn node arrays with each argument Non-static
* methods include the owner of a call at index 0
*
* @return
*/
public List<AbstractInsnNode[]> getArguments() {
@ -76,6 +77,7 @@ public class IdentifyCall {
/**
* Returns an array of insn nodes belonging to the argument at that index
* Non-static methods include the owner of a call at index 0
*
* @return
*/
public AbstractInsnNode[] getArgument(int index) {
@ -88,4 +90,4 @@ public class IdentifyCall {
}
insns.remove(invoke);
}
}
}

View file

@ -67,17 +67,17 @@ public class InsnHelper {
public static InsnList clone(Iterable<AbstractInsnNode> insnList) {
Map<LabelNode, LabelNode> labels = new HashMap<LabelNode, LabelNode>();
for (AbstractInsnNode insn : insnList) {
if (insn.getType() == LABEL) {
LabelNode label = (LabelNode) insn;
labels.put(label, new LabelNode());
}
for(AbstractInsnNode insn : insnList) {
if(insn.getType() == LABEL) {
LabelNode label = (LabelNode) insn;
labels.put(label, new LabelNode());
}
}
InsnList destList = new InsnList();
for (AbstractInsnNode insn : insnList) {
AbstractInsnNode insnCopy = insn.clone(labels);
destList.add(insnCopy);
for(AbstractInsnNode insn : insnList) {
AbstractInsnNode insnCopy = insn.clone(labels);
destList.add(insnCopy);
}
return destList;
}
@ -92,7 +92,7 @@ public class InsnHelper {
current = current.getPrevious();
}
if(current.getType() == LABEL) {
return (LabelNode)current;
return (LabelNode) current;
}
return null;
}
@ -110,7 +110,7 @@ public class InsnHelper {
public static boolean containsInvoke(InsnList insns, MethodInsnNode invoke) {
for(AbstractInsnNode insn : insns) {
if(insn.getType() == METHOD_INSN) {
MethodInsnNode invoke2 = (MethodInsnNode)insn;
MethodInsnNode invoke2 = (MethodInsnNode) insn;
if(invoke2.getOpcode() == invoke.getOpcode() && invoke2.owner.equals(invoke.owner) && invoke2.name.equals(invoke.name) && invoke2.desc.equals(invoke.desc)) {
return true;
}
@ -153,8 +153,8 @@ public class InsnHelper {
AbstractInsnNode insn = instructions.getFirst();
while(insn != null) {
if(insn.getType() == VAR_INSN) {
VarInsnNode var = (VarInsnNode)insn;
lastFree = Math.max(lastFree, var.var + 1); //FIXME 2 if it's a double or long?
VarInsnNode var = (VarInsnNode) insn;
lastFree = Math.max(lastFree, var.var + 1); // FIXME 2 if it's a double or long?
}
insn = insn.getNext();
}
@ -163,41 +163,37 @@ public class InsnHelper {
public static AbstractInsnNode intInsn(int value) {
switch(value) {
case -1:
return new InsnNode(ICONST_M1);
case 0:
return new InsnNode(ICONST_0);
case 1:
return new InsnNode(ICONST_1);
case 2:
return new InsnNode(ICONST_2);
case 3:
return new InsnNode(ICONST_3);
case 4:
return new InsnNode(ICONST_4);
case 5:
return new InsnNode(ICONST_5);
default:
if(value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
return new IntInsnNode(BIPUSH, value);
}
else if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
return new IntInsnNode(SIPUSH, value);
}
else {
return new LdcInsnNode(value);
}
case -1:
return new InsnNode(ICONST_M1);
case 0:
return new InsnNode(ICONST_0);
case 1:
return new InsnNode(ICONST_1);
case 2:
return new InsnNode(ICONST_2);
case 3:
return new InsnNode(ICONST_3);
case 4:
return new InsnNode(ICONST_4);
case 5:
return new InsnNode(ICONST_5);
default:
if(value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
return new IntInsnNode(BIPUSH, value);
} else if(value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
return new IntInsnNode(SIPUSH, value);
} else {
return new LdcInsnNode(value);
}
}
}
public static AbstractInsnNode longInsn(long value) {
if(value == 0L) {
return new InsnNode(LCONST_0);
}
else if(value == 1L) {
} else if(value == 1L) {
return new InsnNode(LCONST_1);
}
else {
} else {
return new LdcInsnNode(value);
}
}
@ -209,14 +205,11 @@ public class InsnHelper {
public static AbstractInsnNode floatInsn(float value) {
if(value == 0F) {
return new InsnNode(FCONST_0);
}
else if(value == 1F) {
} else if(value == 1F) {
return new InsnNode(FCONST_1);
}
else if(value == 2F) {
} else if(value == 2F) {
return new InsnNode(FCONST_2);
}
else {
} else {
return new LdcInsnNode(value);
}
}
@ -224,11 +217,9 @@ public class InsnHelper {
public static AbstractInsnNode doubleInsn(double value) {
if(value == 0D) {
return new InsnNode(DCONST_0);
}
else if(value == 1D) {
} else if(value == 1D) {
return new InsnNode(DCONST_1);
}
else {
} else {
return new LdcInsnNode(value);
}
}

View file

@ -10,9 +10,9 @@ import static org.objectweb.asm.Opcodes.*;
import org.objectweb.asm.Type;
public final class OPHelper {
private static final int[] STACK_SIZE_DELTA = new int[0xFF];
static {
STACK_SIZE_DELTA[NOP] = 0;
STACK_SIZE_DELTA[ACONST_NULL] = 1;
@ -179,14 +179,14 @@ public final class OPHelper {
return 0;
}
if(insn.getType() == AbstractInsnNode.LDC_INSN) {
LdcInsnNode ldc = (LdcInsnNode)insn;
LdcInsnNode ldc = (LdcInsnNode) insn;
if(ldc.cst instanceof Double || ldc.cst instanceof Long) {
return 2;
}
return 1;
}
if(insn.getType() == AbstractInsnNode.METHOD_INSN) {
MethodInsnNode invoke = (MethodInsnNode)insn;
MethodInsnNode invoke = (MethodInsnNode) insn;
int sizes = Type.getArgumentsAndReturnSizes(invoke.desc);
int argumentSizes = sizes >> 2;
if(opcode == INVOKESTATIC) {
@ -196,189 +196,180 @@ public final class OPHelper {
return returnSize - argumentSizes;
}
if(insn.getType() == AbstractInsnNode.FIELD_INSN) {
FieldInsnNode field = (FieldInsnNode)insn;
FieldInsnNode field = (FieldInsnNode) insn;
int returnSize = Type.getType(field.desc).getSize();
if(opcode == GETSTATIC) {
return returnSize;
}
return returnSize - 1;
}
else if(opcode != ATHROW && opcode != MULTIANEWARRAY && opcode != INVOKEDYNAMIC) {
} else if(opcode != ATHROW && opcode != MULTIANEWARRAY && opcode != INVOKEDYNAMIC) {
return STACK_SIZE_DELTA[opcode];
}
throw new IllegalArgumentException("Could not get stack size delta for " + opcode);
}
public static boolean isReturn(int opcode) {
return
opcode == RETURN ||
opcode == IRETURN ||
opcode == LRETURN ||
opcode == FRETURN ||
opcode == DRETURN ||
opcode == ARETURN;
return opcode == RETURN || opcode == IRETURN || opcode == LRETURN || opcode == FRETURN || opcode == DRETURN || opcode == ARETURN;
}
public static final boolean isArrayLoad(int opcode) {
switch (opcode) {
case AALOAD:
case BALOAD: // for booleans and bytes
case CALOAD:
case DALOAD:
case FALOAD:
case IALOAD:
case LALOAD:
case SALOAD:
return true;
default:
return false;
switch(opcode) {
case AALOAD:
case BALOAD: // for booleans and bytes
case CALOAD:
case DALOAD:
case FALOAD:
case IALOAD:
case LALOAD:
case SALOAD:
return true;
default:
return false;
}
}
public static final boolean isVarLoad(int opcode) {
switch (opcode) {
case ALOAD:
//case BLOAD: // bytes & booleans are also regular integers
//case CLOAD: // characters are regular integers (?) under the hood
case DLOAD:
case FLOAD:
case ILOAD:
case LLOAD:
//case SLOAD: // and so are shorts
return true;
default:
return false;
switch(opcode) {
case ALOAD:
// case BLOAD: // bytes & booleans are also regular integers
// case CLOAD: // characters are regular integers (?) under the hood
case DLOAD:
case FLOAD:
case ILOAD:
case LLOAD:
// case SLOAD: // and so are shorts
return true;
default:
return false;
}
}
public static final int reverseVarOpcode(int opcode) {
switch (opcode) {
case AALOAD:
return AASTORE;
case BALOAD:
return BASTORE;
case CALOAD:
return CASTORE;
case IALOAD:
return IASTORE;
case SALOAD:
return IASTORE;
case DALOAD:
return IASTORE;
case FALOAD:
return IASTORE;
case LALOAD:
return IASTORE;
case ALOAD:
return IASTORE;
case DLOAD:
return IASTORE;
case FLOAD:
return IASTORE;
case ILOAD:
return IASTORE;
case LLOAD:
return IASTORE;
case AASTORE:
return AALOAD;
case BASTORE:
return BALOAD;
case CASTORE:
return CALOAD;
case IASTORE:
return IALOAD;
case SASTORE:
return SALOAD;
case DASTORE:
return DALOAD;
case FASTORE:
return FALOAD;
case LASTORE:
return LALOAD;
case ASTORE:
return ALOAD;
case DSTORE:
return DLOAD;
case FSTORE:
return FLOAD;
case ISTORE:
return ILOAD;
case LSTORE:
return LLOAD;
default:
throw new IllegalArgumentException("Opcode not valid.");
switch(opcode) {
case AALOAD:
return AASTORE;
case BALOAD:
return BASTORE;
case CALOAD:
return CASTORE;
case IALOAD:
return IASTORE;
case SALOAD:
return IASTORE;
case DALOAD:
return IASTORE;
case FALOAD:
return IASTORE;
case LALOAD:
return IASTORE;
case ALOAD:
return IASTORE;
case DLOAD:
return IASTORE;
case FLOAD:
return IASTORE;
case ILOAD:
return IASTORE;
case LLOAD:
return IASTORE;
case AASTORE:
return AALOAD;
case BASTORE:
return BALOAD;
case CASTORE:
return CALOAD;
case IASTORE:
return IALOAD;
case SASTORE:
return SALOAD;
case DASTORE:
return DALOAD;
case FASTORE:
return FALOAD;
case LASTORE:
return LALOAD;
case ASTORE:
return ALOAD;
case DSTORE:
return DLOAD;
case FSTORE:
return FLOAD;
case ISTORE:
return ILOAD;
case LSTORE:
return LLOAD;
default:
throw new IllegalArgumentException("Opcode not valid.");
}
}
public static final boolean isVarSimilarType(int opcode1, int opcode2) {
switch (opcode1) {
case AALOAD:
return opcode2 == ALOAD;
case BALOAD:
case CALOAD:
case IALOAD:
case SALOAD:
return opcode2 == ILOAD;
case DALOAD:
return opcode2 == DLOAD;
case FALOAD:
return opcode2 == FLOAD;
case LALOAD:
return opcode2 == LLOAD;
case ALOAD:
return opcode2 == AALOAD;
case DLOAD:
return opcode2 == DALOAD;
case FLOAD:
return opcode2 == FALOAD;
case ILOAD:
return opcode2 == IALOAD || opcode2 == SALOAD
|| opcode2 == BALOAD || opcode2 == CALOAD;
case LLOAD:
return opcode2 == LALOAD;
// -- The same story for the store operation family --
case AASTORE:
return opcode2 == ASTORE;
case BASTORE:
case CASTORE:
case IASTORE:
case SASTORE:
return opcode2 == ISTORE;
case DASTORE:
return opcode2 == DSTORE;
case FASTORE:
return opcode2 == FSTORE;
case LASTORE:
return opcode2 == LSTORE;
case ASTORE:
return opcode2 == ASTORE;
case DSTORE:
return opcode2 == DSTORE;
case FSTORE:
return opcode2 == FSTORE;
case ISTORE:
return opcode2 == IASTORE || opcode2 == SASTORE
|| opcode2 == BASTORE || opcode2 == CASTORE;
case LSTORE:
return opcode2 == LSTORE;
default:
throw new IllegalArgumentException("Opcode1 not valid.");
switch(opcode1) {
case AALOAD:
return opcode2 == ALOAD;
case BALOAD:
case CALOAD:
case IALOAD:
case SALOAD:
return opcode2 == ILOAD;
case DALOAD:
return opcode2 == DLOAD;
case FALOAD:
return opcode2 == FLOAD;
case LALOAD:
return opcode2 == LLOAD;
case ALOAD:
return opcode2 == AALOAD;
case DLOAD:
return opcode2 == DALOAD;
case FLOAD:
return opcode2 == FALOAD;
case ILOAD:
return opcode2 == IALOAD || opcode2 == SALOAD || opcode2 == BALOAD || opcode2 == CALOAD;
case LLOAD:
return opcode2 == LALOAD;
// -- The same story for the store operation family --
case AASTORE:
return opcode2 == ASTORE;
case BASTORE:
case CASTORE:
case IASTORE:
case SASTORE:
return opcode2 == ISTORE;
case DASTORE:
return opcode2 == DSTORE;
case FASTORE:
return opcode2 == FSTORE;
case LASTORE:
return opcode2 == LSTORE;
case ASTORE:
return opcode2 == ASTORE;
case DSTORE:
return opcode2 == DSTORE;
case FSTORE:
return opcode2 == FSTORE;
case ISTORE:
return opcode2 == IASTORE || opcode2 == SASTORE || opcode2 == BASTORE || opcode2 == CASTORE;
case LSTORE:
return opcode2 == LSTORE;
default:
throw new IllegalArgumentException("Opcode1 not valid.");
}
}
public static final boolean isVarStore(int opcode) {
switch (opcode) {
case ASTORE:
//case BSTORE: // bytes & booleans are also regular integers
//case CSTORE: // characters are regular integers (?) under the hood
case DSTORE:
case FSTORE:
case ISTORE:
case LSTORE:
//case SSTORE: // and so are shorts
return true;
default:
return false;
switch(opcode) {
case ASTORE:
// case BSTORE: // bytes & booleans are also regular integers
// case CSTORE: // characters are regular integers (?) under the hood
case DSTORE:
case FSTORE:
case ISTORE:
case LSTORE:
// case SSTORE: // and so are shorts
return true;
default:
return false;
}
}
}
}