diff --git a/src/main/java/com/falsepattern/endlessids/asm/ClassEdit.java b/src/main/java/com/falsepattern/endlessids/asm/ClassEdit.java index 6118676..3f9d3a2 100644 --- a/src/main/java/com/falsepattern/endlessids/asm/ClassEdit.java +++ b/src/main/java/com/falsepattern/endlessids/asm/ClassEdit.java @@ -14,7 +14,6 @@ import com.falsepattern.endlessids.asm.transformer.VanillaS26PacketMapChunkBulk; import com.falsepattern.endlessids.asm.transformer.VanillaS24PacketBlockActivation; import com.falsepattern.endlessids.asm.transformer.VanillaS22PacketMultiBlockChange; import com.falsepattern.endlessids.asm.transformer.VanillaNetHandlerPlayClient; -import com.falsepattern.endlessids.asm.transformer.VanillaDataWatcher; import java.util.Map; public enum ClassEdit @@ -25,7 +24,7 @@ public enum ClassEdit //VanillaAnvilChunkLoader(new VanillaAnvilChunkLoader(), new String[] { "net.minecraft.world.chunk.storage.AnvilChunkLoader" }), //VanillaChunk(new VanillaChunk(), new String[] { "net.minecraft.world.chunk.Chunk" }), //VanillaExtendedBlockStorage(new VanillaExtendedBlockStorage(), new String[] { "net.minecraft.world.chunk.storage.ExtendedBlockStorage" }), - VanillaDataWatcher(new VanillaDataWatcher(), new String[] { "net.minecraft.entity.DataWatcher" }), + //VanillaDataWatcher(new VanillaDataWatcher(), new String[] { "net.minecraft.entity.DataWatcher" }), VanillaNetHandlerPlayClient(new VanillaNetHandlerPlayClient(), new String[] { "net.minecraft.client.network.NetHandlerPlayClient" }), //VanillaS21PacketChunkData(new VanillaS21PacketChunkData(), new String[] { "net.minecraft.network.play.server.S21PacketChunkData" }), VanillaS22PacketMultiBlockChange(new VanillaS22PacketMultiBlockChange(), new String[] { "net.minecraft.network.play.server.S22PacketMultiBlockChange" }), diff --git a/src/main/java/com/falsepattern/endlessids/asm/transformer/VanillaDataWatcher.java b/src/main/java/com/falsepattern/endlessids/asm/transformer/VanillaDataWatcher.java deleted file mode 100644 index 64eb3f8..0000000 --- a/src/main/java/com/falsepattern/endlessids/asm/transformer/VanillaDataWatcher.java +++ /dev/null @@ -1,78 +0,0 @@ -package com.falsepattern.endlessids.asm.transformer; - -import java.util.ListIterator; -import org.objectweb.asm.tree.MethodNode; -import org.objectweb.asm.tree.MethodInsnNode; -import org.objectweb.asm.tree.AbstractInsnNode; -import com.falsepattern.endlessids.asm.AsmUtil; -import com.falsepattern.endlessids.asm.Name; -import com.falsepattern.endlessids.IEConfig; -import org.objectweb.asm.tree.ClassNode; -import com.falsepattern.endlessids.asm.IClassNodeTransformer; - -public class VanillaDataWatcher implements IClassNodeTransformer -{ - public VanillaDataWatcher() { - super(); - } - - @Override - public void transform(final ClassNode cn, final boolean obfuscated) { - if (IEConfig.extendDataWatcher) { - MethodNode method = AsmUtil.findMethod(cn, Name.dataWatcher_addObject); - AsmUtil.transformInlinedSizeMethod(cn, method, 31, 127); - method = AsmUtil.findMethod(cn, Name.dataWatcher_writeWatchableObjectToPacketBuffer); - AsmUtil.transformInlinedSizeMethod(cn, method, 31, 127); - AsmUtil.transformInlinedSizeMethod(cn, method, 255, 1023); - AsmUtil.transformInlinedSizeMethod(cn, method, 5, 7); - final ListIterator it = (ListIterator)method.instructions.iterator(); - while (it.hasNext()) { - final AbstractInsnNode insn = (AbstractInsnNode)it.next(); - if (insn.getOpcode() == 182 && ((MethodInsnNode)insn).name.equals("writeByte")) { - it.set((AbstractInsnNode)new MethodInsnNode(182, "net/minecraft/network/PacketBuffer", "writeShort", "(I)Lio/netty/buffer/ByteBuf;", false)); - break; - } - } - method = AsmUtil.findMethod(cn, Name.dataWatcher_readWatchedListFromPacketBuffer); - AsmUtil.transformInlinedSizeMethod(cn, method, 127, 32767); - AsmUtil.transformInlinedSizeMethod(cn, method, 224, 896); - AsmUtil.transformInlinedSizeMethod(cn, method, 31, 127); - AsmUtil.transformInlinedSizeMethod(cn, method, 5, 7); - int num = 0; - ListIterator it2 = (ListIterator)method.instructions.iterator(); - while (it2.hasNext()) { - final AbstractInsnNode insn2 = (AbstractInsnNode)it2.next(); - if (insn2.getOpcode() == 182 && ((MethodInsnNode)insn2).name.equals("readByte")) { - if (++num == 2) { - continue; - } - it2.set((AbstractInsnNode)new MethodInsnNode(182, "net/minecraft/network/PacketBuffer", "readShort", "()S", false)); - if (num == 3) { - break; - } - continue; - } - } - method = AsmUtil.findMethod(cn, Name.dataWatcher_writeWatchedListToPacketBuffer); - AsmUtil.transformInlinedSizeMethod(cn, method, 127, 32767); - it2 = (ListIterator)method.instructions.iterator(); - while (it2.hasNext()) { - final AbstractInsnNode insn2 = (AbstractInsnNode)it2.next(); - if (insn2.getOpcode() == 182 && ((MethodInsnNode)insn2).name.equals("writeByte")) { - it2.set((AbstractInsnNode)new MethodInsnNode(182, "net/minecraft/network/PacketBuffer", "writeShort", "(I)Lio/netty/buffer/ByteBuf;", false)); - break; - } - } - method = AsmUtil.findMethod(cn, Name.dataWatcher_func_151509_a); - AsmUtil.transformInlinedSizeMethod(cn, method, 127, 32767); - it2 = (ListIterator)method.instructions.iterator(); - while (it2.hasNext()) { - final AbstractInsnNode insn2 = (AbstractInsnNode)it2.next(); - if (insn2.getOpcode() == 182 && ((MethodInsnNode)insn2).name.equals("writeByte")) { - it2.set((AbstractInsnNode)new MethodInsnNode(182, "net/minecraft/network/PacketBuffer", "writeShort", "(I)Lio/netty/buffer/ByteBuf;", false)); - break; - } - } - } - } -} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/DataWatcherMixin.java b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/DataWatcherMixin.java new file mode 100644 index 0000000..25d3e74 --- /dev/null +++ b/src/main/java/com/falsepattern/endlessids/mixin/mixins/common/DataWatcherMixin.java @@ -0,0 +1,96 @@ +package com.falsepattern.endlessids.mixin.mixins.common; + +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.DataWatcher; +import net.minecraft.network.PacketBuffer; +import net.minecraft.util.ChunkCoordinates; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Overwrite; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.Redirect; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@Mixin(DataWatcher.class) +public abstract class DataWatcherMixin { + @ModifyConstant(method = {"addObject", "writeWatchedListToPacketBuffer", "func_151509_a", "writeWatchableObjectToPacketBuffer"}, + constant = @Constant(intValue = 31), + require = 4) + private static int extend1(int constant) { + return 127; + } + + @ModifyConstant(method = "writeWatchableObjectToPacketBuffer", + constant = @Constant(intValue = 5, ordinal = 0), + require = 1) + private static int extend2(int constant) { + return 7; + } + + @ModifyConstant(method = "writeWatchableObjectToPacketBuffer", + constant = @Constant(intValue = 255, ordinal = 0), + require = 1) + private static int extend3(int constant) { + return 1023; + } + + @Redirect(method = "writeWatchableObjectToPacketBuffer", + at = @At(value = "INVOKE", + target = "Lnet/minecraft/network/PacketBuffer;writeByte(I)Lio/netty/buffer/ByteBuf;"), + require = 1) + private static ByteBuf extendWrite(PacketBuffer instance, int p_writeByte_1_) { + return instance.writeShort(p_writeByte_1_); + } + + /** + * @author FalsePattern + * @reason Direct port from dumped code + */ + @Overwrite + public static List readWatchedListFromPacketBuffer(PacketBuffer packet) throws IOException { + ArrayList watchables = null; + + for(short id = packet.readShort(); id != 32767; id = packet.readShort()) { + if (watchables == null) { + watchables = new ArrayList<>(); + } + + int var3 = (id & 896) >> 7; + int var4 = id & 127; + DataWatcher.WatchableObject watchable = null; + switch(var3) { + case 0: + watchable = new DataWatcher.WatchableObject(var3, var4, packet.readByte()); + break; + case 1: + watchable = new DataWatcher.WatchableObject(var3, var4, packet.readShort()); + break; + case 2: + watchable = new DataWatcher.WatchableObject(var3, var4, packet.readInt()); + break; + case 3: + watchable = new DataWatcher.WatchableObject(var3, var4, packet.readFloat()); + break; + case 4: + watchable = new DataWatcher.WatchableObject(var3, var4, packet.readStringFromBuffer(32767)); + break; + case 5: + watchable = new DataWatcher.WatchableObject(var3, var4, packet.readItemStackFromBuffer()); + break; + case 6: + int x = packet.readInt(); + int y = packet.readInt(); + int z = packet.readInt(); + watchable = new DataWatcher.WatchableObject(var3, var4, new ChunkCoordinates(x, y, z)); + } + + watchables.add(watchable); + } + + return watchables; + } +} diff --git a/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java b/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java index adba610..4e469d8 100644 --- a/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java +++ b/src/main/java/com/falsepattern/endlessids/mixin/plugin/Mixin.java @@ -1,14 +1,17 @@ package com.falsepattern.endlessids.mixin.plugin; +import com.falsepattern.endlessids.IEConfig; import cpw.mods.fml.relauncher.FMLLaunchHandler; import java.util.HashSet; import java.util.List; import java.util.Set; +import java.util.function.Supplier; public enum Mixin { AnvilChunkLoaderMixin(builder(Side.COMMON).mixin("AnvilChunkLoaderMixin")), ChunkMixin(builder(Side.COMMON).mixin("ChunkMixin")), + DataWatcherMixin(builder(Side.COMMON).condition(() -> IEConfig.extendDataWatcher).mixin("DataWatcherMixin")), StatListMixin(builder(Side.COMMON).mixin("StatListMixin")), BlockFireMixin(builder(Side.COMMON).mixin("BlockFireMixin")), WorldMixin(builder(Side.COMMON).mixin("WorldMixin")), @@ -19,12 +22,14 @@ public enum Mixin { public final String mixin; public final Set targetedMods; public final Set avoidedMods; + public final Set> allowConditions; private final Side side; Mixin(Builder builder) { this.mixin = builder.mixin; this.targetedMods = builder.targetedMods; this.avoidedMods = builder.avoidedMods; + this.allowConditions = builder.allowConditions; this.side = builder.side; } @@ -32,7 +37,9 @@ public enum Mixin { return (side == Side.COMMON || side == Side.SERVER && FMLLaunchHandler.side().isServer() || side == Side.CLIENT && FMLLaunchHandler.side().isClient()) - && loadedMods.containsAll(targetedMods) && avoidedMods.stream().noneMatch(loadedMods::contains); + && loadedMods.containsAll(targetedMods) + && avoidedMods.stream().noneMatch(loadedMods::contains) + && allowConditions.stream().allMatch(Supplier::get); } @@ -44,8 +51,9 @@ public enum Mixin { private static class Builder { public String mixin; public Side side; - public Set targetedMods = new HashSet<>(); + public final Set targetedMods = new HashSet<>(); public final Set avoidedMods = new HashSet<>(); + public final Set> allowConditions = new HashSet<>(); public Builder(Side side) { this.side = side; @@ -65,6 +73,11 @@ public enum Mixin { avoidedMods.add(mod); return this; } + + public Builder condition(Supplier cond) { + allowConditions.add(cond); + return this; + } } private enum Side {