Commit fd2df210fcdc89137c8b3d847f42146f4121ab3c
1 parent
84ea1ab3
Quick and dirty 1.10 update
Showing
14 changed files
with
685 additions
and
838 deletions
build.gradle
| ... | ... | @@ -71,15 +71,12 @@ repositories { |
| 71 | 71 | } |
| 72 | 72 | |
| 73 | 73 | dependencies { |
| 74 | -// compile 'org.ow2.asm:asm-debug-all:5.0.3' | |
| 75 | - compile('org.spongepowered:mixin:0.5.6-SNAPSHOT') { | |
| 74 | + compile('org.spongepowered:mixin:0.5.10-SNAPSHOT') { | |
| 76 | 75 | exclude module: 'asm-commons' |
| 77 | 76 | exclude module: 'asm-tree' |
| 78 | 77 | exclude module: 'launchwrapper' |
| 79 | 78 | exclude module: 'guava' |
| 80 | 79 | } |
| 81 | -// compile 'com.google.guava:guava:17.0' | |
| 82 | -// compile 'com.google.code.gson:gson:2.2.4' | |
| 83 | 80 | } |
| 84 | 81 | |
| 85 | 82 | minecraft { | ... | ... |
gradle.properties
| ... | ... | @@ -5,6 +5,6 @@ description=LiteLoader |
| 5 | 5 | url=http://www.liteloader.com |
| 6 | 6 | organization=LiteLoader |
| 7 | 7 | buildType=SNAPSHOT |
| 8 | -buildVersion=1.9.4 | |
| 9 | -mcVersion=1.9.4 | |
| 10 | -mcMappings=snapshot_20160517 | |
| 11 | 8 | \ No newline at end of file |
| 9 | +buildVersion=1.10 | |
| 10 | +mcVersion=1.10 | |
| 11 | +mcMappings=snapshot_custom | |
| 12 | 12 | \ No newline at end of file | ... | ... |
src/client/java/com/mumfrey/liteloader/client/mixin/MixinIntIdentityHashBiMap.java
| ... | ... | @@ -15,8 +15,8 @@ import net.minecraft.util.IntIdentityHashBiMap; |
| 15 | 15 | @Mixin(IntIdentityHashBiMap.class) |
| 16 | 16 | public abstract class MixinIntIdentityHashBiMap<V> implements IIntIdentityHashBiMap<V> |
| 17 | 17 | { |
| 18 | - @Shadow private V[] keys; | |
| 19 | - @Shadow private int[] values; | |
| 18 | + @Shadow private V[] values; | |
| 19 | + @Shadow private int[] intKeys; | |
| 20 | 20 | @Shadow private V[] byId; |
| 21 | 21 | @Shadow private int nextFreeIndex; |
| 22 | 22 | @Shadow private int mapSize; |
| ... | ... | @@ -35,9 +35,9 @@ public abstract class MixinIntIdentityHashBiMap<V> implements IIntIdentityHashBi |
| 35 | 35 | public void removeObject(V object) |
| 36 | 36 | { |
| 37 | 37 | int index = this.getIndex(object, this.hashObject(object)); |
| 38 | - int intKey = this.values[index]; | |
| 39 | - this.keys[index] = null; | |
| 40 | - this.values[index] = 0; | |
| 38 | + int intKey = this.intKeys[index]; | |
| 39 | + this.values[index] = null; | |
| 40 | + this.intKeys[index] = 0; | |
| 41 | 41 | this.byId[intKey] = null; |
| 42 | 42 | } |
| 43 | 43 | } | ... | ... |
src/client/java/com/mumfrey/liteloader/util/ModUtilities.java
| ... | ... | @@ -5,33 +5,25 @@ |
| 5 | 5 | */ |
| 6 | 6 | package com.mumfrey.liteloader.util; |
| 7 | 7 | |
| 8 | -import java.lang.reflect.Field; | |
| 9 | -import java.lang.reflect.Modifier; | |
| 10 | 8 | import java.util.Map; |
| 11 | 9 | |
| 12 | 10 | import org.lwjgl.LWJGLException; |
| 13 | 11 | import org.lwjgl.opengl.Display; |
| 14 | 12 | import org.lwjgl.opengl.DisplayMode; |
| 15 | 13 | |
| 16 | -import com.mumfrey.liteloader.client.ducks.IMutableRegistry; | |
| 17 | 14 | import com.mumfrey.liteloader.client.ducks.IRenderManager; |
| 18 | 15 | import com.mumfrey.liteloader.client.ducks.ITileEntityRendererDispatcher; |
| 19 | 16 | import com.mumfrey.liteloader.client.overlays.IMinecraft; |
| 20 | 17 | import com.mumfrey.liteloader.client.util.PrivateFieldsClient; |
| 21 | 18 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; |
| 22 | 19 | |
| 23 | -import net.minecraft.block.Block; | |
| 24 | 20 | import net.minecraft.client.Minecraft; |
| 25 | 21 | import net.minecraft.client.renderer.entity.Render; |
| 26 | 22 | import net.minecraft.client.renderer.entity.RenderManager; |
| 27 | 23 | import net.minecraft.client.renderer.tileentity.TileEntityRendererDispatcher; |
| 28 | 24 | import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer; |
| 29 | 25 | import net.minecraft.entity.Entity; |
| 30 | -import net.minecraft.init.Blocks; | |
| 31 | -import net.minecraft.init.Items; | |
| 32 | -import net.minecraft.item.Item; | |
| 33 | 26 | import net.minecraft.tileentity.TileEntity; |
| 34 | -import net.minecraft.util.ResourceLocation; | |
| 35 | 27 | |
| 36 | 28 | /** |
| 37 | 29 | * A small collection of useful functions for mods |
| ... | ... | @@ -103,115 +95,6 @@ public abstract class ModUtilities |
| 103 | 95 | } |
| 104 | 96 | } |
| 105 | 97 | |
| 106 | - /** | |
| 107 | - * Add a block to the blocks registry | |
| 108 | - * | |
| 109 | - * @param blockId Block ID to insert | |
| 110 | - * @param blockName Block identifier | |
| 111 | - * @param block Block to register | |
| 112 | - * @param force Force insertion even if the operation is blocked by FMl | |
| 113 | - * | |
| 114 | - * @deprecated Register blocks directly with the registry | |
| 115 | - */ | |
| 116 | - @SuppressWarnings("unchecked") | |
| 117 | - @Deprecated | |
| 118 | - public static void addBlock(int blockId, ResourceLocation blockName, Block block, boolean force) | |
| 119 | - { | |
| 120 | - boolean exists = Block.REGISTRY.containsKey(blockName); | |
| 121 | - Block existingBlock = Block.REGISTRY.getObject(blockName); | |
| 122 | - | |
| 123 | - try | |
| 124 | - { | |
| 125 | - Block.REGISTRY.register(blockId, blockName, block); | |
| 126 | - } | |
| 127 | - catch (IllegalArgumentException ex) | |
| 128 | - { | |
| 129 | - if (!force) throw new IllegalArgumentException("Could not register block '" + blockName + "', the operation was blocked by FML.", ex); | |
| 130 | - | |
| 131 | - if (Block.REGISTRY instanceof IMutableRegistry) | |
| 132 | - { | |
| 133 | - ((IMutableRegistry<ResourceLocation, Block>)Block.REGISTRY).removeObjectFromRegistry(blockName); | |
| 134 | - Block.REGISTRY.register(blockId, blockName, block); | |
| 135 | - } | |
| 136 | - } | |
| 137 | - | |
| 138 | - if (exists) | |
| 139 | - { | |
| 140 | - try | |
| 141 | - { | |
| 142 | - for (Field field : Blocks.class.getDeclaredFields()) | |
| 143 | - { | |
| 144 | - field.setAccessible(true); | |
| 145 | - if (field.isAccessible() && Block.class.isAssignableFrom(field.getType())) | |
| 146 | - { | |
| 147 | - Block fieldValue = (Block)field.get(null); | |
| 148 | - if (fieldValue == existingBlock) | |
| 149 | - { | |
| 150 | - ModUtilities.setFinalStaticField(field, block); | |
| 151 | - } | |
| 152 | - } | |
| 153 | - } | |
| 154 | - } | |
| 155 | - catch (Exception ex) | |
| 156 | - { | |
| 157 | - ex.printStackTrace(); | |
| 158 | - } | |
| 159 | - } | |
| 160 | - } | |
| 161 | - | |
| 162 | - /** | |
| 163 | - * Add an item to the items registry | |
| 164 | - * | |
| 165 | - * @param itemId Item ID to insert | |
| 166 | - * @param itemName Item identifier | |
| 167 | - * @param item Item to register | |
| 168 | - * @param force Force insertion even if the operation is blocked by FMl | |
| 169 | - * | |
| 170 | - * @deprecated Register items directly with the registry | |
| 171 | - */ | |
| 172 | - @SuppressWarnings("unchecked") | |
| 173 | - @Deprecated | |
| 174 | - public static void addItem(int itemId, ResourceLocation itemName, Item item, boolean force) | |
| 175 | - { | |
| 176 | - boolean exists = Item.REGISTRY.containsKey(itemName); | |
| 177 | - Item existingItem = Item.REGISTRY.getObject(itemName); | |
| 178 | - | |
| 179 | - try | |
| 180 | - { | |
| 181 | - Item.REGISTRY.register(itemId, itemName, item); | |
| 182 | - } | |
| 183 | - catch (IllegalArgumentException ex) | |
| 184 | - { | |
| 185 | - if (!force) throw new IllegalArgumentException("Could not register item '" + itemName + "', the operation was blocked by FML.", ex); | |
| 186 | - | |
| 187 | - if (Block.REGISTRY instanceof IMutableRegistry) | |
| 188 | - { | |
| 189 | - ((IMutableRegistry<ResourceLocation, Block>)Item.REGISTRY).removeObjectFromRegistry(itemName); | |
| 190 | - Item.REGISTRY.register(itemId, itemName, item); | |
| 191 | - } | |
| 192 | - } | |
| 193 | - | |
| 194 | - if (exists) | |
| 195 | - { | |
| 196 | - try | |
| 197 | - { | |
| 198 | - for (Field field : Items.class.getDeclaredFields()) | |
| 199 | - { | |
| 200 | - field.setAccessible(true); | |
| 201 | - if (field.isAccessible() && Item.class.isAssignableFrom(field.getType())) | |
| 202 | - { | |
| 203 | - Item fieldValue = (Item)field.get(null); | |
| 204 | - if (fieldValue == existingItem) | |
| 205 | - { | |
| 206 | - ModUtilities.setFinalStaticField(field, item); | |
| 207 | - } | |
| 208 | - } | |
| 209 | - } | |
| 210 | - } | |
| 211 | - catch (Exception ex) {} | |
| 212 | - } | |
| 213 | - } | |
| 214 | - | |
| 215 | 98 | @SuppressWarnings("unchecked") |
| 216 | 99 | public static void addTileEntity(String entityName, Class<? extends TileEntity> tileEntityClass) |
| 217 | 100 | { |
| ... | ... | @@ -227,13 +110,4 @@ public abstract class ModUtilities |
| 227 | 110 | ex.printStackTrace(); |
| 228 | 111 | } |
| 229 | 112 | } |
| 230 | - | |
| 231 | - private static void setFinalStaticField(Field field, Object value) | |
| 232 | - throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException | |
| 233 | - { | |
| 234 | - Field modifiers = Field.class.getDeclaredField("modifiers"); | |
| 235 | - modifiers.setAccessible(true); | |
| 236 | - modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL); | |
| 237 | - field.set(null, value); | |
| 238 | - } | |
| 239 | 113 | } | ... | ... |
src/client/resources/mixins.liteloader.client.json
src/main/java/com/mumfrey/liteloader/api/MixinConfigProvider.java
| ... | ... | @@ -5,23 +5,12 @@ |
| 5 | 5 | */ |
| 6 | 6 | package com.mumfrey.liteloader.api; |
| 7 | 7 | |
| 8 | -import org.spongepowered.asm.mixin.MixinEnvironment.CompatibilityLevel; | |
| 9 | - | |
| 10 | 8 | /** |
| 11 | 9 | * Container for all of an API's mixin environment configuration |
| 12 | 10 | */ |
| 13 | 11 | public interface MixinConfigProvider |
| 14 | 12 | { |
| 15 | 13 | /** |
| 16 | - * Get the minimum required mixin operating compatibility level for this | |
| 17 | - * API, can return null. | |
| 18 | - * | |
| 19 | - * @deprecated Specify level in configs | |
| 20 | - */ | |
| 21 | - @Deprecated | |
| 22 | - public abstract CompatibilityLevel getCompatibilityLevel(); | |
| 23 | - | |
| 24 | - /** | |
| 25 | 14 | * Get mixin configuration files for this API, all returned configs will be |
| 26 | 15 | * added to the DEFAULT environment. Can return null. |
| 27 | 16 | */ | ... | ... |
src/main/java/com/mumfrey/liteloader/api/manager/APIProviderBasic.java
| ... | ... | @@ -13,8 +13,6 @@ import java.util.List; |
| 13 | 13 | import java.util.Map; |
| 14 | 14 | import java.util.regex.Matcher; |
| 15 | 15 | |
| 16 | -import org.spongepowered.asm.mixin.MixinEnvironment; | |
| 17 | -import org.spongepowered.asm.mixin.MixinEnvironment.CompatibilityLevel; | |
| 18 | 16 | import org.spongepowered.asm.mixin.Mixins; |
| 19 | 17 | |
| 20 | 18 | import com.mumfrey.liteloader.api.CoreProvider; |
| ... | ... | @@ -76,12 +74,6 @@ class APIProviderBasic implements APIProvider, APIAdapter |
| 76 | 74 | MixinConfigProvider mixins = api.getMixins(); |
| 77 | 75 | if (mixins != null) |
| 78 | 76 | { |
| 79 | - CompatibilityLevel level = mixins.getCompatibilityLevel(); | |
| 80 | - if (level != null) | |
| 81 | - { | |
| 82 | - MixinEnvironment.setCompatibilityLevel(level); | |
| 83 | - } | |
| 84 | - | |
| 85 | 77 | String[] configs = mixins.getMixinConfigs(); |
| 86 | 78 | if (configs != null) |
| 87 | 79 | { | ... | ... |
src/main/java/com/mumfrey/liteloader/core/LiteLoaderVersion.java
| ... | ... | @@ -46,12 +46,13 @@ public enum LiteLoaderVersion |
| 46 | 46 | MC_1_8_0_R0(32, 0, "1.8", "1.8.0", "1.8", "1.8.0"), |
| 47 | 47 | MC_1_8_9_R0(34, 0, "1.8.9", "1.8.9", "1.8.9"), |
| 48 | 48 | MC_1_9_0_R0(35, 0, "1.9", "1.9.0", "1.9", "1.9.0"), |
| 49 | - MC_1_9_4_R0(36, 0, "1.9.4", "1.9.4", "1.9.4"); | |
| 49 | + MC_1_9_4_R0(36, 0, "1.9.4", "1.9.4", "1.9.4"), | |
| 50 | + MC_1_10_R0(37, 0, "1.10", "1.10", "1.10", "1.10.0"); | |
| 50 | 51 | |
| 51 | 52 | /** |
| 52 | 53 | * Current loader version |
| 53 | 54 | */ |
| 54 | - public static final LiteLoaderVersion CURRENT = LiteLoaderVersion.MC_1_9_4_R0; | |
| 55 | + public static final LiteLoaderVersion CURRENT = LiteLoaderVersion.MC_1_10_R0; | |
| 55 | 56 | |
| 56 | 57 | private static final LiteLoaderUpdateSite updateSite = new LiteLoaderUpdateSite(LiteLoaderVersion.CURRENT.getMinecraftVersion(), |
| 57 | 58 | LiteLoaderVersion.CURRENT.getReleaseTimestamp()); | ... | ... |
src/main/java/com/mumfrey/liteloader/core/api/LiteLoaderCoreAPI.java
| ... | ... | @@ -10,8 +10,6 @@ import java.util.ArrayList; |
| 10 | 10 | import java.util.Collections; |
| 11 | 11 | import java.util.List; |
| 12 | 12 | |
| 13 | -import org.spongepowered.asm.mixin.MixinEnvironment.CompatibilityLevel; | |
| 14 | - | |
| 15 | 13 | import com.mumfrey.liteloader.api.EnumeratorModule; |
| 16 | 14 | import com.mumfrey.liteloader.api.LiteAPI; |
| 17 | 15 | import com.mumfrey.liteloader.api.MixinConfigProvider; |
| ... | ... | @@ -160,12 +158,6 @@ public abstract class LiteLoaderCoreAPI implements LiteAPI, MixinConfigProvider |
| 160 | 158 | } |
| 161 | 159 | |
| 162 | 160 | @Override |
| 163 | - public CompatibilityLevel getCompatibilityLevel() | |
| 164 | - { | |
| 165 | - return null; | |
| 166 | - } | |
| 167 | - | |
| 168 | - @Override | |
| 169 | 161 | public String[] getMixinConfigs() |
| 170 | 162 | { |
| 171 | 163 | return new String[] { | ... | ... |
src/main/java/com/mumfrey/liteloader/core/runtime/Obf.java
| ... | ... | @@ -17,7 +17,7 @@ import org.spongepowered.asm.obfuscation.SrgMethod; |
| 17 | 17 | * Centralised obfuscation table for LiteLoader |
| 18 | 18 | * |
| 19 | 19 | * @author Adam Mummery-Smith |
| 20 | - * TODO Obfuscation 1.9.4 | |
| 20 | + * TODO Obfuscation 1.10 | |
| 21 | 21 | */ |
| 22 | 22 | public class Obf |
| 23 | 23 | { |
| ... | ... | @@ -43,14 +43,14 @@ public class Obf |
| 43 | 43 | |
| 44 | 44 | // Classes |
| 45 | 45 | // ----------------------------------------------------------------------------------------- |
| 46 | - public static final Obf Minecraft = new Obf("net.minecraft.client.Minecraft", "bcd" ); | |
| 47 | - public static final Obf EntityRenderer = new Obf("net.minecraft.client.renderer.EntityRenderer", "bnd" ); | |
| 48 | - public static final Obf Blocks = new Obf("net.minecraft.init.Blocks", "aju" ); | |
| 46 | + public static final Obf Minecraft = new Obf("net.minecraft.client.Minecraft", "bcx" ); | |
| 47 | + public static final Obf EntityRenderer = new Obf("net.minecraft.client.renderer.EntityRenderer", "bnz" ); | |
| 48 | + public static final Obf Blocks = new Obf("net.minecraft.init.Blocks", "akg" ); | |
| 49 | 49 | public static final Obf CrashReport$6 = new Obf("net.minecraft.crash.CrashReport$6", "b$6" ); |
| 50 | - public static final Obf INetHandler = new Obf("net.minecraft.network.INetHandler", "er" ); | |
| 51 | - public static final Obf Items = new Obf("net.minecraft.init.Items", "ads" ); | |
| 52 | - public static final Obf Profiler = new Obf("net.minecraft.profiler.Profiler", "oo" ); | |
| 53 | - public static final Obf TileEntity = new Obf("net.minecraft.tileentity.TileEntity", "apv" ); | |
| 50 | + public static final Obf INetHandler = new Obf("net.minecraft.network.INetHandler", "et" ); | |
| 51 | + public static final Obf Items = new Obf("net.minecraft.init.Items", "aeb" ); | |
| 52 | + public static final Obf Profiler = new Obf("net.minecraft.profiler.Profiler", "oq" ); | |
| 53 | + public static final Obf TileEntity = new Obf("net.minecraft.tileentity.TileEntity", "aqk" ); | |
| 54 | 54 | |
| 55 | 55 | // Fields |
| 56 | 56 | // ----------------------------------------------------------------------------------------- | ... | ... |
src/main/java/com/mumfrey/liteloader/core/runtime/Packets.java
| ... | ... | @@ -12,7 +12,7 @@ import java.util.Map; |
| 12 | 12 | * Packet obfuscation table |
| 13 | 13 | * |
| 14 | 14 | * @author Adam Mummery-Smith |
| 15 | - * TODO Obfuscation 1.9.4 | |
| 15 | + * TODO Obfuscation 1.10 | |
| 16 | 16 | */ |
| 17 | 17 | public final class Packets extends Obf |
| 18 | 18 | { |
| ... | ... | @@ -37,123 +37,123 @@ public final class Packets extends Obf |
| 37 | 37 | |
| 38 | 38 | private static Map<String, Packets> packetMap = new HashMap<String, Packets>(); |
| 39 | 39 | |
| 40 | - public static Packets CPacketEncryptionResponse = new Packets("net/minecraft/network/login/client/CPacketEncryptionResponse", "ju", Context.SERVER); | |
| 41 | - public static Packets CPacketLoginStart = new Packets("net/minecraft/network/login/client/CPacketLoginStart", "jt", Context.SERVER); | |
| 42 | - public static Packets SPacketDisconnectLogin = new Packets("net/minecraft/network/login/server/SPacketDisconnect", "jr", Context.CLIENT); | |
| 43 | - public static Packets SPacketEnableCompression = new Packets("net/minecraft/network/login/server/SPacketEnableCompression", "jq", Context.CLIENT); | |
| 44 | - public static Packets SPacketEncryptionRequest = new Packets("net/minecraft/network/login/server/SPacketEncryptionRequest", "jp", Context.CLIENT); | |
| 45 | - public static Packets SPacketLoginSuccess = new Packets("net/minecraft/network/login/server/SPacketLoginSuccess", "jo", Context.CLIENT); | |
| 46 | - public static Packets CPacketAnimation = new Packets("net/minecraft/network/play/client/CPacketAnimation", "jf", Context.SERVER); | |
| 47 | - public static Packets CPacketChatMessage = new Packets("net/minecraft/network/play/client/CPacketChatMessage", "ik", Context.SERVER); | |
| 48 | - public static Packets CPacketClickWindow = new Packets("net/minecraft/network/play/client/CPacketClickWindow", "ip", Context.SERVER); | |
| 49 | - public static Packets CPacketClientSettings = new Packets("net/minecraft/network/play/client/CPacketClientSettings", "im", Context.SERVER); | |
| 50 | - public static Packets CPacketClientStatus = new Packets("net/minecraft/network/play/client/CPacketClientStatus", "il", Context.SERVER); | |
| 51 | - public static Packets CPacketCloseWindow = new Packets("net/minecraft/network/play/client/CPacketCloseWindow", "iq", Context.SERVER); | |
| 52 | - public static Packets CPacketConfirmTeleport = new Packets("net/minecraft/network/play/client/CPacketConfirmTeleport", "ii", Context.SERVER); | |
| 53 | - public static Packets CPacketConfirmTransaction = new Packets("net/minecraft/network/play/client/CPacketConfirmTransaction", "in", Context.SERVER); | |
| 54 | - public static Packets CPacketCreativeInventoryAction = new Packets("net/minecraft/network/play/client/CPacketCreativeInventoryAction", "jd", Context.SERVER); | |
| 55 | - public static Packets CPacketCustomPayload = new Packets("net/minecraft/network/play/client/CPacketCustomPayload", "ir", Context.SERVER); | |
| 56 | - public static Packets CPacketEnchantItem = new Packets("net/minecraft/network/play/client/CPacketEnchantItem", "io", Context.SERVER); | |
| 57 | - public static Packets CPacketEntityAction = new Packets("net/minecraft/network/play/client/CPacketEntityAction", "iz", Context.SERVER); | |
| 58 | - public static Packets CPacketHeldItemChange = new Packets("net/minecraft/network/play/client/CPacketHeldItemChange", "jc", Context.SERVER); | |
| 59 | - public static Packets CPacketInput = new Packets("net/minecraft/network/play/client/CPacketInput", "ja", Context.SERVER); | |
| 60 | - public static Packets C00Handshake = new Packets("net/minecraft/network/handshake/client/C00Handshake", "jk", Context.SERVER); | |
| 61 | - public static Packets CPacketKeepAlive = new Packets("net/minecraft/network/play/client/CPacketKeepAlive", "it", Context.SERVER); | |
| 62 | - public static Packets CPacketPlayer = new Packets("net/minecraft/network/play/client/CPacketPlayer", "iu", Context.SERVER); | |
| 63 | - public static Packets CPacketPlayerPosition = new Packets("net/minecraft/network/play/client/CPacketPlayer$Position", "iu$a", Context.SERVER); | |
| 64 | - public static Packets CPacketPlayerPositionRotation = new Packets("net/minecraft/network/play/client/CPacketPlayer$PositionRotation", "iu$b", Context.SERVER); | |
| 65 | - public static Packets CPacketPlayerRotation = new Packets("net/minecraft/network/play/client/CPacketPlayer$Rotation", "iu$c", Context.SERVER); | |
| 66 | - public static Packets CPacketPlayerAbilities = new Packets("net/minecraft/network/play/client/CPacketPlayerAbilities", "ix", Context.SERVER); | |
| 67 | - public static Packets CPacketPlayerDigging = new Packets("net/minecraft/network/play/client/CPacketPlayerDigging", "iy", Context.SERVER); | |
| 68 | - public static Packets CPacketPlayerTryUseItem = new Packets("net/minecraft/network/play/client/CPacketPlayerTryUseItem", "ji", Context.SERVER); | |
| 69 | - public static Packets CPacketPlayerTryUseItemOnBlock = new Packets("net/minecraft/network/play/client/CPacketPlayerTryUseItemOnBlock", "jh", Context.SERVER); | |
| 70 | - public static Packets CPacketResourcePackStatus = new Packets("net/minecraft/network/play/client/CPacketResourcePackStatus", "jb", Context.SERVER); | |
| 71 | - public static Packets CPacketSpectate = new Packets("net/minecraft/network/play/client/CPacketSpectate", "jg", Context.SERVER); | |
| 72 | - public static Packets CPacketSteerBoat = new Packets("net/minecraft/network/play/client/CPacketSteerBoat", "iw", Context.SERVER); | |
| 73 | - public static Packets CPacketTabComplete = new Packets("net/minecraft/network/play/client/CPacketTabComplete", "ij", Context.SERVER); | |
| 74 | - public static Packets CPacketUpdateSign = new Packets("net/minecraft/network/play/client/CPacketUpdateSign", "je", Context.SERVER); | |
| 75 | - public static Packets CPacketUseEntity = new Packets("net/minecraft/network/play/client/CPacketUseEntity", "is", Context.SERVER); | |
| 76 | - public static Packets CPacketVehicleMove = new Packets("net/minecraft/network/play/client/CPacketVehicleMove", "iv", Context.SERVER); | |
| 77 | - public static Packets SPacketAnimation = new Packets("net/minecraft/network/play/server/SPacketAnimation", "fr", Context.CLIENT); | |
| 78 | - public static Packets SPacketBlockAction = new Packets("net/minecraft/network/play/server/SPacketBlockAction", "fv", Context.CLIENT); | |
| 79 | - public static Packets SPacketBlockBreakAnim = new Packets("net/minecraft/network/play/server/SPacketBlockBreakAnim", "ft", Context.CLIENT); | |
| 80 | - public static Packets SPacketBlockChange = new Packets("net/minecraft/network/play/server/SPacketBlockChange", "fw", Context.CLIENT); | |
| 81 | - public static Packets SPacketCamera = new Packets("net/minecraft/network/play/server/SPacketCamera", "hk", Context.CLIENT); | |
| 82 | - public static Packets SPacketChangeGameState = new Packets("net/minecraft/network/play/server/SPacketChangeGameState", "gp", Context.CLIENT); | |
| 83 | - public static Packets SPacketChat = new Packets("net/minecraft/network/play/server/SPacketChat", "ga", Context.CLIENT); | |
| 84 | - public static Packets SPacketChunkData = new Packets("net/minecraft/network/play/server/SPacketChunkData", "gr", Context.CLIENT); | |
| 85 | - public static Packets SPacketCloseWindow = new Packets("net/minecraft/network/play/server/SPacketCloseWindow", "gd", Context.CLIENT); | |
| 86 | - public static Packets SPacketCollectItem = new Packets("net/minecraft/network/play/server/SPacketCollectItem", "ic", Context.CLIENT); | |
| 87 | - public static Packets SPacketCombatEvent = new Packets("net/minecraft/network/play/server/SPacketCombatEvent", "ha", Context.CLIENT); | |
| 88 | - public static Packets SPacketConfirmTransaction = new Packets("net/minecraft/network/play/server/SPacketConfirmTransaction", "gc", Context.CLIENT); | |
| 89 | - public static Packets SPacketCooldown = new Packets("net/minecraft/network/play/server/SPacketCooldown", "gi", Context.CLIENT); | |
| 90 | - public static Packets SPacketCustomPayload = new Packets("net/minecraft/network/play/server/SPacketCustomPayload", "gj", Context.CLIENT); | |
| 91 | - public static Packets SPacketCustomSound = new Packets("net/minecraft/network/play/server/SPacketCustomSound", "gk", Context.CLIENT); | |
| 92 | - public static Packets SPacketDestroyEntities = new Packets("net/minecraft/network/play/server/SPacketDestroyEntities", "he", Context.CLIENT); | |
| 93 | - public static Packets SPacketDisconnect = new Packets("net/minecraft/network/play/server/SPacketDisconnect", "gl", Context.CLIENT); | |
| 94 | - public static Packets SPacketDisplayObjective = new Packets("net/minecraft/network/play/server/SPacketDisplayObjective", "hm", Context.CLIENT); | |
| 95 | - public static Packets SPacketEffect = new Packets("net/minecraft/network/play/server/SPacketEffect", "gs", Context.CLIENT); | |
| 96 | - public static Packets SPacketEntity = new Packets("net/minecraft/network/play/server/SPacketEntity", "gw", Context.CLIENT); | |
| 97 | - public static Packets S15PacketEntityRelMove = new Packets("net/minecraft/network/play/server/SPacketEntity$S15PacketEntityRelMove", "gw$a", Context.CLIENT); | |
| 98 | - public static Packets S16PacketEntityLook = new Packets("net/minecraft/network/play/server/SPacketEntity$S16PacketEntityLook", "gw$c", Context.CLIENT); | |
| 99 | - public static Packets S17PacketEntityLookMove = new Packets("net/minecraft/network/play/server/SPacketEntity$S17PacketEntityLookMove", "gw$b", Context.CLIENT); | |
| 100 | - public static Packets SPacketEntityAttach = new Packets("net/minecraft/network/play/server/SPacketEntityAttach", "ho", Context.CLIENT); | |
| 101 | - public static Packets SPacketEntityEffect = new Packets("net/minecraft/network/play/server/SPacketEntityEffect", "ig", Context.CLIENT); | |
| 102 | - public static Packets SPacketEntityEquipment = new Packets("net/minecraft/network/play/server/SPacketEntityEquipment", "hq", Context.CLIENT); | |
| 103 | - public static Packets SPacketEntityHeadLook = new Packets("net/minecraft/network/play/server/SPacketEntityHeadLook", "hi", Context.CLIENT); | |
| 104 | - public static Packets SPacketEntityMetadata = new Packets("net/minecraft/network/play/server/SPacketEntityMetadata", "hn", Context.CLIENT); | |
| 105 | - public static Packets SPacketEntityProperties = new Packets("net/minecraft/network/play/server/SPacketEntityProperties", "ie", Context.CLIENT); | |
| 106 | - public static Packets SPacketEntityStatus = new Packets("net/minecraft/network/play/server/SPacketEntityStatus", "gm", Context.CLIENT); | |
| 107 | - public static Packets SPacketEntityTeleport = new Packets("net/minecraft/network/play/server/SPacketEntityTeleport", "id", Context.CLIENT); | |
| 108 | - public static Packets SPacketEntityVelocity = new Packets("net/minecraft/network/play/server/SPacketEntityVelocity", "hp", Context.CLIENT); | |
| 109 | - public static Packets SPacketExplosion = new Packets("net/minecraft/network/play/server/SPacketExplosion", "gn", Context.CLIENT); | |
| 110 | - public static Packets SPacketHeldItemChange = new Packets("net/minecraft/network/play/server/SPacketHeldItemChange", "hl", Context.CLIENT); | |
| 111 | - public static Packets SPacketJoinGame = new Packets("net/minecraft/network/play/server/SPacketJoinGame", "gu", Context.CLIENT); | |
| 112 | - public static Packets SPacketKeepAlive = new Packets("net/minecraft/network/play/server/SPacketKeepAlive", "gq", Context.CLIENT); | |
| 113 | - public static Packets SPacketMaps = new Packets("net/minecraft/network/play/server/SPacketMaps", "gv", Context.CLIENT); | |
| 114 | - public static Packets SPacketMoveVehicle = new Packets("net/minecraft/network/play/server/SPacketMoveVehicle", "gx", Context.CLIENT); | |
| 115 | - public static Packets SPacketMultiBlockChange = new Packets("net/minecraft/network/play/server/SPacketMultiBlockChange", "gb", Context.CLIENT); | |
| 116 | - public static Packets SPacketOpenWindow = new Packets("net/minecraft/network/play/server/SPacketOpenWindow", "ge", Context.CLIENT); | |
| 117 | - public static Packets SPacketParticles = new Packets("net/minecraft/network/play/server/SPacketParticles", "gt", Context.CLIENT); | |
| 118 | - public static Packets SPacketPlayerAbilities = new Packets("net/minecraft/network/play/server/SPacketPlayerAbilities", "gz", Context.CLIENT); | |
| 119 | - public static Packets SPacketPlayerListHeaderFooter = new Packets("net/minecraft/network/play/server/SPacketPlayerListHeaderFooter", "ib", Context.CLIENT); | |
| 120 | - public static Packets SPacketPlayerListItem = new Packets("net/minecraft/network/play/server/SPacketPlayerListItem", "hb", Context.CLIENT); | |
| 121 | - public static Packets SPacketPlayerPosLook = new Packets("net/minecraft/network/play/server/SPacketPlayerPosLook", "hc", Context.CLIENT); | |
| 122 | - public static Packets SPacketRemoveEntityEffect = new Packets("net/minecraft/network/play/server/SPacketRemoveEntityEffect", "hf", Context.CLIENT); | |
| 123 | - public static Packets SPacketResourcePackSend = new Packets("net/minecraft/network/play/server/SPacketResourcePackSend", "hg", Context.CLIENT); | |
| 124 | - public static Packets SPacketRespawn = new Packets("net/minecraft/network/play/server/SPacketRespawn", "hh", Context.CLIENT); | |
| 125 | - public static Packets SPacketScoreboardObjective = new Packets("net/minecraft/network/play/server/SPacketScoreboardObjective", "ht", Context.CLIENT); | |
| 126 | - public static Packets SPacketServerDifficulty = new Packets("net/minecraft/network/play/server/SPacketServerDifficulty", "fy", Context.CLIENT); | |
| 127 | - public static Packets SPacketSetExperience = new Packets("net/minecraft/network/play/server/SPacketSetExperience", "hr", Context.CLIENT); | |
| 128 | - public static Packets SPacketSetPassengers = new Packets("net/minecraft/network/play/server/SPacketSetPassengers", "hu", Context.CLIENT); | |
| 129 | - public static Packets SPacketSetSlot = new Packets("net/minecraft/network/play/server/SPacketSetSlot", "gh", Context.CLIENT); | |
| 130 | - public static Packets SPacketSignEditorOpen = new Packets("net/minecraft/network/play/server/SPacketSignEditorOpen", "gy", Context.CLIENT); | |
| 131 | - public static Packets SPacketSoundEffect = new Packets("net/minecraft/network/play/server/SPacketSoundEffect", "ia", Context.CLIENT); | |
| 132 | - public static Packets SPacketSpawnExperienceOrb = new Packets("net/minecraft/network/play/server/SPacketSpawnExperienceOrb", "fm", Context.CLIENT); | |
| 133 | - public static Packets SPacketSpawnGlobalEntity = new Packets("net/minecraft/network/play/server/SPacketSpawnGlobalEntity", "fn", Context.CLIENT); | |
| 134 | - public static Packets SPacketSpawnMob = new Packets("net/minecraft/network/play/server/SPacketSpawnMob", "fo", Context.CLIENT); | |
| 135 | - public static Packets SPacketSpawnObject = new Packets("net/minecraft/network/play/server/SPacketSpawnObject", "fl", Context.CLIENT); | |
| 136 | - public static Packets SPacketSpawnPainting = new Packets("net/minecraft/network/play/server/SPacketSpawnPainting", "fp", Context.CLIENT); | |
| 137 | - public static Packets SPacketSpawnPlayer = new Packets("net/minecraft/network/play/server/SPacketSpawnPlayer", "fq", Context.CLIENT); | |
| 138 | - public static Packets SPacketSpawnPosition = new Packets("net/minecraft/network/play/server/SPacketSpawnPosition", "hx", Context.CLIENT); | |
| 139 | - public static Packets SPacketStatistics = new Packets("net/minecraft/network/play/server/SPacketStatistics", "fs", Context.CLIENT); | |
| 140 | - public static Packets SPacketTabComplete = new Packets("net/minecraft/network/play/server/SPacketTabComplete", "fz", Context.CLIENT); | |
| 141 | - public static Packets SPacketTeams = new Packets("net/minecraft/network/play/server/SPacketTeams", "hv", Context.CLIENT); | |
| 142 | - public static Packets SPacketTimeUpdate = new Packets("net/minecraft/network/play/server/SPacketTimeUpdate", "hy", Context.CLIENT); | |
| 143 | - public static Packets SPacketTitle = new Packets("net/minecraft/network/play/server/SPacketTitle", "hz", Context.CLIENT); | |
| 144 | - public static Packets SPacketUnloadChunk = new Packets("net/minecraft/network/play/server/SPacketUnloadChunk", "go", Context.CLIENT); | |
| 145 | - public static Packets SPacketUpdateBossInfo = new Packets("net/minecraft/network/play/server/SPacketUpdateBossInfo", "fx", Context.CLIENT); | |
| 146 | - public static Packets SPacketUpdateHealth = new Packets("net/minecraft/network/play/server/SPacketUpdateHealth", "hs", Context.CLIENT); | |
| 147 | - public static Packets SPacketUpdateScore = new Packets("net/minecraft/network/play/server/SPacketUpdateScore", "hw", Context.CLIENT); | |
| 148 | - public static Packets SPacketUpdateTileEntity = new Packets("net/minecraft/network/play/server/SPacketUpdateTileEntity", "fu", Context.CLIENT); | |
| 149 | - public static Packets SPacketUseBed = new Packets("net/minecraft/network/play/server/SPacketUseBed", "hd", Context.CLIENT); | |
| 150 | - public static Packets SPacketWindowItems = new Packets("net/minecraft/network/play/server/SPacketWindowItems", "gf", Context.CLIENT); | |
| 151 | - public static Packets SPacketWindowProperty = new Packets("net/minecraft/network/play/server/SPacketWindowProperty", "gg", Context.CLIENT); | |
| 152 | - public static Packets SPacketWorldBorder = new Packets("net/minecraft/network/play/server/SPacketWorldBorder", "hj", Context.CLIENT); | |
| 153 | - public static Packets CPacketPing = new Packets("net/minecraft/network/status/client/CPacketPing", "kc", Context.SERVER); | |
| 154 | - public static Packets CPacketServerQuery = new Packets("net/minecraft/network/status/client/CPacketServerQuery", "kd", Context.SERVER); | |
| 155 | - public static Packets SPacketPong = new Packets("net/minecraft/network/status/server/SPacketPong", "jy", Context.CLIENT); | |
| 156 | - public static Packets SPacketServerInfo = new Packets("net/minecraft/network/status/server/SPacketServerInfo", "jz", Context.CLIENT); | |
| 40 | + public static Packets C00Handshake = new Packets("net/minecraft/network/handshake/client/C00Handshake", "jm", Context.SERVER); | |
| 41 | + public static Packets CPacketEncryptionResponse = new Packets("net/minecraft/network/login/client/CPacketEncryptionResponse", "jw", Context.SERVER); | |
| 42 | + public static Packets CPacketLoginStart = new Packets("net/minecraft/network/login/client/CPacketLoginStart", "jv", Context.SERVER); | |
| 43 | + public static Packets SPacketDisconnectLogin = new Packets("net/minecraft/network/login/server/SPacketDisconnect", "jt", Context.CLIENT); | |
| 44 | + public static Packets SPacketEnableCompression = new Packets("net/minecraft/network/login/server/SPacketEnableCompression", "js", Context.CLIENT); | |
| 45 | + public static Packets SPacketEncryptionRequest = new Packets("net/minecraft/network/login/server/SPacketEncryptionRequest", "jr", Context.CLIENT); | |
| 46 | + public static Packets SPacketLoginSuccess = new Packets("net/minecraft/network/login/server/SPacketLoginSuccess", "jq", Context.CLIENT); | |
| 47 | + public static Packets CPacketAnimation = new Packets("net/minecraft/network/play/client/CPacketAnimation", "jh", Context.SERVER); | |
| 48 | + public static Packets CPacketChatMessage = new Packets("net/minecraft/network/play/client/CPacketChatMessage", "im", Context.SERVER); | |
| 49 | + public static Packets CPacketClickWindow = new Packets("net/minecraft/network/play/client/CPacketClickWindow", "ir", Context.SERVER); | |
| 50 | + public static Packets CPacketClientSettings = new Packets("net/minecraft/network/play/client/CPacketClientSettings", "io", Context.SERVER); | |
| 51 | + public static Packets CPacketClientStatus = new Packets("net/minecraft/network/play/client/CPacketClientStatus", "in", Context.SERVER); | |
| 52 | + public static Packets CPacketCloseWindow = new Packets("net/minecraft/network/play/client/CPacketCloseWindow", "is", Context.SERVER); | |
| 53 | + public static Packets CPacketConfirmTeleport = new Packets("net/minecraft/network/play/client/CPacketConfirmTeleport", "ik", Context.SERVER); | |
| 54 | + public static Packets CPacketConfirmTransaction = new Packets("net/minecraft/network/play/client/CPacketConfirmTransaction", "ip", Context.SERVER); | |
| 55 | + public static Packets CPacketCreativeInventoryAction = new Packets("net/minecraft/network/play/client/CPacketCreativeInventoryAction", "jf", Context.SERVER); | |
| 56 | + public static Packets CPacketCustomPayload = new Packets("net/minecraft/network/play/client/CPacketCustomPayload", "it", Context.SERVER); | |
| 57 | + public static Packets CPacketEnchantItem = new Packets("net/minecraft/network/play/client/CPacketEnchantItem", "iq", Context.SERVER); | |
| 58 | + public static Packets CPacketEntityAction = new Packets("net/minecraft/network/play/client/CPacketEntityAction", "jb", Context.SERVER); | |
| 59 | + public static Packets CPacketHeldItemChange = new Packets("net/minecraft/network/play/client/CPacketHeldItemChange", "je", Context.SERVER); | |
| 60 | + public static Packets CPacketInput = new Packets("net/minecraft/network/play/client/CPacketInput", "jc", Context.SERVER); | |
| 61 | + public static Packets CPacketKeepAlive = new Packets("net/minecraft/network/play/client/CPacketKeepAlive", "iv", Context.SERVER); | |
| 62 | + public static Packets CPacketPlayer = new Packets("net/minecraft/network/play/client/CPacketPlayer", "iw", Context.SERVER); | |
| 63 | + public static Packets CPacketPlayerPosition = new Packets("net/minecraft/network/play/client/CPacketPlayer$Position", "iw$a", Context.SERVER); | |
| 64 | + public static Packets CPacketPlayerPositionRotation = new Packets("net/minecraft/network/play/client/CPacketPlayer$PositionRotation", "iw$b", Context.SERVER); | |
| 65 | + public static Packets CPacketPlayerRotation = new Packets("net/minecraft/network/play/client/CPacketPlayer$Rotation", "iw$c", Context.SERVER); | |
| 66 | + public static Packets CPacketPlayerAbilities = new Packets("net/minecraft/network/play/client/CPacketPlayerAbilities", "iz", Context.SERVER); | |
| 67 | + public static Packets CPacketPlayerDigging = new Packets("net/minecraft/network/play/client/CPacketPlayerDigging", "ja", Context.SERVER); | |
| 68 | + public static Packets CPacketPlayerTryUseItem = new Packets("net/minecraft/network/play/client/CPacketPlayerTryUseItem", "jk", Context.SERVER); | |
| 69 | + public static Packets CPacketPlayerTryUseItemOnBlock = new Packets("net/minecraft/network/play/client/CPacketPlayerTryUseItemOnBlock", "jj", Context.SERVER); | |
| 70 | + public static Packets CPacketResourcePackStatus = new Packets("net/minecraft/network/play/client/CPacketResourcePackStatus", "jd", Context.SERVER); | |
| 71 | + public static Packets CPacketSpectate = new Packets("net/minecraft/network/play/client/CPacketSpectate", "ji", Context.SERVER); | |
| 72 | + public static Packets CPacketSteerBoat = new Packets("net/minecraft/network/play/client/CPacketSteerBoat", "iy", Context.SERVER); | |
| 73 | + public static Packets CPacketTabComplete = new Packets("net/minecraft/network/play/client/CPacketTabComplete", "il", Context.SERVER); | |
| 74 | + public static Packets CPacketUpdateSign = new Packets("net/minecraft/network/play/client/CPacketUpdateSign", "jg", Context.SERVER); | |
| 75 | + public static Packets CPacketUseEntity = new Packets("net/minecraft/network/play/client/CPacketUseEntity", "iu", Context.SERVER); | |
| 76 | + public static Packets CPacketVehicleMove = new Packets("net/minecraft/network/play/client/CPacketVehicleMove", "ix", Context.SERVER); | |
| 77 | + public static Packets SPacketAnimation = new Packets("net/minecraft/network/play/server/SPacketAnimation", "ft", Context.CLIENT); | |
| 78 | + public static Packets SPacketBlockAction = new Packets("net/minecraft/network/play/server/SPacketBlockAction", "fx", Context.CLIENT); | |
| 79 | + public static Packets SPacketBlockBreakAnim = new Packets("net/minecraft/network/play/server/SPacketBlockBreakAnim", "fv", Context.CLIENT); | |
| 80 | + public static Packets SPacketBlockChange = new Packets("net/minecraft/network/play/server/SPacketBlockChange", "fy", Context.CLIENT); | |
| 81 | + public static Packets SPacketCamera = new Packets("net/minecraft/network/play/server/SPacketCamera", "hm", Context.CLIENT); | |
| 82 | + public static Packets SPacketChangeGameState = new Packets("net/minecraft/network/play/server/SPacketChangeGameState", "gr", Context.CLIENT); | |
| 83 | + public static Packets SPacketChat = new Packets("net/minecraft/network/play/server/SPacketChat", "gc", Context.CLIENT); | |
| 84 | + public static Packets SPacketChunkData = new Packets("net/minecraft/network/play/server/SPacketChunkData", "gt", Context.CLIENT); | |
| 85 | + public static Packets SPacketCloseWindow = new Packets("net/minecraft/network/play/server/SPacketCloseWindow", "gf", Context.CLIENT); | |
| 86 | + public static Packets SPacketCollectItem = new Packets("net/minecraft/network/play/server/SPacketCollectItem", "ie", Context.CLIENT); | |
| 87 | + public static Packets SPacketCombatEvent = new Packets("net/minecraft/network/play/server/SPacketCombatEvent", "hc", Context.CLIENT); | |
| 88 | + public static Packets SPacketConfirmTransaction = new Packets("net/minecraft/network/play/server/SPacketConfirmTransaction", "ge", Context.CLIENT); | |
| 89 | + public static Packets SPacketCooldown = new Packets("net/minecraft/network/play/server/SPacketCooldown", "gk", Context.CLIENT); | |
| 90 | + public static Packets SPacketCustomPayload = new Packets("net/minecraft/network/play/server/SPacketCustomPayload", "gl", Context.CLIENT); | |
| 91 | + public static Packets SPacketCustomSound = new Packets("net/minecraft/network/play/server/SPacketCustomSound", "gm", Context.CLIENT); | |
| 92 | + public static Packets SPacketDestroyEntities = new Packets("net/minecraft/network/play/server/SPacketDestroyEntities", "hg", Context.CLIENT); | |
| 93 | + public static Packets SPacketDisconnect = new Packets("net/minecraft/network/play/server/SPacketDisconnect", "gn", Context.CLIENT); | |
| 94 | + public static Packets SPacketDisplayObjective = new Packets("net/minecraft/network/play/server/SPacketDisplayObjective", "ho", Context.CLIENT); | |
| 95 | + public static Packets SPacketEffect = new Packets("net/minecraft/network/play/server/SPacketEffect", "gu", Context.CLIENT); | |
| 96 | + public static Packets SPacketEntity = new Packets("net/minecraft/network/play/server/SPacketEntity", "gy", Context.CLIENT); | |
| 97 | + public static Packets S15PacketEntityRelMove = new Packets("net/minecraft/network/play/server/SPacketEntity$S15PacketEntityRelMove", "gy$a", Context.CLIENT); | |
| 98 | + public static Packets S16PacketEntityLook = new Packets("net/minecraft/network/play/server/SPacketEntity$S16PacketEntityLook", "gy$c", Context.CLIENT); | |
| 99 | + public static Packets S17PacketEntityLookMove = new Packets("net/minecraft/network/play/server/SPacketEntity$S17PacketEntityLookMove", "gy$b", Context.CLIENT); | |
| 100 | + public static Packets SPacketEntityAttach = new Packets("net/minecraft/network/play/server/SPacketEntityAttach", "hq", Context.CLIENT); | |
| 101 | + public static Packets SPacketEntityEffect = new Packets("net/minecraft/network/play/server/SPacketEntityEffect", "ii", Context.CLIENT); | |
| 102 | + public static Packets SPacketEntityEquipment = new Packets("net/minecraft/network/play/server/SPacketEntityEquipment", "hs", Context.CLIENT); | |
| 103 | + public static Packets SPacketEntityHeadLook = new Packets("net/minecraft/network/play/server/SPacketEntityHeadLook", "hk", Context.CLIENT); | |
| 104 | + public static Packets SPacketEntityMetadata = new Packets("net/minecraft/network/play/server/SPacketEntityMetadata", "hp", Context.CLIENT); | |
| 105 | + public static Packets SPacketEntityProperties = new Packets("net/minecraft/network/play/server/SPacketEntityProperties", "ih", Context.CLIENT); | |
| 106 | + public static Packets SPacketEntityStatus = new Packets("net/minecraft/network/play/server/SPacketEntityStatus", "go", Context.CLIENT); | |
| 107 | + public static Packets SPacketEntityTeleport = new Packets("net/minecraft/network/play/server/SPacketEntityTeleport", "ig", Context.CLIENT); | |
| 108 | + public static Packets SPacketEntityVelocity = new Packets("net/minecraft/network/play/server/SPacketEntityVelocity", "hr", Context.CLIENT); | |
| 109 | + public static Packets SPacketExplosion = new Packets("net/minecraft/network/play/server/SPacketExplosion", "gp", Context.CLIENT); | |
| 110 | + public static Packets SPacketHeldItemChange = new Packets("net/minecraft/network/play/server/SPacketHeldItemChange", "hn", Context.CLIENT); | |
| 111 | + public static Packets SPacketJoinGame = new Packets("net/minecraft/network/play/server/SPacketJoinGame", "gw", Context.CLIENT); | |
| 112 | + public static Packets SPacketKeepAlive = new Packets("net/minecraft/network/play/server/SPacketKeepAlive", "gs", Context.CLIENT); | |
| 113 | + public static Packets SPacketMaps = new Packets("net/minecraft/network/play/server/SPacketMaps", "gx", Context.CLIENT); | |
| 114 | + public static Packets SPacketMoveVehicle = new Packets("net/minecraft/network/play/server/SPacketMoveVehicle", "gz", Context.CLIENT); | |
| 115 | + public static Packets SPacketMultiBlockChange = new Packets("net/minecraft/network/play/server/SPacketMultiBlockChange", "gd", Context.CLIENT); | |
| 116 | + public static Packets SPacketOpenWindow = new Packets("net/minecraft/network/play/server/SPacketOpenWindow", "gg", Context.CLIENT); | |
| 117 | + public static Packets SPacketParticles = new Packets("net/minecraft/network/play/server/SPacketParticles", "gv", Context.CLIENT); | |
| 118 | + public static Packets SPacketPlayerAbilities = new Packets("net/minecraft/network/play/server/SPacketPlayerAbilities", "hb", Context.CLIENT); | |
| 119 | + public static Packets SPacketPlayerListHeaderFooter = new Packets("net/minecraft/network/play/server/SPacketPlayerListHeaderFooter", "id", Context.CLIENT); | |
| 120 | + public static Packets SPacketPlayerListItem = new Packets("net/minecraft/network/play/server/SPacketPlayerListItem", "hd", Context.CLIENT); | |
| 121 | + public static Packets SPacketPlayerPosLook = new Packets("net/minecraft/network/play/server/SPacketPlayerPosLook", "he", Context.CLIENT); | |
| 122 | + public static Packets SPacketRemoveEntityEffect = new Packets("net/minecraft/network/play/server/SPacketRemoveEntityEffect", "hh", Context.CLIENT); | |
| 123 | + public static Packets SPacketResourcePackSend = new Packets("net/minecraft/network/play/server/SPacketResourcePackSend", "hi", Context.CLIENT); | |
| 124 | + public static Packets SPacketRespawn = new Packets("net/minecraft/network/play/server/SPacketRespawn", "hj", Context.CLIENT); | |
| 125 | + public static Packets SPacketScoreboardObjective = new Packets("net/minecraft/network/play/server/SPacketScoreboardObjective", "hv", Context.CLIENT); | |
| 126 | + public static Packets SPacketServerDifficulty = new Packets("net/minecraft/network/play/server/SPacketServerDifficulty", "ga", Context.CLIENT); | |
| 127 | + public static Packets SPacketSetExperience = new Packets("net/minecraft/network/play/server/SPacketSetExperience", "ht", Context.CLIENT); | |
| 128 | + public static Packets SPacketSetPassengers = new Packets("net/minecraft/network/play/server/SPacketSetPassengers", "hw", Context.CLIENT); | |
| 129 | + public static Packets SPacketSetSlot = new Packets("net/minecraft/network/play/server/SPacketSetSlot", "gj", Context.CLIENT); | |
| 130 | + public static Packets SPacketSignEditorOpen = new Packets("net/minecraft/network/play/server/SPacketSignEditorOpen", "ha", Context.CLIENT); | |
| 131 | + public static Packets SPacketSoundEffect = new Packets("net/minecraft/network/play/server/SPacketSoundEffect", "ic", Context.CLIENT); | |
| 132 | + public static Packets SPacketSpawnExperienceOrb = new Packets("net/minecraft/network/play/server/SPacketSpawnExperienceOrb", "fo", Context.CLIENT); | |
| 133 | + public static Packets SPacketSpawnGlobalEntity = new Packets("net/minecraft/network/play/server/SPacketSpawnGlobalEntity", "fp", Context.CLIENT); | |
| 134 | + public static Packets SPacketSpawnMob = new Packets("net/minecraft/network/play/server/SPacketSpawnMob", "fq", Context.CLIENT); | |
| 135 | + public static Packets SPacketSpawnObject = new Packets("net/minecraft/network/play/server/SPacketSpawnObject", "fn", Context.CLIENT); | |
| 136 | + public static Packets SPacketSpawnPainting = new Packets("net/minecraft/network/play/server/SPacketSpawnPainting", "fr", Context.CLIENT); | |
| 137 | + public static Packets SPacketSpawnPlayer = new Packets("net/minecraft/network/play/server/SPacketSpawnPlayer", "fs", Context.CLIENT); | |
| 138 | + public static Packets SPacketSpawnPosition = new Packets("net/minecraft/network/play/server/SPacketSpawnPosition", "hz", Context.CLIENT); | |
| 139 | + public static Packets SPacketStatistics = new Packets("net/minecraft/network/play/server/SPacketStatistics", "fu", Context.CLIENT); | |
| 140 | + public static Packets SPacketTabComplete = new Packets("net/minecraft/network/play/server/SPacketTabComplete", "gb", Context.CLIENT); | |
| 141 | + public static Packets SPacketTeams = new Packets("net/minecraft/network/play/server/SPacketTeams", "hx", Context.CLIENT); | |
| 142 | + public static Packets SPacketTimeUpdate = new Packets("net/minecraft/network/play/server/SPacketTimeUpdate", "ia", Context.CLIENT); | |
| 143 | + public static Packets SPacketTitle = new Packets("net/minecraft/network/play/server/SPacketTitle", "ib", Context.CLIENT); | |
| 144 | + public static Packets SPacketUnloadChunk = new Packets("net/minecraft/network/play/server/SPacketUnloadChunk", "gq", Context.CLIENT); | |
| 145 | + public static Packets SPacketUpdateBossInfo = new Packets("net/minecraft/network/play/server/SPacketUpdateBossInfo", "fz", Context.CLIENT); | |
| 146 | + public static Packets SPacketUpdateHealth = new Packets("net/minecraft/network/play/server/SPacketUpdateHealth", "hu", Context.CLIENT); | |
| 147 | + public static Packets SPacketUpdateScore = new Packets("net/minecraft/network/play/server/SPacketUpdateScore", "hy", Context.CLIENT); | |
| 148 | + public static Packets SPacketUpdateTileEntity = new Packets("net/minecraft/network/play/server/SPacketUpdateTileEntity", "fw", Context.CLIENT); | |
| 149 | + public static Packets SPacketUseBed = new Packets("net/minecraft/network/play/server/SPacketUseBed", "hf", Context.CLIENT); | |
| 150 | + public static Packets SPacketWindowItems = new Packets("net/minecraft/network/play/server/SPacketWindowItems", "gh", Context.CLIENT); | |
| 151 | + public static Packets SPacketWindowProperty = new Packets("net/minecraft/network/play/server/SPacketWindowProperty", "gi", Context.CLIENT); | |
| 152 | + public static Packets SPacketWorldBorder = new Packets("net/minecraft/network/play/server/SPacketWorldBorder", "hl", Context.CLIENT); | |
| 153 | + public static Packets CPacketPing = new Packets("net/minecraft/network/status/client/CPacketPing", "ke", Context.SERVER); | |
| 154 | + public static Packets CPacketServerQuery = new Packets("net/minecraft/network/status/client/CPacketServerQuery", "kf", Context.SERVER); | |
| 155 | + public static Packets SPacketPong = new Packets("net/minecraft/network/status/server/SPacketPong", "ka", Context.CLIENT); | |
| 156 | + public static Packets SPacketServerInfo = new Packets("net/minecraft/network/status/server/SPacketServerInfo", "kb", Context.CLIENT); | |
| 157 | 157 | |
| 158 | 158 | // CHECKSTYLE:ON |
| 159 | 159 | ... | ... |
src/main/java/com/mumfrey/liteloader/launch/LiteLoaderTweaker.java
| ... | ... | @@ -38,8 +38,8 @@ public class LiteLoaderTweaker implements ITweaker |
| 38 | 38 | public static final int ENV_TYPE_CLIENT = 0; |
| 39 | 39 | public static final int ENV_TYPE_DEDICATEDSERVER = 1; |
| 40 | 40 | |
| 41 | - // TODO Version - 1.9.4 | |
| 42 | - public static final String VERSION = "1.9.4"; | |
| 41 | + // TODO Version - 1.10 | |
| 42 | + public static final String VERSION = "1.10"; | |
| 43 | 43 | |
| 44 | 44 | protected static final String bootstrapClassName = "com.mumfrey.liteloader.core.LiteLoaderBootstrap"; |
| 45 | 45 | ... | ... |
src/main/java/com/mumfrey/liteloader/transformers/ClassOverlayTransformer.java
| 1 | -/* | |
| 2 | - * This file is part of LiteLoader. | |
| 3 | - * Copyright (C) 2012-16 Adam Mummery-Smith | |
| 4 | - * All Rights Reserved. | |
| 5 | - */ | |
| 6 | -package com.mumfrey.liteloader.transformers; | |
| 7 | - | |
| 8 | -import java.io.IOException; | |
| 9 | -import java.util.HashMap; | |
| 10 | -import java.util.HashSet; | |
| 11 | -import java.util.Iterator; | |
| 12 | -import java.util.List; | |
| 13 | -import java.util.Map; | |
| 14 | -import java.util.Set; | |
| 15 | - | |
| 16 | -import org.objectweb.asm.ClassReader; | |
| 17 | -import org.objectweb.asm.ClassWriter; | |
| 18 | -import org.objectweb.asm.Opcodes; | |
| 19 | -import org.objectweb.asm.Type; | |
| 20 | -import org.objectweb.asm.commons.RemappingClassAdapter; | |
| 21 | -import org.objectweb.asm.commons.SimpleRemapper; | |
| 22 | -import org.objectweb.asm.tree.AbstractInsnNode; | |
| 23 | -import org.objectweb.asm.tree.AnnotationNode; | |
| 24 | -import org.objectweb.asm.tree.ClassNode; | |
| 25 | -import org.objectweb.asm.tree.FieldInsnNode; | |
| 26 | -import org.objectweb.asm.tree.FieldNode; | |
| 27 | -import org.objectweb.asm.tree.LineNumberNode; | |
| 28 | -import org.objectweb.asm.tree.MethodInsnNode; | |
| 29 | -import org.objectweb.asm.tree.MethodNode; | |
| 30 | - | |
| 31 | -import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | |
| 32 | - | |
| 33 | -import net.minecraft.launchwrapper.Launch; | |
| 34 | - | |
| 35 | -/** | |
| 36 | - * This transformer applies one class to another as an "overlay". This works by | |
| 37 | - * merging down and replacing all methods and fields from the "overlay" class | |
| 38 | - * into the "target" class being transformed. Fields and methods marked with the | |
| 39 | - * {@link Obfuscated} annotation will search through the list of provided names | |
| 40 | - * to find a matching member in the target class, this allows methods and fields | |
| 41 | - * in the target class to be referenced even if they have different names after | |
| 42 | - * obfuscation. | |
| 43 | - * | |
| 44 | - * <p>The "target" class is identified by a special field which must be named | |
| 45 | - * <tt>__TARGET</tt> in the overlay class which must be a private static field | |
| 46 | - * of the appropriate target type.</p> | |
| 47 | - * | |
| 48 | - * <h3>Notes:</h3> | |
| 49 | - * | |
| 50 | - * <ul> | |
| 51 | - * <li>Constructors WILL NOT BE overlaid, see below for instruction merging. | |
| 52 | - * Constructors in the overlay class should throw an InstantiationError. | |
| 53 | - * </li> | |
| 54 | - * | |
| 55 | - * <li>Static method invocations will not be processed by "transformMethod", | |
| 56 | - * this means that any static methods invoked must be accessible from the | |
| 57 | - * context of the transformed class (eg. public or package-private in the | |
| 58 | - * same package).</li> | |
| 59 | - * | |
| 60 | - * <li>The overlay class MUST be a sibling of the target class to ensure | |
| 61 | - * that calls to super.xxx are properly transformed. In other words the | |
| 62 | - * overlay and the transformed class should have the same parent class | |
| 63 | - * although they need not be in the same package unless any package-private | |
| 64 | - * members are accessed.</li> | |
| 65 | - * | |
| 66 | - * <li>It is also possible to merge instructions from a "source" method into | |
| 67 | - * a specific method in the transformed class by annotating the method with | |
| 68 | - * a {@link AppendInsns} annotation, specifying the name of the target | |
| 69 | - * method as the annotation value. The target method signature must match | |
| 70 | - * the source method's signature and both methods must return VOID. The | |
| 71 | - * instructions from the source method will be inserted immediately before | |
| 72 | - * the RETURN opcode in the target method.</li> | |
| 73 | - * | |
| 74 | - * <li>To create a method stub for private methods you wish to invoke in the | |
| 75 | - * target class, decorate the stub method with an {@link Stub} annotation, | |
| 76 | - * this will cause the overlay transformer to NOT merge the method into the | |
| 77 | - * target, but merely verify that it exists in the target class.</li> | |
| 78 | - * | |
| 79 | - * <li>Merge instructions into the constructor by specifying "<init>" as the | |
| 80 | - * target method name.</li> | |
| 81 | - * </ul> | |
| 82 | - * | |
| 83 | - * @author Adam Mummery-Smith | |
| 84 | - * @deprecated Use mixins instead! | |
| 85 | - */ | |
| 86 | -@Deprecated | |
| 87 | -public abstract class ClassOverlayTransformer extends ClassTransformer | |
| 88 | -{ | |
| 89 | - /** | |
| 90 | - * Global list of overlaid classes, used to transform references in other | |
| 91 | - * classes. | |
| 92 | - */ | |
| 93 | - private static final Map<String, String> overlayMap = new HashMap<String, String>(); | |
| 94 | - | |
| 95 | - /** | |
| 96 | - * Remapper for dynamically renaming references to overlays in other classes | |
| 97 | - */ | |
| 98 | - private static SimpleRemapper referenceRemapper; | |
| 99 | - | |
| 100 | - /** | |
| 101 | - * The first ClassOverlayTransformer to be instantiated accepts | |
| 102 | - * responsibility for performing remapping operations and becomes the | |
| 103 | - * "remapping agent" transformer. This flag is set to true to indicate that | |
| 104 | - * this instance is the remapping agent. | |
| 105 | - */ | |
| 106 | - private boolean remappingAgent = false; | |
| 107 | - | |
| 108 | - /** | |
| 109 | - * Name of the overlay class | |
| 110 | - */ | |
| 111 | - private final String overlayClassName, overlayClassRef; | |
| 112 | - | |
| 113 | - /** | |
| 114 | - * Target class to be transformed | |
| 115 | - */ | |
| 116 | - private final String targetClassName; | |
| 117 | - | |
| 118 | - /** | |
| 119 | - * Fields which get a different name from an {@link Obfuscated} annotation | |
| 120 | - */ | |
| 121 | - private final Map<String, String> renamedFields = new HashMap<String, String>(); | |
| 122 | - | |
| 123 | - /** | |
| 124 | - * Methods which get a different name from an {@link Obfuscated} annotation | |
| 125 | - */ | |
| 126 | - private final Map<String, String> renamedMethods = new HashMap<String, String>(); | |
| 127 | - | |
| 128 | - /** | |
| 129 | - * True to set the sourceFile property when applying the overlay | |
| 130 | - */ | |
| 131 | - protected boolean setSourceFile = true; | |
| 132 | - | |
| 133 | - /** | |
| 134 | - * @param overlayClassName | |
| 135 | - */ | |
| 136 | - protected ClassOverlayTransformer(String overlayClassName) | |
| 137 | - { | |
| 138 | - this.overlayClassName = overlayClassName; | |
| 139 | - this.overlayClassRef = overlayClassName.replace('.', '/'); | |
| 140 | - | |
| 141 | - String targetClassName = null; | |
| 142 | - ClassNode overlayClass = this.loadOverlayClass("<none>", true); | |
| 143 | - for (FieldNode field : overlayClass.fields) | |
| 144 | - { | |
| 145 | - if ("__TARGET".equals(field.name) && ((field.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC)) | |
| 146 | - { | |
| 147 | - targetClassName = Type.getType(field.desc).getClassName(); | |
| 148 | - } | |
| 149 | - } | |
| 150 | - | |
| 151 | - if (targetClassName == null) | |
| 152 | - { | |
| 153 | - throw new RuntimeException(String.format("Overlay class %s is missing a __TARGET field, unable to identify target class", | |
| 154 | - this.overlayClassName)); | |
| 155 | - } | |
| 156 | - | |
| 157 | - this.targetClassName = targetClassName; | |
| 158 | - ClassOverlayTransformer.overlayMap.put(this.overlayClassRef, this.targetClassName.replace('.', '/')); | |
| 159 | - | |
| 160 | - // If this is the first ClassOverlayTransformer, the referenceMapper will be null | |
| 161 | - if (ClassOverlayTransformer.referenceRemapper == null) | |
| 162 | - { | |
| 163 | - // Therefore create the referenceMapper and accept responsibility for class remapping | |
| 164 | - ClassOverlayTransformer.referenceRemapper = new SimpleRemapper(ClassOverlayTransformer.overlayMap); | |
| 165 | - this.remappingAgent = true; | |
| 166 | - } | |
| 167 | - } | |
| 168 | - | |
| 169 | - /* (non-Javadoc) | |
| 170 | - * @see net.minecraft.launchwrapper.IClassTransformer | |
| 171 | - * #transform(java.lang.String, java.lang.String, byte[]) | |
| 172 | - */ | |
| 173 | - @Override | |
| 174 | - public byte[] transform(String name, String transformedName, byte[] basicClass) | |
| 175 | - { | |
| 176 | - if (this.targetClassName != null && this.targetClassName.equals(transformedName)) | |
| 177 | - { | |
| 178 | - try | |
| 179 | - { | |
| 180 | - return this.applyOverlay(transformedName, basicClass); | |
| 181 | - } | |
| 182 | - catch (InvalidOverlayException th) | |
| 183 | - { | |
| 184 | - LiteLoaderLogger.severe(th, "Class overlay failed: %s %s", th.getClass().getName(), th.getMessage()); | |
| 185 | - th.printStackTrace(); | |
| 186 | - } | |
| 187 | - } | |
| 188 | - else if (this.overlayClassName.equals(transformedName)) | |
| 189 | - { | |
| 190 | - throw new RuntimeException(String.format("%s is an overlay class and cannot be referenced directly", this.overlayClassName)); | |
| 191 | - } | |
| 192 | - else if (this.remappingAgent && basicClass != null) | |
| 193 | - { | |
| 194 | - return this.remapClass(transformedName, basicClass); | |
| 195 | - } | |
| 196 | - | |
| 197 | - return basicClass; | |
| 198 | - } | |
| 199 | - | |
| 200 | - /** | |
| 201 | - * Remap references to overlay classes in other classes to the overlay class | |
| 202 | - * | |
| 203 | - * @param transformedName | |
| 204 | - * @param basicClass | |
| 205 | - */ | |
| 206 | - private byte[] remapClass(String transformedName, byte[] basicClass) | |
| 207 | - { | |
| 208 | - ClassReader classReader = new ClassReader(basicClass); | |
| 209 | - ClassWriter classWriter = new ClassWriter(classReader, 0); | |
| 210 | - | |
| 211 | - RemappingClassAdapter remappingAdapter = new RemappingClassAdapter(classWriter, ClassOverlayTransformer.referenceRemapper); | |
| 212 | - classReader.accept(remappingAdapter, ClassReader.EXPAND_FRAMES); | |
| 213 | - | |
| 214 | - return classWriter.toByteArray(); | |
| 215 | - } | |
| 216 | - | |
| 217 | - /** | |
| 218 | - * Apply the overlay to the class described by basicClass | |
| 219 | - * | |
| 220 | - * @param transformedName | |
| 221 | - * @param classBytes | |
| 222 | - */ | |
| 223 | - protected byte[] applyOverlay(String transformedName, byte[] classBytes) | |
| 224 | - { | |
| 225 | - ClassNode overlayClass = this.loadOverlayClass(transformedName, true); | |
| 226 | - ClassNode targetClass = this.readClass(classBytes, true); | |
| 227 | - | |
| 228 | - LiteLoaderLogger.info("Applying overlay %s to %s", this.overlayClassName, transformedName); | |
| 229 | - | |
| 230 | - try | |
| 231 | - { | |
| 232 | - this.verifyClasses(targetClass, overlayClass); | |
| 233 | - this.overlayInterfaces(targetClass, overlayClass); | |
| 234 | - this.overlayAttributes(targetClass, overlayClass); | |
| 235 | - this.overlayFields(targetClass, overlayClass); | |
| 236 | - this.findRenamedMethods(targetClass, overlayClass); | |
| 237 | - this.overlayMethods(targetClass, overlayClass); | |
| 238 | - } | |
| 239 | - catch (Exception ex) | |
| 240 | - { | |
| 241 | - throw new InvalidOverlayException("Unexpecteded error whilst applying the overlay class", ex); | |
| 242 | - } | |
| 243 | - | |
| 244 | - this.postOverlayTransform(transformedName, targetClass, overlayClass); | |
| 245 | - | |
| 246 | - return this.writeClass(targetClass); | |
| 247 | - } | |
| 248 | - | |
| 249 | - protected void postOverlayTransform(String transformedName, ClassNode targetClass, ClassNode overlayClass) | |
| 250 | - { | |
| 251 | - // Stub | |
| 252 | - } | |
| 253 | - | |
| 254 | - /** | |
| 255 | - * Perform pre-flight checks on the overlay and target classes | |
| 256 | - * | |
| 257 | - * @param targetClass | |
| 258 | - * @param overlayClass | |
| 259 | - */ | |
| 260 | - protected void verifyClasses(ClassNode targetClass, ClassNode overlayClass) | |
| 261 | - { | |
| 262 | - if (targetClass.superName == null || overlayClass.superName == null || !targetClass.superName.equals(overlayClass.superName)) | |
| 263 | - { | |
| 264 | - throw new InvalidOverlayException("Overlay classes must have the same superclass as their target class"); | |
| 265 | - } | |
| 266 | - } | |
| 267 | - | |
| 268 | - /** | |
| 269 | - * Overlay interfaces implemented by the overlay class onto the target class | |
| 270 | - * | |
| 271 | - * @param targetClass | |
| 272 | - * @param overlayClass | |
| 273 | - */ | |
| 274 | - private void overlayInterfaces(ClassNode targetClass, ClassNode overlayClass) | |
| 275 | - { | |
| 276 | - for (String interfaceName : overlayClass.interfaces) | |
| 277 | - { | |
| 278 | - if (!targetClass.interfaces.contains(interfaceName)) | |
| 279 | - { | |
| 280 | - targetClass.interfaces.add(interfaceName); | |
| 281 | - } | |
| 282 | - } | |
| 283 | - } | |
| 284 | - | |
| 285 | - /** | |
| 286 | - * Overlay misc attributes from overlay class onto the target class | |
| 287 | - * | |
| 288 | - * @param targetClass | |
| 289 | - * @param overlayClass | |
| 290 | - */ | |
| 291 | - private void overlayAttributes(ClassNode targetClass, ClassNode overlayClass) | |
| 292 | - { | |
| 293 | - if (this.setSourceFile ) targetClass.sourceFile = overlayClass.sourceFile; | |
| 294 | - } | |
| 295 | - | |
| 296 | - /** | |
| 297 | - * Overlay fields from overlay class into the target class. It is vital that | |
| 298 | - * this is done before overlayMethods because we need to compute renamed | |
| 299 | - * fields so that transformMethod can rename field references in the | |
| 300 | - * method body. | |
| 301 | - * | |
| 302 | - * @param targetClass | |
| 303 | - * @param overlayClass | |
| 304 | - */ | |
| 305 | - private void overlayFields(ClassNode targetClass, ClassNode overlayClass) | |
| 306 | - { | |
| 307 | - for (FieldNode field : overlayClass.fields) | |
| 308 | - { | |
| 309 | - if ((field.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC && (field.access & Opcodes.ACC_PRIVATE) != Opcodes.ACC_PRIVATE) | |
| 310 | - { | |
| 311 | - throw new InvalidOverlayException(String.format("Overlay classes cannot contain non-private static methods or fields, found %s", | |
| 312 | - field.name)); | |
| 313 | - } | |
| 314 | - | |
| 315 | - FieldNode target = ByteCodeUtilities.findTargetField(targetClass, field); | |
| 316 | - if (target == null) | |
| 317 | - { | |
| 318 | - targetClass.fields.add(field); | |
| 319 | - } | |
| 320 | - else | |
| 321 | - { | |
| 322 | - if (!target.desc.equals(field.desc)) | |
| 323 | - { | |
| 324 | - throw new InvalidOverlayException(String.format("The field %s in the target class has a conflicting signature", field.name)); | |
| 325 | - } | |
| 326 | - | |
| 327 | - if (!target.name.equals(field.name)) | |
| 328 | - { | |
| 329 | - this.renamedFields.put(field.name, target.name); | |
| 330 | - } | |
| 331 | - } | |
| 332 | - } | |
| 333 | - } | |
| 334 | - | |
| 335 | - /** | |
| 336 | - * Called before merging methods to build the map of original method names | |
| 337 | - * -> new method names, this is then used by transformMethod to remap. | |
| 338 | - * | |
| 339 | - * @param targetClass | |
| 340 | - * @param overlayClass | |
| 341 | - */ | |
| 342 | - private void findRenamedMethods(ClassNode targetClass, ClassNode overlayClass) | |
| 343 | - { | |
| 344 | - for (MethodNode overlayMethod : overlayClass.methods) | |
| 345 | - { | |
| 346 | - if (ByteCodeUtilities.getVisibleAnnotation(overlayMethod, Stub.class) != null | |
| 347 | - || (ByteCodeUtilities.getVisibleAnnotation(overlayMethod, AppendInsns.class) == null && !overlayMethod.name.startsWith("<"))) | |
| 348 | - { | |
| 349 | - this.checkRenameMethod(targetClass, overlayMethod); | |
| 350 | - } | |
| 351 | - } | |
| 352 | - } | |
| 353 | - | |
| 354 | - /** | |
| 355 | - * Overlay methods from the overlay class into the target class | |
| 356 | - * | |
| 357 | - * @param targetClass | |
| 358 | - * @param overlayClass | |
| 359 | - */ | |
| 360 | - private void overlayMethods(ClassNode targetClass, ClassNode overlayClass) | |
| 361 | - { | |
| 362 | - for (MethodNode overlayMethod : overlayClass.methods) | |
| 363 | - { | |
| 364 | - this.transformMethod(overlayMethod, overlayClass.name, targetClass.name); | |
| 365 | - | |
| 366 | - AnnotationNode appendAnnotation = ByteCodeUtilities.getVisibleAnnotation(overlayMethod, AppendInsns.class); | |
| 367 | - AnnotationNode stubAnnotation = ByteCodeUtilities.getVisibleAnnotation(overlayMethod, Stub.class); | |
| 368 | - | |
| 369 | - if (stubAnnotation != null) | |
| 370 | - { | |
| 371 | - MethodNode target = ByteCodeUtilities.findTargetMethod(targetClass, overlayMethod); | |
| 372 | - if (target == null) | |
| 373 | - { | |
| 374 | - throw new InvalidOverlayException(String.format("Stub method %s was not located in the target class", overlayMethod.name)); | |
| 375 | - } | |
| 376 | - } | |
| 377 | - else if (appendAnnotation != null) | |
| 378 | - { | |
| 379 | - String targetMethodName = ByteCodeUtilities.<String>getAnnotationValue(appendAnnotation); | |
| 380 | - this.appendInsns(targetClass, targetMethodName, overlayMethod); | |
| 381 | - } | |
| 382 | - else if (!overlayMethod.name.startsWith("<")) | |
| 383 | - { | |
| 384 | - if ((overlayMethod.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC | |
| 385 | - && (overlayMethod.access & Opcodes.ACC_PRIVATE) != Opcodes.ACC_PRIVATE) | |
| 386 | - { | |
| 387 | - continue; | |
| 388 | - } | |
| 389 | - | |
| 390 | - MethodNode target = ByteCodeUtilities.findTargetMethod(targetClass, overlayMethod); | |
| 391 | - if (target != null) targetClass.methods.remove(target); | |
| 392 | - targetClass.methods.add(overlayMethod); | |
| 393 | - } | |
| 394 | - else if ("<clinit>".equals(overlayMethod.name)) | |
| 395 | - { | |
| 396 | - this.appendInsns(targetClass, overlayMethod.name, overlayMethod); | |
| 397 | - } | |
| 398 | - } | |
| 399 | - } | |
| 400 | - | |
| 401 | - /** | |
| 402 | - * Handles "re-parenting" the method supplied, changes all references to the | |
| 403 | - * overlay class to refer to the target class (for field accesses and method | |
| 404 | - * invocations) and also renames fields accesses to their obfuscated | |
| 405 | - * versions. | |
| 406 | - * | |
| 407 | - * @param method | |
| 408 | - * @param fromClass | |
| 409 | - * @param toClass | |
| 410 | - */ | |
| 411 | - private void transformMethod(MethodNode method, String fromClass, String toClass) | |
| 412 | - { | |
| 413 | - Iterator<AbstractInsnNode> iter = method.instructions.iterator(); | |
| 414 | - while (iter.hasNext()) | |
| 415 | - { | |
| 416 | - AbstractInsnNode insn = iter.next(); | |
| 417 | - | |
| 418 | - if (insn instanceof MethodInsnNode) | |
| 419 | - { | |
| 420 | - MethodInsnNode methodInsn = (MethodInsnNode)insn; | |
| 421 | - if (methodInsn.owner.equals(fromClass)) | |
| 422 | - { | |
| 423 | - methodInsn.owner = toClass; | |
| 424 | - | |
| 425 | - String methodDescriptor = methodInsn.name + methodInsn.desc; | |
| 426 | - if (this.renamedMethods.containsKey(methodDescriptor)) | |
| 427 | - { | |
| 428 | - methodInsn.name = this.renamedMethods.get(methodDescriptor); | |
| 429 | - } | |
| 430 | - } | |
| 431 | - } | |
| 432 | - if (insn instanceof FieldInsnNode) | |
| 433 | - { | |
| 434 | - FieldInsnNode fieldInsn = (FieldInsnNode)insn; | |
| 435 | - if (fieldInsn.owner.equals(fromClass)) fieldInsn.owner = toClass; | |
| 436 | - | |
| 437 | - if (this.renamedFields.containsKey(fieldInsn.name)) | |
| 438 | - { | |
| 439 | - String newName = this.renamedFields.get(fieldInsn.name); | |
| 440 | - fieldInsn.name = newName; | |
| 441 | - } | |
| 442 | - } | |
| 443 | - } | |
| 444 | - } | |
| 445 | - | |
| 446 | - /** | |
| 447 | - * Handles appending instructions from the source method to the target | |
| 448 | - * method. | |
| 449 | - * | |
| 450 | - * @param targetClass | |
| 451 | - * @param targetMethodName | |
| 452 | - * @param sourceMethod | |
| 453 | - */ | |
| 454 | - private void appendInsns(ClassNode targetClass, String targetMethodName, MethodNode sourceMethod) | |
| 455 | - { | |
| 456 | - if (Type.getReturnType(sourceMethod.desc) != Type.VOID_TYPE) | |
| 457 | - { | |
| 458 | - throw new IllegalArgumentException("Attempted to merge insns into a method which does not return void"); | |
| 459 | - } | |
| 460 | - | |
| 461 | - if (targetMethodName == null || targetMethodName.length() == 0) targetMethodName = sourceMethod.name; | |
| 462 | - | |
| 463 | - Set<String> obfuscatedNames = new HashSet<String>(); | |
| 464 | - AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getVisibleAnnotation(sourceMethod, Obfuscated.class); | |
| 465 | - if (obfuscatedAnnotation != null) | |
| 466 | - { | |
| 467 | - obfuscatedNames.addAll(ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)); | |
| 468 | - } | |
| 469 | - | |
| 470 | - for (MethodNode method : targetClass.methods) | |
| 471 | - { | |
| 472 | - if ((targetMethodName.equals(method.name) || obfuscatedNames.contains(method.name)) && sourceMethod.desc.equals(method.desc)) | |
| 473 | - { | |
| 474 | - AbstractInsnNode returnNode = null; | |
| 475 | - Iterator<AbstractInsnNode> findReturnIter = method.instructions.iterator(); | |
| 476 | - while (findReturnIter.hasNext()) | |
| 477 | - { | |
| 478 | - AbstractInsnNode insn = findReturnIter.next(); | |
| 479 | - if (insn.getOpcode() == Opcodes.RETURN) | |
| 480 | - { | |
| 481 | - returnNode = insn; | |
| 482 | - break; | |
| 483 | - } | |
| 484 | - } | |
| 485 | - | |
| 486 | - Iterator<AbstractInsnNode> injectIter = sourceMethod.instructions.iterator(); | |
| 487 | - while (injectIter.hasNext()) | |
| 488 | - { | |
| 489 | - AbstractInsnNode insn = injectIter.next(); | |
| 490 | - if (!(insn instanceof LineNumberNode) && insn.getOpcode() != Opcodes.RETURN) | |
| 491 | - { | |
| 492 | - method.instructions.insertBefore(returnNode, insn); | |
| 493 | - } | |
| 494 | - } | |
| 495 | - } | |
| 496 | - } | |
| 497 | - } | |
| 498 | - | |
| 499 | - /** | |
| 500 | - * @param targetClass | |
| 501 | - * @param searchFor | |
| 502 | - */ | |
| 503 | - private void checkRenameMethod(ClassNode targetClass, MethodNode searchFor) | |
| 504 | - { | |
| 505 | - MethodNode target = ByteCodeUtilities.findTargetMethod(targetClass, searchFor); | |
| 506 | - if (target != null && !target.name.equals(searchFor.name)) | |
| 507 | - { | |
| 508 | - String methodDescriptor = searchFor.name + searchFor.desc; | |
| 509 | - this.renamedMethods.put(methodDescriptor, target.name); | |
| 510 | - searchFor.name = target.name; | |
| 511 | - } | |
| 512 | - } | |
| 513 | - | |
| 514 | - /** | |
| 515 | - * @param transformedName | |
| 516 | - * @throws InvalidOverlayException | |
| 517 | - */ | |
| 518 | - private ClassNode loadOverlayClass(String transformedName, boolean runTransformers) | |
| 519 | - { | |
| 520 | - byte[] overlayBytes = null; | |
| 521 | - | |
| 522 | - try | |
| 523 | - { | |
| 524 | - if ((overlayBytes = Launch.classLoader.getClassBytes(this.overlayClassName)) == null) | |
| 525 | - { | |
| 526 | - throw new InvalidOverlayException(String.format("The specified overlay '%s' was not found", this.overlayClassName)); | |
| 527 | - } | |
| 528 | - | |
| 529 | - if (runTransformers) | |
| 530 | - { | |
| 531 | - overlayBytes = ByteCodeUtilities.applyTransformers(this.overlayClassName, overlayBytes, this); | |
| 532 | - } | |
| 533 | - } | |
| 534 | - catch (IOException ex) | |
| 535 | - { | |
| 536 | - LiteLoaderLogger.severe("Failed to load overlay %s for %s, no overlay was applied", this.overlayClassName, transformedName); | |
| 537 | - throw new InvalidOverlayException("An error was encountered whilst loading the overlay class", ex); | |
| 538 | - } | |
| 539 | - | |
| 540 | - return this.readClass(overlayBytes, false); | |
| 541 | - } | |
| 542 | -} | |
| 1 | +///* | |
| 2 | +// * This file is part of LiteLoader. | |
| 3 | +// * Copyright (C) 2012-16 Adam Mummery-Smith | |
| 4 | +// * All Rights Reserved. | |
| 5 | +// */ | |
| 6 | +//package com.mumfrey.liteloader.transformers; | |
| 7 | +// | |
| 8 | +//import java.io.IOException; | |
| 9 | +//import java.util.HashMap; | |
| 10 | +//import java.util.HashSet; | |
| 11 | +//import java.util.Iterator; | |
| 12 | +//import java.util.List; | |
| 13 | +//import java.util.Map; | |
| 14 | +//import java.util.Set; | |
| 15 | +// | |
| 16 | +//import org.objectweb.asm.ClassReader; | |
| 17 | +//import org.objectweb.asm.ClassWriter; | |
| 18 | +//import org.objectweb.asm.Opcodes; | |
| 19 | +//import org.objectweb.asm.Type; | |
| 20 | +//import org.objectweb.asm.commons.RemappingClassAdapter; | |
| 21 | +//import org.objectweb.asm.commons.SimpleRemapper; | |
| 22 | +//import org.objectweb.asm.tree.AbstractInsnNode; | |
| 23 | +//import org.objectweb.asm.tree.AnnotationNode; | |
| 24 | +//import org.objectweb.asm.tree.ClassNode; | |
| 25 | +//import org.objectweb.asm.tree.FieldInsnNode; | |
| 26 | +//import org.objectweb.asm.tree.FieldNode; | |
| 27 | +//import org.objectweb.asm.tree.LineNumberNode; | |
| 28 | +//import org.objectweb.asm.tree.MethodInsnNode; | |
| 29 | +//import org.objectweb.asm.tree.MethodNode; | |
| 30 | +// | |
| 31 | +//import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | |
| 32 | +// | |
| 33 | +//import net.minecraft.launchwrapper.Launch; | |
| 34 | +// | |
| 35 | +///** | |
| 36 | +// * This transformer applies one class to another as an "overlay". This works by | |
| 37 | +// * merging down and replacing all methods and fields from the "overlay" class | |
| 38 | +// * into the "target" class being transformed. Fields and methods marked with the | |
| 39 | +// * {@link Obfuscated} annotation will search through the list of provided names | |
| 40 | +// * to find a matching member in the target class, this allows methods and fields | |
| 41 | +// * in the target class to be referenced even if they have different names after | |
| 42 | +// * obfuscation. | |
| 43 | +// * | |
| 44 | +// * <p>The "target" class is identified by a special field which must be named | |
| 45 | +// * <tt>__TARGET</tt> in the overlay class which must be a private static field | |
| 46 | +// * of the appropriate target type.</p> | |
| 47 | +// * | |
| 48 | +// * <h3>Notes:</h3> | |
| 49 | +// * | |
| 50 | +// * <ul> | |
| 51 | +// * <li>Constructors WILL NOT BE overlaid, see below for instruction merging. | |
| 52 | +// * Constructors in the overlay class should throw an InstantiationError. | |
| 53 | +// * </li> | |
| 54 | +// * | |
| 55 | +// * <li>Static method invocations will not be processed by "transformMethod", | |
| 56 | +// * this means that any static methods invoked must be accessible from the | |
| 57 | +// * context of the transformed class (eg. public or package-private in the | |
| 58 | +// * same package).</li> | |
| 59 | +// * | |
| 60 | +// * <li>The overlay class MUST be a sibling of the target class to ensure | |
| 61 | +// * that calls to super.xxx are properly transformed. In other words the | |
| 62 | +// * overlay and the transformed class should have the same parent class | |
| 63 | +// * although they need not be in the same package unless any package-private | |
| 64 | +// * members are accessed.</li> | |
| 65 | +// * | |
| 66 | +// * <li>It is also possible to merge instructions from a "source" method into | |
| 67 | +// * a specific method in the transformed class by annotating the method with | |
| 68 | +// * a {@link AppendInsns} annotation, specifying the name of the target | |
| 69 | +// * method as the annotation value. The target method signature must match | |
| 70 | +// * the source method's signature and both methods must return VOID. The | |
| 71 | +// * instructions from the source method will be inserted immediately before | |
| 72 | +// * the RETURN opcode in the target method.</li> | |
| 73 | +// * | |
| 74 | +// * <li>To create a method stub for private methods you wish to invoke in the | |
| 75 | +// * target class, decorate the stub method with an {@link Stub} annotation, | |
| 76 | +// * this will cause the overlay transformer to NOT merge the method into the | |
| 77 | +// * target, but merely verify that it exists in the target class.</li> | |
| 78 | +// * | |
| 79 | +// * <li>Merge instructions into the constructor by specifying "<init>" as the | |
| 80 | +// * target method name.</li> | |
| 81 | +// * </ul> | |
| 82 | +// * | |
| 83 | +// * @author Adam Mummery-Smith | |
| 84 | +// * @deprecated Use mixins instead! | |
| 85 | +// */ | |
| 86 | +//@Deprecated | |
| 87 | +//public abstract class ClassOverlayTransformer extends ClassTransformer | |
| 88 | +//{ | |
| 89 | +// /** | |
| 90 | +// * Global list of overlaid classes, used to transform references in other | |
| 91 | +// * classes. | |
| 92 | +// */ | |
| 93 | +// private static final Map<String, String> overlayMap = new HashMap<String, String>(); | |
| 94 | +// | |
| 95 | +// /** | |
| 96 | +// * Remapper for dynamically renaming references to overlays in other classes | |
| 97 | +// */ | |
| 98 | +// private static SimpleRemapper referenceRemapper; | |
| 99 | +// | |
| 100 | +// /** | |
| 101 | +// * The first ClassOverlayTransformer to be instantiated accepts | |
| 102 | +// * responsibility for performing remapping operations and becomes the | |
| 103 | +// * "remapping agent" transformer. This flag is set to true to indicate that | |
| 104 | +// * this instance is the remapping agent. | |
| 105 | +// */ | |
| 106 | +// private boolean remappingAgent = false; | |
| 107 | +// | |
| 108 | +// /** | |
| 109 | +// * Name of the overlay class | |
| 110 | +// */ | |
| 111 | +// private final String overlayClassName, overlayClassRef; | |
| 112 | +// | |
| 113 | +// /** | |
| 114 | +// * Target class to be transformed | |
| 115 | +// */ | |
| 116 | +// private final String targetClassName; | |
| 117 | +// | |
| 118 | +// /** | |
| 119 | +// * Fields which get a different name from an {@link Obfuscated} annotation | |
| 120 | +// */ | |
| 121 | +// private final Map<String, String> renamedFields = new HashMap<String, String>(); | |
| 122 | +// | |
| 123 | +// /** | |
| 124 | +// * Methods which get a different name from an {@link Obfuscated} annotation | |
| 125 | +// */ | |
| 126 | +// private final Map<String, String> renamedMethods = new HashMap<String, String>(); | |
| 127 | +// | |
| 128 | +// /** | |
| 129 | +// * True to set the sourceFile property when applying the overlay | |
| 130 | +// */ | |
| 131 | +// protected boolean setSourceFile = true; | |
| 132 | +// | |
| 133 | +// /** | |
| 134 | +// * @param overlayClassName | |
| 135 | +// */ | |
| 136 | +// protected ClassOverlayTransformer(String overlayClassName) | |
| 137 | +// { | |
| 138 | +// this.overlayClassName = overlayClassName; | |
| 139 | +// this.overlayClassRef = overlayClassName.replace('.', '/'); | |
| 140 | +// | |
| 141 | +// String targetClassName = null; | |
| 142 | +// ClassNode overlayClass = this.loadOverlayClass("<none>", true); | |
| 143 | +// for (FieldNode field : overlayClass.fields) | |
| 144 | +// { | |
| 145 | +// if ("__TARGET".equals(field.name) && ((field.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC)) | |
| 146 | +// { | |
| 147 | +// targetClassName = Type.getType(field.desc).getClassName(); | |
| 148 | +// } | |
| 149 | +// } | |
| 150 | +// | |
| 151 | +// if (targetClassName == null) | |
| 152 | +// { | |
| 153 | +// throw new RuntimeException(String.format("Overlay class %s is missing a __TARGET field, unable to identify target class", | |
| 154 | +// this.overlayClassName)); | |
| 155 | +// } | |
| 156 | +// | |
| 157 | +// this.targetClassName = targetClassName; | |
| 158 | +// ClassOverlayTransformer.overlayMap.put(this.overlayClassRef, this.targetClassName.replace('.', '/')); | |
| 159 | +// | |
| 160 | +// // If this is the first ClassOverlayTransformer, the referenceMapper will be null | |
| 161 | +// if (ClassOverlayTransformer.referenceRemapper == null) | |
| 162 | +// { | |
| 163 | +// // Therefore create the referenceMapper and accept responsibility for class remapping | |
| 164 | +// ClassOverlayTransformer.referenceRemapper = new SimpleRemapper(ClassOverlayTransformer.overlayMap); | |
| 165 | +// this.remappingAgent = true; | |
| 166 | +// } | |
| 167 | +// } | |
| 168 | +// | |
| 169 | +// /* (non-Javadoc) | |
| 170 | +// * @see net.minecraft.launchwrapper.IClassTransformer | |
| 171 | +// * #transform(java.lang.String, java.lang.String, byte[]) | |
| 172 | +// */ | |
| 173 | +// @Override | |
| 174 | +// public byte[] transform(String name, String transformedName, byte[] basicClass) | |
| 175 | +// { | |
| 176 | +// if (this.targetClassName != null && this.targetClassName.equals(transformedName)) | |
| 177 | +// { | |
| 178 | +// try | |
| 179 | +// { | |
| 180 | +// return this.applyOverlay(transformedName, basicClass); | |
| 181 | +// } | |
| 182 | +// catch (InvalidOverlayException th) | |
| 183 | +// { | |
| 184 | +// LiteLoaderLogger.severe(th, "Class overlay failed: %s %s", th.getClass().getName(), th.getMessage()); | |
| 185 | +// th.printStackTrace(); | |
| 186 | +// } | |
| 187 | +// } | |
| 188 | +// else if (this.overlayClassName.equals(transformedName)) | |
| 189 | +// { | |
| 190 | +// throw new RuntimeException(String.format("%s is an overlay class and cannot be referenced directly", this.overlayClassName)); | |
| 191 | +// } | |
| 192 | +// else if (this.remappingAgent && basicClass != null) | |
| 193 | +// { | |
| 194 | +// return this.remapClass(transformedName, basicClass); | |
| 195 | +// } | |
| 196 | +// | |
| 197 | +// return basicClass; | |
| 198 | +// } | |
| 199 | +// | |
| 200 | +// /** | |
| 201 | +// * Remap references to overlay classes in other classes to the overlay class | |
| 202 | +// * | |
| 203 | +// * @param transformedName | |
| 204 | +// * @param basicClass | |
| 205 | +// */ | |
| 206 | +// private byte[] remapClass(String transformedName, byte[] basicClass) | |
| 207 | +// { | |
| 208 | +// ClassReader classReader = new ClassReader(basicClass); | |
| 209 | +// ClassWriter classWriter = new ClassWriter(classReader, 0); | |
| 210 | +// | |
| 211 | +// RemappingClassAdapter remappingAdapter = new RemappingClassAdapter(classWriter, ClassOverlayTransformer.referenceRemapper); | |
| 212 | +// classReader.accept(remappingAdapter, ClassReader.EXPAND_FRAMES); | |
| 213 | +// | |
| 214 | +// return classWriter.toByteArray(); | |
| 215 | +// } | |
| 216 | +// | |
| 217 | +// /** | |
| 218 | +// * Apply the overlay to the class described by basicClass | |
| 219 | +// * | |
| 220 | +// * @param transformedName | |
| 221 | +// * @param classBytes | |
| 222 | +// */ | |
| 223 | +// protected byte[] applyOverlay(String transformedName, byte[] classBytes) | |
| 224 | +// { | |
| 225 | +// ClassNode overlayClass = this.loadOverlayClass(transformedName, true); | |
| 226 | +// ClassNode targetClass = this.readClass(classBytes, true); | |
| 227 | +// | |
| 228 | +// LiteLoaderLogger.info("Applying overlay %s to %s", this.overlayClassName, transformedName); | |
| 229 | +// | |
| 230 | +// try | |
| 231 | +// { | |
| 232 | +// this.verifyClasses(targetClass, overlayClass); | |
| 233 | +// this.overlayInterfaces(targetClass, overlayClass); | |
| 234 | +// this.overlayAttributes(targetClass, overlayClass); | |
| 235 | +// this.overlayFields(targetClass, overlayClass); | |
| 236 | +// this.findRenamedMethods(targetClass, overlayClass); | |
| 237 | +// this.overlayMethods(targetClass, overlayClass); | |
| 238 | +// } | |
| 239 | +// catch (Exception ex) | |
| 240 | +// { | |
| 241 | +// throw new InvalidOverlayException("Unexpecteded error whilst applying the overlay class", ex); | |
| 242 | +// } | |
| 243 | +// | |
| 244 | +// this.postOverlayTransform(transformedName, targetClass, overlayClass); | |
| 245 | +// | |
| 246 | +// return this.writeClass(targetClass); | |
| 247 | +// } | |
| 248 | +// | |
| 249 | +// protected void postOverlayTransform(String transformedName, ClassNode targetClass, ClassNode overlayClass) | |
| 250 | +// { | |
| 251 | +// // Stub | |
| 252 | +// } | |
| 253 | +// | |
| 254 | +// /** | |
| 255 | +// * Perform pre-flight checks on the overlay and target classes | |
| 256 | +// * | |
| 257 | +// * @param targetClass | |
| 258 | +// * @param overlayClass | |
| 259 | +// */ | |
| 260 | +// protected void verifyClasses(ClassNode targetClass, ClassNode overlayClass) | |
| 261 | +// { | |
| 262 | +// if (targetClass.superName == null || overlayClass.superName == null || !targetClass.superName.equals(overlayClass.superName)) | |
| 263 | +// { | |
| 264 | +// throw new InvalidOverlayException("Overlay classes must have the same superclass as their target class"); | |
| 265 | +// } | |
| 266 | +// } | |
| 267 | +// | |
| 268 | +// /** | |
| 269 | +// * Overlay interfaces implemented by the overlay class onto the target class | |
| 270 | +// * | |
| 271 | +// * @param targetClass | |
| 272 | +// * @param overlayClass | |
| 273 | +// */ | |
| 274 | +// private void overlayInterfaces(ClassNode targetClass, ClassNode overlayClass) | |
| 275 | +// { | |
| 276 | +// for (String interfaceName : overlayClass.interfaces) | |
| 277 | +// { | |
| 278 | +// if (!targetClass.interfaces.contains(interfaceName)) | |
| 279 | +// { | |
| 280 | +// targetClass.interfaces.add(interfaceName); | |
| 281 | +// } | |
| 282 | +// } | |
| 283 | +// } | |
| 284 | +// | |
| 285 | +// /** | |
| 286 | +// * Overlay misc attributes from overlay class onto the target class | |
| 287 | +// * | |
| 288 | +// * @param targetClass | |
| 289 | +// * @param overlayClass | |
| 290 | +// */ | |
| 291 | +// private void overlayAttributes(ClassNode targetClass, ClassNode overlayClass) | |
| 292 | +// { | |
| 293 | +// if (this.setSourceFile ) targetClass.sourceFile = overlayClass.sourceFile; | |
| 294 | +// } | |
| 295 | +// | |
| 296 | +// /** | |
| 297 | +// * Overlay fields from overlay class into the target class. It is vital that | |
| 298 | +// * this is done before overlayMethods because we need to compute renamed | |
| 299 | +// * fields so that transformMethod can rename field references in the | |
| 300 | +// * method body. | |
| 301 | +// * | |
| 302 | +// * @param targetClass | |
| 303 | +// * @param overlayClass | |
| 304 | +// */ | |
| 305 | +// private void overlayFields(ClassNode targetClass, ClassNode overlayClass) | |
| 306 | +// { | |
| 307 | +// for (FieldNode field : overlayClass.fields) | |
| 308 | +// { | |
| 309 | +// if ((field.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC && (field.access & Opcodes.ACC_PRIVATE) != Opcodes.ACC_PRIVATE) | |
| 310 | +// { | |
| 311 | +// throw new InvalidOverlayException(String.format("Overlay classes cannot contain non-private static methods or fields, found %s", | |
| 312 | +// field.name)); | |
| 313 | +// } | |
| 314 | +// | |
| 315 | +// FieldNode target = ByteCodeUtilities.findTargetField(targetClass, field); | |
| 316 | +// if (target == null) | |
| 317 | +// { | |
| 318 | +// targetClass.fields.add(field); | |
| 319 | +// } | |
| 320 | +// else | |
| 321 | +// { | |
| 322 | +// if (!target.desc.equals(field.desc)) | |
| 323 | +// { | |
| 324 | +// throw new InvalidOverlayException(String.format("The field %s in the target class has a conflicting signature", field.name)); | |
| 325 | +// } | |
| 326 | +// | |
| 327 | +// if (!target.name.equals(field.name)) | |
| 328 | +// { | |
| 329 | +// this.renamedFields.put(field.name, target.name); | |
| 330 | +// } | |
| 331 | +// } | |
| 332 | +// } | |
| 333 | +// } | |
| 334 | +// | |
| 335 | +// /** | |
| 336 | +// * Called before merging methods to build the map of original method names | |
| 337 | +// * -> new method names, this is then used by transformMethod to remap. | |
| 338 | +// * | |
| 339 | +// * @param targetClass | |
| 340 | +// * @param overlayClass | |
| 341 | +// */ | |
| 342 | +// private void findRenamedMethods(ClassNode targetClass, ClassNode overlayClass) | |
| 343 | +// { | |
| 344 | +// for (MethodNode overlayMethod : overlayClass.methods) | |
| 345 | +// { | |
| 346 | +// if (ByteCodeUtilities.getVisibleAnnotation(overlayMethod, Stub.class) != null | |
| 347 | +// || (ByteCodeUtilities.getVisibleAnnotation(overlayMethod, AppendInsns.class) == null && !overlayMethod.name.startsWith("<"))) | |
| 348 | +// { | |
| 349 | +// this.checkRenameMethod(targetClass, overlayMethod); | |
| 350 | +// } | |
| 351 | +// } | |
| 352 | +// } | |
| 353 | +// | |
| 354 | +// /** | |
| 355 | +// * Overlay methods from the overlay class into the target class | |
| 356 | +// * | |
| 357 | +// * @param targetClass | |
| 358 | +// * @param overlayClass | |
| 359 | +// */ | |
| 360 | +// private void overlayMethods(ClassNode targetClass, ClassNode overlayClass) | |
| 361 | +// { | |
| 362 | +// for (MethodNode overlayMethod : overlayClass.methods) | |
| 363 | +// { | |
| 364 | +// this.transformMethod(overlayMethod, overlayClass.name, targetClass.name); | |
| 365 | +// | |
| 366 | +// AnnotationNode appendAnnotation = ByteCodeUtilities.getVisibleAnnotation(overlayMethod, AppendInsns.class); | |
| 367 | +// AnnotationNode stubAnnotation = ByteCodeUtilities.getVisibleAnnotation(overlayMethod, Stub.class); | |
| 368 | +// | |
| 369 | +// if (stubAnnotation != null) | |
| 370 | +// { | |
| 371 | +// MethodNode target = ByteCodeUtilities.findTargetMethod(targetClass, overlayMethod); | |
| 372 | +// if (target == null) | |
| 373 | +// { | |
| 374 | +// throw new InvalidOverlayException(String.format("Stub method %s was not located in the target class", overlayMethod.name)); | |
| 375 | +// } | |
| 376 | +// } | |
| 377 | +// else if (appendAnnotation != null) | |
| 378 | +// { | |
| 379 | +// String targetMethodName = ByteCodeUtilities.<String>getAnnotationValue(appendAnnotation); | |
| 380 | +// this.appendInsns(targetClass, targetMethodName, overlayMethod); | |
| 381 | +// } | |
| 382 | +// else if (!overlayMethod.name.startsWith("<")) | |
| 383 | +// { | |
| 384 | +// if ((overlayMethod.access & Opcodes.ACC_STATIC) == Opcodes.ACC_STATIC | |
| 385 | +// && (overlayMethod.access & Opcodes.ACC_PRIVATE) != Opcodes.ACC_PRIVATE) | |
| 386 | +// { | |
| 387 | +// continue; | |
| 388 | +// } | |
| 389 | +// | |
| 390 | +// MethodNode target = ByteCodeUtilities.findTargetMethod(targetClass, overlayMethod); | |
| 391 | +// if (target != null) targetClass.methods.remove(target); | |
| 392 | +// targetClass.methods.add(overlayMethod); | |
| 393 | +// } | |
| 394 | +// else if ("<clinit>".equals(overlayMethod.name)) | |
| 395 | +// { | |
| 396 | +// this.appendInsns(targetClass, overlayMethod.name, overlayMethod); | |
| 397 | +// } | |
| 398 | +// } | |
| 399 | +// } | |
| 400 | +// | |
| 401 | +// /** | |
| 402 | +// * Handles "re-parenting" the method supplied, changes all references to the | |
| 403 | +// * overlay class to refer to the target class (for field accesses and method | |
| 404 | +// * invocations) and also renames fields accesses to their obfuscated | |
| 405 | +// * versions. | |
| 406 | +// * | |
| 407 | +// * @param method | |
| 408 | +// * @param fromClass | |
| 409 | +// * @param toClass | |
| 410 | +// */ | |
| 411 | +// private void transformMethod(MethodNode method, String fromClass, String toClass) | |
| 412 | +// { | |
| 413 | +// Iterator<AbstractInsnNode> iter = method.instructions.iterator(); | |
| 414 | +// while (iter.hasNext()) | |
| 415 | +// { | |
| 416 | +// AbstractInsnNode insn = iter.next(); | |
| 417 | +// | |
| 418 | +// if (insn instanceof MethodInsnNode) | |
| 419 | +// { | |
| 420 | +// MethodInsnNode methodInsn = (MethodInsnNode)insn; | |
| 421 | +// if (methodInsn.owner.equals(fromClass)) | |
| 422 | +// { | |
| 423 | +// methodInsn.owner = toClass; | |
| 424 | +// | |
| 425 | +// String methodDescriptor = methodInsn.name + methodInsn.desc; | |
| 426 | +// if (this.renamedMethods.containsKey(methodDescriptor)) | |
| 427 | +// { | |
| 428 | +// methodInsn.name = this.renamedMethods.get(methodDescriptor); | |
| 429 | +// } | |
| 430 | +// } | |
| 431 | +// } | |
| 432 | +// if (insn instanceof FieldInsnNode) | |
| 433 | +// { | |
| 434 | +// FieldInsnNode fieldInsn = (FieldInsnNode)insn; | |
| 435 | +// if (fieldInsn.owner.equals(fromClass)) fieldInsn.owner = toClass; | |
| 436 | +// | |
| 437 | +// if (this.renamedFields.containsKey(fieldInsn.name)) | |
| 438 | +// { | |
| 439 | +// String newName = this.renamedFields.get(fieldInsn.name); | |
| 440 | +// fieldInsn.name = newName; | |
| 441 | +// } | |
| 442 | +// } | |
| 443 | +// } | |
| 444 | +// } | |
| 445 | +// | |
| 446 | +// /** | |
| 447 | +// * Handles appending instructions from the source method to the target | |
| 448 | +// * method. | |
| 449 | +// * | |
| 450 | +// * @param targetClass | |
| 451 | +// * @param targetMethodName | |
| 452 | +// * @param sourceMethod | |
| 453 | +// */ | |
| 454 | +// private void appendInsns(ClassNode targetClass, String targetMethodName, MethodNode sourceMethod) | |
| 455 | +// { | |
| 456 | +// if (Type.getReturnType(sourceMethod.desc) != Type.VOID_TYPE) | |
| 457 | +// { | |
| 458 | +// throw new IllegalArgumentException("Attempted to merge insns into a method which does not return void"); | |
| 459 | +// } | |
| 460 | +// | |
| 461 | +// if (targetMethodName == null || targetMethodName.length() == 0) targetMethodName = sourceMethod.name; | |
| 462 | +// | |
| 463 | +// Set<String> obfuscatedNames = new HashSet<String>(); | |
| 464 | +// AnnotationNode obfuscatedAnnotation = ByteCodeUtilities.getVisibleAnnotation(sourceMethod, Obfuscated.class); | |
| 465 | +// if (obfuscatedAnnotation != null) | |
| 466 | +// { | |
| 467 | +// obfuscatedNames.addAll(ByteCodeUtilities.<List<String>>getAnnotationValue(obfuscatedAnnotation)); | |
| 468 | +// } | |
| 469 | +// | |
| 470 | +// for (MethodNode method : targetClass.methods) | |
| 471 | +// { | |
| 472 | +// if ((targetMethodName.equals(method.name) || obfuscatedNames.contains(method.name)) && sourceMethod.desc.equals(method.desc)) | |
| 473 | +// { | |
| 474 | +// AbstractInsnNode returnNode = null; | |
| 475 | +// Iterator<AbstractInsnNode> findReturnIter = method.instructions.iterator(); | |
| 476 | +// while (findReturnIter.hasNext()) | |
| 477 | +// { | |
| 478 | +// AbstractInsnNode insn = findReturnIter.next(); | |
| 479 | +// if (insn.getOpcode() == Opcodes.RETURN) | |
| 480 | +// { | |
| 481 | +// returnNode = insn; | |
| 482 | +// break; | |
| 483 | +// } | |
| 484 | +// } | |
| 485 | +// | |
| 486 | +// Iterator<AbstractInsnNode> injectIter = sourceMethod.instructions.iterator(); | |
| 487 | +// while (injectIter.hasNext()) | |
| 488 | +// { | |
| 489 | +// AbstractInsnNode insn = injectIter.next(); | |
| 490 | +// if (!(insn instanceof LineNumberNode) && insn.getOpcode() != Opcodes.RETURN) | |
| 491 | +// { | |
| 492 | +// method.instructions.insertBefore(returnNode, insn); | |
| 493 | +// } | |
| 494 | +// } | |
| 495 | +// } | |
| 496 | +// } | |
| 497 | +// } | |
| 498 | +// | |
| 499 | +// /** | |
| 500 | +// * @param targetClass | |
| 501 | +// * @param searchFor | |
| 502 | +// */ | |
| 503 | +// private void checkRenameMethod(ClassNode targetClass, MethodNode searchFor) | |
| 504 | +// { | |
| 505 | +// MethodNode target = ByteCodeUtilities.findTargetMethod(targetClass, searchFor); | |
| 506 | +// if (target != null && !target.name.equals(searchFor.name)) | |
| 507 | +// { | |
| 508 | +// String methodDescriptor = searchFor.name + searchFor.desc; | |
| 509 | +// this.renamedMethods.put(methodDescriptor, target.name); | |
| 510 | +// searchFor.name = target.name; | |
| 511 | +// } | |
| 512 | +// } | |
| 513 | +// | |
| 514 | +// /** | |
| 515 | +// * @param transformedName | |
| 516 | +// * @throws InvalidOverlayException | |
| 517 | +// */ | |
| 518 | +// private ClassNode loadOverlayClass(String transformedName, boolean runTransformers) | |
| 519 | +// { | |
| 520 | +// byte[] overlayBytes = null; | |
| 521 | +// | |
| 522 | +// try | |
| 523 | +// { | |
| 524 | +// if ((overlayBytes = Launch.classLoader.getClassBytes(this.overlayClassName)) == null) | |
| 525 | +// { | |
| 526 | +// throw new InvalidOverlayException(String.format("The specified overlay '%s' was not found", this.overlayClassName)); | |
| 527 | +// } | |
| 528 | +// | |
| 529 | +// if (runTransformers) | |
| 530 | +// { | |
| 531 | +// overlayBytes = ByteCodeUtilities.applyTransformers(this.overlayClassName, overlayBytes, this); | |
| 532 | +// } | |
| 533 | +// } | |
| 534 | +// catch (IOException ex) | |
| 535 | +// { | |
| 536 | +// LiteLoaderLogger.severe("Failed to load overlay %s for %s, no overlay was applied", this.overlayClassName, transformedName); | |
| 537 | +// throw new InvalidOverlayException("An error was encountered whilst loading the overlay class", ex); | |
| 538 | +// } | |
| 539 | +// | |
| 540 | +// return this.readClass(overlayBytes, false); | |
| 541 | +// } | |
| 542 | +//} | ... | ... |