aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlkalus <3060479+draknyte1@users.noreply.github.com>2019-09-09 03:33:08 +0100
committerAlkalus <3060479+draknyte1@users.noreply.github.com>2019-09-09 03:33:08 +0100
commit195b8cc8f14af96bdec7c6ecaf795c69388ef1f6 (patch)
tree64c1eed3f731c2dcaa15491c30eef02972bcaad7 /src
parentfd7e3cd040e1247bc207af6ed29565808d3444a9 (diff)
downloadGT5-Unofficial-195b8cc8f14af96bdec7c6ecaf795c69388ef1f6.tar.gz
GT5-Unofficial-195b8cc8f14af96bdec7c6ecaf795c69388ef1f6.tar.bz2
GT5-Unofficial-195b8cc8f14af96bdec7c6ecaf795c69388ef1f6.zip
$ Added ASM to fix LWJGL. Closes #544
Diffstat (limited to 'src')
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/AsmConfig.java7
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java172
-rw-r--r--src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java6
3 files changed, 185 insertions, 0 deletions
diff --git a/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java b/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java
index 5a59f07580..b3fbcb2d61 100644
--- a/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java
+++ b/src/Java/gtPlusPlus/preloader/asm/AsmConfig.java
@@ -21,6 +21,7 @@ public class AsmConfig {
public static boolean enableRcFlowFix;
public static boolean enableRcItemDupeFix;
public static boolean enableTcAspectSafety;
+ public static boolean enabledLwjglKeybindingFix;
public static boolean disableAllLogging;
@@ -77,6 +78,12 @@ public class AsmConfig {
prop.setLanguageKey("gtpp.enableTiConFluidLighting").setRequiresMcRestart(true);
enableTiConFluidLighting = prop.getBoolean(true);
propOrder.add(prop.getName());
+
+ prop = config.get("general", "enabledLwjglKeybindingFix", true);
+ prop.comment = "Prevents the game crashing from having invalid keybinds. https://github.com/alkcorp/GTplusplus/issues/544";
+ prop.setLanguageKey("gtpp.enabledLwjglKeybindingFix").setRequiresMcRestart(true);
+ enabledLwjglKeybindingFix = prop.getBoolean(true);
+ propOrder.add(prop.getName());
prop = config.get("general", "enableGtTooltipFix", true);
prop.comment = "Enable/Disable Custom GT Tooltips";
diff --git a/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java
new file mode 100644
index 0000000000..7a92c3d18c
--- /dev/null
+++ b/src/Java/gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard.java
@@ -0,0 +1,172 @@
+package gtPlusPlus.preloader.asm.transformers;
+
+import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static org.objectweb.asm.Opcodes.ACC_STATIC;
+import static org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;
+import static org.objectweb.asm.Opcodes.ARETURN;
+import static org.objectweb.asm.Opcodes.ASM5;
+import static org.objectweb.asm.Opcodes.ILOAD;
+import static org.objectweb.asm.Opcodes.INVOKESTATIC;
+
+import java.lang.reflect.Field;
+
+import org.apache.logging.log4j.Level;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.ClassWriter;
+import org.objectweb.asm.Label;
+import org.objectweb.asm.MethodVisitor;
+
+import cpw.mods.fml.relauncher.FMLRelaunchLog;
+import gtPlusPlus.core.util.reflect.ReflectionUtils;
+
+public class ClassTransformer_LWJGL_Keyboard {
+
+ private final boolean isValid;
+ private final ClassReader reader;
+ private final ClassWriter writer;
+
+ /**
+ * Gets a key's name
+ *
+ * @param key The key
+ * @return a String with the key's human readable name in it or null if the key
+ * is unnamed
+ */
+ public static synchronized String getKeyName(int key) {
+ if (init()) {
+ String[] aTemp = getKeyName();
+ if (key < aTemp.length && key >= 0) {
+ return aTemp[key];
+ }
+ }
+ return getKeyName()[0x00]; // Return nothing
+ }
+
+ @SuppressWarnings("rawtypes")
+ private static Class mKeyboard;
+ private static Field mKeyName;
+
+ @SuppressWarnings("rawtypes")
+ private static boolean init() {
+ if (mKeyName != null) {
+ return true;
+ }
+ Class aKeyboard = ReflectionUtils.getClass("org.lwjgl.input.Keyboard");
+ if (aKeyboard != null) {
+ mKeyboard = aKeyboard;
+ Field aKeyName = ReflectionUtils.getField(mKeyboard, "keyName");
+ if (aKeyName != null) {
+ mKeyName = aKeyName;
+ }
+ }
+ return mKeyName != null;
+ }
+
+ private static String[] getKeyName() {
+ if (init()) {
+ try {
+ Object o = mKeyName.get(null);
+ if (o instanceof String[]) {
+ String[] y = (String[]) o;
+ return y;
+ }
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ }
+ }
+ return new String[] {};
+ }
+
+ public ClassTransformer_LWJGL_Keyboard(byte[] basicClass) {
+ ClassReader aTempReader = null;
+ ClassWriter aTempWriter = null;
+ aTempReader = new ClassReader(basicClass);
+ aTempWriter = new ClassWriter(aTempReader, ClassWriter.COMPUTE_FRAMES);
+ aTempReader.accept(new AddFieldAdapter(aTempWriter), 0);
+ injectMethod("getKeyName", aTempWriter);
+ if (aTempReader != null && aTempWriter != null) {
+ isValid = true;
+ } else {
+ isValid = false;
+ }
+ FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO,
+ "Valid? " + isValid + ".");
+ reader = aTempReader;
+ writer = aTempWriter;
+ }
+
+ public boolean isValidTransformer() {
+ return isValid;
+ }
+
+ public ClassReader getReader() {
+ return reader;
+ }
+
+ public ClassWriter getWriter() {
+ return writer;
+ }
+
+ public boolean injectMethod(String aMethodName, ClassWriter cw) {
+ MethodVisitor mv;
+ boolean didInject = false;
+ FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO,
+ "Injecting " + aMethodName + ".");
+ if (aMethodName.equals("getKeyName")) {
+ mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC + ACC_SYNCHRONIZED, "getKeyName", "(I)Ljava/lang/String;", null,
+ null);
+ mv.visitCode();
+ Label l0 = new Label();
+ mv.visitLabel(l0);
+ mv.visitLineNumber(49, l0);
+ mv.visitVarInsn(ILOAD, 0);
+ mv.visitMethodInsn(INVOKESTATIC, "gtPlusPlus/preloader/asm/transformers/ClassTransformer_LWJGL_Keyboard",
+ "getKeyName", "(I)Ljava/lang/String;", false);
+ mv.visitInsn(ARETURN);
+ Label l1 = new Label();
+ mv.visitLabel(l1);
+ mv.visitLocalVariable("key", "I", null, l0, l1, 0);
+ mv.visitMaxs(1, 1);
+ mv.visitEnd();
+ didInject = true;
+ }
+ FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO,
+ "Method injection complete.");
+ return didInject;
+ }
+
+ public class AddFieldAdapter extends ClassVisitor {
+
+ public AddFieldAdapter(ClassVisitor cv) {
+ super(ASM5, cv);
+ this.cv = cv;
+ }
+
+ private final String[] aMethodsToStrip = new String[] { "getKeyName" };
+
+ @Override
+ public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+ MethodVisitor methodVisitor;
+ boolean found = false;
+
+ for (String s : aMethodsToStrip) {
+ if (name.equals(s)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ methodVisitor = super.visitMethod(access, name, desc, signature, exceptions);
+ } else {
+ methodVisitor = null;
+ }
+ if (found) {
+ FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO,
+ "Found method " + name + ", removing.");
+ }
+ return methodVisitor;
+ }
+
+ }
+
+}
diff --git a/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java b/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java
index d9b6ab7149..0e06b360b1 100644
--- a/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java
+++ b/src/Java/gtPlusPlus/preloader/asm/transformers/Preloader_Transformer_Handler.java
@@ -65,6 +65,12 @@ public class Preloader_Transformer_Handler implements IClassTransformer {
boolean obfuscated = checkObfuscated();
boolean probablyShouldBeFalse = false;
+ // Fix LWJGL index array out of bounds on keybinding IDs
+ if (transformedName.equals("org.lwjgl.input.Keyboard") && mConfig.enabledLwjglKeybindingFix) {
+ FMLRelaunchLog.log("[GT++ ASM] LWJGL Keybinding index out of bounds fix", Level.INFO, "Transforming %s", transformedName);
+ return new ClassTransformer_LWJGL_Keyboard(basicClass).getWriter().toByteArray();
+ }
+
//Enable mapping of Tickets and loaded chunks. - Forge
if (transformedName.equals("net.minecraftforge.common.ForgeChunkManager") && mConfig.enableChunkDebugging) {
FMLRelaunchLog.log("[GT++ ASM] Chunkloading Patch", Level.INFO, "Transforming %s", transformedName);