Commit fba0e0ffc742dfd2c78a379dcdc7097c3cef12a2
1 parent
0ec79e75
adding AccessorTransformer and replacing MinecraftOverlay with accessor injection
Showing
17 changed files
with
724 additions
and
170 deletions
debug/obfuscation.properties
| 1 | field_71424_I=mcProfiler | 1 | field_71424_I=mcProfiler |
| 2 | -field_78729_o=entityRenderMap field_110546_b=reloadListeners | 2 | +field_78729_o=entityRenderMap |
| 3 | +field_110546_b=reloadListeners | ||
| 3 | field_147393_d=networkManager | 4 | field_147393_d=networkManager |
| 4 | -field_82596_a=registryObjects field_148759_a=underlyingIntegerMap field_148749_a=identityMap | ||
| 5 | -field_148748_b=objectList field_147559_m=mapSpecialRenderers | 5 | +field_82596_a=registryObjects |
| 6 | +field_148759_a=underlyingIntegerMap | ||
| 7 | +field_148749_a=identityMap | ||
| 8 | +field_148748_b=objectList | ||
| 9 | +field_147559_m=mapSpecialRenderers | ||
| 6 | field_145855_i=nameToClassMap | 10 | field_145855_i=nameToClassMap |
| 7 | -field_145853_j=classToNameMap func_148833_a=processPacket func_71411_J=runGameLoop func_71407_l=runTick func_78480_b=updateCameraAndRender | ||
| 8 | -func_78471_a=renderWorld func_175180_a=renderGameOverlay func_76320_a=startSection | 11 | +field_145853_j=classToNameMap |
| 12 | +field_71428_T=timer | ||
| 13 | +field_71424_I=mcProfiler | ||
| 14 | +field_71425_J=running | ||
| 15 | +field_110449_ao=defaultResourcePacks | ||
| 16 | +field_71475_ae=serverName | ||
| 17 | +field_71477_af=serverPort | ||
| 18 | +func_148833_a=processPacket | ||
| 19 | +func_71411_J=runGameLoop | ||
| 20 | +func_71407_l=runTick | ||
| 21 | +func_78480_b=updateCameraAndRender | ||
| 22 | +func_78471_a=renderWorld | ||
| 23 | +func_175180_a=renderGameOverlay | ||
| 24 | +func_76320_a=startSection | ||
| 9 | func_76319_b=endSection | 25 | func_76319_b=endSection |
| 10 | func_76318_c=endStartSection | 26 | func_76318_c=endStartSection |
| 11 | func_148545_a=createPlayerForUser | 27 | func_148545_a=createPlayerForUser |
| @@ -28,4 +44,5 @@ func_148256_e=getProfile | @@ -28,4 +44,5 @@ func_148256_e=getProfile | ||
| 28 | func_148260_a=saveScreenshot | 44 | func_148260_a=saveScreenshot |
| 29 | func_148822_b=isFramebufferEnabled | 45 | func_148822_b=isFramebufferEnabled |
| 30 | func_147939_a=doRenderEntity | 46 | func_147939_a=doRenderEntity |
| 31 | -func_76986_a=doRender | ||
| 32 | \ No newline at end of file | 47 | \ No newline at end of file |
| 48 | +func_76986_a=doRender | ||
| 49 | +func_71370_a=resize | ||
| 33 | \ No newline at end of file | 50 | \ No newline at end of file |
java/client/com/mumfrey/liteloader/client/api/LiteLoaderCoreAPIClient.java
| @@ -35,7 +35,7 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | @@ -35,7 +35,7 @@ public class LiteLoaderCoreAPIClient extends LiteLoaderCoreAPI | ||
| 35 | private static final String[] requiredDownstreamTransformers = { | 35 | private static final String[] requiredDownstreamTransformers = { |
| 36 | LiteLoaderCoreAPI.PKG_LITELOADER_COMMON + ".transformers.LiteLoaderPacketTransformer", | 36 | LiteLoaderCoreAPI.PKG_LITELOADER_COMMON + ".transformers.LiteLoaderPacketTransformer", |
| 37 | LiteLoaderCoreAPIClient.PKG_LITELOADER_CLIENT + ".transformers.LiteLoaderEventInjectionTransformer", | 37 | LiteLoaderCoreAPIClient.PKG_LITELOADER_CLIENT + ".transformers.LiteLoaderEventInjectionTransformer", |
| 38 | - LiteLoaderCoreAPIClient.PKG_LITELOADER_CLIENT + ".transformers.MinecraftOverlayTransformer", | 38 | + LiteLoaderCoreAPIClient.PKG_LITELOADER_CLIENT + ".transformers.MinecraftTransformer", |
| 39 | LiteLoaderCoreAPI.PKG_LITELOADER + ".transformers.event.json.ModEventInjectionTransformer" | 39 | LiteLoaderCoreAPI.PKG_LITELOADER + ".transformers.event.json.ModEventInjectionTransformer" |
| 40 | }; | 40 | }; |
| 41 | 41 |
java/client/com/mumfrey/liteloader/client/overlays/IMinecraft.java
| @@ -5,43 +5,56 @@ import java.util.List; | @@ -5,43 +5,56 @@ import java.util.List; | ||
| 5 | import net.minecraft.client.resources.IResourcePack; | 5 | import net.minecraft.client.resources.IResourcePack; |
| 6 | import net.minecraft.util.Timer; | 6 | import net.minecraft.util.Timer; |
| 7 | 7 | ||
| 8 | +import com.mumfrey.liteloader.core.runtime.Obf; | ||
| 9 | +import com.mumfrey.liteloader.transformers.access.Accessor; | ||
| 10 | +import com.mumfrey.liteloader.transformers.access.Invoker; | ||
| 11 | +import com.mumfrey.liteloader.transformers.access.ObfTableClass; | ||
| 12 | + | ||
| 8 | /** | 13 | /** |
| 9 | - * Interface containing injected accessors which are provided by MinecraftOverlay | 14 | + * Interface containing injected accessors for Minecraft |
| 10 | * | 15 | * |
| 11 | * @author Adam Mummery-Smith | 16 | * @author Adam Mummery-Smith |
| 12 | */ | 17 | */ |
| 18 | +@ObfTableClass(Obf.class) | ||
| 19 | +@Accessor("Minecraft") | ||
| 13 | public interface IMinecraft | 20 | public interface IMinecraft |
| 14 | { | 21 | { |
| 15 | /** | 22 | /** |
| 16 | * Get the timer instance | 23 | * Get the timer instance |
| 17 | */ | 24 | */ |
| 25 | + @Accessor("timer") | ||
| 18 | public abstract Timer getTimer(); | 26 | public abstract Timer getTimer(); |
| 19 | 27 | ||
| 20 | /** | 28 | /** |
| 21 | * Get the "running" flag | 29 | * Get the "running" flag |
| 22 | */ | 30 | */ |
| 31 | + @Accessor("running") | ||
| 23 | public abstract boolean isRunning(); | 32 | public abstract boolean isRunning(); |
| 24 | 33 | ||
| 25 | /** | 34 | /** |
| 26 | * Get the default resource packs set | 35 | * Get the default resource packs set |
| 27 | */ | 36 | */ |
| 37 | + @Accessor("defaultResourcePacks") | ||
| 28 | public abstract List<IResourcePack> getDefaultResourcePacks(); | 38 | public abstract List<IResourcePack> getDefaultResourcePacks(); |
| 29 | - | ||
| 30 | - /** | ||
| 31 | - * Resize the window | ||
| 32 | - * | ||
| 33 | - * @param width | ||
| 34 | - * @param height | ||
| 35 | - */ | ||
| 36 | - public abstract void setSize(int width, int height); | ||
| 37 | 39 | ||
| 38 | /** | 40 | /** |
| 39 | * Get the current server address (from connection) | 41 | * Get the current server address (from connection) |
| 40 | */ | 42 | */ |
| 43 | + @Accessor("serverName") | ||
| 41 | public abstract String getServerName(); | 44 | public abstract String getServerName(); |
| 42 | 45 | ||
| 43 | /** | 46 | /** |
| 44 | * Get the current server port (from connection) | 47 | * Get the current server port (from connection) |
| 45 | */ | 48 | */ |
| 49 | + @Accessor("serverPort") | ||
| 46 | public abstract int getServerPort(); | 50 | public abstract int getServerPort(); |
| 51 | + | ||
| 52 | + /** | ||
| 53 | + * Notify the client that the window was resized | ||
| 54 | + * | ||
| 55 | + * @param width | ||
| 56 | + * @param height | ||
| 57 | + */ | ||
| 58 | + @Invoker("resize") | ||
| 59 | + public abstract void onResizeWindow(int width, int height); | ||
| 47 | } | 60 | } |
java/client/com/mumfrey/liteloader/client/overlays/MinecraftOverlay.java deleted
100644 โ 0
| 1 | -package com.mumfrey.liteloader.client.overlays; | ||
| 2 | - | ||
| 3 | -import java.util.List; | ||
| 4 | - | ||
| 5 | -import org.lwjgl.LWJGLException; | ||
| 6 | -import org.lwjgl.opengl.Display; | ||
| 7 | -import org.lwjgl.opengl.DisplayMode; | ||
| 8 | - | ||
| 9 | -import net.minecraft.client.Minecraft; | ||
| 10 | -import net.minecraft.client.resources.IResourcePack; | ||
| 11 | -import net.minecraft.profiler.Profiler; | ||
| 12 | -import net.minecraft.util.Timer; | ||
| 13 | - | ||
| 14 | -import com.google.common.collect.Lists; | ||
| 15 | -import com.mumfrey.liteloader.transformers.Obfuscated; | ||
| 16 | -import com.mumfrey.liteloader.transformers.Stub; | ||
| 17 | - | ||
| 18 | -/** | ||
| 19 | - * Overlay to inject accessors into Minecraft main class | ||
| 20 | - * | ||
| 21 | - * @author Adam Mummery-Smith | ||
| 22 | - */ | ||
| 23 | -public abstract class MinecraftOverlay implements IMinecraft | ||
| 24 | -{ | ||
| 25 | - @SuppressWarnings("unused") | ||
| 26 | - private static Minecraft __TARGET; | ||
| 27 | - | ||
| 28 | - // TODO Obfuscation 1.8 | ||
| 29 | - // Fields | ||
| 30 | - @Obfuscated({"field_71428_T", "U"}) private Timer timer; | ||
| 31 | - @Obfuscated({"field_71424_I", "y"}) private Profiler mcProfiler; | ||
| 32 | - @Obfuscated({"field_71425_J", "z"}) private boolean running; | ||
| 33 | - @Obfuscated({"field_110449_ao", "aw"}) private List<?> defaultResourcePacks = Lists.newArrayList(); | ||
| 34 | - @Obfuscated({"field_71475_ae", "am"}) private String serverName; | ||
| 35 | - @Obfuscated({"field_71477_af", "an"}) private int serverPort; | ||
| 36 | - | ||
| 37 | - // Methods | ||
| 38 | - @Obfuscated({"func_71370_a", "a"}) @Stub abstract void resize(int width, int height); | ||
| 39 | - | ||
| 40 | - /* (non-Javadoc) | ||
| 41 | - * @see com.mumfrey.liteloader.client.overlays.IMinecraft#getTimer() | ||
| 42 | - */ | ||
| 43 | - @Override | ||
| 44 | - public Timer getTimer() | ||
| 45 | - { | ||
| 46 | - return this.timer; | ||
| 47 | - } | ||
| 48 | - | ||
| 49 | - /* (non-Javadoc) | ||
| 50 | - * @see com.mumfrey.liteloader.client.overlays.IMinecraft#isRunning() | ||
| 51 | - */ | ||
| 52 | - @Override | ||
| 53 | - public boolean isRunning() | ||
| 54 | - { | ||
| 55 | - return this.running; | ||
| 56 | - } | ||
| 57 | - | ||
| 58 | - /* (non-Javadoc) | ||
| 59 | - * @see com.mumfrey.liteloader.client.overlays.IMinecraft#getDefaultResourcePacks() | ||
| 60 | - */ | ||
| 61 | - @Override | ||
| 62 | - @SuppressWarnings("unchecked") | ||
| 63 | - public List<IResourcePack> getDefaultResourcePacks() | ||
| 64 | - { | ||
| 65 | - return (List<IResourcePack>)this.defaultResourcePacks; | ||
| 66 | - } | ||
| 67 | - | ||
| 68 | - /* (non-Javadoc) | ||
| 69 | - * @see com.mumfrey.liteloader.client.overlays.IMinecraft#setSize(int, int) | ||
| 70 | - */ | ||
| 71 | - @Override | ||
| 72 | - public void setSize(int width, int height) | ||
| 73 | - { | ||
| 74 | - try | ||
| 75 | - { | ||
| 76 | - Display.setDisplayMode(new DisplayMode(width, height)); | ||
| 77 | - this.resize(width, height); | ||
| 78 | - Display.setVSyncEnabled(Minecraft.getMinecraft().gameSettings.enableVsync); | ||
| 79 | - } | ||
| 80 | - catch (LWJGLException ex) | ||
| 81 | - { | ||
| 82 | - ex.printStackTrace(); | ||
| 83 | - } | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | - /* (non-Javadoc) | ||
| 87 | - * @see com.mumfrey.liteloader.client.overlays.IMinecraft#getServerName() | ||
| 88 | - */ | ||
| 89 | - @Override | ||
| 90 | - public String getServerName() | ||
| 91 | - { | ||
| 92 | - return this.serverName; | ||
| 93 | - } | ||
| 94 | - | ||
| 95 | - /* (non-Javadoc) | ||
| 96 | - * @see com.mumfrey.liteloader.client.overlays.IMinecraft#getServerPort() | ||
| 97 | - */ | ||
| 98 | - @Override | ||
| 99 | - public int getServerPort() | ||
| 100 | - { | ||
| 101 | - return this.serverPort; | ||
| 102 | - } | ||
| 103 | -} |
java/client/com/mumfrey/liteloader/client/transformers/MinecraftOverlayTransformer.java renamed to java/client/com/mumfrey/liteloader/client/transformers/MinecraftTransformer.java
| @@ -13,30 +13,25 @@ import org.objectweb.asm.tree.TypeInsnNode; | @@ -13,30 +13,25 @@ import org.objectweb.asm.tree.TypeInsnNode; | ||
| 13 | 13 | ||
| 14 | import com.mumfrey.liteloader.core.runtime.Obf; | 14 | import com.mumfrey.liteloader.core.runtime.Obf; |
| 15 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; | 15 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; |
| 16 | -import com.mumfrey.liteloader.transformers.ClassOverlayTransformer; | 16 | +import com.mumfrey.liteloader.transformers.access.AccessorTransformer; |
| 17 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | 17 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; |
| 18 | 18 | ||
| 19 | -public class MinecraftOverlayTransformer extends ClassOverlayTransformer | 19 | +public class MinecraftTransformer extends AccessorTransformer |
| 20 | { | 20 | { |
| 21 | - private static final String overlayClassName = "com.mumfrey.liteloader.client.overlays.MinecraftOverlay"; | 21 | + private static final String TWEAKCLASS = LiteLoaderTweaker.class.getName().replace('.', '/'); |
| 22 | 22 | ||
| 23 | - private static final String LITELOADER_TWEAKER_CLASS = LiteLoaderTweaker.class.getName().replace('.', '/'); | ||
| 24 | - | ||
| 25 | - private static final String METHOD_INIT = "init"; | ||
| 26 | - private static final String METHOD_POSTINIT = "postInit"; | ||
| 27 | - | ||
| 28 | - public MinecraftOverlayTransformer() | 23 | + @Override |
| 24 | + protected void addAccessors() | ||
| 29 | { | 25 | { |
| 30 | - super(MinecraftOverlayTransformer.overlayClassName); | ||
| 31 | - this.setSourceFile = false; | 26 | + this.addAccessor(Obf.IMinecraft.name); |
| 32 | } | 27 | } |
| 33 | 28 | ||
| 34 | @Override | 29 | @Override |
| 35 | - protected void postOverlayTransform(String transformedName, ClassNode targetClass, ClassNode overlayClass) | 30 | + protected void postTransform(String name, String transformedName, ClassNode classNode) |
| 36 | { | 31 | { |
| 37 | if ((Obf.Minecraft.name.equals(transformedName) || Obf.Minecraft.obf.equals(transformedName))) | 32 | if ((Obf.Minecraft.name.equals(transformedName) || Obf.Minecraft.obf.equals(transformedName))) |
| 38 | { | 33 | { |
| 39 | - for (MethodNode method : targetClass.methods) | 34 | + for (MethodNode method : classNode.methods) |
| 40 | { | 35 | { |
| 41 | if (Obf.startGame.obf.equals(method.name) || Obf.startGame.srg.equals(method.name) || Obf.startGame.name.equals(method.name)) | 36 | if (Obf.startGame.obf.equals(method.name) || Obf.startGame.srg.equals(method.name) || Obf.startGame.name.equals(method.name)) |
| 42 | { | 37 | { |
| @@ -63,11 +58,11 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer | @@ -63,11 +58,11 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer | ||
| 63 | TypeInsnNode typeNode = (TypeInsnNode)insn; | 58 | TypeInsnNode typeNode = (TypeInsnNode)insn; |
| 64 | if (!found && (Obf.EntityRenderer.obf.equals(typeNode.desc) || Obf.EntityRenderer.ref.equals(typeNode.desc))) | 59 | if (!found && (Obf.EntityRenderer.obf.equals(typeNode.desc) || Obf.EntityRenderer.ref.equals(typeNode.desc))) |
| 65 | { | 60 | { |
| 66 | - LiteLoaderLogger.info("MinecraftOverlayTransformer found INIT injection point, this is good."); | 61 | + LiteLoaderLogger.info("MinecraftTransformer found INIT injection point, this is good."); |
| 67 | found = true; | 62 | found = true; |
| 68 | 63 | ||
| 69 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftOverlayTransformer.LITELOADER_TWEAKER_CLASS, MinecraftOverlayTransformer.METHOD_INIT, "()V", false)); | ||
| 70 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftOverlayTransformer.LITELOADER_TWEAKER_CLASS, MinecraftOverlayTransformer.METHOD_POSTINIT, "()V", false)); | 64 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftTransformer.TWEAKCLASS, Obf.init.name, "()V", false)); |
| 65 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftTransformer.TWEAKCLASS, Obf.postInit.name, "()V", false)); | ||
| 71 | } | 66 | } |
| 72 | } | 67 | } |
| 73 | 68 | ||
| @@ -88,6 +83,6 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer | @@ -88,6 +83,6 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer | ||
| 88 | 83 | ||
| 89 | method.instructions = insns; | 84 | method.instructions = insns; |
| 90 | 85 | ||
| 91 | - if (!found) LiteLoaderLogger.severe("MinecraftOverlayTransformer failed to find the INIT injection point, the game will probably crash pretty soon."); | 86 | + if (!found) LiteLoaderLogger.severe("MinecraftTransformer failed to find the INIT injection point, the game will probably crash pretty soon."); |
| 92 | } | 87 | } |
| 93 | } | 88 | } |
java/client/com/mumfrey/liteloader/util/ModUtilities.java
| @@ -6,6 +6,10 @@ import java.util.IdentityHashMap; | @@ -6,6 +6,10 @@ import java.util.IdentityHashMap; | ||
| 6 | import java.util.List; | 6 | import java.util.List; |
| 7 | import java.util.Map; | 7 | import java.util.Map; |
| 8 | 8 | ||
| 9 | +import org.lwjgl.LWJGLException; | ||
| 10 | +import org.lwjgl.opengl.Display; | ||
| 11 | +import org.lwjgl.opengl.DisplayMode; | ||
| 12 | + | ||
| 9 | import net.minecraft.block.Block; | 13 | import net.minecraft.block.Block; |
| 10 | import net.minecraft.client.Minecraft; | 14 | import net.minecraft.client.Minecraft; |
| 11 | import net.minecraft.client.renderer.Tessellator; | 15 | import net.minecraft.client.renderer.Tessellator; |
| @@ -25,6 +29,7 @@ import net.minecraft.util.RegistryNamespaced; | @@ -25,6 +29,7 @@ import net.minecraft.util.RegistryNamespaced; | ||
| 25 | import net.minecraft.util.RegistrySimple; | 29 | import net.minecraft.util.RegistrySimple; |
| 26 | import net.minecraft.util.ResourceLocation; | 30 | import net.minecraft.util.ResourceLocation; |
| 27 | 31 | ||
| 32 | +import com.mumfrey.liteloader.client.overlays.IMinecraft; | ||
| 28 | import com.mumfrey.liteloader.client.util.PrivateFields; | 33 | import com.mumfrey.liteloader.client.util.PrivateFields; |
| 29 | import com.mumfrey.liteloader.core.runtime.Obf; | 34 | import com.mumfrey.liteloader.core.runtime.Obf; |
| 30 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | 35 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; |
| @@ -74,6 +79,21 @@ public abstract class ModUtilities | @@ -74,6 +79,21 @@ public abstract class ModUtilities | ||
| 74 | return false; | 79 | return false; |
| 75 | } | 80 | } |
| 76 | 81 | ||
| 82 | + public static void setWindowSize(int width, int height) | ||
| 83 | + { | ||
| 84 | + try | ||
| 85 | + { | ||
| 86 | + Minecraft mc = Minecraft.getMinecraft(); | ||
| 87 | + Display.setDisplayMode(new DisplayMode(width, height)); | ||
| 88 | + ((IMinecraft)mc).onResizeWindow(width, height); | ||
| 89 | + Display.setVSyncEnabled(mc.gameSettings.enableVsync); | ||
| 90 | + } | ||
| 91 | + catch (LWJGLException ex) | ||
| 92 | + { | ||
| 93 | + ex.printStackTrace(); | ||
| 94 | + } | ||
| 95 | + } | ||
| 96 | + | ||
| 77 | /** | 97 | /** |
| 78 | * Add a renderer map entry for the specified entity class | 98 | * Add a renderer map entry for the specified entity class |
| 79 | * | 99 | * |
java/common/com/mumfrey/liteloader/core/runtime/Obf.java
| @@ -25,11 +25,14 @@ public class Obf | @@ -25,11 +25,14 @@ public class Obf | ||
| 25 | public static final Obf PacketEvents = new Obf("com.mumfrey.liteloader.core.PacketEvents" ); | 25 | public static final Obf PacketEvents = new Obf("com.mumfrey.liteloader.core.PacketEvents" ); |
| 26 | public static final Obf PacketEventsClient = new Obf("com.mumfrey.liteloader.client.PacketEventsClient" ); | 26 | public static final Obf PacketEventsClient = new Obf("com.mumfrey.liteloader.client.PacketEventsClient" ); |
| 27 | public static final Obf LoadingBar = new Obf("com.mumfrey.liteloader.client.gui.startup.LoadingBar" ); | 27 | public static final Obf LoadingBar = new Obf("com.mumfrey.liteloader.client.gui.startup.LoadingBar" ); |
| 28 | + public static final Obf IMinecraft = new Obf("com.mumfrey.liteloader.client.overlays.IMinecraft" ); | ||
| 28 | public static final Obf GameProfile = new Obf("com.mojang.authlib.GameProfile" ); | 29 | public static final Obf GameProfile = new Obf("com.mojang.authlib.GameProfile" ); |
| 29 | public static final Obf MinecraftMain = new Obf("net.minecraft.client.main.Main" ); | 30 | public static final Obf MinecraftMain = new Obf("net.minecraft.client.main.Main" ); |
| 30 | public static final Obf MinecraftServer = new Obf("net.minecraft.server.MinecraftServer" ); | 31 | public static final Obf MinecraftServer = new Obf("net.minecraft.server.MinecraftServer" ); |
| 31 | public static final Obf GL11 = new Obf("org.lwjgl.opengl.GL11" ); | 32 | public static final Obf GL11 = new Obf("org.lwjgl.opengl.GL11" ); |
| 32 | public static final Obf RealmsMainScreen = new Obf("com.mojang.realmsclient.RealmsMainScreen" ); | 33 | public static final Obf RealmsMainScreen = new Obf("com.mojang.realmsclient.RealmsMainScreen" ); |
| 34 | + public static final Obf init = new Obf("init" ); | ||
| 35 | + public static final Obf postInit = new Obf("postInit" ); | ||
| 33 | public static final Obf constructor = new Obf("<init>" ); | 36 | public static final Obf constructor = new Obf("<init>" ); |
| 34 | 37 | ||
| 35 | // Classes | 38 | // Classes |
| @@ -73,6 +76,12 @@ public class Obf | @@ -73,6 +76,12 @@ public class Obf | ||
| 73 | public static final Obf mapSpecialRenderers = new Obf("field_147559_m", "m" ); | 76 | public static final Obf mapSpecialRenderers = new Obf("field_147559_m", "m" ); |
| 74 | public static final Obf tileEntityNameToClassMap = new Obf("field_145855_i", "f" ); | 77 | public static final Obf tileEntityNameToClassMap = new Obf("field_145855_i", "f" ); |
| 75 | public static final Obf tileEntityClassToNameMap = new Obf("field_145853_j", "g" ); | 78 | public static final Obf tileEntityClassToNameMap = new Obf("field_145853_j", "g" ); |
| 79 | + public static final Obf timer = new Obf("field_71428_T", "U" ); | ||
| 80 | + public static final Obf mcProfiler = new Obf("field_71424_I", "y" ); | ||
| 81 | + public static final Obf running = new Obf("field_71425_J", "z" ); | ||
| 82 | + public static final Obf defaultResourcePacks = new Obf("field_110449_ao", "aw" ); | ||
| 83 | + public static final Obf serverName = new Obf("field_71475_ae", "am" ); | ||
| 84 | + public static final Obf serverPort = new Obf("field_71477_af", "an" ); | ||
| 76 | 85 | ||
| 77 | // Methods | 86 | // Methods |
| 78 | // ----------------------------------------------------------------------------------------- | 87 | // ----------------------------------------------------------------------------------------- |
| @@ -107,6 +116,7 @@ public class Obf | @@ -107,6 +116,7 @@ public class Obf | ||
| 107 | public static final Obf doRenderEntity = new Obf("func_147939_a", "a" ); | 116 | public static final Obf doRenderEntity = new Obf("func_147939_a", "a" ); |
| 108 | public static final Obf doRender = new Obf("func_76986_a", "a" ); | 117 | public static final Obf doRender = new Obf("func_76986_a", "a" ); |
| 109 | public static final Obf doRenderShadowAndFire = new Obf("func_76979_b", "b" ); | 118 | public static final Obf doRenderShadowAndFire = new Obf("func_76979_b", "b" ); |
| 119 | + public static final Obf resize = new Obf("func_71370_a", "a" ); | ||
| 110 | 120 | ||
| 111 | public static final int MCP = 0; | 121 | public static final int MCP = 0; |
| 112 | public static final int SRG = 1; | 122 | public static final int SRG = 1; |
| @@ -239,4 +249,24 @@ public class Obf | @@ -239,4 +249,24 @@ public class Obf | ||
| 239 | { | 249 | { |
| 240 | return Obf.obfs.get(name); | 250 | return Obf.obfs.get(name); |
| 241 | } | 251 | } |
| 252 | + | ||
| 253 | + public static Obf getByName(Class<? extends Obf> obf, String name) | ||
| 254 | + { | ||
| 255 | + try | ||
| 256 | + { | ||
| 257 | + for (Field fd : obf.getFields()) | ||
| 258 | + { | ||
| 259 | + if (fd.getType().equals(Obf.class)) | ||
| 260 | + { | ||
| 261 | + String fieldName = fd.getName(); | ||
| 262 | + Obf entry = (Obf)fd.get(null); | ||
| 263 | + if (name.equals(fieldName) || name.equals(entry.name)) | ||
| 264 | + return entry; | ||
| 265 | + } | ||
| 266 | + } | ||
| 267 | + } | ||
| 268 | + catch (Exception ex) {} | ||
| 269 | + | ||
| 270 | + return Obf.getByName(name); | ||
| 271 | + } | ||
| 242 | } | 272 | } |
java/common/com/mumfrey/liteloader/transformers/ByteCodeUtilities.java
| 1 | package com.mumfrey.liteloader.transformers; | 1 | package com.mumfrey.liteloader.transformers; |
| 2 | 2 | ||
| 3 | +import java.io.IOException; | ||
| 3 | import java.lang.annotation.Annotation; | 4 | import java.lang.annotation.Annotation; |
| 4 | import java.util.ArrayList; | 5 | import java.util.ArrayList; |
| 5 | import java.util.HashMap; | 6 | import java.util.HashMap; |
| @@ -7,6 +8,10 @@ import java.util.Iterator; | @@ -7,6 +8,10 @@ import java.util.Iterator; | ||
| 7 | import java.util.List; | 8 | import java.util.List; |
| 8 | import java.util.Map; | 9 | import java.util.Map; |
| 9 | 10 | ||
| 11 | +import net.minecraft.launchwrapper.IClassTransformer; | ||
| 12 | +import net.minecraft.launchwrapper.Launch; | ||
| 13 | + | ||
| 14 | +import org.objectweb.asm.ClassReader; | ||
| 10 | import org.objectweb.asm.Opcodes; | 15 | import org.objectweb.asm.Opcodes; |
| 11 | import org.objectweb.asm.Type; | 16 | import org.objectweb.asm.Type; |
| 12 | import org.objectweb.asm.tree.*; | 17 | import org.objectweb.asm.tree.*; |
| @@ -476,7 +481,7 @@ public abstract class ByteCodeUtilities | @@ -476,7 +481,7 @@ public abstract class ByteCodeUtilities | ||
| 476 | return target; | 481 | return target; |
| 477 | } | 482 | } |
| 478 | 483 | ||
| 479 | - AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getAnnotation(searchFor, Obfuscated.class); | 484 | + AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getVisibleAnnotation(searchFor, Obfuscated.class); |
| 480 | if (obfuscatedAnnotation != null) | 485 | if (obfuscatedAnnotation != null) |
| 481 | { | 486 | { |
| 482 | for (String obfuscatedName : ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)) | 487 | for (String obfuscatedName : ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)) |
| @@ -506,7 +511,7 @@ public abstract class ByteCodeUtilities | @@ -506,7 +511,7 @@ public abstract class ByteCodeUtilities | ||
| 506 | return target; | 511 | return target; |
| 507 | } | 512 | } |
| 508 | 513 | ||
| 509 | - AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getAnnotation(searchFor, Obfuscated.class); | 514 | + AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getVisibleAnnotation(searchFor, Obfuscated.class); |
| 510 | if (obfuscatedAnnotation != null) | 515 | if (obfuscatedAnnotation != null) |
| 511 | { | 516 | { |
| 512 | for (String obfuscatedName : ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)) | 517 | for (String obfuscatedName : ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)) |
| @@ -521,24 +526,111 @@ public abstract class ByteCodeUtilities | @@ -521,24 +526,111 @@ public abstract class ByteCodeUtilities | ||
| 521 | 526 | ||
| 522 | return null; | 527 | return null; |
| 523 | } | 528 | } |
| 529 | + | ||
| 530 | + public static ClassNode loadClass(String className) throws IOException | ||
| 531 | + { | ||
| 532 | + return ByteCodeUtilities.loadClass(className, true, null); | ||
| 533 | + } | ||
| 534 | + | ||
| 535 | + public static ClassNode loadClass(String className, boolean runTransformers) throws IOException | ||
| 536 | + { | ||
| 537 | + return ByteCodeUtilities.loadClass(className, runTransformers, null); | ||
| 538 | + } | ||
| 539 | + | ||
| 540 | + public static ClassNode loadClass(String className, IClassTransformer source) throws IOException | ||
| 541 | + { | ||
| 542 | + return ByteCodeUtilities.loadClass(className, source != null, source); | ||
| 543 | + } | ||
| 544 | + | ||
| 545 | + public static ClassNode loadClass(String className, boolean runTransformers, IClassTransformer source) throws IOException | ||
| 546 | + { | ||
| 547 | + byte[] bytes = Launch.classLoader.getClassBytes(className); | ||
| 548 | + | ||
| 549 | + if (runTransformers) | ||
| 550 | + { | ||
| 551 | + bytes = ByteCodeUtilities.applyTransformers(className, bytes, source); | ||
| 552 | + } | ||
| 553 | + | ||
| 554 | + return ByteCodeUtilities.readClass(bytes); | ||
| 555 | + } | ||
| 556 | + | ||
| 557 | + public static ClassNode readClass(byte[] basicClass) | ||
| 558 | + { | ||
| 559 | + ClassReader classReader = new ClassReader(basicClass); | ||
| 560 | + ClassNode classNode = new ClassNode(); | ||
| 561 | + classReader.accept(classNode, ClassReader.EXPAND_FRAMES); | ||
| 562 | + return classNode; | ||
| 563 | + } | ||
| 564 | + | ||
| 565 | + public static byte[] applyTransformers(String className, byte[] basicClass) | ||
| 566 | + { | ||
| 567 | + return ByteCodeUtilities.applyTransformers(className, basicClass, null); | ||
| 568 | + } | ||
| 569 | + | ||
| 570 | + public static byte[] applyTransformers(String className, byte[] basicClass, IClassTransformer source) | ||
| 571 | + { | ||
| 572 | + final List<IClassTransformer> transformers = Launch.classLoader.getTransformers(); | ||
| 573 | + | ||
| 574 | + for (final IClassTransformer transformer : transformers) | ||
| 575 | + { | ||
| 576 | + if (transformer != source) | ||
| 577 | + { | ||
| 578 | + basicClass = transformer.transform(className, className, basicClass); | ||
| 579 | + } | ||
| 580 | + } | ||
| 581 | + | ||
| 582 | + return basicClass; | ||
| 583 | + } | ||
| 524 | 584 | ||
| 525 | /** | 585 | /** |
| 526 | * Get an annotation of the specified class from the supplied field node | 586 | * Get an annotation of the specified class from the supplied field node |
| 527 | */ | 587 | */ |
| 528 | - public static AnnotationNode getAnnotation(FieldNode field, Class<? extends Annotation> annotationClass) | 588 | + public static AnnotationNode getVisibleAnnotation(FieldNode field, Class<? extends Annotation> annotationClass) |
| 529 | { | 589 | { |
| 530 | return ByteCodeUtilities.getAnnotation(field.visibleAnnotations, Type.getDescriptor(annotationClass)); | 590 | return ByteCodeUtilities.getAnnotation(field.visibleAnnotations, Type.getDescriptor(annotationClass)); |
| 531 | } | 591 | } |
| 592 | + | ||
| 593 | + /** | ||
| 594 | + * Get an annotation of the specified class from the supplied field node | ||
| 595 | + */ | ||
| 596 | + public static AnnotationNode getInvisibleAnnotation(FieldNode field, Class<? extends Annotation> annotationClass) | ||
| 597 | + { | ||
| 598 | + return ByteCodeUtilities.getAnnotation(field.invisibleAnnotations, Type.getDescriptor(annotationClass)); | ||
| 599 | + } | ||
| 532 | 600 | ||
| 533 | /** | 601 | /** |
| 534 | * Get an annotation of the specified class from the supplied method node | 602 | * Get an annotation of the specified class from the supplied method node |
| 535 | */ | 603 | */ |
| 536 | - public static AnnotationNode getAnnotation(MethodNode method, Class<? extends Annotation> annotationClass) | 604 | + public static AnnotationNode getVisibleAnnotation(MethodNode method, Class<? extends Annotation> annotationClass) |
| 537 | { | 605 | { |
| 538 | return ByteCodeUtilities.getAnnotation(method.visibleAnnotations, Type.getDescriptor(annotationClass)); | 606 | return ByteCodeUtilities.getAnnotation(method.visibleAnnotations, Type.getDescriptor(annotationClass)); |
| 539 | } | 607 | } |
| 608 | + | ||
| 609 | + /** | ||
| 610 | + * Get an annotation of the specified class from the supplied method node | ||
| 611 | + */ | ||
| 612 | + public static AnnotationNode getInvisibleAnnotation(MethodNode method, Class<? extends Annotation> annotationClass) | ||
| 613 | + { | ||
| 614 | + return ByteCodeUtilities.getAnnotation(method.invisibleAnnotations, Type.getDescriptor(annotationClass)); | ||
| 615 | + } | ||
| 540 | 616 | ||
| 541 | /** | 617 | /** |
| 618 | + * Get an annotation of the specified class from the supplied class node | ||
| 619 | + */ | ||
| 620 | + public static AnnotationNode getVisibleAnnotation(ClassNode classNode, Class<? extends Annotation> annotationClass) | ||
| 621 | + { | ||
| 622 | + return ByteCodeUtilities.getAnnotation(classNode.visibleAnnotations, Type.getDescriptor(annotationClass)); | ||
| 623 | + } | ||
| 624 | + | ||
| 625 | + /** | ||
| 626 | + * Get an annotation of the specified class from the supplied class node | ||
| 627 | + */ | ||
| 628 | + public static AnnotationNode getInvisibleAnnotation(ClassNode classNode, Class<? extends Annotation> annotationClass) | ||
| 629 | + { | ||
| 630 | + return ByteCodeUtilities.getAnnotation(classNode.invisibleAnnotations, Type.getDescriptor(annotationClass)); | ||
| 631 | + } | ||
| 632 | + | ||
| 633 | + /** | ||
| 542 | * Get an annotation of the specified class from the supplied list of annotations, returns null if no matching annotation was found | 634 | * Get an annotation of the specified class from the supplied list of annotations, returns null if no matching annotation was found |
| 543 | */ | 635 | */ |
| 544 | public static AnnotationNode getAnnotation(List<AnnotationNode> annotations, String annotationType) | 636 | public static AnnotationNode getAnnotation(List<AnnotationNode> annotations, String annotationType) |
| @@ -574,6 +666,9 @@ public abstract class ByteCodeUtilities | @@ -574,6 +666,9 @@ public abstract class ByteCodeUtilities | ||
| 574 | @SuppressWarnings("unchecked") | 666 | @SuppressWarnings("unchecked") |
| 575 | public static <T> T getAnnotationValue(AnnotationNode annotation, String key) | 667 | public static <T> T getAnnotationValue(AnnotationNode annotation, String key) |
| 576 | { | 668 | { |
| 669 | + if (annotation == null || annotation.values == null) | ||
| 670 | + return null; | ||
| 671 | + | ||
| 577 | boolean getNextValue = false; | 672 | boolean getNextValue = false; |
| 578 | for (Object value : annotation.values) | 673 | for (Object value : annotation.values) |
| 579 | { | 674 | { |
java/common/com/mumfrey/liteloader/transformers/ClassOverlayTransformer.java
| @@ -8,7 +8,6 @@ import java.util.List; | @@ -8,7 +8,6 @@ import java.util.List; | ||
| 8 | import java.util.Map; | 8 | import java.util.Map; |
| 9 | import java.util.Set; | 9 | import java.util.Set; |
| 10 | 10 | ||
| 11 | -import net.minecraft.launchwrapper.IClassTransformer; | ||
| 12 | import net.minecraft.launchwrapper.Launch; | 11 | import net.minecraft.launchwrapper.Launch; |
| 13 | 12 | ||
| 14 | import org.objectweb.asm.ClassReader; | 13 | import org.objectweb.asm.ClassReader; |
| @@ -314,7 +313,7 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | @@ -314,7 +313,7 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | ||
| 314 | { | 313 | { |
| 315 | for (MethodNode overlayMethod : overlayClass.methods) | 314 | for (MethodNode overlayMethod : overlayClass.methods) |
| 316 | { | 315 | { |
| 317 | - if (ByteCodeUtilities.getAnnotation(overlayMethod, Stub.class) != null || (ByteCodeUtilities.getAnnotation(overlayMethod, AppendInsns.class) == null && !overlayMethod.name.startsWith("<"))) | 316 | + if (ByteCodeUtilities.getVisibleAnnotation(overlayMethod, Stub.class) != null || (ByteCodeUtilities.getVisibleAnnotation(overlayMethod, AppendInsns.class) == null && !overlayMethod.name.startsWith("<"))) |
| 318 | { | 317 | { |
| 319 | this.checkRenameMethod(targetClass, overlayMethod); | 318 | this.checkRenameMethod(targetClass, overlayMethod); |
| 320 | } | 319 | } |
| @@ -333,8 +332,8 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | @@ -333,8 +332,8 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | ||
| 333 | { | 332 | { |
| 334 | this.transformMethod(overlayMethod, overlayClass.name, targetClass.name); | 333 | this.transformMethod(overlayMethod, overlayClass.name, targetClass.name); |
| 335 | 334 | ||
| 336 | - AnnotationNode appendAnnotation = ByteCodeUtilities.getAnnotation(overlayMethod, AppendInsns.class); | ||
| 337 | - AnnotationNode stubAnnotation = ByteCodeUtilities.getAnnotation(overlayMethod, Stub.class); | 335 | + AnnotationNode appendAnnotation = ByteCodeUtilities.getVisibleAnnotation(overlayMethod, AppendInsns.class); |
| 336 | + AnnotationNode stubAnnotation = ByteCodeUtilities.getVisibleAnnotation(overlayMethod, Stub.class); | ||
| 338 | 337 | ||
| 339 | if (stubAnnotation != null) | 338 | if (stubAnnotation != null) |
| 340 | { | 339 | { |
| @@ -428,7 +427,7 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | @@ -428,7 +427,7 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | ||
| 428 | if (targetMethodName == null || targetMethodName.length() == 0) targetMethodName = sourceMethod.name; | 427 | if (targetMethodName == null || targetMethodName.length() == 0) targetMethodName = sourceMethod.name; |
| 429 | 428 | ||
| 430 | Set<String> obfuscatedNames = new HashSet<String>(); | 429 | Set<String> obfuscatedNames = new HashSet<String>(); |
| 431 | - AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getAnnotation(sourceMethod, Obfuscated.class); | 430 | + AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getVisibleAnnotation(sourceMethod, Obfuscated.class); |
| 432 | if (obfuscatedAnnotation != null) | 431 | if (obfuscatedAnnotation != null) |
| 433 | { | 432 | { |
| 434 | obfuscatedNames.addAll(ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)); | 433 | obfuscatedNames.addAll(ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)); |
| @@ -495,7 +494,7 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | @@ -495,7 +494,7 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | ||
| 495 | 494 | ||
| 496 | if (runTransformers) | 495 | if (runTransformers) |
| 497 | { | 496 | { |
| 498 | - overlayBytes = this.applyTransformers(this.overlayClassName, overlayBytes); | 497 | + overlayBytes = ByteCodeUtilities.applyTransformers(this.overlayClassName, overlayBytes, this); |
| 499 | } | 498 | } |
| 500 | } | 499 | } |
| 501 | catch (IOException ex) | 500 | catch (IOException ex) |
| @@ -506,25 +505,4 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | @@ -506,25 +505,4 @@ public abstract class ClassOverlayTransformer extends ClassTransformer | ||
| 506 | 505 | ||
| 507 | return this.readClass(overlayBytes, false); | 506 | return this.readClass(overlayBytes, false); |
| 508 | } | 507 | } |
| 509 | - | ||
| 510 | - /** | ||
| 511 | - * Since we obtain the overlay class bytes with getClassBytes(), we need to apply the transformers ourself | ||
| 512 | - * | ||
| 513 | - * @param name | ||
| 514 | - * @param basicClass | ||
| 515 | - */ | ||
| 516 | - private byte[] applyTransformers(String name, byte[] basicClass) | ||
| 517 | - { | ||
| 518 | - final List<IClassTransformer> transformers = Launch.classLoader.getTransformers(); | ||
| 519 | - | ||
| 520 | - for (final IClassTransformer transformer : transformers) | ||
| 521 | - { | ||
| 522 | - if (transformer != this) | ||
| 523 | - { | ||
| 524 | - basicClass = transformer.transform(name, name, basicClass); | ||
| 525 | - } | ||
| 526 | - } | ||
| 527 | - | ||
| 528 | - return basicClass; | ||
| 529 | - } | ||
| 530 | } | 508 | } |
java/common/com/mumfrey/liteloader/transformers/access/Accessor.java
0 โ 100644
| 1 | +package com.mumfrey.liteloader.transformers.access; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.ElementType; | ||
| 4 | +import java.lang.annotation.Retention; | ||
| 5 | +import java.lang.annotation.RetentionPolicy; | ||
| 6 | +import java.lang.annotation.Target; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * Defines an accessor method within an accessor injection interface, or an accessor interface itself | ||
| 10 | + * | ||
| 11 | + * @author Adam Mummery-Smith | ||
| 12 | + */ | ||
| 13 | +@Target({ElementType.METHOD, ElementType.TYPE}) | ||
| 14 | +@Retention(RetentionPolicy.CLASS) | ||
| 15 | +public @interface Accessor | ||
| 16 | +{ | ||
| 17 | + public String value(); | ||
| 18 | +} |
java/common/com/mumfrey/liteloader/transformers/access/AccessorTransformer.java
0 โ 100644
| 1 | +package com.mumfrey.liteloader.transformers.access; | ||
| 2 | + | ||
| 3 | +import java.io.IOException; | ||
| 4 | +import java.util.ArrayList; | ||
| 5 | +import java.util.Iterator; | ||
| 6 | +import java.util.List; | ||
| 7 | + | ||
| 8 | +import net.minecraft.launchwrapper.Launch; | ||
| 9 | + | ||
| 10 | +import org.objectweb.asm.ClassReader; | ||
| 11 | +import org.objectweb.asm.Opcodes; | ||
| 12 | +import org.objectweb.asm.Type; | ||
| 13 | +import org.objectweb.asm.tree.AnnotationNode; | ||
| 14 | +import org.objectweb.asm.tree.ClassNode; | ||
| 15 | +import org.objectweb.asm.tree.FieldInsnNode; | ||
| 16 | +import org.objectweb.asm.tree.FieldNode; | ||
| 17 | +import org.objectweb.asm.tree.InsnNode; | ||
| 18 | +import org.objectweb.asm.tree.MethodInsnNode; | ||
| 19 | +import org.objectweb.asm.tree.MethodNode; | ||
| 20 | +import org.objectweb.asm.tree.VarInsnNode; | ||
| 21 | + | ||
| 22 | +import com.mumfrey.liteloader.core.runtime.Obf; | ||
| 23 | +import com.mumfrey.liteloader.transformers.ByteCodeUtilities; | ||
| 24 | +import com.mumfrey.liteloader.transformers.ClassTransformer; | ||
| 25 | +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | ||
| 26 | + | ||
| 27 | +/** | ||
| 28 | + * Transformer which can inject accessor methods into a target class | ||
| 29 | + * | ||
| 30 | + * @author Adam Mummery-Smith | ||
| 31 | + */ | ||
| 32 | +public abstract class AccessorTransformer extends ClassTransformer | ||
| 33 | +{ | ||
| 34 | + /** | ||
| 35 | + * An injection record | ||
| 36 | + * | ||
| 37 | + * @author Adam Mummery-Smith | ||
| 38 | + */ | ||
| 39 | + class AccessorInjection | ||
| 40 | + { | ||
| 41 | + /** | ||
| 42 | + * Full name of the interface to inject | ||
| 43 | + */ | ||
| 44 | + private final String iface; | ||
| 45 | + | ||
| 46 | + /** | ||
| 47 | + * Obfuscation table class specified by the interface | ||
| 48 | + */ | ||
| 49 | + private final Class<? extends Obf> table; | ||
| 50 | + | ||
| 51 | + /** | ||
| 52 | + * Target class to inject into | ||
| 53 | + */ | ||
| 54 | + private final Obf target; | ||
| 55 | + | ||
| 56 | + protected AccessorInjection(String iface) throws IOException | ||
| 57 | + { | ||
| 58 | + ClassNode ifaceNode = this.loadClass(iface); | ||
| 59 | + this.table = this.setupTable(ifaceNode); | ||
| 60 | + this.target = this.setupTarget(ifaceNode); | ||
| 61 | + this.iface = iface; | ||
| 62 | + } | ||
| 63 | + | ||
| 64 | + private ClassNode loadClass(String iface) throws IOException | ||
| 65 | + { | ||
| 66 | + byte[] bytes = this.getClassBytes(iface); | ||
| 67 | + ClassReader classReader = new ClassReader(bytes); | ||
| 68 | + ClassNode classNode = new ClassNode(); | ||
| 69 | + classReader.accept(classNode, 0); | ||
| 70 | + return classNode; | ||
| 71 | + } | ||
| 72 | + | ||
| 73 | + private byte[] getClassBytes(String iface) throws IOException | ||
| 74 | + { | ||
| 75 | + return Launch.classLoader.getClassBytes(iface); | ||
| 76 | + } | ||
| 77 | + | ||
| 78 | + private Obf getObf(String name) | ||
| 79 | + { | ||
| 80 | + return Obf.getByName(this.table, name); | ||
| 81 | + } | ||
| 82 | + | ||
| 83 | + protected Obf getTarget() | ||
| 84 | + { | ||
| 85 | + return this.target; | ||
| 86 | + } | ||
| 87 | + | ||
| 88 | + @SuppressWarnings("unchecked") | ||
| 89 | + private Class<? extends Obf> setupTable(ClassNode ifaceNode) | ||
| 90 | + { | ||
| 91 | + AnnotationNode annotation = ByteCodeUtilities.getInvisibleAnnotation(ifaceNode, ObfTableClass.class); | ||
| 92 | + if (annotation != null) | ||
| 93 | + { | ||
| 94 | + try | ||
| 95 | + { | ||
| 96 | + Type obfTableType = ByteCodeUtilities.getAnnotationValue(annotation); | ||
| 97 | + return (Class<? extends Obf>)Class.forName(obfTableType.getClassName(), true, Launch.classLoader); | ||
| 98 | + } | ||
| 99 | + catch (ClassNotFoundException ex) | ||
| 100 | + { | ||
| 101 | + ex.printStackTrace(); | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + | ||
| 105 | + return Obf.class; | ||
| 106 | + } | ||
| 107 | + | ||
| 108 | + private Obf setupTarget(ClassNode ifaceNode) | ||
| 109 | + { | ||
| 110 | + AnnotationNode annotation = ByteCodeUtilities.getInvisibleAnnotation(ifaceNode, Accessor.class); | ||
| 111 | + return this.getObf(ByteCodeUtilities.<String>getAnnotationValue(annotation)); | ||
| 112 | + } | ||
| 113 | + | ||
| 114 | + protected void apply(ClassNode classNode) | ||
| 115 | + { | ||
| 116 | + String ifaceRef = this.iface.replace('.', '/'); | ||
| 117 | + | ||
| 118 | + if (classNode.interfaces.contains(ifaceRef)) | ||
| 119 | + { | ||
| 120 | + LiteLoaderLogger.debug("[AccessorTransformer] Skipping %s because %s was already applied", classNode.name, this.iface); | ||
| 121 | + return; | ||
| 122 | + } | ||
| 123 | + | ||
| 124 | + classNode.interfaces.add(ifaceRef); | ||
| 125 | + | ||
| 126 | + try | ||
| 127 | + { | ||
| 128 | + LiteLoaderLogger.debug("[AccessorTransformer] Loading %s", this.iface); | ||
| 129 | + ClassNode ifaceNode = ByteCodeUtilities.loadClass(this.iface, AccessorTransformer.this); | ||
| 130 | + | ||
| 131 | + for (MethodNode method : ifaceNode.methods) | ||
| 132 | + { | ||
| 133 | + this.addMethod(classNode, method); | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + catch (Exception ex) | ||
| 137 | + { | ||
| 138 | + ex.printStackTrace(); | ||
| 139 | + } | ||
| 140 | + } | ||
| 141 | + | ||
| 142 | + private void addMethod(ClassNode classNode, MethodNode method) | ||
| 143 | + { | ||
| 144 | + if (!this.addMethodToClass(classNode, method)) | ||
| 145 | + { | ||
| 146 | + LiteLoaderLogger.debug("[AccessorTransformer] Method %s already exists in %s", method.name, classNode.name); | ||
| 147 | + return; | ||
| 148 | + } | ||
| 149 | + | ||
| 150 | + LiteLoaderLogger.debug("[AccessorTransformer] Attempting to add %s to %s", method.name, classNode.name); | ||
| 151 | + | ||
| 152 | + AnnotationNode accessor = ByteCodeUtilities.getInvisibleAnnotation(method, Accessor.class); | ||
| 153 | + AnnotationNode invoker = ByteCodeUtilities.getInvisibleAnnotation(method, Invoker.class); | ||
| 154 | + if (accessor != null) | ||
| 155 | + { | ||
| 156 | + Obf targetName = this.getObf(ByteCodeUtilities.<String>getAnnotationValue(accessor)); | ||
| 157 | + if (this.injectAccessor(classNode, method, targetName)) return; | ||
| 158 | + } | ||
| 159 | + else if (invoker != null) | ||
| 160 | + { | ||
| 161 | + Obf targetName = this.getObf(ByteCodeUtilities.<String>getAnnotationValue(invoker)); | ||
| 162 | + if (this.injectInvoker(classNode, method, targetName)) return; | ||
| 163 | + } | ||
| 164 | + else | ||
| 165 | + { | ||
| 166 | + LiteLoaderLogger.severe("[AccessorTransformer] Method %s for %s has no @Accessor or @Invoker annotation, the method will be ABSTRACT!", method.name, this.iface); | ||
| 167 | + } | ||
| 168 | + | ||
| 169 | + LiteLoaderLogger.severe("[AccessorTransformer] Method %s for %s could not locate target member, the method will be ABSTRACT!", method.name, this.iface); | ||
| 170 | + } | ||
| 171 | + | ||
| 172 | + private boolean injectAccessor(ClassNode classNode, MethodNode method, Obf targetName) | ||
| 173 | + { | ||
| 174 | + FieldNode targetField = this.findField(classNode, targetName); | ||
| 175 | + if (targetField != null) | ||
| 176 | + { | ||
| 177 | + LiteLoaderLogger.debug("[AccessorTransformer] Found field %s for %s", targetField.name, method.name); | ||
| 178 | + if (Type.getReturnType(method.desc) != Type.VOID_TYPE) | ||
| 179 | + { | ||
| 180 | + this.populateGetter(classNode, method, targetField); | ||
| 181 | + } | ||
| 182 | + else | ||
| 183 | + { | ||
| 184 | + this.populateSetter(classNode, method, targetField); | ||
| 185 | + } | ||
| 186 | + | ||
| 187 | + return true; | ||
| 188 | + } | ||
| 189 | + | ||
| 190 | + return false; | ||
| 191 | + } | ||
| 192 | + | ||
| 193 | + private boolean injectInvoker(ClassNode classNode, MethodNode method, Obf targetName) | ||
| 194 | + { | ||
| 195 | + MethodNode targetMethod = this.findMethod(classNode, targetName, method.desc); | ||
| 196 | + if (targetMethod != null) | ||
| 197 | + { | ||
| 198 | + LiteLoaderLogger.debug("[AccessorTransformer] Found method %s for %s", targetMethod.name, method.name); | ||
| 199 | + this.populateInvoker(classNode, method, targetMethod); | ||
| 200 | + return true; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + return false; | ||
| 204 | + } | ||
| 205 | + | ||
| 206 | + private void populateGetter(ClassNode classNode, MethodNode method, FieldNode field) | ||
| 207 | + { | ||
| 208 | + Type returnType = Type.getReturnType(method.desc); | ||
| 209 | + Type fieldType = Type.getType(field.desc); | ||
| 210 | + if (!returnType.equals(fieldType)) | ||
| 211 | + { | ||
| 212 | + throw new RuntimeException("Incompatible types! Field type: " + fieldType + " Method type: " + returnType); | ||
| 213 | + } | ||
| 214 | + | ||
| 215 | + method.instructions.clear(); | ||
| 216 | + method.maxLocals = ByteCodeUtilities.getFirstNonArgLocalIndex(method); | ||
| 217 | + method.maxStack = fieldType.getSize(); | ||
| 218 | + | ||
| 219 | + if ((field.access & Opcodes.ACC_STATIC) == 0) | ||
| 220 | + { | ||
| 221 | + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); | ||
| 222 | + method.instructions.add(new FieldInsnNode(Opcodes.GETFIELD, classNode.name, field.name, field.desc)); | ||
| 223 | + } | ||
| 224 | + else | ||
| 225 | + { | ||
| 226 | + method.instructions.add(new FieldInsnNode(Opcodes.GETSTATIC, classNode.name, field.name, field.desc)); | ||
| 227 | + } | ||
| 228 | + | ||
| 229 | + method.instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN))); | ||
| 230 | + } | ||
| 231 | + | ||
| 232 | + private void populateSetter(ClassNode classNode, MethodNode method, FieldNode field) | ||
| 233 | + { | ||
| 234 | + Type[] argTypes = Type.getArgumentTypes(method.desc); | ||
| 235 | + if (argTypes.length != 1) | ||
| 236 | + { | ||
| 237 | + throw new RuntimeException("Invalid setter! " + method.name + " must take exactly one argument"); | ||
| 238 | + } | ||
| 239 | + Type argType = argTypes[0]; | ||
| 240 | + Type fieldType = Type.getType(field.desc); | ||
| 241 | + if (!argType.equals(fieldType)) | ||
| 242 | + { | ||
| 243 | + throw new RuntimeException("Incompatible types! Field type: " + fieldType + " Method type: " + argType); | ||
| 244 | + } | ||
| 245 | + | ||
| 246 | + method.instructions.clear(); | ||
| 247 | + method.maxLocals = ByteCodeUtilities.getFirstNonArgLocalIndex(method); | ||
| 248 | + method.maxStack = fieldType.getSize(); | ||
| 249 | + | ||
| 250 | + if ((field.access & Opcodes.ACC_STATIC) == 0) | ||
| 251 | + { | ||
| 252 | + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); | ||
| 253 | + method.instructions.add(new VarInsnNode(argType.getOpcode(Opcodes.ILOAD), 1)); | ||
| 254 | + method.instructions.add(new FieldInsnNode(Opcodes.PUTFIELD, classNode.name, field.name, field.desc)); | ||
| 255 | + } | ||
| 256 | + else | ||
| 257 | + { | ||
| 258 | + method.instructions.add(new VarInsnNode(argType.getOpcode(Opcodes.ILOAD), 0)); | ||
| 259 | + method.instructions.add(new FieldInsnNode(Opcodes.PUTSTATIC, classNode.name, field.name, field.desc)); | ||
| 260 | + } | ||
| 261 | + | ||
| 262 | + method.instructions.add(new InsnNode(Opcodes.RETURN)); | ||
| 263 | + } | ||
| 264 | + | ||
| 265 | + private void populateInvoker(ClassNode classNode, MethodNode method, MethodNode targetMethod) | ||
| 266 | + { | ||
| 267 | + Type[] args = Type.getArgumentTypes(targetMethod.desc); | ||
| 268 | + Type returnType = Type.getReturnType(targetMethod.desc); | ||
| 269 | + boolean isStatic = (targetMethod.access & Opcodes.ACC_STATIC) != 0; | ||
| 270 | + | ||
| 271 | + method.instructions.clear(); | ||
| 272 | + method.maxStack = (method.maxLocals = ByteCodeUtilities.getFirstNonArgLocalIndex(method)) + 1; | ||
| 273 | + | ||
| 274 | + if (isStatic) | ||
| 275 | + { | ||
| 276 | + ByteCodeUtilities.loadArgs(args, method.instructions, 0); | ||
| 277 | + method.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, classNode.name, targetMethod.name, targetMethod.desc, false)); | ||
| 278 | + } | ||
| 279 | + else | ||
| 280 | + { | ||
| 281 | + method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); | ||
| 282 | + ByteCodeUtilities.loadArgs(args, method.instructions, 1); | ||
| 283 | + method.instructions.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, classNode.name, targetMethod.name, targetMethod.desc, false)); | ||
| 284 | + } | ||
| 285 | + | ||
| 286 | + method.instructions.add(new InsnNode(returnType.getOpcode(Opcodes.IRETURN))); | ||
| 287 | + } | ||
| 288 | + | ||
| 289 | + private FieldNode findField(ClassNode classNode, Obf fieldName) | ||
| 290 | + { | ||
| 291 | + for (FieldNode field : classNode.fields) | ||
| 292 | + { | ||
| 293 | + if (fieldName.obf.equals(field.name) || fieldName.srg.equals(field.name)|| fieldName.name.equals(field.name)) | ||
| 294 | + return field; | ||
| 295 | + } | ||
| 296 | + | ||
| 297 | + return null; | ||
| 298 | + } | ||
| 299 | + | ||
| 300 | + private MethodNode findMethod(ClassNode classNode, Obf methodName, String desc) | ||
| 301 | + { | ||
| 302 | + for (MethodNode method : classNode.methods) | ||
| 303 | + { | ||
| 304 | + if ((methodName.obf.equals(method.name) || methodName.srg.equals(method.name)|| methodName.name.equals(method.name)) && method.desc.equals(desc)) | ||
| 305 | + return method; | ||
| 306 | + } | ||
| 307 | + | ||
| 308 | + return null; | ||
| 309 | + } | ||
| 310 | + | ||
| 311 | + private boolean addMethodToClass(ClassNode classNode, MethodNode method) | ||
| 312 | + { | ||
| 313 | + MethodNode existingMethod = ByteCodeUtilities.findTargetMethod(classNode, method); | ||
| 314 | + if (existingMethod != null) return false; | ||
| 315 | + classNode.methods.add(method); | ||
| 316 | + method.access = method.access & ~Opcodes.ACC_ABSTRACT; | ||
| 317 | + return true; | ||
| 318 | + } | ||
| 319 | + } | ||
| 320 | + | ||
| 321 | + private List<AccessorInjection> accessors = new ArrayList<AccessorInjection>(); | ||
| 322 | + | ||
| 323 | + public AccessorTransformer() | ||
| 324 | + { | ||
| 325 | + this.addAccessors(); | ||
| 326 | + } | ||
| 327 | + | ||
| 328 | + public void addAccessor(String interfaceName) | ||
| 329 | + { | ||
| 330 | + try | ||
| 331 | + { | ||
| 332 | + this.accessors.add(new AccessorInjection(interfaceName)); | ||
| 333 | + } | ||
| 334 | + catch (Exception ex) | ||
| 335 | + { | ||
| 336 | + LiteLoaderLogger.debug(ex); | ||
| 337 | + } | ||
| 338 | + } | ||
| 339 | + | ||
| 340 | + @Override | ||
| 341 | + public byte[] transform(String name, String transformedName, byte[] basicClass) | ||
| 342 | + { | ||
| 343 | + ClassNode classNode = null; | ||
| 344 | + | ||
| 345 | + classNode = this.apply(name, transformedName, basicClass, classNode); | ||
| 346 | + | ||
| 347 | + if (classNode != null) | ||
| 348 | + { | ||
| 349 | + this.postTransform(name, transformedName, classNode); | ||
| 350 | + return this.writeClass(classNode); | ||
| 351 | + } | ||
| 352 | + | ||
| 353 | + return basicClass; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + public ClassNode apply(String name, String transformedName, byte[] basicClass, ClassNode classNode) | ||
| 357 | + { | ||
| 358 | + for (Iterator<AccessorInjection> iter = this.accessors.iterator(); iter.hasNext(); ) | ||
| 359 | + { | ||
| 360 | + AccessorInjection accessor = iter.next(); | ||
| 361 | + Obf target = accessor.getTarget(); | ||
| 362 | + if (target.obf.equals(transformedName) || target.name.equals(transformedName)) | ||
| 363 | + { | ||
| 364 | + LiteLoaderLogger.debug("[AccessorTransformer] Processing access injections in %s", transformedName); | ||
| 365 | + if (classNode == null) classNode = this.readClass(basicClass, true); | ||
| 366 | + accessor.apply(classNode); | ||
| 367 | + iter.remove(); | ||
| 368 | + } | ||
| 369 | + } | ||
| 370 | + | ||
| 371 | + return classNode; | ||
| 372 | + } | ||
| 373 | + | ||
| 374 | + protected void addAccessors() | ||
| 375 | + { | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + protected void postTransform(String name, String transformedName, ClassNode classNode) | ||
| 379 | + { | ||
| 380 | + } | ||
| 381 | +} |
java/common/com/mumfrey/liteloader/transformers/access/Invoker.java
0 โ 100644
| 1 | +package com.mumfrey.liteloader.transformers.access; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.ElementType; | ||
| 4 | +import java.lang.annotation.Retention; | ||
| 5 | +import java.lang.annotation.RetentionPolicy; | ||
| 6 | +import java.lang.annotation.Target; | ||
| 7 | + | ||
| 8 | +/** | ||
| 9 | + * Defines an invoker method within an accessor injection interface | ||
| 10 | + * | ||
| 11 | + * @author Adam Mummery-Smith | ||
| 12 | + */ | ||
| 13 | +@Target({ElementType.METHOD, ElementType.TYPE}) | ||
| 14 | +@Retention(RetentionPolicy.CLASS) | ||
| 15 | +public @interface Invoker | ||
| 16 | +{ | ||
| 17 | + public String value(); | ||
| 18 | +} |
java/common/com/mumfrey/liteloader/transformers/access/ObfTableClass.java
0 โ 100644
| 1 | +package com.mumfrey.liteloader.transformers.access; | ||
| 2 | + | ||
| 3 | +import java.lang.annotation.ElementType; | ||
| 4 | +import java.lang.annotation.Retention; | ||
| 5 | +import java.lang.annotation.RetentionPolicy; | ||
| 6 | +import java.lang.annotation.Target; | ||
| 7 | + | ||
| 8 | +import com.mumfrey.liteloader.core.runtime.Obf; | ||
| 9 | + | ||
| 10 | +/** | ||
| 11 | + * Defines the obfuscation table class to use for an accessor injection interface | ||
| 12 | + * | ||
| 13 | + * @author Adam Mummery-Smith | ||
| 14 | + */ | ||
| 15 | +@Target(ElementType.TYPE) | ||
| 16 | +@Retention(RetentionPolicy.CLASS) | ||
| 17 | +public @interface ObfTableClass | ||
| 18 | +{ | ||
| 19 | + public Class<? extends Obf> value(); | ||
| 20 | +} |
java/common/com/mumfrey/liteloader/transformers/event/EventInjectionTransformer.java
| @@ -75,4 +75,14 @@ public abstract class EventInjectionTransformer implements IClassTransformer | @@ -75,4 +75,14 @@ public abstract class EventInjectionTransformer implements IClassTransformer | ||
| 75 | 75 | ||
| 76 | return event; | 76 | return event; |
| 77 | } | 77 | } |
| 78 | + | ||
| 79 | + /** | ||
| 80 | + * Register an access injection interface | ||
| 81 | + * | ||
| 82 | + * @param interfaceName | ||
| 83 | + */ | ||
| 84 | + protected final void addAccessor(String interfaceName) | ||
| 85 | + { | ||
| 86 | + EventTransformer.addAccessor(interfaceName); | ||
| 87 | + } | ||
| 78 | } | 88 | } |
java/common/com/mumfrey/liteloader/transformers/event/EventTransformer.java
| @@ -19,6 +19,7 @@ import org.objectweb.asm.util.CheckClassAdapter; | @@ -19,6 +19,7 @@ import org.objectweb.asm.util.CheckClassAdapter; | ||
| 19 | 19 | ||
| 20 | import com.mumfrey.liteloader.transformers.ByteCodeUtilities; | 20 | import com.mumfrey.liteloader.transformers.ByteCodeUtilities; |
| 21 | import com.mumfrey.liteloader.transformers.ClassTransformer; | 21 | import com.mumfrey.liteloader.transformers.ClassTransformer; |
| 22 | +import com.mumfrey.liteloader.transformers.access.AccessorTransformer; | ||
| 22 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | 23 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; |
| 23 | 24 | ||
| 24 | /** | 25 | /** |
| @@ -55,12 +56,14 @@ public final class EventTransformer extends ClassTransformer | @@ -55,12 +56,14 @@ public final class EventTransformer extends ClassTransformer | ||
| 55 | */ | 56 | */ |
| 56 | private static Map<String, Map<String, Map<Event, InjectionPoint>>> eventMappings = new HashMap<String, Map<String, Map<Event, InjectionPoint>>>(); | 57 | private static Map<String, Map<String, Map<Event, InjectionPoint>>> eventMappings = new HashMap<String, Map<String, Map<Event, InjectionPoint>>>(); |
| 57 | 58 | ||
| 59 | + private static AccessorTransformer accessorTransformer; | ||
| 60 | + | ||
| 58 | /** | 61 | /** |
| 59 | * Runs the validator on the generated classes, only for debugging purposes | 62 | * Runs the validator on the generated classes, only for debugging purposes |
| 60 | */ | 63 | */ |
| 61 | private final boolean runValidator = false; | 64 | private final boolean runValidator = false; |
| 62 | 65 | ||
| 63 | - private int globalEventID = 0; | 66 | + private int globalEventID = 0; |
| 64 | 67 | ||
| 65 | static class Injection | 68 | static class Injection |
| 66 | { | 69 | { |
| @@ -186,18 +189,37 @@ public final class EventTransformer extends ClassTransformer | @@ -186,18 +189,37 @@ public final class EventTransformer extends ClassTransformer | ||
| 186 | events.put(event, injectionPoint); | 189 | events.put(event, injectionPoint); |
| 187 | } | 190 | } |
| 188 | 191 | ||
| 192 | + static void addAccessor(String interfaceName) | ||
| 193 | + { | ||
| 194 | + if (EventTransformer.accessorTransformer == null) | ||
| 195 | + { | ||
| 196 | + EventTransformer.accessorTransformer = new AccessorTransformer() | ||
| 197 | + { | ||
| 198 | + @Override | ||
| 199 | + protected void addAccessors() {} | ||
| 200 | + }; | ||
| 201 | + } | ||
| 202 | + | ||
| 203 | + EventTransformer.accessorTransformer.addAccessor(interfaceName); | ||
| 204 | + } | ||
| 205 | + | ||
| 189 | @Override | 206 | @Override |
| 190 | public final byte[] transform(String name, String transformedName, byte[] basicClass) | 207 | public final byte[] transform(String name, String transformedName, byte[] basicClass) |
| 191 | { | 208 | { |
| 192 | if (basicClass != null && EventTransformer.eventMappings.containsKey(transformedName)) | 209 | if (basicClass != null && EventTransformer.eventMappings.containsKey(transformedName)) |
| 193 | { | 210 | { |
| 194 | - return this.injectEvents(basicClass, EventTransformer.eventMappings.get(transformedName)); | 211 | + return this.injectEvents(name, transformedName, basicClass, EventTransformer.eventMappings.get(transformedName)); |
| 212 | + } | ||
| 213 | + | ||
| 214 | + if (EventTransformer.accessorTransformer != null) | ||
| 215 | + { | ||
| 216 | + return EventTransformer.accessorTransformer.transform(name, transformedName, basicClass); | ||
| 195 | } | 217 | } |
| 196 | 218 | ||
| 197 | return basicClass; | 219 | return basicClass; |
| 198 | } | 220 | } |
| 199 | 221 | ||
| 200 | - private byte[] injectEvents(byte[] basicClass, Map<String, Map<Event, InjectionPoint>> mappings) | 222 | + private byte[] injectEvents(String name, String transformedName, byte[] basicClass, Map<String, Map<Event, InjectionPoint>> mappings) |
| 201 | { | 223 | { |
| 202 | if (mappings == null) return basicClass; | 224 | if (mappings == null) return basicClass; |
| 203 | 225 | ||
| @@ -213,6 +235,11 @@ public final class EventTransformer extends ClassTransformer | @@ -213,6 +235,11 @@ public final class EventTransformer extends ClassTransformer | ||
| 213 | } | 235 | } |
| 214 | } | 236 | } |
| 215 | 237 | ||
| 238 | + if (EventTransformer.accessorTransformer != null) | ||
| 239 | + { | ||
| 240 | + EventTransformer.accessorTransformer.apply(name, transformedName, basicClass, classNode); | ||
| 241 | + } | ||
| 242 | + | ||
| 216 | if (this.runValidator) | 243 | if (this.runValidator) |
| 217 | { | 244 | { |
| 218 | ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); | 245 | ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES); |
java/common/com/mumfrey/liteloader/transformers/event/json/JsonEvents.java
| 1 | package com.mumfrey.liteloader.transformers.event.json; | 1 | package com.mumfrey.liteloader.transformers.event.json; |
| 2 | 2 | ||
| 3 | import java.io.Serializable; | 3 | import java.io.Serializable; |
| 4 | +import java.util.ArrayList; | ||
| 4 | import java.util.List; | 5 | import java.util.List; |
| 5 | import java.util.regex.Matcher; | 6 | import java.util.regex.Matcher; |
| 6 | import java.util.regex.Pattern; | 7 | import java.util.regex.Pattern; |
| @@ -8,6 +9,7 @@ import java.util.regex.Pattern; | @@ -8,6 +9,7 @@ import java.util.regex.Pattern; | ||
| 8 | import com.google.gson.Gson; | 9 | import com.google.gson.Gson; |
| 9 | import com.google.gson.GsonBuilder; | 10 | import com.google.gson.GsonBuilder; |
| 10 | import com.google.gson.annotations.SerializedName; | 11 | import com.google.gson.annotations.SerializedName; |
| 12 | +import com.mumfrey.liteloader.core.runtime.Obf; | ||
| 11 | 13 | ||
| 12 | /** | 14 | /** |
| 13 | * Serialisable class which represents a set of event injection definitions. Instances of this class are | 15 | * Serialisable class which represents a set of event injection definitions. Instances of this class are |
| @@ -49,11 +51,22 @@ public class JsonEvents implements Serializable | @@ -49,11 +51,22 @@ public class JsonEvents implements Serializable | ||
| 49 | private List<JsonEvent> events; | 51 | private List<JsonEvent> events; |
| 50 | 52 | ||
| 51 | /** | 53 | /** |
| 54 | + * List of accessor interfaces | ||
| 55 | + */ | ||
| 56 | + @SerializedName("accessors") | ||
| 57 | + private List<String> accessors; | ||
| 58 | + | ||
| 59 | + /** | ||
| 52 | * Parsed method descriptors | 60 | * Parsed method descriptors |
| 53 | */ | 61 | */ |
| 54 | private transient JsonMethods methods; | 62 | private transient JsonMethods methods; |
| 55 | 63 | ||
| 56 | /** | 64 | /** |
| 65 | + * Parsed accessors | ||
| 66 | + */ | ||
| 67 | + private transient List<String> accessorInterfaces = new ArrayList<String>(); | ||
| 68 | + | ||
| 69 | + /** | ||
| 57 | * Attempts to parse the information in this object | 70 | * Attempts to parse the information in this object |
| 58 | */ | 71 | */ |
| 59 | private void parse() | 72 | private void parse() |
| @@ -76,6 +89,18 @@ public class JsonEvents implements Serializable | @@ -76,6 +89,18 @@ public class JsonEvents implements Serializable | ||
| 76 | { | 89 | { |
| 77 | event.parse(this.methods); | 90 | event.parse(this.methods); |
| 78 | } | 91 | } |
| 92 | + | ||
| 93 | + if (this.accessors != null) | ||
| 94 | + { | ||
| 95 | + for (String accessor : this.accessors) | ||
| 96 | + { | ||
| 97 | + if (accessor != null) | ||
| 98 | + { | ||
| 99 | + Obf accessorName = this.obfuscation.parseClass(accessor); | ||
| 100 | + this.accessorInterfaces.add(accessorName.name); | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | + } | ||
| 79 | } | 104 | } |
| 80 | catch (InvalidEventJsonException ex) | 105 | catch (InvalidEventJsonException ex) |
| 81 | { | 106 | { |
| @@ -116,6 +141,11 @@ public class JsonEvents implements Serializable | @@ -116,6 +141,11 @@ public class JsonEvents implements Serializable | ||
| 116 | { | 141 | { |
| 117 | event.register(transformer); | 142 | event.register(transformer); |
| 118 | } | 143 | } |
| 144 | + | ||
| 145 | + for (String interfaceName : this.accessorInterfaces) | ||
| 146 | + { | ||
| 147 | + transformer.registerAccessor(interfaceName); | ||
| 148 | + } | ||
| 119 | } | 149 | } |
| 120 | 150 | ||
| 121 | // public String toJson() | 151 | // public String toJson() |
java/common/com/mumfrey/liteloader/transformers/event/json/ModEventInjectionTransformer.java
| @@ -74,4 +74,9 @@ public class ModEventInjectionTransformer extends EventInjectionTransformer | @@ -74,4 +74,9 @@ public class ModEventInjectionTransformer extends EventInjectionTransformer | ||
| 74 | { | 74 | { |
| 75 | return super.addEvent(event, targetMethod, injectionPoint); | 75 | return super.addEvent(event, targetMethod, injectionPoint); |
| 76 | } | 76 | } |
| 77 | + | ||
| 78 | + protected void registerAccessor(String interfaceName) | ||
| 79 | + { | ||
| 80 | + super.addAccessor(interfaceName); | ||
| 81 | + } | ||
| 77 | } | 82 | } |