From c57c06697f96d73bb1e7980f6cb0436f3e02db1a Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Sun, 29 Nov 2015 02:55:29 +1300 Subject: [PATCH] Patch file --- ...l-version-patch-and-some-other-fixes.patch | 7380 +++++++++++++++++ 1 file changed, 7380 insertions(+) create mode 100644 Patches/CraftBukkit-Patches/0177-Dual-version-patch-and-some-other-fixes.patch diff --git a/Patches/CraftBukkit-Patches/0177-Dual-version-patch-and-some-other-fixes.patch b/Patches/CraftBukkit-Patches/0177-Dual-version-patch-and-some-other-fixes.patch new file mode 100644 index 000000000..31947a9ff --- /dev/null +++ b/Patches/CraftBukkit-Patches/0177-Dual-version-patch-and-some-other-fixes.patch @@ -0,0 +1,7380 @@ +From 4b151cd529c5de0d32cc78357f417c9fa4866198 Mon Sep 17 00:00:00 2001 +From: libraryaddict +Date: Sun, 29 Nov 2015 02:53:00 +1300 +Subject: [PATCH] Dual version patch and some other fixes + + +diff --git a/src/main/java/com/mineplex/chunk/BlockMap.java b/src/main/java/com/mineplex/chunk/BlockMap.java +new file mode 100644 +index 0000000..22b362a +--- /dev/null ++++ b/src/main/java/com/mineplex/chunk/BlockMap.java +@@ -0,0 +1,64 @@ ++package com.mineplex.chunk; ++ ++import net.minecraft.server.MathHelper; ++ ++import org.apache.commons.lang3.Validate; ++ ++public class BlockMap ++{ ++ private final long[] a; ++ private final int b; ++ private final long c; ++ private final int d; ++ ++ public BlockMap(int n2, int n3) ++ { ++ Validate.inclusiveBetween(1, 32, n2); ++ this.d = n3; ++ this.b = n2; ++ this.c = (1 << n2) - 1; ++ this.a = new long[MathHelper.c(n3 * n2, 64) / 64]; ++ } ++ ++ public void a(int n2, int n3) ++ { ++ Validate.inclusiveBetween(0, this.d - 1, n2); ++ Validate.inclusiveBetween(0, this.c, n3); ++ int n4 = n2 * this.b; ++ int n5 = n4 / 64; ++ int n6 = ((n2 + 1) * this.b - 1) / 64; ++ int n7 = n4 % 64; ++ this.a[n5] = this.a[n5] & (this.c << n7 ^ -1) | ((long) n3 & this.c) << n7; ++ if (n5 != n6) ++ { ++ int n8 = 64 - n7; ++ int n9 = this.b - n8; ++ this.a[n6] = this.a[n6] >>> n9 << n9 | ((long) n3 & this.c) >> n8; ++ } ++ } ++ ++ public int a(int n2) ++ { ++ Validate.inclusiveBetween(0, this.d - 1, n2); ++ int n3 = n2 * this.b; ++ int n4 = n3 / 64; ++ int n5 = ((n2 + 1) * this.b - 1) / 64; ++ int n6 = n3 % 64; ++ if (n4 == n5) ++ { ++ return (int) (this.a[n4] >>> n6 & this.c); ++ } ++ int n7 = 64 - n6; ++ return (int) ((this.a[n4] >>> n6 | this.a[n5] << n7) & this.c); ++ } ++ ++ public long[] a() ++ { ++ return this.a; ++ } ++ ++ public int b() ++ { ++ return this.d; ++ } ++} +diff --git a/src/main/java/com/mineplex/chunk/BlockPalette.java b/src/main/java/com/mineplex/chunk/BlockPalette.java +new file mode 100644 +index 0000000..527796c +--- /dev/null ++++ b/src/main/java/com/mineplex/chunk/BlockPalette.java +@@ -0,0 +1,15 @@ ++package com.mineplex.chunk; ++ ++import net.minecraft.server.IBlockData; ++import net.minecraft.server.PacketDataSerializer; ++ ++public interface BlockPalette ++{ ++ public int addGetIndex(IBlockData data); ++ ++ public IBlockData getBlock(int index); ++ ++ public void writeSerializer(PacketDataSerializer dataSerializer); ++ ++ public int getLength(); ++} +diff --git a/src/main/java/com/mineplex/chunk/LargeBlockPalette.java b/src/main/java/com/mineplex/chunk/LargeBlockPalette.java +new file mode 100644 +index 0000000..b68ab86 +--- /dev/null ++++ b/src/main/java/com/mineplex/chunk/LargeBlockPalette.java +@@ -0,0 +1,39 @@ ++package com.mineplex.chunk; ++ ++import net.minecraft.server.Block; ++import net.minecraft.server.Blocks; ++import net.minecraft.server.IBlockData; ++import net.minecraft.server.PacketDataSerializer; ++ ++public class LargeBlockPalette implements BlockPalette ++{ ++ ++ // Get index ++ @Override ++ public int addGetIndex(IBlockData aqt2) ++ { ++ int n2 = Block.d.b(aqt2); ++ return n2 == -1 ? 0 : n2; ++ } ++ ++ // Get from index ++ @Override ++ public IBlockData getBlock(int index) ++ { ++ IBlockData aqt2 = (IBlockData) Block.d.a(index); ++ return aqt2 == null ? Blocks.AIR.getBlockData() : aqt2; ++ } ++ ++ @Override ++ public void writeSerializer(PacketDataSerializer em2) ++ { ++ em2.b(0); ++ } ++ ++ @Override ++ public int getLength() ++ { ++ return PacketDataSerializer.a(0); ++ } ++ ++} +diff --git a/src/main/java/com/mineplex/chunk/MediumBlockPalette.java b/src/main/java/com/mineplex/chunk/MediumBlockPalette.java +new file mode 100644 +index 0000000..4c0dcc5 +--- /dev/null ++++ b/src/main/java/com/mineplex/chunk/MediumBlockPalette.java +@@ -0,0 +1,63 @@ ++package com.mineplex.chunk; ++ ++import java.util.ArrayList; ++import java.util.LinkedHashMap; ++ ++import net.minecraft.server.Block; ++import net.minecraft.server.IBlockData; ++import net.minecraft.server.PacketDataSerializer; ++import net.minecraft.server.ChunkSection; ++ ++public class MediumBlockPalette implements BlockPalette ++{ ++ private PaletteMediumList a; ++ private ChunkSection b; ++ private int bitShift; ++ ++ public MediumBlockPalette(int bitShift, ChunkSection section) ++ { ++ this.bitShift = bitShift; ++ b = section; ++ this.a = new PaletteMediumList(1 << bitShift); ++ } ++ ++ @Override ++ public int addGetIndex(IBlockData data) ++ { ++ int n2 = this.a.a(data); ++ if (n2 == -1 && (n2 = this.a.c(data)) >= 1 << this.bitShift) ++ { ++ n2 = this.b.resizePalette(this.bitShift + 1, data); ++ } ++ return n2; ++ } ++ ++ @Override ++ public IBlockData getBlock(int index) ++ { ++ return a.get(index); ++ } ++ ++ @Override ++ public void writeSerializer(PacketDataSerializer dataSerializer) ++ { ++ int n2 = this.a.b(); ++ dataSerializer.b(n2); ++ for (int i2 = 0; i2 < n2; ++i2) ++ { ++ dataSerializer.b(Block.d.b(this.a.get(i2))); ++ } ++ } ++ ++ @Override ++ public int getLength() ++ { ++ int n2 = PacketDataSerializer.a(this.a.b()); ++ for (int i2 = 0; i2 < this.a.b(); ++i2) ++ { ++ n2 += PacketDataSerializer.a(Block.d.b(this.a.get(i2))); ++ } ++ return n2; ++ } ++ ++} +diff --git a/src/main/java/com/mineplex/chunk/PaletteMediumList.java b/src/main/java/com/mineplex/chunk/PaletteMediumList.java +new file mode 100644 +index 0000000..41917be +--- /dev/null ++++ b/src/main/java/com/mineplex/chunk/PaletteMediumList.java +@@ -0,0 +1,171 @@ ++package com.mineplex.chunk; ++ ++import java.util.Iterator; ++ ++import com.google.common.base.Predicates; ++import com.google.common.collect.Iterators; ++ ++public class PaletteMediumList implements Iterable ++{ ++ private static final Object a = null; ++ private T[] b; ++ private int[] c; ++ private T[] d; ++ private int e; ++ private int f; ++ ++ public PaletteMediumList(int n2) ++ { ++ n2 = (int) ((float) n2 / 0.8f); ++ this.b = (T[]) new Object[n2]; ++ this.c = new int[n2]; ++ this.d = (T[]) new Object[n2]; ++ } ++ ++ public int a(T k2) ++ { ++ return this.c(this.b(k2, this.d(k2))); ++ } ++ ++ public T get(int n2) ++ { ++ if (n2 < 0 || n2 >= this.d.length) ++ { ++ return null; ++ } ++ return this.d[n2]; ++ } ++ ++ private int c(int n2) ++ { ++ if (n2 == -1) ++ { ++ return -1; ++ } ++ return this.c[n2]; ++ } ++ ++ public int c(T k2) ++ { ++ int n2 = this.c(); ++ this.a(k2, n2); ++ return n2; ++ } ++ ++ private int c() ++ { ++ while (this.e < this.d.length && this.d[this.e] != null) ++ { ++ ++this.e; ++ } ++ return this.e++; ++ } ++ ++ private void d(int n2) ++ { ++ T[] arrK = this.b; ++ int[] arrn = this.c; ++ this.b = (T[]) new Object[n2]; ++ this.c = new int[n2]; ++ this.d = (T[]) new Object[n2]; ++ this.e = 0; ++ this.f = 0; ++ for (int i2 = 0; i2 < arrK.length; ++i2) ++ { ++ if (arrK[i2] == null) ++ continue; ++ this.a(arrK[i2], arrn[i2]); ++ } ++ } ++ ++ public void a(T k2, int n2) ++ { ++ int n3; ++ int n4; ++ if ((float) (n4 = Math.max(n2, ++this.f)) >= (float) this.b.length * 0.8f) ++ { ++ for (n3 = this.b.length << 1; n3 < n2; n3 <<= 1) ++ { ++ } ++ this.d(n3); ++ } ++ n3 = this.e(this.d(k2)); ++ this.b[n3] = k2; ++ this.c[n3] = n2; ++ this.d[n2] = k2; ++ } ++ ++ public static int math(int n2) ++ { ++ n2 ^= n2 >>> 16; ++ n2 *= -2048144789; ++ n2 ^= n2 >>> 13; ++ n2 *= -1028477387; ++ n2 ^= n2 >>> 16; ++ return n2; ++ } ++ ++ private int d(T k2) ++ { ++ return (math(System.identityHashCode(k2)) & Integer.MAX_VALUE) % this.b.length; ++ } ++ ++ private int b(T k2, int n2) ++ { ++ int n3; ++ for (n3 = n2; n3 < this.b.length; ++n3) ++ { ++ if (this.b[n3] == k2) ++ { ++ return n3; ++ } ++ if (this.b[n3] != a) ++ continue; ++ return -1; ++ } ++ for (n3 = 0; n3 < n2; ++n3) ++ { ++ if (this.b[n3] == k2) ++ { ++ return n3; ++ } ++ if (this.b[n3] != a) ++ continue; ++ return -1; ++ } ++ return -1; ++ } ++ ++ private int e(int n2) ++ { ++ int n3; ++ StringBuilder stringBuilder = new StringBuilder(""); ++ for (n3 = n2; n3 < this.b.length; ++n3) ++ { ++ if (this.b[n3] == a) ++ { ++ return n3; ++ } ++ stringBuilder.append(n3).append(' '); ++ } ++ for (n3 = 0; n3 < n2; ++n3) ++ { ++ if (this.b[n3] == a) ++ { ++ return n3; ++ } ++ stringBuilder.append(n3).append(' '); ++ } ++ throw new RuntimeException("Overflowed :("); ++ } ++ ++ public Iterator iterator() ++ { ++ return Iterators.filter(Iterators.forArray(this.d), Predicates.notNull()); ++ } ++ ++ public int b() ++ { ++ return this.f + 1; ++ } ++} +diff --git a/src/main/java/com/mineplex/chunk/SmallBlockPalette.java b/src/main/java/com/mineplex/chunk/SmallBlockPalette.java +new file mode 100644 +index 0000000..66c2e14 +--- /dev/null ++++ b/src/main/java/com/mineplex/chunk/SmallBlockPalette.java +@@ -0,0 +1,78 @@ ++package com.mineplex.chunk; ++ ++import net.minecraft.server.Block; ++import net.minecraft.server.IBlockData; ++import net.minecraft.server.PacketDataSerializer; ++import net.minecraft.server.ChunkSection; ++ ++public class SmallBlockPalette implements BlockPalette ++{ ++ private final IBlockData[] a; ++ private final ChunkSection b; ++ private final int bitShift; ++ private int d; ++ ++ public SmallBlockPalette(int bitShift, ChunkSection section) ++ { ++ this.a = new IBlockData[1 << bitShift]; ++ this.bitShift = bitShift; ++ this.b = section; ++ } ++ ++ @Override ++ public int addGetIndex(IBlockData data) ++ { ++ int n2; ++ for (n2 = 0; n2 < this.d; ++n2) ++ { ++ if (this.a[n2] != data) ++ continue; ++ return n2; ++ } ++ ++ if ((n2 = this.d++) < this.a.length) ++ { ++ this.a[n2] = data; ++ if (n2 == 16) ++ { ++ System.out.println(""); ++ } ++ return n2; ++ } ++ ++ return this.b.resizePalette(this.bitShift + 1, data); ++ } ++ ++ @Override ++ public IBlockData getBlock(int index) ++ { ++ if (index > 0 && index < this.d) ++ { ++ return this.a[index]; ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public void writeSerializer(PacketDataSerializer dataSerializer) ++ { ++ dataSerializer.b(this.d); ++ for (int i2 = 0; i2 < this.d; ++i2) ++ { ++ dataSerializer.b(Block.d.b(this.a[i2])); ++ } ++ } ++ ++ @Override ++ public int getLength() ++ { ++ int n2 = PacketDataSerializer.a(this.d); ++ for (int i2 = 0; i2 < this.d; ++i2) ++ { ++ n2 += PacketDataSerializer.a(Block.d.b(this.a[i2])); ++ } ++ return n2; ++ } ++ ++} +diff --git a/src/main/java/com/mineplex/spigot/MineplexTranslateItem.java b/src/main/java/com/mineplex/spigot/MineplexTranslateItem.java +new file mode 100644 +index 0000000..81954a4 +--- /dev/null ++++ b/src/main/java/com/mineplex/spigot/MineplexTranslateItem.java +@@ -0,0 +1,570 @@ ++package com.mineplex.spigot; ++ ++import java.lang.reflect.Field; ++import java.util.Map; ++ ++import org.bukkit.Material; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++ ++import com.google.common.base.Objects; ++ ++import net.minecraft.server.ChatComponentText; ++import net.minecraft.server.ChatMessage; ++import net.minecraft.server.EntityTypes; ++import net.minecraft.server.IChatBaseComponent; ++import net.minecraft.server.Item; ++import net.minecraft.server.ItemStack; ++import net.minecraft.server.NBTTagCompound; ++import net.minecraft.server.NBTTagList; ++import net.minecraft.server.NBTTagString; ++import net.minecraft.server.PacketDataSerializer; ++ ++public class MineplexTranslateItem ++{ ++ private static final String[] potionNames = new String[128]; ++ private static Map entityTypes; ++ ++ public static IChatBaseComponent convertChat(IChatBaseComponent eu2) throws Exception ++ { ++ Object[] arrobject = null; ++ IChatBaseComponent eu3 = null; ++ ++ if (eu2 instanceof ChatComponentText) ++ { ++ eu3 = new ChatComponentText(((ChatComponentText) eu2).g()); ++ } ++ else if (eu2 instanceof ChatMessage) ++ { ++ arrobject = ((ChatMessage) eu2).j(); ++ for (int i2 = 0; i2 < arrobject.length; ++i2) ++ { ++ Object object = arrobject[i2]; ++ if (!(object instanceof IChatBaseComponent)) ++ continue; ++ arrobject[i2] = convertChat((IChatBaseComponent) object); ++ } ++ eu3 = new ChatMessage(((ChatMessage) eu2).i(), arrobject); ++ } ++ else ++ { ++ return eu2; ++ } ++ ++ for (IChatBaseComponent eu4 : eu2.a()) ++ { ++ eu3.addSibling(convertChat(eu4)); ++ } ++ return eu3; ++ } ++ ++ public static ItemStack receiveItemStack(int id, byte amount, short data, NBTTagCompound nbt) ++ { ++ ItemStack itemstack = new ItemStack(Item.getById(id == 438 ? 373 : id), amount, data); ++ itemstack.setTag(nbt); ++ ++ switch (id) ++ { ++ case 383: ++ if (nbt == null) ++ { ++ break; ++ } ++ ++ if (!nbt.hasKey("EntityTag")) ++ { ++ break; ++ } ++ ++ if (!((NBTTagCompound) nbt.get("EntityTag")).hasKey("id")) ++ { ++ break; ++ } ++ ++ Integer entId = entityTypes.get(((NBTTagCompound) nbt.get("EntityTag")).getString("id")); ++ ++ itemstack.setData(entId); ++ break; ++ case 373: ++ itemstack = receivePotion(itemstack, false); ++ break; ++ case 438: ++ itemstack = receivePotion(itemstack, true); ++ break; ++ default: ++ break; ++ } ++ ++ return itemstack; ++ } ++ ++ public static void sendItemStack(PacketDataSerializer serializer, ItemStack itemstack) ++ { ++ if (itemstack == null || itemstack.getItem() == null || serializer.version == 47) ++ { ++ writeItemStack(serializer, itemstack); ++ return; ++ } ++ ++ switch (Item.getId(itemstack.getItem())) ++ { ++ case 383: ++ itemstack = itemstack.cloneItemStack(); ++ ++ CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); ++ ++ NBTTagCompound nbt = itemstack.getTag(); ++ ++ if (nbt == null) ++ { ++ nbt = new NBTTagCompound(); ++ } ++ ++ String entity = EntityTypes.b(itemstack.getData()); ++ ++ if (entity == null) ++ { ++ nbt.remove("EntityTag"); ++ } ++ else ++ { ++ if (!nbt.hasKey("EntityTag")) ++ { ++ nbt.set("EntityTag", new NBTTagCompound()); ++ } ++ ++ ((NBTTagCompound) nbt.get("EntityTag")).setString("id", entity); ++ } ++ ++ serializer.writeShort(Material.MONSTER_EGG.getId()); ++ serializer.writeByte(itemstack.count); ++ serializer.writeShort(0); ++ ++ serializer.a(nbt); ++ ++ return; ++ case 373: ++ sendPotion(serializer, itemstack.cloneItemStack()); ++ return; ++ case 387: ++ //sendBook(serializer, itemstack.cloneItemStack()); ++ //return; ++ default: ++ break; ++ } ++ ++ writeItemStack(serializer, itemstack); ++ } ++ ++ private static void sendBook(PacketDataSerializer serializer, ItemStack itemstack) ++ { ++ CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); ++ ++ NBTTagCompound nbt = itemstack.getTag(); ++ ++ if (nbt == null) ++ { ++ writeItemStack(serializer, itemstack); ++ return; ++ } ++ ++ nbt.remove("generation"); ++ nbt.setInt("resolved", 1); ++ NBTTagList list = nbt.getList("pages", 8); ++ NBTTagList newList = new NBTTagList(); ++ ++ for (int i = 0; i < list.size(); i++) ++ { ++ String string = list.getString(i); ++ ++ if (string.endsWith(",\"text\":\"\"}")) ++ { ++ string = string.replace(",\"text\":\"\"}", "}").replaceFirst("extra", "text"); ++ } ++ else if (string.startsWith("\"")) ++ string = "{\"text\":" + string + "}"; ++ ++ newList.add(new NBTTagString(string)); ++ ++ /*IChatBaseComponent arg; ++ try ++ { ++ arg = IChatBaseComponent.ChatSerializer.a(string); ++ arg = convertChat(arg); ++ } ++ catch (Exception ex) ++ { ++ arg = new ChatComponentText(string); ++ } ++ ++ list.a(i, new NBTTagString(IChatBaseComponent.ChatSerializer.a(arg)));*/ ++ } ++ nbt.set("pages", newList); ++ ++ for (String n : nbt.c()) ++ { ++ System.out.print("Key: " + n); ++ System.out.print("Value: " + nbt.get(n)); ++ ++ if (nbt.get(n) instanceof NBTTagList) ++ { ++ for (int i = 0; i < nbt.getList(n, 8).size(); i++) ++ { ++ System.out.print("List: " + nbt.getList(n, 8).getString(i)); ++ } ++ } ++ } ++ ++ serializer.writeShort(Item.getId(itemstack.getItem())); ++ serializer.writeByte(itemstack.count); ++ serializer.writeShort(itemstack.getData()); ++ ++ serializer.a(nbt); ++ } ++ ++ private static void writeItemStack(PacketDataSerializer serializer, ItemStack itemstack) ++ { ++ if (itemstack == null || itemstack.getItem() == null) ++ { // CraftBukkit - NPE fix itemstack.getItem() ++ serializer.writeShort(-1); ++ } ++ else ++ { ++ serializer.writeShort(Item.getId(itemstack.getItem())); ++ serializer.writeByte(itemstack.count); ++ serializer.writeShort(itemstack.getData()); ++ NBTTagCompound nbttagcompound = null; ++ ++ if (itemstack.getItem().usesDurability() || itemstack.getItem().p()) ++ { ++ // Spigot start - filter ++ itemstack = itemstack.cloneItemStack(); ++ CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); ++ // Spigot end ++ nbttagcompound = itemstack.getTag(); ++ } ++ ++ serializer.a(nbttagcompound); ++ } ++ } ++ ++ public static void sendPotion(PacketDataSerializer serializer, ItemStack item) ++ { ++ CraftItemStack.setItemMeta(item, CraftItemStack.getItemMeta(item)); ++ ++ NBTTagCompound itemNbt = item.getTag(); ++ ++ if (itemNbt == null) ++ { ++ itemNbt = new NBTTagCompound(); ++ } ++ ++ int dura = item.getData(); ++ boolean splash = (dura & 16384) == 16384; ++ ++ String string = potionNames[dura & 127]; ++ itemNbt.setString("Potion", string == null ? "minecraft:water" : string); ++ ++ int id = !splash ? 373 : 438; ++ ++ serializer.writeShort(id); ++ serializer.writeByte(item.count); ++ serializer.writeShort(0); ++ ++ serializer.a(itemNbt); ++ } ++ ++ public static ItemStack receivePotion(ItemStack itemstack, boolean splash) ++ { ++ NBTTagCompound itemNbt = itemstack.getTag(); ++ ++ if (itemNbt == null || !itemNbt.hasKey("Potion")) ++ { ++ return itemstack; ++ } ++ ++ String type = itemNbt.getString("Potion"); ++ ++ int dura = 0; ++ ++ if (type != null && !type.equals("minecraft:water")) ++ { ++ for (int i = 0; i < potionNames.length; i++) ++ { ++ String b = potionNames[i]; ++ ++ if (Objects.equal(b, type)) ++ { ++ dura = i; ++ break; ++ } ++ } ++ } ++ ++ if (splash) ++ { ++ dura += 16384; ++ } ++ else if (dura > 0) ++ { ++ dura += 8192; ++ } ++ ++ itemstack.setData(dura); ++ ++ return itemstack; ++ } ++ ++ static ++ { ++ potionNames[0] = "minecraft:water"; ++ potionNames[1] = "minecraft:regeneration"; ++ potionNames[2] = "minecraft:swiftness"; ++ potionNames[3] = "minecraft:fire_resistance"; ++ potionNames[4] = "minecraft:poison"; ++ potionNames[5] = "minecraft:healing"; ++ potionNames[6] = "minecraft:night_vision"; ++ potionNames[7] = null; ++ potionNames[8] = "minecraft:weakness"; ++ potionNames[9] = "minecraft:strength"; ++ potionNames[10] = "minecraft:slowness"; ++ potionNames[11] = "minecraft:leaping"; ++ potionNames[12] = "minecraft:harming"; ++ potionNames[13] = "minecraft:water_breathing"; ++ potionNames[14] = "minecraft:invisibility"; ++ potionNames[15] = null; ++ potionNames[16] = "minecraft:awkward"; ++ potionNames[17] = "minecraft:regeneration"; ++ potionNames[18] = "minecraft:swiftness"; ++ potionNames[19] = "minecraft:fire_resistance"; ++ potionNames[20] = "minecraft:poison"; ++ potionNames[21] = "minecraft:healing"; ++ potionNames[22] = "minecraft:night_vision"; ++ potionNames[23] = null; ++ potionNames[24] = "minecraft:weakness"; ++ potionNames[25] = "minecraft:strength"; ++ potionNames[26] = "minecraft:slowness"; ++ potionNames[27] = "minecraft:leaping"; ++ potionNames[28] = "minecraft:harming"; ++ potionNames[29] = "minecraft:water_breathing"; ++ potionNames[30] = "minecraft:invisibility"; ++ potionNames[31] = null; ++ potionNames[32] = "minecraft:thick"; ++ potionNames[33] = "minecraft:strong_regeneration"; ++ potionNames[34] = "minecraft:strong_swiftness"; ++ potionNames[35] = "minecraft:fire_resistance"; ++ potionNames[36] = "minecraft:strong_poison"; ++ potionNames[37] = "minecraft:strong_healing"; ++ potionNames[38] = "minecraft:night_vision"; ++ potionNames[39] = null; ++ potionNames[40] = "minecraft:weakness"; ++ potionNames[41] = "minecraft:strong_strength"; ++ potionNames[42] = "minecraft:slowness"; ++ potionNames[43] = "minecraft:strong_leaping"; ++ potionNames[44] = "minecraft:strong_harming"; ++ potionNames[45] = "minecraft:water_breathing"; ++ potionNames[46] = "minecraft:invisibility"; ++ potionNames[47] = null; ++ potionNames[48] = null; ++ potionNames[49] = "minecraft:strong_regeneration"; ++ potionNames[50] = "minecraft:strong_swiftness"; ++ potionNames[51] = "minecraft:fire_resistance"; ++ potionNames[52] = "minecraft:strong_poison"; ++ potionNames[53] = "minecraft:strong_healing"; ++ potionNames[54] = "minecraft:night_vision"; ++ potionNames[55] = null; ++ potionNames[56] = "minecraft:weakness"; ++ potionNames[57] = "minecraft:strong_strength"; ++ potionNames[58] = "minecraft:slowness"; ++ potionNames[59] = "minecraft:strong_leaping"; ++ potionNames[60] = "minecraft:strong_harming"; ++ potionNames[61] = "minecraft:water_breathing"; ++ potionNames[62] = "minecraft:invisibility"; ++ potionNames[63] = null; ++ potionNames[64] = "minecraft:mundane"; ++ potionNames[65] = "minecraft:long_regeneration"; ++ potionNames[66] = "minecraft:long_swiftness"; ++ potionNames[67] = "minecraft:long_fire_resistance"; ++ potionNames[68] = "minecraft:long_poison"; ++ potionNames[69] = "minecraft:healing"; ++ potionNames[70] = "minecraft:long_night_vision"; ++ potionNames[71] = null; ++ potionNames[72] = "minecraft:long_weakness"; ++ potionNames[73] = "minecraft:long_strength"; ++ potionNames[74] = "minecraft:long_slowness"; ++ potionNames[75] = "minecraft:long_leaping"; ++ potionNames[76] = "minecraft:harming"; ++ potionNames[77] = "minecraft:long_water_breathing"; ++ potionNames[78] = "minecraft:long_invisibility"; ++ potionNames[79] = null; ++ potionNames[80] = "minecraft:awkward"; ++ potionNames[81] = "minecraft:long_regeneration"; ++ potionNames[82] = "minecraft:long_swiftness"; ++ potionNames[83] = "minecraft:long_fire_resistance"; ++ potionNames[84] = "minecraft:long_poison"; ++ potionNames[85] = "minecraft:healing"; ++ potionNames[86] = "minecraft:long_night_vision"; ++ potionNames[87] = null; ++ potionNames[88] = "minecraft:long_weakness"; ++ potionNames[89] = "minecraft:long_strength"; ++ potionNames[90] = "minecraft:long_slowness"; ++ potionNames[91] = "minecraft:long_leaping"; ++ potionNames[92] = "minecraft:harming"; ++ potionNames[93] = "minecraft:long_water_breathing"; ++ potionNames[94] = "minecraft:long_invisibility"; ++ potionNames[95] = null; ++ potionNames[96] = "minecraft:thick"; ++ potionNames[97] = "minecraft:regeneration"; ++ potionNames[98] = "minecraft:swiftness"; ++ potionNames[99] = "minecraft:long_fire_resistance"; ++ potionNames[100] = "minecraft:poison"; ++ potionNames[101] = "minecraft:strong_healing"; ++ potionNames[102] = "minecraft:long_night_vision"; ++ potionNames[103] = null; ++ potionNames[104] = "minecraft:long_weakness"; ++ potionNames[105] = "minecraft:strength"; ++ potionNames[106] = "minecraft:long_slowness"; ++ potionNames[107] = "minecraft:leaping"; ++ potionNames[108] = "minecraft:strong_harming"; ++ potionNames[109] = "minecraft:long_water_breathing"; ++ potionNames[110] = "minecraft:long_invisibility"; ++ potionNames[111] = null; ++ potionNames[112] = null; ++ potionNames[113] = "minecraft:regeneration"; ++ potionNames[114] = "minecraft:swiftness"; ++ potionNames[115] = "minecraft:long_fire_resistance"; ++ potionNames[116] = "minecraft:poison"; ++ potionNames[117] = "minecraft:strong_healing"; ++ potionNames[118] = "minecraft:long_night_vision"; ++ potionNames[119] = null; ++ potionNames[120] = "minecraft:long_weakness"; ++ potionNames[121] = "minecraft:strength"; ++ potionNames[122] = "minecraft:long_slowness"; ++ potionNames[123] = "minecraft:leaping"; ++ potionNames[124] = "minecraft:strong_harming"; ++ potionNames[125] = "minecraft:long_water_breathing"; ++ potionNames[126] = "minecraft:long_invisibility"; ++ potionNames[127] = null; ++ ++ // b[0] = 0; ++ // b[1] = 8193; ++ // b[2] = 8194; ++ // b[3] = 8195; ++ // b[4] = 8196; ++ // b[5] = 8197; ++ // b[6] = 8198; ++ // b[8] = 8200; ++ // b[9] = 8265; ++ // b[10] = 8202; ++ // b[11] = 8203; ++ // b[12] = 8204; ++ // b[13] = 8205; ++ // b[14] = 8206; ++ // b[16] = 8207; ++ // b[17] = 8193; ++ // b[18] = 8194; ++ // b[19] = 8195; ++ // b[20] = 8196; ++ // b[21] = 8197; ++ // b[22] = 8198; ++ // b[24] = 8200; ++ // b[25] = 8265; ++ // b[26] = 8202; ++ // b[27] = 8203; ++ // b[28] = 8204; ++ // b[29] = 8205; ++ // b[30] = 8206; ++ // b[32] = "minecraft:thick"; ++ // b[33] = 8225; ++ // b[34] = 8226; ++ // b[35] = 8195; ++ // b[36] = 8228; ++ // b[37] = 8229; ++ // b[38] = 8198; ++ // b[40] = 8200; ++ // b[41] = 8233; ++ // b[42] = 8202; ++ // b[43] = 8235; ++ // b[44] = 8236; ++ // b[45] = 8205; ++ // b[46] = 8206; ++ // b[49] = 8225; ++ // b[50] = 8226; ++ // b[51] = 8195; ++ // b[52] = 8228; ++ // b[53] = 8229; ++ // b[54] = 8198; ++ // b[56] = 8200; ++ // b[57] = 8233; ++ // b[58] = 8202; ++ // b[59] = 8235; ++ // b[60] = 8236; ++ // b[61] = 8205; ++ // b[62] = 8206; ++ // b[64] = "minecraft:mundane"; ++ // b[65] = 8257; ++ // b[66] = 8258; ++ // b[67] = 8259; ++ // b[68] = 8260; ++ // b[69] = 8197; ++ // b[70] = 8198; ++ // b[72] = 8264; ++ // b[73] = 8265; ++ // b[74] = 8266; ++ // b[75] = 8267; ++ // b[76] = 8204; ++ // b[77] = 8269; ++ // b[78] = 8270; ++ // b[80] = "minecraft:awkward"; ++ // b[81] = 8257; ++ // b[82] = 8258; ++ // b[83] = 8259; ++ // b[84] = 8260; ++ // b[85] = 8197; ++ // b[86] = 8198; ++ // b[88] = 8264; ++ // b[89] = 8265; ++ // b[90] = 8266; ++ // b[91] = 8267; ++ // b[92] = 8204; ++ // b[93] = 8269; ++ // b[94] = 8270; ++ // b[96] = "minecraft:thick"; ++ // b[97] = 8193; ++ // b[98] = 8194; ++ // b[99] = 8259; ++ // b[100] = 8196; ++ // b[101] = 8229; ++ // b[102] = 8198; ++ // b[104] = 8264; ++ // b[105] = 8265; ++ // b[106] = 8266; ++ // b[107] = 8203; ++ // b[108] = 8236; ++ // b[109] = 8269; ++ // b[110] = 8270; ++ // b[113] = 8193; ++ // b[114] = 8194; ++ // b[115] = 8259; ++ // b[116] = 8196; ++ // b[117] = 8229; ++ // b[118] = 8198; ++ // b[120] = 8264; ++ // b[121] = 8265; ++ // b[122] = 8266; ++ // b[123] = 8203; ++ // b[124] = 8236; ++ // b[125] = 8269; ++ // b[126] = 8270; ++ ++ try ++ { ++ Field field = EntityTypes.class.getDeclaredField("g"); ++ field.setAccessible(true); ++ entityTypes = (Map) field.get(null); ++ } ++ catch (Exception ex) ++ { ++ ex.printStackTrace(); ++ } ++ } ++} +diff --git a/src/main/java/com/mineplex/spigot/PacketProcessor.java b/src/main/java/com/mineplex/spigot/PacketProcessor.java +index 5695899..0fe6930 100644 +--- a/src/main/java/com/mineplex/spigot/PacketProcessor.java ++++ b/src/main/java/com/mineplex/spigot/PacketProcessor.java +@@ -35,6 +35,10 @@ import net.minecraft.server.PacketPlayInBlockPlace; + import net.minecraft.server.PacketPlayInSpectate; + import net.minecraft.server.PacketPlayInResourcePackStatus; + import net.minecraft.server.PacketPlayInArmAnimation; ++import net.minecraft.server.PacketPlayInLeftClick; ++import net.minecraft.server.PacketPlayInRightClick; ++import net.minecraft.server.PacketPlayInUnknownPosition; ++import net.minecraft.server.PacketPlayInUnknownFloats; + + public class PacketProcessor implements PacketListenerPlayIn, IUpdatePlayerListBox + { +@@ -93,13 +97,14 @@ public class PacketProcessor implements PacketListenerPlayIn, IUpdatePlayerListB + + public void processIncomingPacket(final Packet packet) + { +- if (!_listenedPackets.containsKey(packet.getClass())) ++ Boolean isMainThread = _listenedPackets.get(packet.getClass()); ++ if (isMainThread == null) + { + packet.a(_packetListener); + return; + } + +- if (!_packetListener.player.u().isMainThread() && _listenedPackets.get(packet.getClass())) ++ if (!_packetListener.player.u().isMainThread() && isMainThread) + { + _packetListener.player.u().postToMainThread(new Runnable() + { +@@ -243,8 +248,28 @@ public class PacketProcessor implements PacketListenerPlayIn, IUpdatePlayerListB + processIncomingPacket(packet); + } + ++ public void a(PacketPlayInUnknownFloats packet) ++ { ++ processIncomingPacket(packet); ++ } ++ ++ public void a(PacketPlayInUnknownPosition packet) ++ { ++ processIncomingPacket(packet); ++ } ++ + public void a(IChatBaseComponent packet) + { + _packetListener.a(packet); + } ++ ++ public void a(PacketPlayInLeftClick packet) ++ { ++ processIncomingPacket(packet); ++ } ++ ++ public void a(PacketPlayInRightClick packet) ++ { ++ processIncomingPacket(packet); ++ } + } +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/ChunkSection.java b/src/main/java/net/minecraft/server/ChunkSection.java +index f734ab0..3782abd 100644 +--- a/src/main/java/net/minecraft/server/ChunkSection.java ++++ b/src/main/java/net/minecraft/server/ChunkSection.java +@@ -1,5 +1,10 @@ + package net.minecraft.server; + ++import java.util.ArrayList; ++import org.apache.commons.lang3.Validate; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import com.mineplex.chunk.*; ++ + public class ChunkSection { + + private int yPos; +@@ -8,6 +13,10 @@ public class ChunkSection { + private char[] blockIds; + private NibbleArray emittedLight; + private NibbleArray skyLight; ++ private static LargeBlockPalette largePalette = new LargeBlockPalette(); ++ private BlockMap blockMap; ++ private int bitshift; ++ private BlockPalette blockPalette; + + public ChunkSection(int i, boolean flag) { + this.yPos = i; +@@ -17,6 +26,7 @@ public class ChunkSection { + this.skyLight = new NibbleArray(); + } + ++ setSize(4); + } + + // CraftBukkit start +@@ -27,10 +37,72 @@ public class ChunkSection { + if (flag) { + this.skyLight = new NibbleArray(); + } ++ setSize(4); + recalcBlockCounts(); + } + // CraftBukkit end + ++ public void setSize(int newBitShift) ++ { ++ if (newBitShift == this.bitshift) ++ { ++ return; ++ } ++ this.bitshift = newBitShift; ++ if (this.bitshift <= 4) ++ { ++ this.bitshift = 4; ++ this.blockPalette = new SmallBlockPalette(this.bitshift, this); ++ } ++ else if (this.bitshift <= 8) ++ { ++ this.blockPalette = new MediumBlockPalette(this.bitshift, this); ++ } ++ else ++ { ++ this.blockPalette = largePalette; ++ this.bitshift = MathHelper.e(Block.d.a()); ++ } ++ this.blockPalette.addGetIndex(Blocks.AIR.getBlockData()); ++ this.blockMap = new BlockMap(this.bitshift, 4096); ++ } ++ ++ public int resizePalette(int newBitShift, IBlockData aqt2) ++ { ++ BlockMap blockMap = this.blockMap; ++ BlockPalette blockPalette = this.blockPalette; ++ this.setSize(newBitShift); ++ for (int i2 = 0; i2 < blockMap.b(); ++i2) ++ { ++ IBlockData aqt3 = blockPalette.getBlock(blockMap.a(i2)); ++ if (aqt3 == null) ++ continue; ++ ++ // TODO Set data ++ this.setData(i2, aqt3); ++ } ++ // Return index ++ return this.blockPalette.addGetIndex(aqt2); ++ } ++ ++ public void writeSerializer(PacketDataSerializer em2) ++ { ++ em2.writeByte(this.bitshift); ++ this.blockPalette.writeSerializer(em2); ++ em2.b(blockMap.a().length); ++ for (long l : blockMap.a()) ++ { ++ em2.writeLong(l); ++ } ++ } ++ ++ // Get dataserializer size ++ public int getLength() ++ { ++ int n2 = this.blockMap.b(); ++ return 1 + this.blockPalette.getLength() + PacketDataSerializer.a(n2) + n2 * 8; ++ } ++ + public IBlockData getType(int i, int j, int k) { + IBlockData iblockdata = (IBlockData) Block.d.a(this.blockIds[j << 8 | k << 4 | i]); + +@@ -57,8 +129,22 @@ public class ChunkSection { + } + + this.blockIds[j << 8 | k << 4 | i] = (char) Block.d.b(iblockdata); ++ setData(i, j, k, iblockdata); ++ } ++ ++ public void setData(int x, int y, int z, IBlockData blockData) ++ { ++ int bitshift = y << 8 | z << 4 | x; ++ setData(bitshift, blockData); + } + ++ // Set block bitshift, iblockdata ++ protected void setData(int n2, IBlockData aqt2) ++ { ++ int n3 = this.blockPalette.addGetIndex(aqt2); ++ this.blockMap.a(n2, n3); ++ } ++ + public Block b(int i, int j, int k) { + return this.getType(i, j, k).getBlock(); + } +@@ -100,6 +186,7 @@ public class ChunkSection { + public void recalcBlockCounts() { + this.nonEmptyBlockCount = 0; + this.tickingBlockCount = 0; ++ setData(); + + for (int i = 0; i < 16; ++i) { + for (int j = 0; j < 16; ++j) { +@@ -122,8 +209,20 @@ public class ChunkSection { + return this.blockIds; + } + ++ private void setData() ++ { ++ for (int i = 0; i < 16; ++i) { ++ for (int j = 0; j < 16; ++j) { ++ for (int k = 0; k < 16; ++k) { ++ setData(i, j, k, getType(i, j, k)); ++ } ++ } ++ } ++ } ++ + public void a(char[] achar) { + this.blockIds = achar; ++ setData(); + } + + public NibbleArray getEmittedLightArray() { +diff --git a/src/main/java/net/minecraft/server/DataIndex.java b/src/main/java/net/minecraft/server/DataIndex.java +new file mode 100644 +index 0000000..1e9db13 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/DataIndex.java +@@ -0,0 +1,42 @@ ++package net.minecraft.server; ++ ++public class DataIndex ++{ ++ private final int a; ++ private final DataTypeInferface b; ++ ++ public DataIndex(int n2, DataTypeInferface kf2) ++ { ++ this.a = n2; ++ this.b = kf2; ++ } ++ ++ public int a() ++ { ++ return this.a; ++ } ++ ++ public DataTypeInferface b() ++ { ++ return this.b; ++ } ++ ++ public boolean equals(Object object) ++ { ++ if (this == object) ++ { ++ return true; ++ } ++ if (object == null || this.getClass() != object.getClass()) ++ { ++ return false; ++ } ++ DataIndex ke2 = (DataIndex) object; ++ return this.a == ke2.a; ++ } ++ ++ public int hashCode() ++ { ++ return this.a; ++ } ++} +diff --git a/src/main/java/net/minecraft/server/DataType.java b/src/main/java/net/minecraft/server/DataType.java +new file mode 100644 +index 0000000..a8c317d +--- /dev/null ++++ b/src/main/java/net/minecraft/server/DataType.java +@@ -0,0 +1,265 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++import java.util.UUID; ++ ++import com.google.common.base.Optional; ++import com.mineplex.chunk.PaletteMediumList; ++ ++public class DataType ++{ ++ private static final PaletteMediumList> dataTypes = new PaletteMediumList>(16); ++ ++ public static final DataTypeInferface BYTE = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Byte by) ++ { ++ em2.writeByte(by.byteValue()); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface INTEGER = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Integer n2) ++ { ++ em2.b(n2); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface FLOAT = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Float f2) ++ { ++ em2.writeFloat(f2.floatValue()); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface STRING = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, String string) ++ { ++ em2.a(string); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface ICHATBASECOMPONENT = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, IChatBaseComponent eu2) ++ { ++ try ++ { ++ em2.a(eu2); ++ } ++ catch (IOException e) ++ { ++ e.printStackTrace(); ++ } ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface> OPT_ITEMSTACK = new DataTypeInferface>() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Optional optional) ++ { ++ em2.a(optional.orNull()); ++ } ++ ++ @Override ++ public DataIndex> fromIndex(int n2) ++ { ++ return new DataIndex>(n2, this); ++ } ++ }; ++ public static final DataTypeInferface> OPT_IBLOCKDATA = new DataTypeInferface>() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Optional optional) ++ { ++ if (optional.isPresent()) ++ { ++ em2.b(Block.getCombinedId(optional.get())); ++ } ++ else ++ { ++ em2.b(0); ++ } ++ } ++ ++ @Override ++ public DataIndex> fromIndex(int n2) ++ { ++ return new DataIndex>(n2, this); ++ } ++ }; ++ public static final DataTypeInferface BOOLEAN = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Boolean bl2) ++ { ++ em2.writeBoolean(bl2); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface VECTOR3F = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Vector3f dc2) ++ { ++ em2.writeFloat(dc2.getX()); ++ em2.writeFloat(dc2.getY()); ++ em2.writeFloat(dc2.getZ()); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface BLOCKPOSITION = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, BlockPosition cj2) ++ { ++ em2.a(cj2); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface> OPT_BLOCKPOSITION = new DataTypeInferface>() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Optional optional) ++ { ++ em2.writeBoolean(optional.isPresent()); ++ if (optional.isPresent()) ++ { ++ em2.a(optional.get()); ++ } ++ } ++ ++ @Override ++ public DataIndex> fromIndex(int n2) ++ { ++ return new DataIndex>(n2, this); ++ } ++ }; ++ public static final DataTypeInferface ENUM_DIRECTION = new DataTypeInferface() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, EnumDirection cq2) ++ { ++ em2.a(cq2); ++ } ++ ++ @Override ++ public DataIndex fromIndex(int n2) ++ { ++ return new DataIndex(n2, this); ++ } ++ }; ++ public static final DataTypeInferface> OPT_UUID = new DataTypeInferface>() ++ { ++ ++ @Override ++ public void write(PacketDataSerializer em2, Optional optional) ++ { ++ em2.writeBoolean(optional.isPresent()); ++ if (optional.isPresent()) ++ { ++ em2.a(optional.get()); ++ } ++ } ++ ++ @Override ++ public DataIndex> fromIndex(int n2) ++ { ++ return new DataIndex>(n2, this); ++ } ++ }; ++ ++ public static void a(DataTypeInferface kf2) ++ { ++ dataTypes.c(kf2); ++ } ++ ++ public static DataTypeInferface a(int n2) ++ { ++ return dataTypes.get(n2); ++ } ++ ++ public static int b(DataTypeInferface kf2) ++ { ++ return dataTypes.a(kf2); ++ } ++ ++ static ++ { ++ DataType.a(BYTE); ++ DataType.a(INTEGER); ++ DataType.a(FLOAT); ++ DataType.a(STRING); ++ DataType.a(ICHATBASECOMPONENT); ++ DataType.a(OPT_ITEMSTACK); ++ DataType.a(BOOLEAN); ++ DataType.a(VECTOR3F); ++ DataType.a(BLOCKPOSITION); ++ DataType.a(OPT_BLOCKPOSITION); ++ DataType.a(ENUM_DIRECTION); ++ DataType.a(OPT_UUID); ++ DataType.a(OPT_IBLOCKDATA); ++ } ++ ++} +diff --git a/src/main/java/net/minecraft/server/DataTypeInferface.java b/src/main/java/net/minecraft/server/DataTypeInferface.java +new file mode 100644 +index 0000000..36c2eb7 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/DataTypeInferface.java +@@ -0,0 +1,8 @@ ++package net.minecraft.server; ++ ++public interface DataTypeInferface ++{ ++ public void write(PacketDataSerializer var1, T var2); ++ ++ public DataIndex fromIndex(int var1); ++} +diff --git a/src/main/java/net/minecraft/server/DataWatcher.java b/src/main/java/net/minecraft/server/DataWatcher.java +index dec091e..9e351b1 100644 +--- a/src/main/java/net/minecraft/server/DataWatcher.java ++++ b/src/main/java/net/minecraft/server/DataWatcher.java +@@ -10,6 +10,7 @@ import java.util.Map; + import java.util.concurrent.locks.ReadWriteLock; + import java.util.concurrent.locks.ReentrantReadWriteLock; + import org.apache.commons.lang3.ObjectUtils; ++import com.google.common.base.Optional; + + public class DataWatcher { + +@@ -24,12 +25,41 @@ public class DataWatcher { + // Spigot End + private boolean e; + private ReadWriteLock f = new ReentrantReadWriteLock(); ++ private static final Map, Integer> dataTypes = Maps.newHashMap(); + + public DataWatcher(Entity entity) { + this.a = entity; + } + +- public void a(int i, T t0) { ++ public static DataIndex getIndex(Class class_, DataTypeInferface kf2) ++ { ++ int n2; ++ if (dataTypes.containsKey(class_)) ++ { ++ n2 = dataTypes.get(class_) + 1; ++ } ++ else ++ { ++ int n3 = 0; ++ Class class_2 = class_; ++ while (class_2 != Entity.class) ++ { ++ if (!dataTypes.containsKey(class_2 = (Class) class_2.getSuperclass())) ++ continue; ++ n3 = dataTypes.get(class_2) + 1; ++ break; ++ } ++ n2 = n3; ++ } ++ if (n2 > 254) ++ { ++ throw new IllegalArgumentException("Data value id is too big with " + n2 + "! (Max is " + 254 + ")"); ++ } ++ dataTypes.put(class_, n2); ++ return kf2.fromIndex(n2); ++ } ++ ++ public void a(int i, T t0, DataIndex index, Y newValue) { + int integer = classToId.get(t0.getClass()); // Spigot + + if (integer == -1) { // Spigot +@@ -39,7 +69,7 @@ public class DataWatcher { + } else if (this.dataValues.containsKey(i)) { // Spigot + throw new IllegalArgumentException("Duplicate id value for " + i + "!"); + } else { +- DataWatcher.WatchableObject datawatcher_watchableobject = new DataWatcher.WatchableObject(integer, i, t0); // Spigot ++ DataWatcher.WatchableObject datawatcher_watchableobject = new DataWatcher.WatchableObject(integer, i, t0, index, newValue); // Spigot + + this.f.writeLock().lock(); + this.dataValues.put(i, datawatcher_watchableobject); // Spigot +@@ -48,8 +78,8 @@ public class DataWatcher { + } + } + +- public void add(int i, int j) { +- DataWatcher.WatchableObject datawatcher_watchableobject = new DataWatcher.WatchableObject(j, i, (Object) null); ++ public void add(int i, int j, DataIndex index, Y newValue) { ++ DataWatcher.WatchableObject datawatcher_watchableobject = new DataWatcher.WatchableObject(j, i, (Object) null, index, newValue); + + this.f.writeLock().lock(); + this.dataValues.put(i, datawatcher_watchableobject); // Spigot +@@ -104,11 +134,12 @@ public class DataWatcher { + return (Vector3f) this.j(i).b(); + } + +- public void watch(int i, T t0) { ++ public void watch(int i, T t0, DataIndex index, Y newValue) { + DataWatcher.WatchableObject datawatcher_watchableobject = this.j(i); + +- if (ObjectUtils.notEqual(t0, datawatcher_watchableobject.b())) { +- datawatcher_watchableobject.a(t0); ++ if (ObjectUtils.notEqual(t0, datawatcher_watchableobject.b()) || ObjectUtils.notEqual(newValue, datawatcher_watchableobject.getValue())) ++ { ++ datawatcher_watchableobject.a(t0, newValue); + this.a.i(i); + datawatcher_watchableobject.a(true); + this.e = true; +@@ -136,7 +167,10 @@ public class DataWatcher { + } + } + +- packetdataserializer.writeByte(127); ++ if (packetdataserializer.version == 47) ++ packetdataserializer.writeByte(127); ++ else ++ packetdataserializer.writeByte(255); + } + + public List b() { +@@ -162,6 +196,7 @@ public class DataWatcher { + datawatcher_watchableobject.c(), + datawatcher_watchableobject.a(), + ( (ItemStack) datawatcher_watchableobject.b() ).cloneItemStack() ++ , datawatcher_watchableobject.getIndex(), datawatcher_watchableobject.getValue() + ); + } + // Spigot end +@@ -188,7 +223,10 @@ public class DataWatcher { + } + + this.f.readLock().unlock(); +- packetdataserializer.writeByte(127); ++ if (packetdataserializer.version == 47) ++ packetdataserializer.writeByte(127); ++ else ++ packetdataserializer.writeByte(255); + } + + public List c() { +@@ -203,10 +241,20 @@ public class DataWatcher { + WatchableObject watchableobject = (WatchableObject) arraylist.get( i ); + if ( watchableobject.b() instanceof ItemStack ) + { ++ ItemStack itemStack = ( (ItemStack) watchableobject.b() ).cloneItemStack(); ++ Object obj2 = watchableobject.getValue(); ++ ++ if (watchableobject.getValue() instanceof ItemStack) ++ { ++ obj2 = ( (ItemStack) watchableobject.getValue() ).cloneItemStack(); ++ } ++ else if (watchableobject.getValue() instanceof Optional && ((Optional) watchableobject.getValue()).get() instanceof ItemStack) ++ { ++ obj2 = Optional.of(((Optional) watchableobject.getValue()).get().cloneItemStack()); ++ } + watchableobject = new WatchableObject( + watchableobject.c(), +- watchableobject.a(), +- ( (ItemStack) watchableobject.b() ).cloneItemStack() ++ watchableobject.a(), itemStack, watchableobject.getIndex(), obj2 + ); + arraylist.set( i, watchableobject ); + } +@@ -218,6 +266,23 @@ public class DataWatcher { + } + + private static void a(PacketDataSerializer packetdataserializer, DataWatcher.WatchableObject datawatcher_watchableobject) throws IOException { ++ if (packetdataserializer.version != 47) ++ { ++ DataIndex ke2 = datawatcher_watchableobject.getIndex(); ++ int n2 = DataType.b(ke2.b()); ++ if (n2 < 0) ++ { ++ throw new IllegalArgumentException("Unknown serializer type " + ke2.b()); ++ } ++ packetdataserializer.writeByte(ke2.a()); ++ packetdataserializer.b(n2); ++ ke2.b().write(packetdataserializer, datawatcher_watchableobject.getValue()); ++ return; ++ } ++ ++ if (datawatcher_watchableobject.a() < 0) ++ return; ++ + int i = (datawatcher_watchableobject.c() << 5 | datawatcher_watchableobject.a() & 31) & 255; + + packetdataserializer.writeByte(i); +@@ -269,7 +334,7 @@ public class DataWatcher { + public static List b(PacketDataSerializer packetdataserializer) throws IOException { + ArrayList arraylist = null; + +- for (byte b0 = packetdataserializer.readByte(); b0 != 127; b0 = packetdataserializer.readByte()) { ++ /*for (byte b0 = packetdataserializer.readByte(); b0 != 127; b0 = packetdataserializer.readByte()) { + if (arraylist == null) { + arraylist = Lists.newArrayList(); + } +@@ -320,7 +385,7 @@ public class DataWatcher { + } + + arraylist.add(datawatcher_watchableobject); +- } ++ }*/ + + return arraylist; + } +@@ -346,26 +411,41 @@ public class DataWatcher { + // Spigot End + } + +- public static class WatchableObject { ++ public static class WatchableObject { + + private final int a; + private final int b; + private Object c; + private boolean d; ++ private DataIndex index; ++ private Y value; + +- public WatchableObject(int i, int j, Object object) { +- this.b = j; ++ public WatchableObject(int type, int oldIndex, Object object, DataIndex index, Y newValue) { ++ this.b = oldIndex; + this.c = object; +- this.a = i; ++ this.a = type; + this.d = true; ++ this.index = index; ++ this.value = newValue; + } + + public int a() { + return this.b; + } + +- public void a(Object object) { ++ public DataIndex getIndex() ++ { ++ return this.index; ++ } ++ ++ public void a(Object object, Y newValue) { + this.c = object; ++ this.value = newValue; ++ } ++ ++ public Y getValue() ++ { ++ return value; + } + + public Object b() { +diff --git a/src/main/java/net/minecraft/server/Entity.java b/src/main/java/net/minecraft/server/Entity.java +index 7165579..96d9312 100644 +--- a/src/main/java/net/minecraft/server/Entity.java ++++ b/src/main/java/net/minecraft/server/Entity.java +@@ -128,6 +128,12 @@ public abstract class Entity implements ICommandListener { + public boolean fromMobSpawner; + public void inactiveTick() { } + // Spigot end ++ ++ public static DataIndex META_ENTITYDATA = DataWatcher.getIndex(Entity.class, DataType.BYTE); ++ public static DataIndex META_AIR = DataWatcher.getIndex(Entity.class, DataType.INTEGER); ++ public static DataIndex META_CUSTOMNAME = DataWatcher.getIndex(Entity.class, DataType.STRING); ++ public static DataIndex META_CUSTOMNAME_VISIBLE = DataWatcher.getIndex(Entity.class, DataType.BOOLEAN); ++ public static DataIndex META_SILENT = DataWatcher.getIndex(Entity.class, DataType.BOOLEAN); + + public int getId() { + return this.id; +@@ -201,11 +207,11 @@ public abstract class Entity implements ICommandListener { + // Spigot end + + this.datawatcher = new DataWatcher(this); +- this.datawatcher.a(0, Byte.valueOf((byte) 0)); +- this.datawatcher.a(1, Short.valueOf((short) 300)); +- this.datawatcher.a(3, Byte.valueOf((byte) 0)); +- this.datawatcher.a(2, ""); +- this.datawatcher.a(4, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(0, Byte.valueOf((byte) 0), META_ENTITYDATA, (byte) 0); ++ this.datawatcher.a(1, Short.valueOf((short) 300), META_AIR, 300); ++ this.datawatcher.a(3, Byte.valueOf((byte) 0), META_CUSTOMNAME_VISIBLE, false); ++ this.datawatcher.a(2, "", META_CUSTOMNAME, ""); ++ this.datawatcher.a(4, Byte.valueOf((byte) 0), META_SILENT, false); + this.h(); + } + +@@ -839,7 +845,7 @@ public abstract class Entity implements ICommandListener { + } + + public void b(boolean flag) { +- this.datawatcher.watch(4, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.datawatcher.watch(4, Byte.valueOf((byte) (flag ? 1 : 0)), META_SILENT, flag); + } + + protected boolean s_() { +@@ -1612,11 +1618,13 @@ public abstract class Entity implements ICommandListener { + EntityDismountEvent exitEvent1 = null; + if (this.vehicle != null) { + if ((this.bukkitEntity instanceof LivingEntity) && (entity.getBukkitEntity() instanceof Vehicle)) ++ { + exitEvent = new VehicleExitEvent((Vehicle) this.vehicle.getBukkitEntity(), (LivingEntity) this.bukkitEntity); +- pluginManager.callEvent(exitEvent); ++ pluginManager.callEvent(exitEvent); + +- if (exitEvent.isCancelled() || this.vehicle != originalVehicle || (this.vehicle != null && this.vehicle.passenger != originalPassenger)) { +- return; ++ if (exitEvent.isCancelled() || this.vehicle != originalVehicle || (this.vehicle != null && this.vehicle.passenger != originalPassenger)) { ++ return; ++ } + } + + exitEvent1 = new EntityDismountEvent(this.vehicle.getBukkitEntity(), this.bukkitEntity); +@@ -1748,9 +1756,9 @@ public abstract class Entity implements ICommandListener { + byte b0 = this.datawatcher.getByte(0); + + if (flag) { +- this.datawatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << i))); ++ this.datawatcher.watch(0, Byte.valueOf((byte) (b0 | 1 << i)), META_ENTITYDATA, (byte) (b0 | 1 << i)); + } else { +- this.datawatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << i)))); ++ this.datawatcher.watch(0, Byte.valueOf((byte) (b0 & ~(1 << i))), META_ENTITYDATA, (byte) (b0 & ~(1 << i))); + } + + } +@@ -1760,7 +1768,7 @@ public abstract class Entity implements ICommandListener { + } + + public void setAirTicks(int i) { +- this.datawatcher.watch(1, Short.valueOf((short) i)); ++ this.datawatcher.watch(1, Short.valueOf((short) i), META_AIR, i); + } + + public void onLightningStrike(EntityLightning entitylightning) { +@@ -2123,7 +2131,7 @@ public abstract class Entity implements ICommandListener { + s = s.substring(0, 256); + } + // CraftBukkit end +- this.datawatcher.watch(2, s); ++ this.datawatcher.watch(2, s, META_CUSTOMNAME, s); + } + + public String getCustomName() { +@@ -2135,7 +2143,7 @@ public abstract class Entity implements ICommandListener { + } + + public void setCustomNameVisible(boolean flag) { +- this.datawatcher.watch(3, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.datawatcher.watch(3, Byte.valueOf((byte) (flag ? 1 : 0)), META_CUSTOMNAME_VISIBLE, flag); + } + + public boolean getCustomNameVisible() { +diff --git a/src/main/java/net/minecraft/server/EntityAgeable.java b/src/main/java/net/minecraft/server/EntityAgeable.java +index 09d4335..5359cc1 100644 +--- a/src/main/java/net/minecraft/server/EntityAgeable.java ++++ b/src/main/java/net/minecraft/server/EntityAgeable.java +@@ -1,5 +1,8 @@ + package net.minecraft.server; + ++import com.google.common.base.Optional; ++import java.util.UUID; ++ + public abstract class EntityAgeable extends EntityCreature { + + protected int a; +@@ -8,7 +11,8 @@ public abstract class EntityAgeable extends EntityCreature { + private float bm = -1.0F; + private float bn; + public boolean ageLocked = false; // CraftBukkit +- ++ public static DataIndex META_BABY = DataWatcher.getIndex(EntityAgeable.class, DataType.BOOLEAN); ++ + // Spigot start + @Override + public void inactiveTick() +@@ -76,7 +80,7 @@ public abstract class EntityAgeable extends EntityCreature { + + protected void h() { + super.h(); +- this.datawatcher.a(12, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(12, Byte.valueOf((byte) 0), META_BABY, false); + } + + public int getAge() { +@@ -116,7 +120,7 @@ public abstract class EntityAgeable extends EntityCreature { + } + + public void setAgeRaw(int i) { +- this.datawatcher.watch(12, Byte.valueOf((byte) MathHelper.clamp(i, -1, 1))); ++ this.datawatcher.watch(12, Byte.valueOf((byte) MathHelper.clamp(i, -1, 1)), META_BABY, i < 0); + this.a = i; + this.a(this.isBaby()); + } +diff --git a/src/main/java/net/minecraft/server/EntityArmorStand.java b/src/main/java/net/minecraft/server/EntityArmorStand.java +index cd57d69..3957d4d 100644 +--- a/src/main/java/net/minecraft/server/EntityArmorStand.java ++++ b/src/main/java/net/minecraft/server/EntityArmorStand.java +@@ -30,6 +30,13 @@ public class EntityArmorStand extends EntityLiving { + public Vector3f rightArmPose; + public Vector3f leftLegPose; + public Vector3f rightLegPose; ++ public static DataIndex META_ARMOR_OPTION = DataWatcher.getIndex(EntityArmorStand.class, DataType.BYTE); ++ public static DataIndex META_HEAD_POSE = DataWatcher.getIndex(EntityArmorStand.class, DataType.VECTOR3F); ++ public static DataIndex META_BODY_POSE = DataWatcher.getIndex(EntityArmorStand.class, DataType.VECTOR3F); ++ public static DataIndex META_LEFT_ARM_POSE = DataWatcher.getIndex(EntityArmorStand.class, DataType.VECTOR3F); ++ public static DataIndex META_RIGHT_ARM_POSE = DataWatcher.getIndex(EntityArmorStand.class, DataType.VECTOR3F); ++ public static DataIndex META_LEFT_LEG_POSE = DataWatcher.getIndex(EntityArmorStand.class, DataType.VECTOR3F); ++ public static DataIndex META_RIGHT_LEG_POSE = DataWatcher.getIndex(EntityArmorStand.class, DataType.VECTOR3F); + + public EntityArmorStand(World world) { + super(world); +@@ -56,13 +63,13 @@ public class EntityArmorStand extends EntityLiving { + + protected void h() { + super.h(); +- this.datawatcher.a(10, Byte.valueOf((byte) 0)); +- this.datawatcher.a(11, EntityArmorStand.a); +- this.datawatcher.a(12, EntityArmorStand.b); +- this.datawatcher.a(13, EntityArmorStand.c); +- this.datawatcher.a(14, EntityArmorStand.d); +- this.datawatcher.a(15, EntityArmorStand.e); +- this.datawatcher.a(16, EntityArmorStand.f); ++ this.datawatcher.a(10, Byte.valueOf((byte) 0), META_ARMOR_OPTION, (byte) 0); ++ this.datawatcher.a(11, EntityArmorStand.a, META_HEAD_POSE, EntityArmorStand.a); ++ this.datawatcher.a(12, EntityArmorStand.b, META_BODY_POSE, EntityArmorStand.a); ++ this.datawatcher.a(13, EntityArmorStand.c, META_LEFT_ARM_POSE, EntityArmorStand.a); ++ this.datawatcher.a(14, EntityArmorStand.d, META_RIGHT_ARM_POSE, EntityArmorStand.a); ++ this.datawatcher.a(15, EntityArmorStand.e, META_LEFT_LEG_POSE, EntityArmorStand.a); ++ this.datawatcher.a(16, EntityArmorStand.f, META_RIGHT_LEG_POSE, EntityArmorStand.a); + } + + public ItemStack bA() { +@@ -591,7 +598,7 @@ public class EntityArmorStand extends EntityLiving { + b0 &= -2; + } + +- this.datawatcher.watch(10, Byte.valueOf(b0)); ++ this.datawatcher.watch(10, Byte.valueOf(b0), META_ARMOR_OPTION, b0); + } + + public boolean isSmall() { +@@ -607,7 +614,7 @@ public class EntityArmorStand extends EntityLiving { + b0 &= -3; + } + +- this.datawatcher.watch(10, Byte.valueOf(b0)); ++ this.datawatcher.watch(10, Byte.valueOf(b0), META_ARMOR_OPTION, b0); + } + + public boolean hasGravity() { +@@ -623,7 +630,7 @@ public class EntityArmorStand extends EntityLiving { + b0 &= -5; + } + +- this.datawatcher.watch(10, Byte.valueOf(b0)); ++ this.datawatcher.watch(10, Byte.valueOf(b0), META_ARMOR_OPTION, b0); + } + + public boolean hasArms() { +@@ -639,7 +646,7 @@ public class EntityArmorStand extends EntityLiving { + b0 &= -9; + } + +- this.datawatcher.watch(10, Byte.valueOf(b0)); ++ this.datawatcher.watch(10, Byte.valueOf(b0), META_ARMOR_OPTION, b0); + } + + public boolean hasBasePlate() { +@@ -656,7 +663,7 @@ public class EntityArmorStand extends EntityLiving { + b0 &= -17; + } + +- this.datawatcher.watch(10, Byte.valueOf(b0)); ++ this.datawatcher.watch(10, Byte.valueOf(b0), META_ARMOR_OPTION, b0); + } + + // PAIL +@@ -666,32 +673,32 @@ public class EntityArmorStand extends EntityLiving { + + public void setHeadPose(Vector3f vector3f) { + this.headPose = vector3f; +- this.datawatcher.watch(11, vector3f); ++ this.datawatcher.watch(11, vector3f, META_HEAD_POSE, vector3f); + } + + public void setBodyPose(Vector3f vector3f) { + this.bodyPose = vector3f; +- this.datawatcher.watch(12, vector3f); ++ this.datawatcher.watch(12, vector3f, META_BODY_POSE, vector3f); + } + + public void setLeftArmPose(Vector3f vector3f) { + this.leftArmPose = vector3f; +- this.datawatcher.watch(13, vector3f); ++ this.datawatcher.watch(13, vector3f, META_LEFT_ARM_POSE, vector3f); + } + + public void setRightArmPose(Vector3f vector3f) { + this.rightArmPose = vector3f; +- this.datawatcher.watch(14, vector3f); ++ this.datawatcher.watch(14, vector3f, META_RIGHT_ARM_POSE, vector3f); + } + + public void setLeftLegPose(Vector3f vector3f) { + this.leftLegPose = vector3f; +- this.datawatcher.watch(15, vector3f); ++ this.datawatcher.watch(15, vector3f, META_LEFT_LEG_POSE, vector3f); + } + + public void setRightLegPose(Vector3f vector3f) { + this.rightLegPose = vector3f; +- this.datawatcher.watch(16, vector3f); ++ this.datawatcher.watch(16, vector3f, META_RIGHT_LEG_POSE, vector3f); + } + + public Vector3f t() { +diff --git a/src/main/java/net/minecraft/server/EntityArrow.java b/src/main/java/net/minecraft/server/EntityArrow.java +index 3a80776..11bcdbc 100644 +--- a/src/main/java/net/minecraft/server/EntityArrow.java ++++ b/src/main/java/net/minecraft/server/EntityArrow.java +@@ -23,6 +23,7 @@ public class EntityArrow extends Entity implements IProjectile { + private int as; + private double damage = 2.0D; + public int knockbackStrength; ++ public static DataIndex META_CRITICAL = DataWatcher.getIndex(EntityArrow.class, DataType.BYTE); + + // Spigot Start + @Override +@@ -99,7 +100,7 @@ public class EntityArrow extends Entity implements IProjectile { + } + + protected void h() { +- this.datawatcher.a(16, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(16, Byte.valueOf((byte) 0), META_CRITICAL, (byte) 0); + } + + public void shoot(double d0, double d1, double d2, float f, float f1) { +@@ -468,9 +469,9 @@ public class EntityArrow extends Entity implements IProjectile { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1)), META_CRITICAL, (byte) (b0 | 1)); + } else { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2)), META_CRITICAL, (byte) (b0 | 1)); + } + + } +diff --git a/src/main/java/net/minecraft/server/EntityBat.java b/src/main/java/net/minecraft/server/EntityBat.java +index c078fa6..addf413 100644 +--- a/src/main/java/net/minecraft/server/EntityBat.java ++++ b/src/main/java/net/minecraft/server/EntityBat.java +@@ -6,6 +6,7 @@ public class EntityBat extends EntityAmbient { + + private BlockPosition a; + private boolean _vegetated; ++ public static DataIndex META_UPSIDEDOWN = DataWatcher.getIndex(EntityBat.class, DataType.BYTE); + + public EntityBat(World world) { + super(world); +@@ -25,7 +26,7 @@ public class EntityBat extends EntityAmbient { + + protected void h() { + super.h(); +- this.datawatcher.a(16, new Byte((byte) 0)); ++ this.datawatcher.a(16, new Byte((byte) 0), META_UPSIDEDOWN, (byte) 0); + } + + protected float bB() { +@@ -70,9 +71,9 @@ public class EntityBat extends EntityAmbient { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1)), META_UPSIDEDOWN, Byte.valueOf((byte) (b0 | 1))); + } else { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2)), META_UPSIDEDOWN, Byte.valueOf((byte) (b0 & -2))); + } + + } +@@ -169,7 +170,7 @@ public class EntityBat extends EntityAmbient { + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); +- this.datawatcher.watch(16, Byte.valueOf(nbttagcompound.getByte("BatFlags"))); ++ this.datawatcher.watch(16, Byte.valueOf(nbttagcompound.getByte("BatFlags")), META_UPSIDEDOWN, Byte.valueOf(nbttagcompound.getByte("BatFlags"))); + } + + public void b(NBTTagCompound nbttagcompound) { +diff --git a/src/main/java/net/minecraft/server/EntityBlaze.java b/src/main/java/net/minecraft/server/EntityBlaze.java +index a759e00..b596e3c 100644 +--- a/src/main/java/net/minecraft/server/EntityBlaze.java ++++ b/src/main/java/net/minecraft/server/EntityBlaze.java +@@ -4,6 +4,7 @@ public class EntityBlaze extends EntityMonster { + + private float a = 0.5F; + private int b; ++ public static DataIndex META_FIRE = DataWatcher.getIndex(EntityBlaze.class, DataType.BYTE); + + public EntityBlaze(World world) { + super(world); +@@ -27,7 +28,7 @@ public class EntityBlaze extends EntityMonster { + + protected void h() { + super.h(); +- this.datawatcher.a(16, new Byte((byte) 0)); ++ this.datawatcher.a(16, new Byte((byte) 0), META_FIRE, (byte) 0); + } + + protected String z() { +@@ -119,7 +120,7 @@ public class EntityBlaze extends EntityMonster { + b0 &= -2; + } + +- this.datawatcher.watch(16, Byte.valueOf(b0)); ++ this.datawatcher.watch(16, Byte.valueOf(b0), META_FIRE, b0); + } + + protected boolean n_() { +diff --git a/src/main/java/net/minecraft/server/EntityBoat.java b/src/main/java/net/minecraft/server/EntityBoat.java +index f6a43c0..a9ddd00 100644 +--- a/src/main/java/net/minecraft/server/EntityBoat.java ++++ b/src/main/java/net/minecraft/server/EntityBoat.java +@@ -29,6 +29,11 @@ public class EntityBoat extends Entity { + public double unoccupiedDeceleration = -1; + public boolean landBoats = false; + ++ public static DataIndex META_TIME_SINCE_HIT = DataWatcher.getIndex(EntityBoat.class, DataType.INTEGER); ++ public static DataIndex META_FORWARD_DIRECTION = DataWatcher.getIndex(EntityBoat.class, DataType.INTEGER); ++ public static DataIndex META_DAMAGE_TAKEN = DataWatcher.getIndex(EntityBoat.class, DataType.FLOAT); ++ public static DataIndex META_UNKNOWN_INTEGER = DataWatcher.getIndex(EntityBoat.class, DataType.INTEGER); ++ public static DataIndex[] META_UNKNOWN_FLOATS = new DataIndex[] { DataWatcher.getIndex(EntityBoat.class, DataType.FLOAT), DataWatcher.getIndex(EntityBoat.class, DataType.FLOAT), DataWatcher.getIndex(EntityBoat.class, DataType.FLOAT)}; + @Override + public void collide(Entity entity) { + org.bukkit.entity.Entity hitEntity = (entity == null) ? null : entity.getBukkitEntity(); +@@ -57,9 +62,14 @@ public class EntityBoat extends Entity { + } + + protected void h() { +- this.datawatcher.a(17, new Integer(0)); +- this.datawatcher.a(18, new Integer(1)); +- this.datawatcher.a(19, new Float(0.0F)); ++ this.datawatcher.a(17, new Integer(0), META_TIME_SINCE_HIT, 0); ++ this.datawatcher.a(18, new Integer(1), META_FORWARD_DIRECTION, 1); ++ this.datawatcher.a(19, new Float(0.0F), META_DAMAGE_TAKEN, 0F); ++ this.datawatcher.a(-10, 0, META_UNKNOWN_INTEGER, 0); ++ for (int i=0; i<3; i++) ++ { ++ this.datawatcher.a(-15 + i, 0F, META_UNKNOWN_FLOATS[i], 0F); ++ } + } + + public AxisAlignedBB j(Entity entity) { +@@ -473,7 +483,7 @@ public class EntityBoat extends Entity { + } + + public void setDamage(float f) { +- this.datawatcher.watch(19, Float.valueOf(f)); ++ this.datawatcher.watch(19, Float.valueOf(f), META_DAMAGE_TAKEN, f); + } + + public float j() { +@@ -481,7 +491,7 @@ public class EntityBoat extends Entity { + } + + public void a(int i) { +- this.datawatcher.watch(17, Integer.valueOf(i)); ++ this.datawatcher.watch(17, Integer.valueOf(i), META_TIME_SINCE_HIT, i); + } + + public int l() { +@@ -489,7 +499,7 @@ public class EntityBoat extends Entity { + } + + public void b(int i) { +- this.datawatcher.watch(18, Integer.valueOf(i)); ++ this.datawatcher.watch(18, Integer.valueOf(i), META_FORWARD_DIRECTION, i); + } + + public int m() { +diff --git a/src/main/java/net/minecraft/server/EntityCreeper.java b/src/main/java/net/minecraft/server/EntityCreeper.java +index fecf94d..6ac9be8 100644 +--- a/src/main/java/net/minecraft/server/EntityCreeper.java ++++ b/src/main/java/net/minecraft/server/EntityCreeper.java +@@ -13,6 +13,9 @@ public class EntityCreeper extends EntityMonster { + private int explosionRadius = 3; + private int bn = 0; + private int record = -1; // CraftBukkit ++ public static DataIndex META_FUSE_STATE = DataWatcher.getIndex(EntityCreeper.class, DataType.INTEGER); ++ public static DataIndex META_POWERED = DataWatcher.getIndex(EntityCreeper.class, DataType.BOOLEAN); ++ public static DataIndex META_IGNITED = DataWatcher.getIndex(EntityCreeper.class, DataType.BOOLEAN); + + public EntityCreeper(World world) { + super(world); +@@ -47,9 +50,9 @@ public class EntityCreeper extends EntityMonster { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Byte.valueOf((byte) -1)); +- this.datawatcher.a(17, Byte.valueOf((byte) 0)); +- this.datawatcher.a(18, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(16, Byte.valueOf((byte) -1), META_FUSE_STATE, -1); ++ this.datawatcher.a(17, Byte.valueOf((byte) 0), META_POWERED, false); ++ this.datawatcher.a(18, Byte.valueOf((byte) 0), META_IGNITED, false); + } + + public void b(NBTTagCompound nbttagcompound) { +@@ -65,7 +68,7 @@ public class EntityCreeper extends EntityMonster { + + public void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); +- this.datawatcher.watch(17, Byte.valueOf((byte) (nbttagcompound.getBoolean("powered") ? 1 : 0))); ++ this.datawatcher.watch(17, Byte.valueOf((byte) (nbttagcompound.getBoolean("powered") ? 1 : 0)), META_POWERED, nbttagcompound.getBoolean("powered")); + if (nbttagcompound.hasKeyOfType("Fuse", 99)) { + this.maxFuseTicks = nbttagcompound.getShort("Fuse"); + } +@@ -167,7 +170,7 @@ public class EntityCreeper extends EntityMonster { + } + + public void a(int i) { +- this.datawatcher.watch(16, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(16, Byte.valueOf((byte) i), META_FUSE_STATE, i); + } + + public void onLightningStrike(EntityLightning entitylightning) { +@@ -182,9 +185,9 @@ public class EntityCreeper extends EntityMonster { + + public void setPowered(boolean powered) { + if (!powered) { +- this.datawatcher.watch(17, Byte.valueOf((byte) 0)); ++ this.datawatcher.watch(17, Byte.valueOf((byte) 0), META_POWERED, powered); + } else { +- this.datawatcher.watch(17, Byte.valueOf((byte) 1)); ++ this.datawatcher.watch(17, Byte.valueOf((byte) 1), META_POWERED, powered); + } + // CraftBukkit end + } +@@ -228,7 +231,7 @@ public class EntityCreeper extends EntityMonster { + } + + public void co() { +- this.datawatcher.watch(18, Byte.valueOf((byte) 1)); ++ this.datawatcher.watch(18, Byte.valueOf((byte) 1), META_IGNITED, true); + } + + public boolean cp() { +diff --git a/src/main/java/net/minecraft/server/EntityEnderCrystal.java b/src/main/java/net/minecraft/server/EntityEnderCrystal.java +index 07533e4..ddd1a0e 100644 +--- a/src/main/java/net/minecraft/server/EntityEnderCrystal.java ++++ b/src/main/java/net/minecraft/server/EntityEnderCrystal.java +@@ -4,11 +4,14 @@ package net.minecraft.server; + import org.bukkit.craftbukkit.event.CraftEventFactory; + import org.bukkit.event.entity.ExplosionPrimeEvent; + // CraftBukkit end ++import com.google.common.base.Optional; + + public class EntityEnderCrystal extends Entity { + + public int a; + public int b; ++ public static DataIndex> META_BLOCK_POSITION = DataWatcher.getIndex(EntityEnderCrystal.class, DataType.OPT_BLOCKPOSITION); ++ public static DataIndex META_STAND = DataWatcher.getIndex(EntityEnderCrystal.class, DataType.BOOLEAN); + + public EntityEnderCrystal(World world) { + super(world); +@@ -23,7 +26,8 @@ public class EntityEnderCrystal extends Entity { + } + + protected void h() { +- this.datawatcher.a(8, Integer.valueOf(this.b)); ++ this.datawatcher.a(8, Integer.valueOf(this.b), META_BLOCK_POSITION, Optional. absent()); ++ this.datawatcher.a(-2, (byte) 1, META_STAND, true); + } + + public void t_() { +@@ -31,10 +35,10 @@ public class EntityEnderCrystal extends Entity { + this.lastY = this.locY; + this.lastZ = this.locZ; + ++this.a; +- this.datawatcher.watch(8, Integer.valueOf(this.b)); + int i = MathHelper.floor(this.locX); + int j = MathHelper.floor(this.locY); + int k = MathHelper.floor(this.locZ); ++ this.datawatcher.watch(8, Integer.valueOf(this.b), META_BLOCK_POSITION, Optional.of(new BlockPosition(i, j, k))); + + if (this.world.worldProvider instanceof WorldProviderTheEnd && this.world.getType(new BlockPosition(i, j, k)).getBlock() != Blocks.FIRE) { + // CraftBukkit start +diff --git a/src/main/java/net/minecraft/server/EntityEnderDragon.java b/src/main/java/net/minecraft/server/EntityEnderDragon.java +index ed7f549..2198042 100644 +--- a/src/main/java/net/minecraft/server/EntityEnderDragon.java ++++ b/src/main/java/net/minecraft/server/EntityEnderDragon.java +@@ -39,6 +39,7 @@ public class EntityEnderDragon extends EntityInsentient implements IComplex, IMo + public int by; + public EntityEnderCrystal bz; + private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN, true, true); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() ++ public static DataIndex META_UNKNOWN_INTEGER = DataWatcher.getIndex(EntityEnderDragon.class, DataType.INTEGER); + + public EntityEnderDragon(World world) { + super(world); +diff --git a/src/main/java/net/minecraft/server/EntityEnderman.java b/src/main/java/net/minecraft/server/EntityEnderman.java +index a250062..5c09068 100644 +--- a/src/main/java/net/minecraft/server/EntityEnderman.java ++++ b/src/main/java/net/minecraft/server/EntityEnderman.java +@@ -7,6 +7,7 @@ import java.util.List; + import java.util.Random; + import java.util.Set; + import java.util.UUID; ++import com.google.common.base.Optional; + + // CraftBukkit start + import org.bukkit.Location; +@@ -20,6 +21,8 @@ public class EntityEnderman extends EntityMonster { + private static final AttributeModifier b = (new AttributeModifier(EntityEnderman.a, "Attacking speed boost", 0.15000000596046448D, 0)).a(false); + private static final Set c = Sets.newIdentityHashSet(); + private boolean bm; ++ public static DataIndex> META_BLOCK = DataWatcher.getIndex(EntityEnderman.class, DataType.OPT_IBLOCKDATA); ++ public static DataIndex META_ANGRY = DataWatcher.getIndex(EntityEnderman.class, DataType.BOOLEAN); + + public EntityEnderman(World world) { + super(world); +@@ -55,9 +58,9 @@ public class EntityEnderman extends EntityMonster { + + protected void h() { + super.h(); +- this.datawatcher.a(16, new Short((short) 0)); +- this.datawatcher.a(17, new Byte((byte) 0)); +- this.datawatcher.a(18, new Byte((byte) 0)); ++ this.datawatcher.a(16, new Short((short) 0), META_BLOCK, Optional. absent()); ++ this.datawatcher.a(17, new Byte((byte) 0), META_BLOCK, Optional. absent()); ++ this.datawatcher.a(18, new Byte((byte) 0), META_ANGRY, false); + } + + public void b(NBTTagCompound nbttagcompound) { +@@ -254,7 +257,7 @@ public class EntityEnderman extends EntityMonster { + } + + public void setCarried(IBlockData iblockdata) { +- this.datawatcher.watch(16, Short.valueOf((short) (Block.getCombinedId(iblockdata) & '\uffff'))); ++ this.datawatcher.watch(16, Short.valueOf((short) (Block.getCombinedId(iblockdata) & '\uffff')), META_BLOCK, Optional. fromNullable(iblockdata)); + } + + public IBlockData getCarried() { +@@ -306,7 +309,7 @@ public class EntityEnderman extends EntityMonster { + } + + public void a(boolean flag) { +- this.datawatcher.watch(18, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.datawatcher.watch(18, Byte.valueOf((byte) (flag ? 1 : 0)), META_ANGRY, flag); + } + + static { +diff --git a/src/main/java/net/minecraft/server/EntityFireworks.java b/src/main/java/net/minecraft/server/EntityFireworks.java +index d7be6c2..c918c5f 100644 +--- a/src/main/java/net/minecraft/server/EntityFireworks.java ++++ b/src/main/java/net/minecraft/server/EntityFireworks.java +@@ -1,9 +1,12 @@ + package net.minecraft.server; + ++import com.google.common.base.Optional; ++ + public class EntityFireworks extends Entity { + + private int ticksFlown; + public int expectedLifespan; ++ private final DataIndex> META_ITEM = DataWatcher.getIndex(EntityFireworks.class, DataType.OPT_ITEMSTACK); + + // Spigot Start + @Override +@@ -20,7 +23,7 @@ public class EntityFireworks extends Entity { + } + + protected void h() { +- this.datawatcher.add(8, 5); ++ this.datawatcher.add(8, 5, META_ITEM, Optional. absent()); + } + + public EntityFireworks(World world, double d0, double d1, double d2, ItemStack itemstack) { +@@ -31,7 +34,7 @@ public class EntityFireworks extends Entity { + int i = 1; + + if (itemstack != null && itemstack.hasTag()) { +- this.datawatcher.watch(8, itemstack); ++ this.datawatcher.watch(8, itemstack, META_ITEM, Optional.of(itemstack)); + NBTTagCompound nbttagcompound = itemstack.getTag(); + NBTTagCompound nbttagcompound1 = nbttagcompound.getCompound("Fireworks"); + +@@ -116,12 +119,17 @@ public class EntityFireworks extends Entity { + ItemStack itemstack = ItemStack.createStack(nbttagcompound1); + + if (itemstack != null) { +- this.datawatcher.watch(8, itemstack); ++ this.datawatcher.watch(8, itemstack, META_ITEM, Optional.of(itemstack)); + } + } + + } + ++ public void setFireworkItem(ItemStack item) ++ { ++ this.datawatcher.watch(8, item, META_ITEM, Optional.of(item)); ++ } ++ + public float c(float f) { + return super.c(f); + } +diff --git a/src/main/java/net/minecraft/server/EntityGhast.java b/src/main/java/net/minecraft/server/EntityGhast.java +index 51608e9..e098e2b 100644 +--- a/src/main/java/net/minecraft/server/EntityGhast.java ++++ b/src/main/java/net/minecraft/server/EntityGhast.java +@@ -5,6 +5,7 @@ import java.util.Random; + public class EntityGhast extends EntityFlying implements IMonster { + + private int a = 1; ++ public static DataIndex META_ANGRY = DataWatcher.getIndex(EntityGhast.class, DataType.BOOLEAN); + + public EntityGhast(World world) { + super(world); +@@ -19,7 +20,7 @@ public class EntityGhast extends EntityFlying implements IMonster { + } + + public void a(boolean flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (flag ? 1 : 0)), META_ANGRY, flag); + } + + public int cf() { +@@ -48,7 +49,7 @@ public class EntityGhast extends EntityFlying implements IMonster { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(16, Byte.valueOf((byte) 0), META_ANGRY, false); + } + + protected void initAttributes() { +diff --git a/src/main/java/net/minecraft/server/EntityGuardian.java b/src/main/java/net/minecraft/server/EntityGuardian.java +index c14caf2..3b46302 100644 +--- a/src/main/java/net/minecraft/server/EntityGuardian.java ++++ b/src/main/java/net/minecraft/server/EntityGuardian.java +@@ -5,6 +5,17 @@ import java.util.*; + + public class EntityGuardian extends EntityMonster + { ++ private float a; ++ private float b; ++ private float c; ++ private float bm; ++ private float bn; ++ private EntityLiving bo; ++ private int bp; ++ private boolean bq; ++ public PathfinderGoalRandomStroll goalRandomStroll; ++ public static DataIndex META_ELDER = DataWatcher.getIndex(EntityGuardian.class, DataType.BYTE); ++ public static DataIndex META_TARGET = DataWatcher.getIndex(EntityGuardian.class, DataType.INTEGER); + static class ControllerMoveGuardian extends ControllerMove + { + +@@ -203,8 +214,8 @@ public class EntityGuardian extends EntityMonster + protected void h() + { + super.h(); +- datawatcher.a(16, Integer.valueOf(0)); +- datawatcher.a(17, Integer.valueOf(0)); ++ datawatcher.a(16, Integer.valueOf(0), META_ELDER, (byte) 0); ++ datawatcher.a(17, Integer.valueOf(0), META_TARGET, 0); + } + + private boolean a(int j) +@@ -216,9 +227,9 @@ public class EntityGuardian extends EntityMonster + { + int k = datawatcher.getInt(16); + if(flag) +- datawatcher.watch(16, Integer.valueOf(k | j)); ++ datawatcher.watch(16, Integer.valueOf(k | j), META_ELDER, (byte) (k | j)); + else +- datawatcher.watch(16, Integer.valueOf(k & ~j)); ++ datawatcher.watch(16, Integer.valueOf(k & ~j), META_TARGET, Integer.valueOf(k & ~j)); + } + + public boolean n() +@@ -257,7 +268,7 @@ public class EntityGuardian extends EntityMonster + + private void b(int j) + { +- datawatcher.watch(17, Integer.valueOf(j)); ++ datawatcher.watch(17, Integer.valueOf(j), META_TARGET, j); + } + + public boolean cp() +@@ -577,14 +588,4 @@ public class EntityGuardian extends EntityMonster + { + entityguardian.l(flag); + } +- +- private float a; +- private float b; +- private float c; +- private float bm; +- private float bn; +- private EntityLiving bo; +- private int bp; +- private boolean bq; +- public PathfinderGoalRandomStroll goalRandomStroll; + } +diff --git a/src/main/java/net/minecraft/server/EntityHorse.java b/src/main/java/net/minecraft/server/EntityHorse.java +index f293118..00ba9ac 100644 +--- a/src/main/java/net/minecraft/server/EntityHorse.java ++++ b/src/main/java/net/minecraft/server/EntityHorse.java +@@ -3,6 +3,8 @@ package net.minecraft.server; + import com.google.common.base.Predicate; + import java.util.Iterator; + import java.util.List; ++import java.util.UUID; ++import com.google.common.base.Optional; + + import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; // CraftBukkit + +@@ -47,6 +49,11 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { + private String[] bP = new String[3]; + private boolean bQ = false; + public int maxDomestication = 100; // CraftBukkit - store max domestication value ++ public static DataIndex META_HORSE_STATE = DataWatcher.getIndex(EntityHorse.class, DataType.BYTE); ++ public static DataIndex META_TYPE = DataWatcher.getIndex(EntityHorse.class, DataType.INTEGER); ++ public static DataIndex META_VARIANT = DataWatcher.getIndex(EntityHorse.class, DataType.INTEGER); ++ public static DataIndex> META_OWNER = DataWatcher.getIndex(EntityHorse.class, DataType.OPT_UUID); ++ public static DataIndex META_ARMOR = DataWatcher.getIndex(EntityHorse.class, DataType.INTEGER); + + public EntityHorse(World world) { + super(world); +@@ -67,15 +74,15 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Integer.valueOf(0)); +- this.datawatcher.a(19, Byte.valueOf((byte) 0)); +- this.datawatcher.a(20, Integer.valueOf(0)); +- this.datawatcher.a(21, String.valueOf("")); +- this.datawatcher.a(22, Integer.valueOf(0)); ++ this.datawatcher.a(16, Integer.valueOf(0), META_HORSE_STATE, (byte) 0); ++ this.datawatcher.a(19, Byte.valueOf((byte) 0), META_TYPE, 0); ++ this.datawatcher.a(20, Integer.valueOf(0), META_VARIANT, 0); ++ this.datawatcher.a(21, String.valueOf(""), META_OWNER, Optional. absent()); ++ this.datawatcher.a(22, Integer.valueOf(0), META_ARMOR, 0); + } + + public void setType(int i) { +- this.datawatcher.watch(19, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(19, Byte.valueOf((byte) i), META_TYPE, i); + this.dc(); + } + +@@ -84,7 +91,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { + } + + public void setVariant(int i) { +- this.datawatcher.watch(20, Integer.valueOf(i)); ++ this.datawatcher.watch(20, Integer.valueOf(i), META_VARIANT, i); + this.dc(); + } + +@@ -129,9 +136,9 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { + return; + + if (flag) { +- this.datawatcher.watch(16, Integer.valueOf(j | i)); ++ this.datawatcher.watch(16, Integer.valueOf(j | i), META_HORSE_STATE, (byte) (j | i)); + } else { +- this.datawatcher.watch(16, Integer.valueOf(j & ~i)); ++ this.datawatcher.watch(16, Integer.valueOf(j & ~i), META_HORSE_STATE, (byte) (j & ~i)); + } + + } +@@ -153,7 +160,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { + } + + public void setOwnerUUID(String s) { +- this.datawatcher.watch(21, s); ++ this.datawatcher.watch(21, s, META_OWNER, Optional.of(UUID.fromString(s))); + } + + public float cu() { +@@ -227,7 +234,7 @@ public class EntityHorse extends EntityAnimal implements IInventoryListener { + } + + public void e(ItemStack itemstack) { +- this.datawatcher.watch(22, Integer.valueOf(this.f(itemstack))); ++ this.datawatcher.watch(22, Integer.valueOf(this.f(itemstack)), META_ARMOR, Integer.valueOf(this.f(itemstack))); + this.dc(); + } + +diff --git a/src/main/java/net/minecraft/server/EntityHuman.java b/src/main/java/net/minecraft/server/EntityHuman.java +index 66c3d0c..5294c66 100644 +--- a/src/main/java/net/minecraft/server/EntityHuman.java ++++ b/src/main/java/net/minecraft/server/EntityHuman.java +@@ -60,6 +60,10 @@ public abstract class EntityHuman extends EntityLiving { + private final GameProfile bH; + private boolean bI = false; + public EntityFishingHook hookedFish; ++ public static DataIndex META_SCALED_HEALTH = DataWatcher.getIndex(EntityHuman.class, DataType.FLOAT); ++ public static DataIndex META_SCORE = DataWatcher.getIndex(EntityHuman.class, DataType.INTEGER); ++ public static DataIndex META_SKIN = DataWatcher.getIndex(EntityHuman.class, DataType.BYTE); ++ public static DataIndex META_CAPE = DataWatcher.getIndex(EntityHuman.class, DataType.BYTE); + + // CraftBukkit start + public boolean fauxSleeping; +@@ -93,10 +97,10 @@ public abstract class EntityHuman extends EntityLiving { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Byte.valueOf((byte) 0)); +- this.datawatcher.a(17, Float.valueOf(0.0F)); +- this.datawatcher.a(18, Integer.valueOf(0)); +- this.datawatcher.a(10, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(17, Float.valueOf(0.0F), META_SCALED_HEALTH, 0F); ++ this.datawatcher.a(18, Integer.valueOf(0), META_SCORE, 0); ++ this.datawatcher.a(10, Byte.valueOf((byte) 0), META_SKIN, (byte) 0); ++ this.datawatcher.a(16, Byte.valueOf((byte) 0), META_CAPE, (byte) 1); + } + + public boolean bS() { +@@ -453,13 +457,13 @@ public abstract class EntityHuman extends EntityLiving { + } + + public void setScore(int i) { +- this.datawatcher.watch(18, Integer.valueOf(i)); ++ this.datawatcher.watch(18, Integer.valueOf(i), META_SCORE, i); + } + + public void addScore(int i) { + int j = this.getScore(); + +- this.datawatcher.watch(18, Integer.valueOf(j + i)); ++ this.datawatcher.watch(18, Integer.valueOf(j + i), META_SCORE, j + i); + } + + public void die(DamageSource damagesource) { +@@ -1614,7 +1618,7 @@ public abstract class EntityHuman extends EntityLiving { + + this.f = entityhuman.f; + this.enderChest = entityhuman.enderChest; +- this.getDataWatcher().watch(10, Byte.valueOf(entityhuman.getDataWatcher().getByte(10))); ++ this.getDataWatcher().watch(10, Byte.valueOf(entityhuman.getDataWatcher().getByte(10)), META_SKIN, entityhuman.getDataWatcher().getByte(10)); + } + + protected boolean s_() { +@@ -1692,7 +1696,7 @@ public abstract class EntityHuman extends EntityLiving { + f = 0.0F; + } + +- this.getDataWatcher().watch(17, Float.valueOf(f)); ++ this.getDataWatcher().watch(17, Float.valueOf(f), META_SCALED_HEALTH, f); + } + + public float getAbsorptionHearts() { +diff --git a/src/main/java/net/minecraft/server/EntityInsentient.java b/src/main/java/net/minecraft/server/EntityInsentient.java +index b7647bc..c3d5378 100644 +--- a/src/main/java/net/minecraft/server/EntityInsentient.java ++++ b/src/main/java/net/minecraft/server/EntityInsentient.java +@@ -38,6 +38,8 @@ public abstract class EntityInsentient extends EntityLiving { + private boolean _shouldBreakLeash = true; + private boolean _pullWhileLeashed = true; + ++ public static DataIndex META_NOAI = DataWatcher.getIndex(EntityInsentient.class, DataType.BYTE); ++ + public EntityInsentient(World world) { + super(world); + this.goalSelector = new PathfinderGoalSelector(world != null && world.methodProfiler != null ? world.methodProfiler : null); +@@ -159,7 +161,7 @@ public abstract class EntityInsentient extends EntityLiving { + + protected void h() { + super.h(); +- this.datawatcher.a(15, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(15, Byte.valueOf((byte) 0), META_NOAI, (byte) 0); + } + + public int w() { +@@ -958,7 +960,7 @@ public abstract class EntityInsentient extends EntityLiving { + } + + public void k(boolean flag) { +- this.datawatcher.watch(15, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.datawatcher.watch(15, Byte.valueOf((byte) (flag ? 1 : 0)), META_NOAI, (byte) (flag ? 1 : 0)); + } + + public boolean ce() { +diff --git a/src/main/java/net/minecraft/server/EntityIronGolem.java b/src/main/java/net/minecraft/server/EntityIronGolem.java +index ba09cb2..710d1d0 100644 +--- a/src/main/java/net/minecraft/server/EntityIronGolem.java ++++ b/src/main/java/net/minecraft/server/EntityIronGolem.java +@@ -8,6 +8,7 @@ public class EntityIronGolem extends EntityGolem { + Village a; + private int c; + private int bm; ++ public static DataIndex META_PLAYER_CREATED = DataWatcher.getIndex(EntityIronGolem.class, DataType.BYTE); + + public EntityIronGolem(World world) { + super(world); +@@ -28,7 +29,7 @@ public class EntityIronGolem extends EntityGolem { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(16, Byte.valueOf((byte) 0), META_PLAYER_CREATED, Byte.valueOf((byte) 0)); + } + + protected void E() { +@@ -167,9 +168,9 @@ public class EntityIronGolem extends EntityGolem { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1)), META_PLAYER_CREATED, Byte.valueOf((byte) (b0 | 1))); + } else { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2)), META_PLAYER_CREATED, Byte.valueOf((byte) (b0 & -2))); + } + + } +diff --git a/src/main/java/net/minecraft/server/EntityItem.java b/src/main/java/net/minecraft/server/EntityItem.java +index 1f8b1c7..b59ffc5 100644 +--- a/src/main/java/net/minecraft/server/EntityItem.java ++++ b/src/main/java/net/minecraft/server/EntityItem.java +@@ -4,6 +4,7 @@ import java.util.Iterator; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + import org.bukkit.event.player.PlayerPickupItemEvent; // CraftBukkit ++import com.google.common.base.Optional; + + public class EntityItem extends Entity { + +@@ -15,6 +16,7 @@ public class EntityItem extends Entity { + private String g; + public float a; + private int lastTick = MinecraftServer.currentTick; // CraftBukkit ++ public static DataIndex> META_ITEM = DataWatcher.getIndex(EntityItem.class, DataType.OPT_ITEMSTACK); + + public EntityItem(World world, double d0, double d1, double d2) { + super(world); +@@ -51,7 +53,7 @@ public class EntityItem extends Entity { + } + + protected void h() { +- this.getDataWatcher().add(10, 5); ++ this.getDataWatcher().add(10, 5, META_ITEM, Optional. absent()); + } + + public void t_() { +@@ -396,7 +398,7 @@ public class EntityItem extends Entity { + } + + public void setItemStack(ItemStack itemstack) { +- this.getDataWatcher().watch(10, itemstack); ++ this.getDataWatcher().watch(10, itemstack, META_ITEM, Optional.of(itemstack)); + this.getDataWatcher().update(10); + } + +diff --git a/src/main/java/net/minecraft/server/EntityItemFrame.java b/src/main/java/net/minecraft/server/EntityItemFrame.java +index 1008567..a3d7b66 100644 +--- a/src/main/java/net/minecraft/server/EntityItemFrame.java ++++ b/src/main/java/net/minecraft/server/EntityItemFrame.java +@@ -2,10 +2,13 @@ package net.minecraft.server; + + import java.util.UUID; + import org.apache.commons.codec.Charsets; ++import com.google.common.base.Optional; + + public class EntityItemFrame extends EntityHanging { + + private float c = 1.0F; ++ public static DataIndex> META_ITEM = DataWatcher.getIndex(EntityItemFrame.class, DataType.OPT_ITEMSTACK); ++ public static DataIndex META_ROTATION = DataWatcher.getIndex(EntityItemFrame.class, DataType.INTEGER); + + public EntityItemFrame(World world) { + super(world); +@@ -17,8 +20,8 @@ public class EntityItemFrame extends EntityHanging { + } + + protected void h() { +- this.getDataWatcher().add(8, 5); +- this.getDataWatcher().a(9, Byte.valueOf((byte) 0)); ++ this.getDataWatcher().add(8, 5, META_ITEM, Optional. absent()); ++ this.getDataWatcher().a(9, Byte.valueOf((byte) 0), META_ROTATION, 0); + } + + public float ao() { +@@ -110,7 +113,7 @@ public class EntityItemFrame extends EntityHanging { + itemstack.a(this); + } + +- this.getDataWatcher().watch(8, itemstack); ++ this.getDataWatcher().watch(8, itemstack, META_ITEM, Optional.fromNullable(itemstack)); + this.getDataWatcher().update(8); + if (flag && this.blockPosition != null) { + this.world.updateAdjacentComparators(this.blockPosition, Blocks.AIR); +@@ -127,7 +130,7 @@ public class EntityItemFrame extends EntityHanging { + } + + private void setRotation(int i, boolean flag) { +- this.getDataWatcher().watch(9, Byte.valueOf((byte) (i % 8))); ++ this.getDataWatcher().watch(9, Byte.valueOf((byte) (i % 8)), META_ROTATION, i % 8); + if (flag && this.blockPosition != null) { + this.world.updateAdjacentComparators(this.blockPosition, Blocks.AIR); + } +diff --git a/src/main/java/net/minecraft/server/EntityLiving.java b/src/main/java/net/minecraft/server/EntityLiving.java +index 96b3905..d0af93f 100644 +--- a/src/main/java/net/minecraft/server/EntityLiving.java ++++ b/src/main/java/net/minecraft/server/EntityLiving.java +@@ -114,11 +114,17 @@ public abstract class EntityLiving extends Entity { + _ghost = ghost; + } + ++ public static DataIndex META_UNKNOWN_BYTE = DataWatcher.getIndex(EntityLiving.class, DataType.BYTE); ++ public static DataIndex META_HEALTH = DataWatcher.getIndex(EntityLiving.class, DataType.FLOAT); ++ public static DataIndex META_POTION_COLOR = DataWatcher.getIndex(EntityLiving.class, DataType.INTEGER); ++ public static DataIndex META_AMBIENT_POTION = DataWatcher.getIndex(EntityLiving.class, DataType.BOOLEAN); ++ public static DataIndex META_ARROWS = DataWatcher.getIndex(EntityLiving.class, DataType.INTEGER); ++ + public EntityLiving(World world) { + super(world); + this.initAttributes(); + // CraftBukkit - setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor +- this.datawatcher.watch(6, (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue()); ++ this.datawatcher.watch(6, (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue(), META_HEALTH, (float) this.getAttributeInstance(GenericAttributes.maxHealth).getValue()); + this.k = true; + this.aH = (float) ((Math.random() + 1.0D) * 0.009999999776482582D); + this.setPosition(this.locX, this.locY, this.locZ); +@@ -129,10 +135,11 @@ public abstract class EntityLiving extends Entity { + } + + protected void h() { +- this.datawatcher.a(7, Integer.valueOf(0)); +- this.datawatcher.a(8, Byte.valueOf((byte) 0)); +- this.datawatcher.a(9, Byte.valueOf((byte) 0)); +- this.datawatcher.a(6, Float.valueOf(1.0F)); ++ this.datawatcher.a(-1, (byte) 0, META_UNKNOWN_BYTE, (byte) new Random().nextInt(5)); ++ this.datawatcher.a(7, Integer.valueOf(0), META_POTION_COLOR, 0); ++ this.datawatcher.a(8, Byte.valueOf((byte) 0), META_AMBIENT_POTION, false); ++ this.datawatcher.a(9, Byte.valueOf((byte) 0), META_ARROWS, 0); ++ this.datawatcher.a(6, Float.valueOf(1.0F), META_HEALTH, 1F); + } + + protected void initAttributes() { +@@ -547,16 +554,16 @@ public abstract class EntityLiving extends Entity { + } else { + int i = PotionBrewer.a(this.effects.values()); + +- this.datawatcher.watch(8, Byte.valueOf((byte) (PotionBrewer.b(this.effects.values()) ? 1 : 0))); +- this.datawatcher.watch(7, Integer.valueOf(i)); ++ this.datawatcher.watch(8, Byte.valueOf((byte) (PotionBrewer.b(this.effects.values()) ? 1 : 0)), META_AMBIENT_POTION, PotionBrewer.b(this.effects.values())); ++ this.datawatcher.watch(7, Integer.valueOf(i), META_POTION_COLOR, i); + this.setInvisible(this.hasEffect(MobEffectList.INVISIBILITY.id)); + } + + } + + protected void bj() { +- this.datawatcher.watch(8, Byte.valueOf((byte) 0)); +- this.datawatcher.watch(7, Integer.valueOf(0)); ++ this.datawatcher.watch(8, Byte.valueOf((byte) 0), META_AMBIENT_POTION, false); ++ this.datawatcher.watch(7, Integer.valueOf(0), META_POTION_COLOR, 0); + } + + public void removeAllEffects() { +@@ -709,11 +716,11 @@ public abstract class EntityLiving extends Entity { + player.setRealHealth(f); + } + +- this.datawatcher.watch(6, Float.valueOf(player.getScaledHealth())); ++ this.datawatcher.watch(6, Float.valueOf(player.getScaledHealth()), META_HEALTH, player.getScaledHealth()); + return; + } + // CraftBukkit end +- this.datawatcher.watch(6, Float.valueOf(MathHelper.a(f, 0.0F, this.getMaxHealth()))); ++ this.datawatcher.watch(6, Float.valueOf(MathHelper.a(f, 0.0F, this.getMaxHealth())), META_HEALTH, MathHelper.a(f, 0.0F, this.getMaxHealth())); + } + + public boolean damageEntity(DamageSource damagesource, float f) { +@@ -1174,7 +1181,7 @@ public abstract class EntityLiving extends Entity { + } + + public final void o(int i) { +- this.datawatcher.watch(9, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(9, Byte.valueOf((byte) i), META_ARROWS, i); + } + + private int n() { +diff --git a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java +index 4bf790c..5372460 100644 +--- a/src/main/java/net/minecraft/server/EntityMinecartAbstract.java ++++ b/src/main/java/net/minecraft/server/EntityMinecartAbstract.java +@@ -35,6 +35,13 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + private double flyingZ = 0.95; + public double maxSpeed = 0.4D; + // CraftBukkit end ++ ++ public static DataIndex META_SHAKING_POWER = DataWatcher.getIndex(EntityMinecartAbstract.class, DataType.INTEGER); ++ public static DataIndex META_SHAKING_DIRECTION = DataWatcher.getIndex(EntityMinecartAbstract.class, DataType.INTEGER); ++ public static DataIndex META_SHAKING_MULT = DataWatcher.getIndex(EntityMinecartAbstract.class, DataType.FLOAT); ++ public static DataIndex META_BLOCK = DataWatcher.getIndex(EntityMinecartAbstract.class, DataType.INTEGER); ++ public static DataIndex META_Y_OFFSET = DataWatcher.getIndex(EntityMinecartAbstract.class, DataType.INTEGER); ++ public static DataIndex META_SHOW_BLOCK = DataWatcher.getIndex(EntityMinecartAbstract.class, DataType.BOOLEAN); + + public EntityMinecartAbstract(World world) { + super(world); +@@ -72,12 +79,12 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + } + + protected void h() { +- this.datawatcher.a(17, new Integer(0)); +- this.datawatcher.a(18, new Integer(1)); +- this.datawatcher.a(19, new Float(0.0F)); +- this.datawatcher.a(20, new Integer(0)); +- this.datawatcher.a(21, new Integer(6)); +- this.datawatcher.a(22, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(17, new Integer(0), META_SHAKING_POWER, 0); ++ this.datawatcher.a(18, new Integer(1), META_SHAKING_DIRECTION, 0); ++ this.datawatcher.a(19, new Float(0.0F), META_SHAKING_MULT, 0F); ++ this.datawatcher.a(20, new Integer(0), META_BLOCK, 0); ++ this.datawatcher.a(21, new Integer(6), META_Y_OFFSET, 6); ++ this.datawatcher.a(22, Byte.valueOf((byte) 0), META_SHOW_BLOCK, false); + } + + public AxisAlignedBB j(Entity entity) { +@@ -772,7 +779,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + } + + public void setDamage(float f) { +- this.datawatcher.watch(19, Float.valueOf(f)); ++ this.datawatcher.watch(19, Float.valueOf(f), META_SHAKING_MULT, f); + } + + public float getDamage() { +@@ -780,7 +787,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + } + + public void j(int i) { +- this.datawatcher.watch(17, Integer.valueOf(i)); ++ this.datawatcher.watch(17, Integer.valueOf(i), META_SHAKING_POWER, i); + } + + public int getType() { +@@ -788,7 +795,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + } + + public void k(int i) { +- this.datawatcher.watch(18, Integer.valueOf(i)); ++ this.datawatcher.watch(18, Integer.valueOf(i), META_SHAKING_DIRECTION, i); + } + + public int r() { +@@ -814,12 +821,12 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + } + + public void setDisplayBlock(IBlockData iblockdata) { +- this.getDataWatcher().watch(20, Integer.valueOf(Block.getCombinedId(iblockdata))); ++ this.getDataWatcher().watch(20, Integer.valueOf(Block.getCombinedId(iblockdata)), META_BLOCK, Block.getCombinedId(iblockdata)); + this.a(true); + } + + public void SetDisplayBlockOffset(int i) { +- this.getDataWatcher().watch(21, Integer.valueOf(i)); ++ this.getDataWatcher().watch(21, Integer.valueOf(i), META_Y_OFFSET, i); + this.a(true); + } + +@@ -828,7 +835,7 @@ public abstract class EntityMinecartAbstract extends Entity implements INamableT + } + + public void a(boolean flag) { +- this.getDataWatcher().watch(22, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.getDataWatcher().watch(22, Byte.valueOf((byte) (flag ? 1 : 0)), META_SHOW_BLOCK, flag); + } + + public void setCustomName(String s) { +diff --git a/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java b/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java +index 44ae155..5ae66df 100644 +--- a/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java ++++ b/src/main/java/net/minecraft/server/EntityMinecartCommandBlock.java +@@ -7,8 +7,8 @@ public class EntityMinecartCommandBlock extends EntityMinecartAbstract { + this.sender = (org.bukkit.craftbukkit.entity.CraftMinecartCommand) EntityMinecartCommandBlock.this.getBukkitEntity(); // CraftBukkit - Set the sender + } + public void h() { +- EntityMinecartCommandBlock.this.getDataWatcher().watch(23, this.getCommand()); +- EntityMinecartCommandBlock.this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.k())); ++ EntityMinecartCommandBlock.this.getDataWatcher().watch(23, this.getCommand(), META_COMMAND, this.getCommand()); ++ EntityMinecartCommandBlock.this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.k()), META_COMMAND_OUTPUT, this.k()); + } + + public BlockPosition getChunkCoordinates() { +@@ -28,6 +28,8 @@ public class EntityMinecartCommandBlock extends EntityMinecartAbstract { + } + }; + private int b = 0; ++ public static DataIndex META_COMMAND = DataWatcher.getIndex(EntityMinecartCommandBlock.class, DataType.STRING); ++ public static DataIndex META_COMMAND_OUTPUT = DataWatcher.getIndex(EntityMinecartCommandBlock.class, DataType.ICHATBASECOMPONENT); + + public EntityMinecartCommandBlock(World world) { + super(world); +@@ -39,15 +41,15 @@ public class EntityMinecartCommandBlock extends EntityMinecartAbstract { + + protected void h() { + super.h(); +- this.getDataWatcher().a(23, ""); +- this.getDataWatcher().a(24, ""); ++ this.getDataWatcher().a(23, "", META_COMMAND, ""); ++ this.getDataWatcher().a(24, "", META_COMMAND_OUTPUT, new ChatComponentText("")); + } + + protected void a(NBTTagCompound nbttagcompound) { + super.a(nbttagcompound); + this.a.b(nbttagcompound); +- this.getDataWatcher().watch(23, this.getCommandBlock().getCommand()); +- this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.getCommandBlock().k())); ++ this.getDataWatcher().watch(23, this.getCommandBlock().getCommand(), META_COMMAND, this.getCommandBlock().getCommand()); ++ this.getDataWatcher().watch(24, IChatBaseComponent.ChatSerializer.a(this.getCommandBlock().k()), META_COMMAND_OUTPUT, this.getCommandBlock().k()); + } + + protected void b(NBTTagCompound nbttagcompound) { +diff --git a/src/main/java/net/minecraft/server/EntityMinecartFurnace.java b/src/main/java/net/minecraft/server/EntityMinecartFurnace.java +new file mode 100644 +index 0000000..1ffb6bf +--- /dev/null ++++ b/src/main/java/net/minecraft/server/EntityMinecartFurnace.java +@@ -0,0 +1,151 @@ ++package net.minecraft.server; ++ ++import java.util.Random; ++ ++public class EntityMinecartFurnace extends EntityMinecartAbstract ++{ ++ private int c; ++ public double a; ++ public double b; ++ public static DataIndex META_BURNING = DataWatcher.getIndex(EntityMinecartFurnace.class, DataType.BOOLEAN); ++ ++ public EntityMinecartFurnace(World paramWorld) ++ { ++ super(paramWorld); ++ } ++ ++ public EntityMinecartFurnace(World paramWorld, double paramDouble1, double paramDouble2, double paramDouble3) { ++ super(paramWorld, paramDouble1, paramDouble2, paramDouble3); ++ } ++ ++ public EntityMinecartAbstract.EnumMinecartType s() ++ { ++ return EntityMinecartAbstract.EnumMinecartType.FURNACE; ++ } ++ ++ protected void h() ++ { ++ super.h(); ++ this.datawatcher.a(16, new Byte((byte)0), META_BURNING, false); ++ } ++ ++ public void t_() ++ { ++ super.t_(); ++ ++ if (this.c > 0) { ++ this.c -= 1; ++ } ++ if (this.c <= 0) { ++ this.a = (this.b = 0.0D); ++ } ++ i(this.c > 0); ++ ++ if ((j()) && (this.random.nextInt(4) == 0)) ++ this.world.addParticle(EnumParticle.SMOKE_LARGE, this.locX, this.locY + 0.8D, this.locZ, 0.0D, 0.0D, 0.0D, new int[0]); ++ } ++ ++ protected double m() ++ { ++ return 0.2D; ++ } ++ ++ public void a(DamageSource paramDamageSource) ++ { ++ super.a(paramDamageSource); ++ ++ if ((!paramDamageSource.isExplosion()) && (this.world.getGameRules().getBoolean("doEntityDrops"))) ++ a(new ItemStack(Blocks.FURNACE, 1), 0.0F); ++ } ++ ++ protected void a(BlockPosition paramBlockPosition, IBlockData paramIBlockData) ++ { ++ super.a(paramBlockPosition, paramIBlockData); ++ ++ double d1 = this.a * this.a + this.b * this.b; ++ if ((d1 > 0.0001D) && (this.motX * this.motX + this.motZ * this.motZ > 0.001D)) { ++ d1 = MathHelper.sqrt(d1); ++ this.a /= d1; ++ this.b /= d1; ++ ++ if (this.a * this.motX + this.b * this.motZ < 0.0D) { ++ this.a = 0.0D; ++ this.b = 0.0D; ++ } else { ++ double d2 = d1 / m(); ++ this.a *= d2; ++ this.b *= d2; ++ } ++ } ++ } ++ ++ protected void o() ++ { ++ double d1 = this.a * this.a + this.b * this.b; ++ ++ if (d1 > 0.0001D) { ++ d1 = MathHelper.sqrt(d1); ++ this.a /= d1; ++ this.b /= d1; ++ double d2 = 1.0D; ++ this.motX *= 0.800000011920929D; ++ this.motY *= 0.0D; ++ this.motZ *= 0.800000011920929D; ++ this.motX += this.a * d2; ++ this.motZ += this.b * d2; ++ } else { ++ this.motX *= 0.9800000190734863D; ++ this.motY *= 0.0D; ++ this.motZ *= 0.9800000190734863D; ++ } ++ ++ super.o(); ++ } ++ ++ public boolean e(EntityHuman paramEntityHuman) ++ { ++ ItemStack localItemStack = paramEntityHuman.inventory.getItemInHand(); ++ if ((localItemStack != null) && (localItemStack.getItem() == Items.COAL)) { ++ if (!paramEntityHuman.abilities.canInstantlyBuild) if (--localItemStack.count == 0) { ++ paramEntityHuman.inventory.setItem(paramEntityHuman.inventory.itemInHandIndex, null); ++ } ++ this.c += 3600; ++ } ++ this.a = (this.locX - paramEntityHuman.locX); ++ this.b = (this.locZ - paramEntityHuman.locZ); ++ ++ return true; ++ } ++ ++ protected void b(NBTTagCompound paramNBTTagCompound) ++ { ++ super.b(paramNBTTagCompound); ++ paramNBTTagCompound.setDouble("PushX", this.a); ++ paramNBTTagCompound.setDouble("PushZ", this.b); ++ paramNBTTagCompound.setShort("Fuel", (short)this.c); ++ } ++ ++ protected void a(NBTTagCompound paramNBTTagCompound) ++ { ++ super.a(paramNBTTagCompound); ++ this.a = paramNBTTagCompound.getDouble("PushX"); ++ this.b = paramNBTTagCompound.getDouble("PushZ"); ++ this.c = paramNBTTagCompound.getShort("Fuel"); ++ } ++ ++ protected boolean j() { ++ return (this.datawatcher.getByte(16) & 0x1) != 0; ++ } ++ ++ protected void i(boolean paramBoolean) { ++ if (paramBoolean) ++ this.datawatcher.watch(16, Byte.valueOf((byte)(this.datawatcher.getByte(16) | 0x1)), META_BURNING, paramBoolean); ++ else ++ this.datawatcher.watch(16, Byte.valueOf((byte)(this.datawatcher.getByte(16) & 0xFFFFFFFE)), META_BURNING, paramBoolean); ++ } ++ ++ public IBlockData u() ++ { ++ return (j() ? Blocks.LIT_FURNACE : Blocks.FURNACE).getBlockData().set(BlockFurnace.FACING, EnumDirection.NORTH); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/EntityOcelot.java b/src/main/java/net/minecraft/server/EntityOcelot.java +index edcb307..15abdfe 100644 +--- a/src/main/java/net/minecraft/server/EntityOcelot.java ++++ b/src/main/java/net/minecraft/server/EntityOcelot.java +@@ -7,6 +7,7 @@ public class EntityOcelot extends EntityTameableAnimal { + private PathfinderGoalAvoidTarget bo; + private PathfinderGoalTempt bp; + public boolean spawnBonus = true; // Spigot ++ public static DataIndex META_TYPE = DataWatcher.getIndex(EntityOcelot.class, DataType.INTEGER); + + public EntityOcelot(World world) { + super(world); +@@ -27,7 +28,7 @@ public class EntityOcelot extends EntityTameableAnimal { + + protected void h() { + super.h(); +- this.datawatcher.a(18, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(18, Byte.valueOf((byte) 0), META_TYPE, 0); + } + + public void E() { +@@ -184,7 +185,7 @@ public class EntityOcelot extends EntityTameableAnimal { + } + + public void setCatType(int i) { +- this.datawatcher.watch(18, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(18, Byte.valueOf((byte) i), META_TYPE, i); + } + + public boolean bR() { +diff --git a/src/main/java/net/minecraft/server/EntityPig.java b/src/main/java/net/minecraft/server/EntityPig.java +index 3f2ce15..0e5550d 100644 +--- a/src/main/java/net/minecraft/server/EntityPig.java ++++ b/src/main/java/net/minecraft/server/EntityPig.java +@@ -5,6 +5,7 @@ import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit + public class EntityPig extends EntityAnimal { + + private final PathfinderGoalPassengerCarrotStick bm; ++ public static DataIndex META_SADDLED = DataWatcher.getIndex(EntityPig.class, DataType.BOOLEAN); + + public EntityPig(World world) { + super(world); +@@ -36,7 +37,7 @@ public class EntityPig extends EntityAnimal { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(16, Byte.valueOf((byte) 0), META_SADDLED, false); + } + + public void b(NBTTagCompound nbttagcompound) { +@@ -103,9 +104,9 @@ public class EntityPig extends EntityAnimal { + + public void setSaddle(boolean flag) { + if (flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) 1)); ++ this.datawatcher.watch(16, Byte.valueOf((byte) 1), META_SADDLED, true); + } else { +- this.datawatcher.watch(16, Byte.valueOf((byte) 0)); ++ this.datawatcher.watch(16, Byte.valueOf((byte) 0), META_SADDLED, false); + } + + } +diff --git a/src/main/java/net/minecraft/server/EntityPlayer.java b/src/main/java/net/minecraft/server/EntityPlayer.java +index 44ac587..9c46797 100644 +--- a/src/main/java/net/minecraft/server/EntityPlayer.java ++++ b/src/main/java/net/minecraft/server/EntityPlayer.java +@@ -246,7 +246,13 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + if (arraylist.size() == 1) { + this.playerConnection.sendPacket(new PacketPlayOutMapChunk((Chunk) arraylist.get(0), true, '\uffff')); + } else { ++ if (playerConnection.networkManager.getVersion() == 47) + this.playerConnection.sendPacket(new PacketPlayOutMapChunkBulk(arraylist)); ++ else ++ for (Chunk chunk1 : (ArrayList) arraylist) ++ { ++ this.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunk1, true, '\uffff')); ++ } + } + + Iterator iterator2 = arraylist1.iterator(); +@@ -596,7 +602,15 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + + super.mount(entity); + if (this.vehicle != entity1) { // CraftBukkit +- this.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this, this.vehicle)); ++ if (playerConnection.networkManager.getVersion() > 47) ++ { ++ if (entity1 != null) ++ this.playerConnection.sendPacket(new PacketPlayOutNewAttachEntity(entity1, entity1.passenger)); ++ if (this.vehicle != null) ++ this.playerConnection.sendPacket(new PacketPlayOutNewAttachEntity(this.vehicle, this)); ++ } ++ else ++ this.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this, this.vehicle)); + this.playerConnection.a(this.locX, this.locY, this.locZ, this.yaw, this.pitch); + } + +@@ -747,7 +761,11 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + Item item = itemstack.getItem(); + + if (item == Items.WRITTEN_BOOK) { +- this.playerConnection.sendPacket(new PacketPlayOutCustomPayload("MC|BOpen", new PacketDataSerializer(Unpooled.buffer()))); ++ PacketDataSerializer serializer = new PacketDataSerializer(Unpooled.buffer()); ++ ++ if (this.playerConnection.networkManager.getVersion() > 47) ++ serializer.b(0); ++ this.playerConnection.sendPacket(new PacketPlayOutCustomPayload("MC|BOpen", serializer)); + } + + } +@@ -1000,7 +1018,8 @@ public class EntityPlayer extends EntityHuman implements ICrafting { + this.locale = packetplayinsettings.a(); + this.bR = packetplayinsettings.c(); + this.bS = packetplayinsettings.d(); +- this.getDataWatcher().watch(10, Byte.valueOf((byte) packetplayinsettings.e())); ++ this.getDataWatcher().watch(10, (byte) packetplayinsettings.e(), META_SKIN, (byte) packetplayinsettings.e()); ++ this.getDataWatcher().watch(16, (byte) 0, META_CAPE, (byte) 1); + } + + public EntityHuman.EnumChatVisibility getChatFlags() { +diff --git a/src/main/java/net/minecraft/server/EntityPotion.java b/src/main/java/net/minecraft/server/EntityPotion.java +index fd174c3..e2be9db 100644 +--- a/src/main/java/net/minecraft/server/EntityPotion.java ++++ b/src/main/java/net/minecraft/server/EntityPotion.java +@@ -8,11 +8,13 @@ import java.util.HashMap; + + import org.bukkit.craftbukkit.entity.CraftLivingEntity; + import org.bukkit.entity.LivingEntity; ++import com.google.common.base.Optional; + // CraftBukkit end + + public class EntityPotion extends EntityProjectile { + +- public ItemStack item; ++ private ItemStack item; ++ public static DataIndex> META_ITEMSTACK = DataWatcher.getIndex(EntityItem.class, DataType.OPT_ITEMSTACK); + + public EntityPotion(World world) { + super(world); +@@ -25,11 +27,13 @@ public class EntityPotion extends EntityProjectile { + public EntityPotion(World world, EntityLiving entityliving, ItemStack itemstack) { + super(world, entityliving); + this.item = itemstack; ++ this.datawatcher.a(-12, 0, META_ITEMSTACK, Optional.fromNullable(item)); + } + + public EntityPotion(World world, double d0, double d1, double d2, ItemStack itemstack) { + super(world, d0, d1, d2); + this.item = itemstack; ++ this.datawatcher.a(-12, 0, META_ITEMSTACK, Optional.fromNullable(item)); + } + + protected float m() { +@@ -50,6 +54,18 @@ public class EntityPotion extends EntityProjectile { + } + + this.item.setData(i); ++ this.datawatcher.watch(-12, 0, META_ITEMSTACK, Optional.fromNullable(item)); ++ } ++ ++ public void setItem(ItemStack item) ++ { ++ this.item = item; ++ this.datawatcher.watch(-12, 0, META_ITEMSTACK, Optional.fromNullable(item)); ++ } ++ ++ public ItemStack getItem() ++ { ++ return this.item; + } + + public int getPotionValue() { +@@ -139,6 +155,7 @@ public class EntityPotion extends EntityProjectile { + super.a(nbttagcompound); + if (nbttagcompound.hasKeyOfType("Potion", 10)) { + this.item = ItemStack.createStack(nbttagcompound.getCompound("Potion")); ++ this.datawatcher.watch(-12, 0, META_ITEMSTACK, Optional.fromNullable(item)); + } else { + this.setPotionValue(nbttagcompound.getInt("potionValue")); + } +diff --git a/src/main/java/net/minecraft/server/EntityRabbit.java b/src/main/java/net/minecraft/server/EntityRabbit.java +index bb47e09..20b5d17 100644 +--- a/src/main/java/net/minecraft/server/EntityRabbit.java ++++ b/src/main/java/net/minecraft/server/EntityRabbit.java +@@ -11,6 +11,7 @@ public class EntityRabbit extends EntityAnimal { + private EntityRabbit.EnumRabbitState bt; + private int bu; + private EntityHuman bv; ++ public static DataIndex META_TYPE = DataWatcher.getIndex(EntityRabbit.class, DataType.INTEGER); + + public EntityRabbit(World world) { + super(world); +@@ -81,7 +82,7 @@ public class EntityRabbit extends EntityAnimal { + + protected void h() { + super.h(); +- this.datawatcher.a(18, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(18, Byte.valueOf((byte) 0), META_TYPE, 0); + } + + public void E() { +@@ -289,7 +290,7 @@ public class EntityRabbit extends EntityAnimal { + } + } + +- this.datawatcher.watch(18, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(18, Byte.valueOf((byte) i), META_TYPE, i); + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { +diff --git a/src/main/java/net/minecraft/server/EntitySheep.java b/src/main/java/net/minecraft/server/EntitySheep.java +index 29611a1..ef22dba 100644 +--- a/src/main/java/net/minecraft/server/EntitySheep.java ++++ b/src/main/java/net/minecraft/server/EntitySheep.java +@@ -27,6 +27,7 @@ public class EntitySheep extends EntityAnimal { + private static final Map bo = Maps.newEnumMap(EnumColor.class); + private int bp; + private PathfinderGoalEatTile bq = new PathfinderGoalEatTile(this); ++ public static DataIndex META_WOOL_STATE = DataWatcher.getIndex(EntitySheep.class, DataType.BYTE); + + public static float[] a(EnumColor enumcolor) { + return (float[]) EntitySheep.bo.get(enumcolor); +@@ -71,7 +72,7 @@ public class EntitySheep extends EntityAnimal { + + protected void h() { + super.h(); +- this.datawatcher.a(16, new Byte((byte) 0)); ++ this.datawatcher.a(16, new Byte((byte) 0), META_WOOL_STATE, (byte) 0); + } + + protected void dropDeathLoot(boolean flag, int i) { +@@ -162,8 +163,9 @@ public class EntitySheep extends EntityAnimal { + + public void setColor(EnumColor enumcolor) { + byte b0 = this.datawatcher.getByte(16); ++ b0 = (byte) (b0 & 240 | enumcolor.getColorIndex() & 15); + +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & 240 | enumcolor.getColorIndex() & 15))); ++ this.datawatcher.watch(16, Byte.valueOf(b0), META_WOOL_STATE, b0); + } + + public boolean isSheared() { +@@ -174,9 +176,9 @@ public class EntitySheep extends EntityAnimal { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 16))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 16)), META_WOOL_STATE, (byte) (b0 | 16)); + } else { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -17))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -17)), META_WOOL_STATE, (byte) (b0 & -17)); + } + + } +diff --git a/src/main/java/net/minecraft/server/EntitySkeleton.java b/src/main/java/net/minecraft/server/EntitySkeleton.java +index 46bff95..19af049 100644 +--- a/src/main/java/net/minecraft/server/EntitySkeleton.java ++++ b/src/main/java/net/minecraft/server/EntitySkeleton.java +@@ -3,11 +3,14 @@ package net.minecraft.server; + import java.util.Calendar; + + import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit ++import org.bukkit.event.entity.EntityTargetEvent; + + public class EntitySkeleton extends EntityMonster implements IRangedEntity { + + private PathfinderGoalArrowAttack a = new PathfinderGoalArrowAttack(this, 1.0D, 20, 60, 15.0F); + private PathfinderGoalMeleeAttack b = new PathfinderGoalMeleeAttack(this, EntityHuman.class, 1.2D, false); ++ public static DataIndex META_TYPE = DataWatcher.getIndex(EntitySkeleton.class, DataType.INTEGER); ++ public static DataIndex META_AIMING = DataWatcher.getIndex(EntitySkeleton.class, DataType.BOOLEAN); + + public EntitySkeleton(World world) { + super(world); +@@ -34,7 +37,8 @@ public class EntitySkeleton extends EntityMonster implements IRangedEntity { + + protected void h() { + super.h(); +- this.datawatcher.a(13, new Byte((byte) 0)); ++ this.datawatcher.a(13, new Byte((byte) 0), META_TYPE, 0); ++ this.datawatcher.a(-20, (byte) 0, META_AIMING, false); + } + + protected String z() { +@@ -273,7 +277,7 @@ public class EntitySkeleton extends EntityMonster implements IRangedEntity { + } + + public void setSkeletonType(int i) { +- this.datawatcher.watch(13, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(13, Byte.valueOf((byte) i), META_TYPE, i); + this.fireProof = i == 1; + if (i == 1) { + this.setSize(0.72F, 2.535F); +@@ -305,7 +309,14 @@ public class EntitySkeleton extends EntityMonster implements IRangedEntity { + this.n(); + } + +- } ++ } ++ ++ public void setGoalTarget(EntityLiving entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) ++ { ++ super.setGoalTarget(entityliving, reason, fireEvent); ++ ++ this.datawatcher.watch(-20, (byte) 0, META_AIMING, getGoalTarget() != null); ++ } + + public float getHeadHeight() { + return this.getSkeletonType() == 1 ? super.getHeadHeight() : 1.74F; +diff --git a/src/main/java/net/minecraft/server/EntitySlime.java b/src/main/java/net/minecraft/server/EntitySlime.java +index d39df07..8acc3fb 100644 +--- a/src/main/java/net/minecraft/server/EntitySlime.java ++++ b/src/main/java/net/minecraft/server/EntitySlime.java +@@ -10,6 +10,7 @@ public class EntitySlime extends EntityInsentient implements IMonster { + public float b; + public float c; + private boolean bk; ++ public static DataIndex META_SIZE = DataWatcher.getIndex(EntitySlime.class, DataType.INTEGER); + + public EntitySlime(World world) { + super(world); +@@ -24,11 +25,11 @@ public class EntitySlime extends EntityInsentient implements IMonster { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Byte.valueOf((byte) 1)); ++ this.datawatcher.a(16, Byte.valueOf((byte) 1), META_SIZE, 1); + } + + public void setSize(int i) { +- this.datawatcher.watch(16, Byte.valueOf((byte) i)); ++ this.datawatcher.watch(16, Byte.valueOf((byte) i), META_SIZE, i); + this.setSize(0.51000005F * (float) i, 0.51000005F * (float) i); + this.setPosition(this.locX, this.locY, this.locZ); + this.getAttributeInstance(GenericAttributes.maxHealth).setValue((double) (i * i)); +diff --git a/src/main/java/net/minecraft/server/EntitySpider.java b/src/main/java/net/minecraft/server/EntitySpider.java +index 68a253c..e37cf66 100644 +--- a/src/main/java/net/minecraft/server/EntitySpider.java ++++ b/src/main/java/net/minecraft/server/EntitySpider.java +@@ -4,6 +4,8 @@ import java.util.Random; + + public class EntitySpider extends EntityMonster { + ++ public static DataIndex META_CLIMBING = DataWatcher.getIndex(EntitySpider.class, DataType.BYTE); ++ + public EntitySpider(World world) { + super(world); + this.setSize(1.4F, 0.9F); +@@ -29,7 +31,7 @@ public class EntitySpider extends EntityMonster { + + protected void h() { + super.h(); +- this.datawatcher.a(16, new Byte((byte) 0)); ++ this.datawatcher.a(16, new Byte((byte) 0), META_CLIMBING, (byte) 0); + } + + public void t_() { +@@ -101,7 +103,7 @@ public class EntitySpider extends EntityMonster { + b0 &= -2; + } + +- this.datawatcher.watch(16, Byte.valueOf(b0)); ++ this.datawatcher.watch(16, Byte.valueOf(b0), META_CLIMBING, b0); + } + + public GroupDataEntity prepare(DifficultyDamageScaler difficultydamagescaler, GroupDataEntity groupdataentity) { +diff --git a/src/main/java/net/minecraft/server/EntityTNTPrimed.java b/src/main/java/net/minecraft/server/EntityTNTPrimed.java +index 83e71c1..9b13620 100644 +--- a/src/main/java/net/minecraft/server/EntityTNTPrimed.java ++++ b/src/main/java/net/minecraft/server/EntityTNTPrimed.java +@@ -10,6 +10,7 @@ public class EntityTNTPrimed extends Entity { + public boolean isIncendiary = false; // CraftBukkit - add field + + public boolean spectating; ++ public static DataIndex META_FUSE = DataWatcher.getIndex(EntityTNTPrimed.class, DataType.INTEGER); + + public EntityTNTPrimed(World world) { + super(world); +@@ -32,7 +33,9 @@ public class EntityTNTPrimed extends Entity { + this.source = entityliving; + } + +- protected void h() {} ++ protected void h() { ++ datawatcher.a(24, 0, META_FUSE, 80); ++ } + + protected boolean s_() { + return false; +@@ -94,6 +97,13 @@ public class EntityTNTPrimed extends Entity { + + protected void a(NBTTagCompound nbttagcompound) { + this.fuseTicks = nbttagcompound.getByte("Fuse"); ++ datawatcher.a(24, 0, META_FUSE, fuseTicks); ++ } ++ ++ public void setFuseTicks(int newTicks) ++ { ++ fuseTicks = newTicks; ++ datawatcher.a(24, 0, META_FUSE, fuseTicks); + } + + public EntityLiving getSource() { +diff --git a/src/main/java/net/minecraft/server/EntityTameableAnimal.java b/src/main/java/net/minecraft/server/EntityTameableAnimal.java +new file mode 100644 +index 0000000..89b5dd7 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/EntityTameableAnimal.java +@@ -0,0 +1,167 @@ ++package net.minecraft.server; ++ ++import java.util.Random; ++import java.util.UUID; ++import com.google.common.base.Optional; ++ ++public abstract class EntityTameableAnimal extends EntityAnimal ++ implements EntityOwnable ++{ ++ protected PathfinderGoalSit bm = new PathfinderGoalSit(this); ++ public static DataIndex META_SITTING_TAMED = DataWatcher.getIndex(EntityTameableAnimal.class, DataType.BYTE); ++ public static DataIndex> META_OWNER = DataWatcher.getIndex(EntityTameableAnimal.class, DataType.OPT_UUID); ++ ++ public EntityTameableAnimal(World paramWorld) { ++ super(paramWorld); ++ cm(); ++ } ++ ++ protected void h() ++ { ++ super.h(); ++ this.datawatcher.a(16, Byte.valueOf((byte)0), META_SITTING_TAMED, (byte) 0); ++ this.datawatcher.a(17, "", META_OWNER, Optional. absent()); ++ } ++ ++ public void b(NBTTagCompound paramNBTTagCompound) ++ { ++ super.b(paramNBTTagCompound); ++ if (getOwnerUUID() == null) ++ paramNBTTagCompound.setString("OwnerUUID", ""); ++ else { ++ paramNBTTagCompound.setString("OwnerUUID", getOwnerUUID()); ++ } ++ paramNBTTagCompound.setBoolean("Sitting", isSitting()); ++ } ++ ++ public void a(NBTTagCompound paramNBTTagCompound) ++ { ++ super.a(paramNBTTagCompound); ++ String str1 = ""; ++ if (paramNBTTagCompound.hasKeyOfType("OwnerUUID", 8)) { ++ str1 = paramNBTTagCompound.getString("OwnerUUID"); ++ } else { ++ String str2 = paramNBTTagCompound.getString("Owner"); ++ str1 = NameReferencingFileConverter.a(str2); ++ } ++ if (str1.length() > 0) { ++ setOwnerUUID(str1); ++ setTamed(true); ++ } ++ this.bm.setSitting(paramNBTTagCompound.getBoolean("Sitting")); ++ setSitting(paramNBTTagCompound.getBoolean("Sitting")); ++ } ++ ++ protected void l(boolean paramBoolean) { ++ EnumParticle localEnumParticle = EnumParticle.HEART; ++ if (!paramBoolean) { ++ localEnumParticle = EnumParticle.SMOKE_NORMAL; ++ } ++ for (int i = 0; i < 7; i++) { ++ double d1 = this.random.nextGaussian() * 0.02D; ++ double d2 = this.random.nextGaussian() * 0.02D; ++ double d3 = this.random.nextGaussian() * 0.02D; ++ this.world.addParticle(localEnumParticle, this.locX + this.random.nextFloat() * this.width * 2.0F - this.width, this.locY + 0.5D + this.random.nextFloat() * this.length, this.locZ + this.random.nextFloat() * this.width * 2.0F - this.width, d1, d2, d3, new int[0]); ++ } ++ } ++ ++ public boolean isTamed() ++ { ++ return (this.datawatcher.getByte(16) & 0x4) != 0; ++ } ++ ++ public void setTamed(boolean paramBoolean) { ++ int i = this.datawatcher.getByte(16); ++ if (paramBoolean) ++ this.datawatcher.watch(16, Byte.valueOf((byte)(i | 0x4)), META_SITTING_TAMED, (byte)(i | 0x4)); ++ else { ++ this.datawatcher.watch(16, Byte.valueOf((byte)(i & 0xFFFFFFFB)), META_SITTING_TAMED, (byte)(i & 0xFFFFFFFB)); ++ } ++ ++ cm(); ++ } ++ ++ protected void cm() { ++ } ++ ++ public boolean isSitting() { ++ return (this.datawatcher.getByte(16) & 0x1) != 0; ++ } ++ ++ public void setSitting(boolean paramBoolean) { ++ int i = this.datawatcher.getByte(16); ++ if (paramBoolean) ++ this.datawatcher.watch(16, Byte.valueOf((byte)(i | 0x1)), META_SITTING_TAMED, (byte)(i | 0x1)); ++ else ++ this.datawatcher.watch(16, Byte.valueOf((byte)(i & 0xFFFFFFFE)), META_SITTING_TAMED, (byte)(i & 0xFFFFFFFE)); ++ } ++ ++ public String getOwnerUUID() ++ { ++ return this.datawatcher.getString(17); ++ } ++ ++ public void setOwnerUUID(String paramString) { ++ this.datawatcher.watch(17, paramString, META_OWNER, Optional.of(UUID.fromString(getOwnerUUID()))); ++ } ++ ++ public EntityLiving getOwner() ++ { ++ try { ++ UUID localUUID = UUID.fromString(getOwnerUUID()); ++ if (localUUID == null) { ++ return null; ++ } ++ return this.world.b(localUUID); } catch (IllegalArgumentException localIllegalArgumentException) { ++ } ++ return null; ++ } ++ ++ public boolean e(EntityLiving paramEntityLiving) ++ { ++ return paramEntityLiving == getOwner(); ++ } ++ ++ public PathfinderGoalSit getGoalSit() { ++ return this.bm; ++ } ++ ++ public boolean a(EntityLiving paramEntityLiving1, EntityLiving paramEntityLiving2) { ++ return true; ++ } ++ ++ public ScoreboardTeamBase getScoreboardTeam() ++ { ++ if (isTamed()) { ++ EntityLiving localEntityLiving = getOwner(); ++ if (localEntityLiving != null) { ++ return localEntityLiving.getScoreboardTeam(); ++ } ++ } ++ return super.getScoreboardTeam(); ++ } ++ ++ public boolean c(EntityLiving paramEntityLiving) ++ { ++ if (isTamed()) { ++ EntityLiving localEntityLiving = getOwner(); ++ if (paramEntityLiving == localEntityLiving) { ++ return true; ++ } ++ if (localEntityLiving != null) { ++ return localEntityLiving.c(paramEntityLiving); ++ } ++ } ++ return super.c(paramEntityLiving); ++ } ++ ++ public void die(DamageSource paramDamageSource) ++ { ++ if ((!this.world.isClientSide) && (this.world.getGameRules().getBoolean("showDeathMessages")) && (hasCustomName()) && ++ ((getOwner() instanceof EntityPlayer))) { ++ ((EntityPlayer)getOwner()).sendMessage(bs().b()); ++ } ++ ++ super.die(paramDamageSource); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/EntityTrackerEntry.java b/src/main/java/net/minecraft/server/EntityTrackerEntry.java +index 3fb3205..39f0b73 100644 +--- a/src/main/java/net/minecraft/server/EntityTrackerEntry.java ++++ b/src/main/java/net/minecraft/server/EntityTrackerEntry.java +@@ -75,8 +75,35 @@ public class EntityTrackerEntry { + } + + if (this.w != this.tracker.vehicle || this.tracker.vehicle != null && this.m % 60 == 0) { ++ ++ Iterator iterator = this.trackedPlayers.iterator(); ++ ++ Packet[] packets = new Packet[(this.w != null ? 1 : 0) + (this.tracker.vehicle != null ? 1 : 0)]; ++ int index = 0; ++ ++ if (this.w != null) ++ { ++ packets[index++] = new PacketPlayOutNewAttachEntity(this.w, this.w.passenger); ++ } ++ ++ if (this.tracker.vehicle != null) ++ { ++ packets[index++] = new PacketPlayOutNewAttachEntity(this.tracker.vehicle, this.tracker); ++ } ++ + this.w = this.tracker.vehicle; +- this.broadcast(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); ++ ++ while (iterator.hasNext()) { ++ EntityPlayer entityplayer = (EntityPlayer) iterator.next(); ++ ++ if (entityplayer.playerConnection.networkManager.getVersion() > 47) ++ { ++ for (Packet packet : packets) ++ entityplayer.playerConnection.sendPacket(packet); ++ } ++ else ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); ++ } + } + + if (this.tracker instanceof EntityItemFrame /*&& this.m % 10 == 0*/) { // CraftBukkit - Moved below, should always enter this block +@@ -334,7 +361,7 @@ public class EntityTrackerEntry { + + NBTTagCompound nbttagcompound = this.tracker.getNBTTag(); + +- if (nbttagcompound != null) { ++ if (nbttagcompound != null && entityplayer.playerConnection.networkManager.getVersion() == 47) { + entityplayer.playerConnection.sendPacket(new PacketPlayOutUpdateEntityNBT(this.tracker.getId(), nbttagcompound)); + } + +@@ -361,7 +388,10 @@ public class EntityTrackerEntry { + } + + if (this.tracker.vehicle != null) { +- entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); ++ if (entityplayer.playerConnection.networkManager.getVersion() > 47) ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutNewAttachEntity(this.tracker.vehicle, this.tracker)); ++ else ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutAttachEntity(0, this.tracker, this.tracker.vehicle)); + } + + if (this.tracker instanceof EntityInsentient && ((EntityInsentient) this.tracker).getLeashHolder() != null) { +diff --git a/src/main/java/net/minecraft/server/EntityVillager.java b/src/main/java/net/minecraft/server/EntityVillager.java +index f1c905a..784cbec 100644 +--- a/src/main/java/net/minecraft/server/EntityVillager.java ++++ b/src/main/java/net/minecraft/server/EntityVillager.java +@@ -22,6 +22,7 @@ public class EntityVillager extends EntityAgeable implements IMerchant, NPC { + private boolean bz; + private boolean bA; + public InventorySubcontainer inventory; ++ public static DataIndex META_TYPE = DataWatcher.getIndex(EntityVillager.class, DataType.INTEGER); + private static final EntityVillager.IMerchantRecipeOption[][][][] bC = new EntityVillager.IMerchantRecipeOption[][][][] { { { { new EntityVillager.MerchantRecipeOptionBuy(Items.WHEAT, new EntityVillager.MerchantOptionRandomRange(18, 22)), new EntityVillager.MerchantRecipeOptionBuy(Items.POTATO, new EntityVillager.MerchantOptionRandomRange(15, 19)), new EntityVillager.MerchantRecipeOptionBuy(Items.CARROT, new EntityVillager.MerchantOptionRandomRange(15, 19)), new EntityVillager.MerchantRecipeOptionSell(Items.BREAD, new EntityVillager.MerchantOptionRandomRange(-4, -2))}, { new EntityVillager.MerchantRecipeOptionBuy(Item.getItemOf(Blocks.PUMPKIN), new EntityVillager.MerchantOptionRandomRange(8, 13)), new EntityVillager.MerchantRecipeOptionSell(Items.PUMPKIN_PIE, new EntityVillager.MerchantOptionRandomRange(-3, -2))}, { new EntityVillager.MerchantRecipeOptionBuy(Item.getItemOf(Blocks.MELON_BLOCK), new EntityVillager.MerchantOptionRandomRange(7, 12)), new EntityVillager.MerchantRecipeOptionSell(Items.APPLE, new EntityVillager.MerchantOptionRandomRange(-5, -7))}, { new EntityVillager.MerchantRecipeOptionSell(Items.COOKIE, new EntityVillager.MerchantOptionRandomRange(-6, -10)), new EntityVillager.MerchantRecipeOptionSell(Items.CAKE, new EntityVillager.MerchantOptionRandomRange(1, 1))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.STRING, new EntityVillager.MerchantOptionRandomRange(15, 20)), new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionProcess(Items.FISH, new EntityVillager.MerchantOptionRandomRange(6, 6), Items.COOKED_FISH, new EntityVillager.MerchantOptionRandomRange(6, 6))}, { new EntityVillager.MerchantRecipeOptionEnchant(Items.FISHING_ROD, new EntityVillager.MerchantOptionRandomRange(7, 8))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Item.getItemOf(Blocks.WOOL), new EntityVillager.MerchantOptionRandomRange(16, 22)), new EntityVillager.MerchantRecipeOptionSell(Items.SHEARS, new EntityVillager.MerchantOptionRandomRange(3, 4))}, { new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 0), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 1), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 2), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 3), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 4), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 5), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 6), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 7), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 8), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 9), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 10), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 11), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 12), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 13), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 14), new EntityVillager.MerchantOptionRandomRange(1, 2)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Item.getItemOf(Blocks.WOOL), 1, 15), new EntityVillager.MerchantOptionRandomRange(1, 2))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.STRING, new EntityVillager.MerchantOptionRandomRange(15, 20)), new EntityVillager.MerchantRecipeOptionSell(Items.ARROW, new EntityVillager.MerchantOptionRandomRange(-12, -8))}, { new EntityVillager.MerchantRecipeOptionSell(Items.BOW, new EntityVillager.MerchantOptionRandomRange(2, 3)), new EntityVillager.MerchantRecipeOptionProcess(Item.getItemOf(Blocks.GRAVEL), new EntityVillager.MerchantOptionRandomRange(10, 10), Items.FLINT, new EntityVillager.MerchantOptionRandomRange(6, 10))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.PAPER, new EntityVillager.MerchantOptionRandomRange(24, 36)), new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionBuy(Items.BOOK, new EntityVillager.MerchantOptionRandomRange(8, 10)), new EntityVillager.MerchantRecipeOptionSell(Items.COMPASS, new EntityVillager.MerchantOptionRandomRange(10, 12)), new EntityVillager.MerchantRecipeOptionSell(Item.getItemOf(Blocks.BOOKSHELF), new EntityVillager.MerchantOptionRandomRange(3, 4))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.WRITTEN_BOOK, new EntityVillager.MerchantOptionRandomRange(2, 2)), new EntityVillager.MerchantRecipeOptionSell(Items.CLOCK, new EntityVillager.MerchantOptionRandomRange(10, 12)), new EntityVillager.MerchantRecipeOptionSell(Item.getItemOf(Blocks.GLASS), new EntityVillager.MerchantOptionRandomRange(-5, -3))}, { new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionBook()}, { new EntityVillager.MerchantRecipeOptionSell(Items.NAME_TAG, new EntityVillager.MerchantOptionRandomRange(20, 22))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.ROTTEN_FLESH, new EntityVillager.MerchantOptionRandomRange(36, 40)), new EntityVillager.MerchantRecipeOptionBuy(Items.GOLD_INGOT, new EntityVillager.MerchantOptionRandomRange(8, 10))}, { new EntityVillager.MerchantRecipeOptionSell(Items.REDSTONE, new EntityVillager.MerchantOptionRandomRange(-4, -1)), new EntityVillager.MerchantRecipeOptionSell(new ItemStack(Items.DYE, 1, EnumColor.BLUE.getInvColorIndex()), new EntityVillager.MerchantOptionRandomRange(-2, -1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.ENDER_EYE, new EntityVillager.MerchantOptionRandomRange(7, 11)), new EntityVillager.MerchantRecipeOptionSell(Item.getItemOf(Blocks.GLOWSTONE), new EntityVillager.MerchantOptionRandomRange(-3, -1))}, { new EntityVillager.MerchantRecipeOptionSell(Items.EXPERIENCE_BOTTLE, new EntityVillager.MerchantOptionRandomRange(3, 11))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_HELMET, new EntityVillager.MerchantOptionRandomRange(4, 6))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(10, 14))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(16, 19))}, { new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_BOOTS, new EntityVillager.MerchantOptionRandomRange(5, 7)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_LEGGINGS, new EntityVillager.MerchantOptionRandomRange(9, 11)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_HELMET, new EntityVillager.MerchantOptionRandomRange(5, 7)), new EntityVillager.MerchantRecipeOptionSell(Items.CHAINMAIL_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(11, 15))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.IRON_AXE, new EntityVillager.MerchantOptionRandomRange(6, 8))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_SWORD, new EntityVillager.MerchantOptionRandomRange(9, 10))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_SWORD, new EntityVillager.MerchantOptionRandomRange(12, 15)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_AXE, new EntityVillager.MerchantOptionRandomRange(9, 12))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_SHOVEL, new EntityVillager.MerchantOptionRandomRange(5, 7))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.IRON_INGOT, new EntityVillager.MerchantOptionRandomRange(7, 9)), new EntityVillager.MerchantRecipeOptionEnchant(Items.IRON_PICKAXE, new EntityVillager.MerchantOptionRandomRange(9, 11))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.DIAMOND, new EntityVillager.MerchantOptionRandomRange(3, 4)), new EntityVillager.MerchantRecipeOptionEnchant(Items.DIAMOND_PICKAXE, new EntityVillager.MerchantOptionRandomRange(12, 15))}}}, { { { new EntityVillager.MerchantRecipeOptionBuy(Items.PORKCHOP, new EntityVillager.MerchantOptionRandomRange(14, 18)), new EntityVillager.MerchantRecipeOptionBuy(Items.CHICKEN, new EntityVillager.MerchantOptionRandomRange(14, 18))}, { new EntityVillager.MerchantRecipeOptionBuy(Items.COAL, new EntityVillager.MerchantOptionRandomRange(16, 24)), new EntityVillager.MerchantRecipeOptionSell(Items.COOKED_PORKCHOP, new EntityVillager.MerchantOptionRandomRange(-7, -5)), new EntityVillager.MerchantRecipeOptionSell(Items.COOKED_CHICKEN, new EntityVillager.MerchantOptionRandomRange(-8, -6))}}, { { new EntityVillager.MerchantRecipeOptionBuy(Items.LEATHER, new EntityVillager.MerchantOptionRandomRange(9, 12)), new EntityVillager.MerchantRecipeOptionSell(Items.LEATHER_LEGGINGS, new EntityVillager.MerchantOptionRandomRange(2, 4))}, { new EntityVillager.MerchantRecipeOptionEnchant(Items.LEATHER_CHESTPLATE, new EntityVillager.MerchantOptionRandomRange(7, 12))}, { new EntityVillager.MerchantRecipeOptionSell(Items.SADDLE, new EntityVillager.MerchantOptionRandomRange(8, 10))}}}}; + + public EntityVillager(World world) { +@@ -145,7 +146,7 @@ public class EntityVillager extends EntityAgeable implements IMerchant, NPC { + + protected void h() { + super.h(); +- this.datawatcher.a(16, Integer.valueOf(0)); ++ this.datawatcher.a(16, Integer.valueOf(0), META_TYPE, 0); + } + + public void b(NBTTagCompound nbttagcompound) { +@@ -216,7 +217,7 @@ public class EntityVillager extends EntityAgeable implements IMerchant, NPC { + } + + public void setProfession(int i) { +- this.datawatcher.watch(16, Integer.valueOf(i)); ++ this.datawatcher.watch(16, Integer.valueOf(i), META_TYPE, i); + } + + public int getProfession() { +diff --git a/src/main/java/net/minecraft/server/EntityWitch.java b/src/main/java/net/minecraft/server/EntityWitch.java +new file mode 100644 +index 0000000..ce9b56a +--- /dev/null ++++ b/src/main/java/net/minecraft/server/EntityWitch.java +@@ -0,0 +1,185 @@ ++package net.minecraft.server; ++ ++import java.util.List; ++import java.util.Random; ++import java.util.UUID; ++ ++public class EntityWitch extends EntityMonster ++ implements IRangedEntity ++{ ++ private static final UUID a = UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"); ++ private static final AttributeModifier b = new AttributeModifier(a, "Drinking speed penalty", -0.25D, 0).a(false); ++ ++ private static final Item[] c = { Items.GLOWSTONE_DUST, Items.SUGAR, Items.REDSTONE, Items.SPIDER_EYE, Items.GLASS_BOTTLE, Items.GUNPOWDER, Items.STICK, Items.STICK }; ++ public static DataIndex META_AGGRESSIVE = DataWatcher.getIndex(EntityWitch.class, DataType.BOOLEAN); ++ private int bm; ++ ++ public EntityWitch(World paramWorld) ++ { ++ super(paramWorld); ++ setSize(0.6F, 1.95F); ++ ++ this.goalSelector.a(1, new PathfinderGoalFloat(this)); ++ this.goalSelector.a(2, new PathfinderGoalArrowAttack(this, 1.0D, 60, 10.0F)); ++ this.goalSelector.a(2, new PathfinderGoalRandomStroll(this, 1.0D)); ++ this.goalSelector.a(3, new PathfinderGoalLookAtPlayer(this, EntityHuman.class, 8.0F)); ++ this.goalSelector.a(3, new PathfinderGoalRandomLookaround(this)); ++ ++ this.targetSelector.a(1, new PathfinderGoalHurtByTarget(this, false, new Class[0])); ++ this.targetSelector.a(2, new PathfinderGoalNearestAttackableTarget(this, EntityHuman.class, true)); ++ } ++ ++ protected void h() ++ { ++ super.h(); ++ ++ getDataWatcher().a(21, Byte.valueOf((byte)0), META_AGGRESSIVE, false); ++ } ++ ++ protected String z() ++ { ++ return null; ++ } ++ ++ protected String bo() ++ { ++ return null; ++ } ++ ++ protected String bp() ++ { ++ return null; ++ } ++ ++ public void a(boolean paramBoolean) { ++ getDataWatcher().watch(21, Byte.valueOf((byte)(paramBoolean ? 1 : 0)), META_AGGRESSIVE, paramBoolean); ++ } ++ ++ public boolean n() { ++ return getDataWatcher().getByte(21) == 1; ++ } ++ ++ protected void initAttributes() ++ { ++ super.initAttributes(); ++ ++ getAttributeInstance(GenericAttributes.maxHealth).setValue(26.0D); ++ getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).setValue(0.25D); ++ } ++ ++ public void m() ++ { ++ if (!this.world.isClientSide) ++ { ++ Object localObject; ++ if (n()) { ++ if (this.bm-- <= 0) { ++ a(false); ++ ItemStack localItemStack = bA(); ++ setEquipment(0, null); ++ ++ if ((localItemStack != null) && (localItemStack.getItem() == Items.POTION)) { ++ localObject = Items.POTION.h(localItemStack); ++ if (localObject != null) { ++ for (MobEffect localMobEffect : (List)localObject) { ++ addEffect(new MobEffect(localMobEffect)); ++ } ++ } ++ } ++ ++ getAttributeInstance(GenericAttributes.MOVEMENT_SPEED).c(b); ++ } ++ } else { ++ int i = -1; ++ ++ if ((this.random.nextFloat() < 0.15F) && (a(Material.WATER)) && (!hasEffect(MobEffectList.WATER_BREATHING))) ++ i = 8237; ++ else if ((this.random.nextFloat() < 0.15F) && (isBurning()) && (!hasEffect(MobEffectList.FIRE_RESISTANCE))) ++ i = 16307; ++ else if ((this.random.nextFloat() < 0.05F) && (getHealth() < getMaxHealth())) ++ i = 16341; ++ else if ((this.random.nextFloat() < 0.25F) && (getGoalTarget() != null) && (!hasEffect(MobEffectList.FASTER_MOVEMENT)) && (getGoalTarget().h(this) > 121.0D)) ++ i = 16274; ++ else if ((this.random.nextFloat() < 0.25F) && (getGoalTarget() != null) && (!hasEffect(MobEffectList.FASTER_MOVEMENT)) && (getGoalTarget().h(this) > 121.0D)) { ++ i = 16274; ++ } ++ ++ if (i > -1) { ++ setEquipment(0, new ItemStack(Items.POTION, 1, i)); ++ this.bm = bA().l(); ++ a(true); ++ localObject = getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); ++ ((AttributeInstance)localObject).c(b); ++ ((AttributeInstance)localObject).b(b); ++ } ++ } ++ ++ if (this.random.nextFloat() < 0.00075F) { ++ this.world.broadcastEntityEffect(this, (byte)15); ++ } ++ } ++ ++ super.m(); ++ } ++ ++ protected float applyMagicModifier(DamageSource paramDamageSource, float paramFloat) ++ { ++ paramFloat = super.applyMagicModifier(paramDamageSource, paramFloat); ++ ++ if (paramDamageSource.getEntity() == this) { ++ paramFloat = 0.0F; ++ } ++ if (paramDamageSource.isMagic()) { ++ paramFloat = (float)(paramFloat * 0.15D); ++ } ++ ++ return paramFloat; ++ } ++ ++ protected void dropDeathLoot(boolean paramBoolean, int paramInt) ++ { ++ int i = this.random.nextInt(3) + 1; ++ for (int j = 0; j < i; j++) { ++ int k = this.random.nextInt(3); ++ Item localItem = c[this.random.nextInt(c.length)]; ++ if (paramInt > 0) { ++ k += this.random.nextInt(paramInt + 1); ++ } ++ ++ for (int m = 0; m < k; m++) ++ a(localItem, 1); ++ } ++ } ++ ++ public void a(EntityLiving paramEntityLiving, float paramFloat) ++ { ++ if (n()) { ++ return; ++ } ++ ++ EntityPotion localEntityPotion = new EntityPotion(this.world, this, 32732); ++ double d1 = paramEntityLiving.locY + paramEntityLiving.getHeadHeight() - 1.100000023841858D; ++ localEntityPotion.pitch -= -20.0F; ++ double d2 = paramEntityLiving.locX + paramEntityLiving.motX - this.locX; ++ double d3 = d1 - this.locY; ++ double d4 = paramEntityLiving.locZ + paramEntityLiving.motZ - this.locZ; ++ float f = MathHelper.sqrt(d2 * d2 + d4 * d4); ++ ++ if ((f >= 8.0F) && (!paramEntityLiving.hasEffect(MobEffectList.SLOWER_MOVEMENT))) ++ localEntityPotion.setPotionValue(32698); ++ else if ((paramEntityLiving.getHealth() >= 8.0F) && (!paramEntityLiving.hasEffect(MobEffectList.POISON))) ++ localEntityPotion.setPotionValue(32660); ++ else if ((f <= 3.0F) && (!paramEntityLiving.hasEffect(MobEffectList.WEAKNESS)) && (this.random.nextFloat() < 0.25F)) { ++ localEntityPotion.setPotionValue(32696); ++ } ++ ++ localEntityPotion.shoot(d2, d3 + f * 0.2F, d4, 0.75F, 8.0F); ++ ++ this.world.addEntity(localEntityPotion); ++ } ++ ++ public float getHeadHeight() ++ { ++ return 1.62F; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/EntityWither.java b/src/main/java/net/minecraft/server/EntityWither.java +index fb19bad..4efe5bc 100644 +--- a/src/main/java/net/minecraft/server/EntityWither.java ++++ b/src/main/java/net/minecraft/server/EntityWither.java +@@ -30,6 +30,12 @@ public class EntityWither extends EntityMonster implements IRangedEntity { + } + }; + ++ public static DataIndex META_TARGET_1 = DataWatcher.getIndex(EntityWither.class, DataType.INTEGER); ++ public static DataIndex META_TARGET_2 = DataWatcher.getIndex(EntityWither.class, DataType.INTEGER); ++ public static DataIndex META_TARGET_3 = DataWatcher.getIndex(EntityWither.class, DataType.INTEGER); ++ public static DataIndex META_INVUL_TIME = DataWatcher.getIndex(EntityWither.class, DataType.INTEGER); ++ public static DataIndex[] META_HEAD_TARGETS = new DataIndex[] {META_TARGET_1, META_TARGET_2, META_TARGET_3}; ++ + public EntityWither(World world) { + super(world); + this.setHealth(this.getMaxHealth()); +@@ -48,10 +54,10 @@ public class EntityWither extends EntityMonster implements IRangedEntity { + + protected void h() { + super.h(); +- this.datawatcher.a(17, new Integer(0)); +- this.datawatcher.a(18, new Integer(0)); +- this.datawatcher.a(19, new Integer(0)); +- this.datawatcher.a(20, new Integer(0)); ++ this.datawatcher.a(17, new Integer(0), META_TARGET_1, new Integer(0)); ++ this.datawatcher.a(18, new Integer(0), META_TARGET_2, new Integer(0)); ++ this.datawatcher.a(19, new Integer(0), META_TARGET_3, new Integer(0)); ++ this.datawatcher.a(20, new Integer(0), META_INVUL_TIME, new Integer(0)); + } + + public void b(NBTTagCompound nbttagcompound) { +@@ -478,7 +484,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { + } + + public void r(int i) { +- this.datawatcher.watch(20, Integer.valueOf(i)); ++ this.datawatcher.watch(20, Integer.valueOf(i), META_INVUL_TIME, new Integer(i)); + } + + public int s(int i) { +@@ -486,7 +492,7 @@ public class EntityWither extends EntityMonster implements IRangedEntity { + } + + public void b(int i, int j) { +- this.datawatcher.watch(17 + i, Integer.valueOf(j)); ++ this.datawatcher.watch(17 + i, Integer.valueOf(j), META_HEAD_TARGETS[i], j); + } + + public boolean cm() { +diff --git a/src/main/java/net/minecraft/server/EntityWitherSkull.java b/src/main/java/net/minecraft/server/EntityWitherSkull.java +index f0e627b..a66d66a 100644 +--- a/src/main/java/net/minecraft/server/EntityWitherSkull.java ++++ b/src/main/java/net/minecraft/server/EntityWitherSkull.java +@@ -3,6 +3,7 @@ package net.minecraft.server; + import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit + + public class EntityWitherSkull extends EntityFireball { ++ public static DataIndex META_BLUE = DataWatcher.getIndex(EntityWitherSkull.class, DataType.BOOLEAN); + + public EntityWitherSkull(World world) { + super(world); +@@ -90,7 +91,7 @@ public class EntityWitherSkull extends EntityFireball { + } + + protected void h() { +- this.datawatcher.a(10, Byte.valueOf((byte) 0)); ++ this.datawatcher.a(10, Byte.valueOf((byte) 0), META_BLUE, false); + } + + public boolean isCharged() { +@@ -98,6 +99,6 @@ public class EntityWitherSkull extends EntityFireball { + } + + public void setCharged(boolean flag) { +- this.datawatcher.watch(10, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.datawatcher.watch(10, Byte.valueOf((byte) (flag ? 1 : 0)), META_BLUE, flag); + } + } +diff --git a/src/main/java/net/minecraft/server/EntityWolf.java b/src/main/java/net/minecraft/server/EntityWolf.java +index 469c87a..b7c6cc7 100644 +--- a/src/main/java/net/minecraft/server/EntityWolf.java ++++ b/src/main/java/net/minecraft/server/EntityWolf.java +@@ -15,6 +15,9 @@ public class EntityWolf extends EntityTameableAnimal { + private boolean br; + private float bs; + private float bt; ++ public static DataIndex META_WOLF_HEALTH = DataWatcher.getIndex(EntityWolf.class, DataType.FLOAT); ++ public static DataIndex META_BEGGING = DataWatcher.getIndex(EntityWolf.class, DataType.BOOLEAN); ++ public static DataIndex META_COLLAR = DataWatcher.getIndex(EntityWolf.class, DataType.INTEGER); + + public EntityWolf(World world) { + super(world); +@@ -82,14 +85,14 @@ public class EntityWolf extends EntityTameableAnimal { + // CraftBukkit end + + protected void E() { +- this.datawatcher.watch(18, Float.valueOf(this.getHealth())); ++ this.datawatcher.watch(18, Float.valueOf(this.getHealth()), META_WOLF_HEALTH, getHealth()); + } + + protected void h() { + super.h(); +- this.datawatcher.a(18, new Float(this.getHealth())); +- this.datawatcher.a(19, new Byte((byte) 0)); +- this.datawatcher.a(20, new Byte((byte) EnumColor.RED.getColorIndex())); ++ this.datawatcher.a(18, new Float(this.getHealth()), META_WOLF_HEALTH, getHealth()); ++ this.datawatcher.a(19, new Byte((byte) 0), META_BEGGING, false); ++ this.datawatcher.a(20, new Byte((byte) EnumColor.RED.getColorIndex()), META_COLLAR, EnumColor.RED.getColorIndex()); + } + + protected void a(BlockPosition blockposition, Block block) { +@@ -323,9 +326,9 @@ public class EntityWolf extends EntityTameableAnimal { + byte b0 = this.datawatcher.getByte(16); + + if (flag) { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 2))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 2)), META_SITTING_TAMED, (byte) (b0 | 2)); + } else { +- this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -3))); ++ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -3)), META_SITTING_TAMED, (byte) (b0 & -3)); + } + + } +@@ -335,7 +338,7 @@ public class EntityWolf extends EntityTameableAnimal { + } + + public void setCollarColor(EnumColor enumcolor) { +- this.datawatcher.watch(20, Byte.valueOf((byte) (enumcolor.getInvColorIndex() & 15))); ++ this.datawatcher.watch(20, Byte.valueOf((byte) (enumcolor.getInvColorIndex() & 15)), META_COLLAR, enumcolor.getInvColorIndex() & 15); + } + + public EntityWolf b(EntityAgeable entityageable) { +@@ -352,9 +355,9 @@ public class EntityWolf extends EntityTameableAnimal { + + public void p(boolean flag) { + if (flag) { +- this.datawatcher.watch(19, Byte.valueOf((byte) 1)); ++ this.datawatcher.watch(19, Byte.valueOf((byte) 1), META_BEGGING, flag); + } else { +- this.datawatcher.watch(19, Byte.valueOf((byte) 0)); ++ this.datawatcher.watch(19, Byte.valueOf((byte) 0), META_BEGGING, flag); + } + + } +diff --git a/src/main/java/net/minecraft/server/EntityZombie.java b/src/main/java/net/minecraft/server/EntityZombie.java +index 1a8d3d8..253ff5e 100644 +--- a/src/main/java/net/minecraft/server/EntityZombie.java ++++ b/src/main/java/net/minecraft/server/EntityZombie.java +@@ -23,6 +23,10 @@ public class EntityZombie extends EntityMonster { + private float bp = -1.0F; + private float bq; + private int lastTick = MinecraftServer.currentTick; // CraftBukkit - add field ++ public static DataIndex META_CHILD = DataWatcher.getIndex(EntityZombie.class, DataType.BOOLEAN); ++ public static DataIndex META_UNKNOWN_INTEGER = DataWatcher.getIndex(EntityZombie.class, DataType.INTEGER); ++ public static DataIndex META_VILLAGER = DataWatcher.getIndex(EntityZombie.class, DataType.BOOLEAN); ++ public static DataIndex META_CONVERTING = DataWatcher.getIndex(EntityZombie.class, DataType.BOOLEAN); + + public EntityZombie(World world) { + super(world); +@@ -57,9 +61,9 @@ public class EntityZombie extends EntityMonster { + + protected void h() { + super.h(); +- this.getDataWatcher().a(12, Byte.valueOf((byte) 0)); +- this.getDataWatcher().a(13, Byte.valueOf((byte) 0)); +- this.getDataWatcher().a(14, Byte.valueOf((byte) 0)); ++ this.getDataWatcher().a(12, Byte.valueOf((byte) 0), META_CHILD, false); ++ this.getDataWatcher().a(13, Byte.valueOf((byte) 0), META_VILLAGER, false); ++ this.getDataWatcher().a(14, Byte.valueOf((byte) 0), META_CONVERTING, false); + } + + public int br() { +@@ -101,7 +105,7 @@ public class EntityZombie extends EntityMonster { + } + + public void setBaby(boolean flag) { +- this.getDataWatcher().watch(12, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.getDataWatcher().watch(12, Byte.valueOf((byte) (flag ? 1 : 0)), META_CHILD, flag); + if (this.world != null && !this.world.isClientSide) { + AttributeInstance attributeinstance = this.getAttributeInstance(GenericAttributes.MOVEMENT_SPEED); + +@@ -119,7 +123,7 @@ public class EntityZombie extends EntityMonster { + } + + public void setVillager(boolean flag) { +- this.getDataWatcher().watch(13, Byte.valueOf((byte) (flag ? 1 : 0))); ++ this.getDataWatcher().watch(13, Byte.valueOf((byte) (flag ? 1 : 0)), META_VILLAGER, flag); + } + + public void m() { +@@ -462,7 +466,7 @@ public class EntityZombie extends EntityMonster { + + protected void a(int i) { + this.bn = i; +- this.getDataWatcher().watch(14, Byte.valueOf((byte) 1)); ++ this.getDataWatcher().watch(14, Byte.valueOf((byte) 1), META_CONVERTING, true); + this.removeEffect(MobEffectList.WEAKNESS.id); + this.addEffect(new MobEffect(MobEffectList.INCREASE_DAMAGE.id, i, Math.min(this.world.getDifficulty().a() - 1, 0))); + this.world.broadcastEntityEffect(this, (byte) 16); +diff --git a/src/main/java/net/minecraft/server/EnumProtocol.java b/src/main/java/net/minecraft/server/EnumProtocol.java +new file mode 100644 +index 0000000..eb425dc +--- /dev/null ++++ b/src/main/java/net/minecraft/server/EnumProtocol.java +@@ -0,0 +1,304 @@ ++// Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov. ++// Jad home page: http://www.kpdus.com/jad.html ++// Decompiler options: packimports(3) ++// Source File Name: SourceFile ++ ++package net.minecraft.server; ++ ++import com.google.common.collect.*; ++import java.util.*; ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; ++import java.util.Map.Entry; ++ ++public enum EnumProtocol ++{ ++ HANDSHAKING(-1) { ++ ++ ++ { ++ a(EnumProtocolDirection.SERVERBOUND, PacketHandshakingInSetProtocol.class, 0); ++ } ++ }, ++ ++ ++ PLAY(0) { ++ ++ ++ { ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSetCompression.class, 70, -1); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutMapChunkBulk.class, 38, -1); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutUpdateEntityNBT.class, 73, -1); ++ ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSpawnEntity.class, 14, 0); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSpawnEntityExperienceOrb.class, 17, 1); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSpawnEntityWeather.class, 44, 2); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSpawnEntityLiving.class, 15, 3); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSpawnEntityPainting.class, 16, 4); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutNamedEntitySpawn.class, 12, 5); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutAnimation.class, 11, 6); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutStatistic.class, 55, 7); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutBlockBreakAnimation.class, 37, 8); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutTileEntityData.class, 53, 9); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutBlockAction.class, 36, 10); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutBlockChange.class, 35, 11); ++ // Boss bar ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutServerDifficulty.class, 65, 13); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutTabComplete.class, 58, 14); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutChat.class, 2, 15); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutMultiBlockChange.class, 34, 16); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutTransaction.class, 50, 17); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutCloseWindow.class, 46, 18); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutOpenWindow.class, 45, 19); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutWindowItems.class, 48, 20); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutWindowData.class, 49, 21); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSetSlot.class, 47, 22); ++ // Set cooldown ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutCustomPayload.class, 63, 24); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutNamedSoundEffect.class, 41, 25); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutKickDisconnect.class, 64, 26); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityStatus.class, 26, 27); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutExplosion.class, 39, 28); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutUnloadChunk.class, -1, 29); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutGameStateChange.class, 43, 30); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutKeepAlive.class, 0, 31); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutMapChunk.class, 33, 32); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutWorldEvent.class, 40, 33); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutWorldParticles.class, 42, 34); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutLogin.class, 1, 35); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutMap.class, 52, 36); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntity.PacketPlayOutRelEntityMove.class, 21, 37); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntity.PacketPlayOutRelEntityMoveLook.class, 23, 38); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntity.PacketPlayOutEntityLook.class, 22, 39); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntity.class, 20, 40); ++ // ??? double, double, double, float float ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutOpenSignEditor.class, 54, 42); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutAbilities.class, 57, 43); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutCombatEvent.class, 66, 44); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutPlayerInfo.class, 56, 45); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutPosition.class, 8, 46); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutBed.class, 10, 47); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityDestroy.class, 19, 48); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutRemoveEntityEffect.class, 30, 49); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutResourcePackSend.class, 72, 50); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutRespawn.class, 7, 51); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityHeadRotation.class, 25, 52); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutWorldBorder.class, 68, 53); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutCamera.class, 67, 54); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutHeldItemSlot.class, 9, 55); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutScoreboardDisplayObjective.class, 61, 56); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityMetadata.class, 28, 57); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutAttachEntity.class, 27, 58); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityVelocity.class, 18, 59); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityEquipment.class, 4, 60); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutExperience.class, 31, 61); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutUpdateHealth.class, 6, 62); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutScoreboardObjective.class, 59, 63); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutNewAttachEntity.class, -1, 64); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutScoreboardTeam.class, 62, 65); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutScoreboardScore.class, 60, 66); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutSpawnPosition.class, 5, 67); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutUpdateTime.class, 3, 68); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutTitle.class, 69, 69); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutUpdateSign.class, 51, 70); ++ // Subtitle packet ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutPlayerListHeaderFooter.class, 71, 72); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutCollect.class, 13, 73); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityTeleport.class, 24, 74); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutUpdateAttributes.class, 32, 75); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketPlayOutEntityEffect.class, 29, 76); ++ ++ ++ ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInArmAnimation.class, 10, 26); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInTabComplete.class, 20, 1); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInChat.class, 1, 2); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInClientCommand.class, 22, 3); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInSettings.class, 21, 4); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInTransaction.class, 15, 5); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInEnchantItem.class, 17, 6); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInWindowClick.class, 14, 7); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInCloseWindow.class, 13, 8); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInCustomPayload.class, 23, 9); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInUseEntity.class, 2, 10); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInKeepAlive.class, 0, 11); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInFlying.PacketPlayInPosition.class, 4, 12); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInFlying.PacketPlayInPositionLook.class, 6, 13); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInFlying.PacketPlayInLook.class, 5, 14); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInFlying.class, 3, 15); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInUnknownPosition.class, -1, 16); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInUnknownFloats.class, -1, 17); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInAbilities.class, 19, 18); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInBlockDig.class, 7, 19); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInEntityAction.class, 11, 20); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInSteerVehicle.class, 12, 21); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInResourcePackStatus.class, 25, 22); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInHeldItemSlot.class, 9, 23); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInSetCreativeSlot.class, 16, 24); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInUpdateSign.class, 18, 25); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInLeftClick.class, -1, 0); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInSpectate.class, 24, 27); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInBlockPlace.class, 8, 28); ++ a(EnumProtocolDirection.SERVERBOUND, PacketPlayInRightClick.class, -1, 29); ++ ++ } ++ }, ++ ++ ++ STATUS(1) { ++ ++ ++ { ++ a(EnumProtocolDirection.SERVERBOUND, PacketStatusInStart.class, 0); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketStatusOutServerInfo.class, 0); ++ a(EnumProtocolDirection.SERVERBOUND, PacketStatusInPing.class, 1); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketStatusOutPong.class, 1); ++ } ++ }, ++ ++ ++ LOGIN(2) { ++ ++ ++ { ++ a(EnumProtocolDirection.CLIENTBOUND, PacketLoginOutDisconnect.class, 0); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketLoginOutEncryptionBegin.class, 1); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketLoginOutSuccess.class, 2); ++ a(EnumProtocolDirection.CLIENTBOUND, PacketLoginOutSetCompression.class, 3); ++ a(EnumProtocolDirection.SERVERBOUND, PacketLoginInStart.class, 0); ++ a(EnumProtocolDirection.SERVERBOUND, PacketLoginInEncryptionBegin.class, 1); ++ } ++ }; ++ ++ private EnumProtocol(int i1) ++ { ++ j = Maps.newEnumMap(EnumProtocolDirection.class); ++ i = i1; ++ } ++ ++ protected EnumProtocol a(EnumProtocolDirection enumprotocoldirection, Class class1, int id19) ++ { ++ Object obj = (BiMap)j.get(enumprotocoldirection); ++ if(obj == null) ++ { ++ obj = HashBiMap.create(); ++ j.put(enumprotocoldirection, obj); ++ } ++ if(((BiMap) (obj)).containsValue(class1)) ++ { ++ String s = (new StringBuilder()).append(enumprotocoldirection).append(" packet ").append(class1).append(" is already known to ID ").append(((BiMap) (obj)).inverse().get(class1)).toString(); ++ LogManager.getLogger().fatal(s); ++ throw new IllegalArgumentException(s); ++ } else ++ { ++ ((BiMap) (obj)).put(new HashMap.SimpleEntry(((BiMap) (obj)).size(), id19), class1); ++ return this; ++ } ++ } ++ ++ protected EnumProtocol a(EnumProtocolDirection enumprotocoldirection, Class class1, int id18, int id19) ++ { ++ Object obj = (BiMap)j.get(enumprotocoldirection); ++ if(obj == null) ++ { ++ obj = HashBiMap.create(); ++ j.put(enumprotocoldirection, obj); ++ } ++ if(((BiMap) (obj)).containsValue(class1)) ++ { ++ String s = (new StringBuilder()).append(enumprotocoldirection).append(" packet ").append(class1).append(" is already known to ID ").append(((BiMap) (obj)).inverse().get(class1)).toString(); ++ LogManager.getLogger().fatal(s); ++ throw new IllegalArgumentException(s); ++ } else ++ { ++ ((BiMap) (obj)).put(new HashMap.SimpleEntry(id18, id19), class1); ++ return this; ++ } ++ } ++ ++ public Integer a(EnumProtocolDirection enumprotocoldirection, Packet packet, boolean is1_8) ++ { ++ Entry entry = (Entry) ((BiMap)j.get(enumprotocoldirection)).inverse().get(packet.getClass()); ++ if ((Integer) (is1_8 ? entry.getKey() : entry.getValue()) < 0){System.out.print("Trying to send unsupported " + packet.getClass().getSimpleName());Thread.dumpStack();} ++ return (Integer) (is1_8 ? entry.getKey() : entry.getValue()); ++ } ++ ++ public Packet a(EnumProtocolDirection enumprotocoldirection, int l, boolean is1_8) ++ throws IllegalAccessException, InstantiationException ++ { ++ for (Entry entry : (Set) ((BiMap) j.get(enumprotocoldirection)).entrySet()) ++ { ++ Entry entry1 = (Entry) entry.getKey(); ++ if (l == (is1_8 ? (Integer) entry1.getKey() : (Integer) entry1.getValue())) ++ { ++ return (Packet) ((Class) entry.getValue()).newInstance(); ++ } ++ } ++ return null; ++ } ++ ++ public int a() ++ { ++ return i; ++ } ++ ++ public static EnumProtocol a(int l) ++ { ++ if(l < e || l > f) ++ return null; ++ else ++ return g[l - e]; ++ } ++ ++ public static EnumProtocol a(Packet packet) ++ { ++ return (EnumProtocol)h.get(packet.getClass()); ++ } ++ ++ private static int e; ++ private static int f; ++ private static final EnumProtocol g[]; ++ private static final Map h; ++ private final int i; ++ private final Map j; ++ ++ static ++ { ++ e = -1; ++ f = 2; ++ g = new EnumProtocol[(f - e) + 1]; ++ h = Maps.newHashMap(); ++ EnumProtocol aenumprotocol[] = values(); ++ int l = aenumprotocol.length; ++ for(int i1 = 0; i1 < l; i1++) ++ { ++ EnumProtocol enumprotocol = aenumprotocol[i1]; ++ int j1 = enumprotocol.a(); ++ if(j1 < e || j1 > f) ++ throw new Error((new StringBuilder()).append("Invalid protocol ID ").append(Integer.toString(j1)).toString()); ++ g[j1 - e] = enumprotocol; ++ for(Iterator iterator = enumprotocol.j.keySet().iterator(); iterator.hasNext();) ++ { ++ EnumProtocolDirection enumprotocoldirection = (EnumProtocolDirection)iterator.next(); ++ Iterator iterator1 = ((BiMap)enumprotocol.j.get(enumprotocoldirection)).values().iterator(); ++ while(iterator1.hasNext()) ++ { ++ Class class1 = (Class)iterator1.next(); ++ if(h.containsKey(class1) && h.get(class1) != enumprotocol) ++ throw new Error((new StringBuilder()).append("Packet ").append(class1).append(" is already assigned to protocol ").append(h.get(class1)).append(" - can't reassign to ").append(enumprotocol).toString()); ++ try ++ { ++ class1.newInstance(); ++ } ++ catch(Throwable throwable) ++ { ++ throw new Error((new StringBuilder()).append("Packet ").append(class1).append(" fails instantiation checks! ").append(class1).toString()); ++ } ++ h.put(class1, enumprotocol); ++ } ++ } ++ ++ } ++ ++ } ++} +diff --git a/src/main/java/net/minecraft/server/HandshakeListener.java b/src/main/java/net/minecraft/server/HandshakeListener.java +index 64f6a9b..bec9f80 100644 +--- a/src/main/java/net/minecraft/server/HandshakeListener.java ++++ b/src/main/java/net/minecraft/server/HandshakeListener.java +@@ -22,6 +22,16 @@ public class HandshakeListener implements PacketHandshakingInListener { + } + + public void a(PacketHandshakingInSetProtocol packethandshakinginsetprotocol) { ++ ++ int version = packethandshakinginsetprotocol.b(); ++ //System.out.print(version); ++ boolean supported = version == 47 || version == 89 || version == 86; ++ ++ if (supported) ++ { ++ this.b.channel.attr(NetworkManager.protocolVersion).set(Integer.valueOf(version)); ++ } ++ + switch (HandshakeListener.SyntheticClass_1.a[packethandshakinginsetprotocol.a().ordinal()]) { + case 1: + this.b.a(EnumProtocol.LOGIN); +@@ -61,12 +71,8 @@ public class HandshakeListener implements PacketHandshakingInListener { + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); + } + // CraftBukkit end +- +- if (packethandshakinginsetprotocol.b() > 47) { +- chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage, "1.8.8" ) ); // Spigot +- this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); +- this.b.close(chatcomponenttext); +- } else if (packethandshakinginsetprotocol.b() < 47) { ++ ++ if (!supported) { + chatcomponenttext = new ChatComponentText( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage, "1.8.8" ) ); // Spigot + this.b.handle(new PacketLoginOutDisconnect(chatcomponenttext)); + this.b.close(chatcomponenttext); +diff --git a/src/main/java/net/minecraft/server/MathHelper.java b/src/main/java/net/minecraft/server/MathHelper.java +new file mode 100644 +index 0000000..db19ad4 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/MathHelper.java +@@ -0,0 +1,309 @@ ++package net.minecraft.server; ++ ++import java.util.Random; ++import java.util.UUID; ++ ++public class MathHelper { ++ public static final float a; ++ private static final float[] b; ++ private static final int[] c; ++ private static final double d; ++ private static final double[] e; ++ private static final double[] f; ++ ++ public static float sin(float f) { ++ return b[(int)(f * 10430.378f) & 65535]; ++ } ++ ++ public static float cos(float f) { ++ return b[(int)(f * 10430.378f + 16384.0f) & 65535]; ++ } ++ ++ public static float c(float f) { ++ return (float)Math.sqrt(f); ++ } ++ ++ public static float sqrt(double d) { ++ return (float)Math.sqrt(d); ++ } ++ ++ public static int d(float f) { ++ int n = (int)f; ++ return f < (float)n ? n - 1 : n; ++ } ++ ++ public static int floor(double d) { ++ int n = (int)d; ++ return d < (double)n ? n - 1 : n; ++ } ++ ++ public static long d(double d) { ++ long l = (long)d; ++ return d < (double)l ? l - 1 : l; ++ } ++ ++ public static float e(float f) { ++ return f >= 0.0f ? f : - f; ++ } ++ ++ public static int a(int n) { ++ return n >= 0 ? n : - n; ++ } ++ ++ public static int f(float f) { ++ int n = (int)f; ++ return f > (float)n ? n + 1 : n; ++ } ++ ++ public static int f(double d) { ++ int n = (int)d; ++ return d > (double)n ? n + 1 : n; ++ } ++ ++ public static int clamp(int n, int n2, int n3) { ++ if (n < n2) { ++ return n2; ++ } ++ if (n > n3) { ++ return n3; ++ } ++ return n; ++ } ++ ++ public static float a(float f, float f2, float f3) { ++ if (f < f2) { ++ return f2; ++ } ++ if (f > f3) { ++ return f3; ++ } ++ return f; ++ } ++ ++ public static double a(double d, double d2, double d3) { ++ if (d < d2) { ++ return d2; ++ } ++ if (d > d3) { ++ return d3; ++ } ++ return d; ++ } ++ ++ public static double b(double d, double d2, double d3) { ++ if (d3 < 0.0) { ++ return d; ++ } ++ if (d3 > 1.0) { ++ return d2; ++ } ++ return d + (d2 - d) * d3; ++ } ++ ++ public static double a(double d, double d2) { ++ if (d < 0.0) { ++ d = - d; ++ } ++ if (d2 < 0.0) { ++ d2 = - d2; ++ } ++ return d > d2 ? d : d2; ++ } ++ ++ public static int nextInt(Random random, int n, int n2) { ++ if (n >= n2) { ++ return n; ++ } ++ return random.nextInt(n2 - n + 1) + n; ++ } ++ ++ public static float a(Random random, float f, float f2) { ++ if (f >= f2) { ++ return f; ++ } ++ return random.nextFloat() * (f2 - f) + f; ++ } ++ ++ public static double a(Random random, double d, double d2) { ++ if (d >= d2) { ++ return d; ++ } ++ return random.nextDouble() * (d2 - d) + d; ++ } ++ ++ public static double a(long[] arrl) { ++ long l = 0; ++ for (long l2 : arrl) { ++ l += l2; ++ } ++ return (double)l / (double)arrl.length; ++ } ++ ++ public static float g(float f) { ++ if ((f %= 360.0f) >= 180.0f) { ++ f -= 360.0f; ++ } ++ if (f < -180.0f) { ++ f += 360.0f; ++ } ++ return f; ++ } ++ ++ public static double g(double d) { ++ if ((d %= 360.0) >= 180.0) { ++ d -= 360.0; ++ } ++ if (d < -180.0) { ++ d += 360.0; ++ } ++ return d; ++ } ++ ++ public static int a(String string, int n) { ++ try { ++ return Integer.parseInt(string); ++ } ++ catch (Throwable var2_2) { ++ return n; ++ } ++ } ++ ++ public static int a(String string, int n, int n2) { ++ return Math.max(n2, MathHelper.a(string, n)); ++ } ++ ++ public static double a(String string, double d) { ++ try { ++ return Double.parseDouble(string); ++ } ++ catch (Throwable var3_2) { ++ return d; ++ } ++ } ++ ++ public static double a(String string, double d, double d2) { ++ return Math.max(d2, MathHelper.a(string, d)); ++ } ++ ++ public static int b(int n) { ++ int n2 = n - 1; ++ n2 |= n2 >> 1; ++ n2 |= n2 >> 2; ++ n2 |= n2 >> 4; ++ n2 |= n2 >> 8; ++ n2 |= n2 >> 16; ++ return n2 + 1; ++ } ++ ++ private static boolean d(int n) { ++ return n != 0 && (n & n - 1) == 0; ++ } ++ ++ public static int e(int n) { ++ n = MathHelper.d(n) ? n : MathHelper.b(n); ++ return c[(int)((long)n * 125613361 >> 27) & 31]; ++ } ++ ++ public static int c(int n) { ++ return MathHelper.e(n) - (MathHelper.d(n) ? 0 : 1); ++ } ++ ++ public static int c(int n, int n2) { ++ int n3; ++ if (n2 == 0) { ++ return 0; ++ } ++ if (n == 0) { ++ return n2; ++ } ++ if (n < 0) { ++ n2 *= -1; ++ } ++ if ((n3 = n % n2) == 0) { ++ return n; ++ } ++ return n + n2 - n3; ++ } ++ ++ public static UUID a(Random random) { ++ long l = random.nextLong() & -61441 | 16384; ++ long l2 = random.nextLong() & 0x3FFFFFFFFFFFFFFFL | Long.MIN_VALUE; ++ return new UUID(l, l2); ++ } ++ ++ public static double c(double d, double d2, double d3) { ++ return (d - d2) / (d3 - d2); ++ } ++ ++ public static double b(double d, double d2) { ++ boolean bl; ++ double d3; ++ boolean bl2; ++ boolean bl3; ++ double d4 = d2 * d2 + d * d; ++ if (Double.isNaN(d4)) { ++ return Double.NaN; ++ } ++ boolean bl4 = bl2 = d < 0.0; ++ if (bl2) { ++ d = - d; ++ } ++ boolean bl5 = bl3 = d2 < 0.0; ++ if (bl3) { ++ d2 = - d2; ++ } ++ boolean bl6 = bl = d > d2; ++ if (bl) { ++ d3 = d2; ++ d2 = d; ++ d = d3; ++ } ++ d3 = MathHelper.i(d4); ++ double d5 = MathHelper.d + (d *= d3); ++ int n = (int)Double.doubleToRawLongBits(d5); ++ double d6 = e[n]; ++ double d7 = f[n]; ++ double d8 = d5 - MathHelper.d; ++ double d9 = d * d7 - (d2 *= d3) * d8; ++ double d10 = (6.0 + d9 * d9) * d9 * 0.16666666666666666; ++ double d11 = d6 + d10; ++ if (bl) { ++ d11 = 1.5707963267948966 - d11; ++ } ++ if (bl3) { ++ d11 = 3.141592653589793 - d11; ++ } ++ if (bl2) { ++ d11 = - d11; ++ } ++ return d11; ++ } ++ ++ public static double i(double d) { ++ double d2 = 0.5 * d; ++ long l = Double.doubleToRawLongBits(d); ++ l = 6910469410427058090L - (l >> 1); ++ d = Double.longBitsToDouble(l); ++ d *= 1.5 - d2 * d * d; ++ return d; ++ } ++ ++ static { ++ int n; ++ a = MathHelper.c(2.0f); ++ b = new float[65536]; ++ for (n = 0; n < 65536; ++n) { ++ MathHelper.b[n] = (float)Math.sin((double)n * 3.141592653589793 * 2.0 / 65536.0); ++ } ++ c = new int[]{0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9}; ++ d = Double.longBitsToDouble(4805340802404319232L); ++ e = new double[257]; ++ f = new double[257]; ++ for (n = 0; n < 257; ++n) { ++ double d = (double)n / 256.0; ++ double d2 = Math.asin(d); ++ MathHelper.f[n] = Math.cos(d2); ++ MathHelper.e[n] = d2; ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java +index 55e2afd..1e9dc6c 100644 +--- a/src/main/java/net/minecraft/server/MinecraftServer.java ++++ b/src/main/java/net/minecraft/server/MinecraftServer.java +@@ -1023,7 +1023,7 @@ public abstract class MinecraftServer implements Runnable, ICommandListener, IAs + } + + public String getServerModName() { +- return "Spigot"; // Spigot - Spigot > // CraftBukkit - cb > vanilla! ++ return "Mineplex Spigot"; // Spigot - Spigot > // CraftBukkit - cb > vanilla! + } + + public CrashReport b(CrashReport crashreport) { +diff --git a/src/main/java/net/minecraft/server/NetworkManager.java b/src/main/java/net/minecraft/server/NetworkManager.java +index 83a600c..bf324f8 100644 +--- a/src/main/java/net/minecraft/server/NetworkManager.java ++++ b/src/main/java/net/minecraft/server/NetworkManager.java +@@ -76,10 +76,21 @@ public class NetworkManager extends SimpleChannelInboundHandler { + private IChatBaseComponent n; + private boolean o; + private boolean p; ++ public static final AttributeKey protocolVersion = new AttributeKey("protocol_version"); + + public NetworkManager(EnumProtocolDirection enumprotocoldirection) { + this.h = enumprotocoldirection; + } ++ ++ public static int getVersion(Channel attr) ++ { ++ Integer ver = (Integer)attr.attr(protocolVersion).get(); ++ return ver != null ? ver.intValue() : 47; ++ } ++ ++ public int getVersion() { ++ return getVersion(this.channel); ++ } + + public void channelActive(ChannelHandlerContext channelhandlercontext) throws Exception { + super.channelActive(channelhandlercontext); +diff --git a/src/main/java/net/minecraft/server/PacketDataSerializer.java b/src/main/java/net/minecraft/server/PacketDataSerializer.java +index f426c2e..1f98dce 100644 +--- a/src/main/java/net/minecraft/server/PacketDataSerializer.java ++++ b/src/main/java/net/minecraft/server/PacketDataSerializer.java +@@ -20,15 +20,24 @@ import java.nio.channels.GatheringByteChannel; + import java.nio.channels.ScatteringByteChannel; + import java.nio.charset.Charset; + import java.util.UUID; ++import com.mineplex.spigot.MineplexTranslateItem; ++import java.lang.reflect.Method; + + import org.bukkit.craftbukkit.inventory.CraftItemStack; // CraftBukkit + + public class PacketDataSerializer extends ByteBuf { + + private final ByteBuf a; ++ public final int version; + + public PacketDataSerializer(ByteBuf bytebuf) { + this.a = bytebuf; ++ version = 47; ++ } ++ ++ public PacketDataSerializer(ByteBuf bytebuf, int version) { ++ this.a = bytebuf; ++ this.version = version; + } + + public static int a(int i) { +@@ -66,7 +75,14 @@ public class PacketDataSerializer extends ByteBuf { + } + + public void a(IChatBaseComponent ichatbasecomponent) throws IOException { +- this.a(IChatBaseComponent.ChatSerializer.a(ichatbasecomponent)); ++ String s = IChatBaseComponent.ChatSerializer.a(ichatbasecomponent); ++ ++ if (s == null || s.equals("null")) ++ s = "{\"text\":\"\"}"; ++ else if (s.startsWith("\"")) ++ s = "{\"text\":" + s + "}"; ++ ++ this.a(s); + } + + public > T a(Class oclass) { +@@ -164,25 +180,7 @@ public class PacketDataSerializer extends ByteBuf { + } + + public void a(ItemStack itemstack) { +- if (itemstack == null || itemstack.getItem() == null) { // CraftBukkit - NPE fix itemstack.getItem() +- this.writeShort(-1); +- } else { +- this.writeShort(Item.getId(itemstack.getItem())); +- this.writeByte(itemstack.count); +- this.writeShort(itemstack.getData()); +- NBTTagCompound nbttagcompound = null; +- +- if (itemstack.getItem().usesDurability() || itemstack.getItem().p()) { +- // Spigot start - filter +- itemstack = itemstack.cloneItemStack(); +- CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); +- // Spigot end +- nbttagcompound = itemstack.getTag(); +- } +- +- this.a(nbttagcompound); +- } +- ++ MineplexTranslateItem.sendItemStack(this, itemstack); + } + + public ItemStack i() throws IOException { +@@ -193,8 +191,14 @@ public class PacketDataSerializer extends ByteBuf { + byte b0 = this.readByte(); + short short1 = this.readShort(); + +- itemstack = new ItemStack(Item.getById(short0), b0, short1); +- itemstack.setTag(this.h()); ++ if (version == 47) ++ { ++ itemstack = new ItemStack(Item.getById(short0), b0, short1); ++ itemstack.setTag(this.h()); ++ } ++ else ++ itemstack = MineplexTranslateItem.receiveItemStack(short0, b0, short1, this.h()); ++ + // CraftBukkit start + if (itemstack.getTag() != null) { + CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack)); +diff --git a/src/main/java/net/minecraft/server/PacketDecoder.java b/src/main/java/net/minecraft/server/PacketDecoder.java +new file mode 100644 +index 0000000..7790f68 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketDecoder.java +@@ -0,0 +1,50 @@ ++package net.minecraft.server; ++ ++import io.netty.buffer.ByteBuf; ++import io.netty.channel.Channel; ++import io.netty.channel.ChannelHandlerContext; ++import io.netty.handler.codec.ByteToMessageDecoder; ++import io.netty.util.Attribute; ++import java.io.IOException; ++import java.util.List; ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; ++import org.apache.logging.log4j.Marker; ++import org.apache.logging.log4j.MarkerManager; ++ ++public class PacketDecoder extends ByteToMessageDecoder ++{ ++ private static final Logger a = LogManager.getLogger(); ++ private static final Marker b = MarkerManager.getMarker("PACKET_RECEIVED", NetworkManager.b); ++ private final EnumProtocolDirection c; ++ ++ public PacketDecoder(EnumProtocolDirection paramEnumProtocolDirection) ++ { ++ this.c = paramEnumProtocolDirection; ++ } ++ ++ protected void decode(ChannelHandlerContext paramChannelHandlerContext, ByteBuf paramByteBuf, List paramList) throws Exception ++ { ++ if (paramByteBuf.readableBytes() == 0) { ++ return; ++ } ++ ++ int version = NetworkManager.getVersion(paramChannelHandlerContext.channel()); ++ PacketDataSerializer localPacketDataSerializer = new PacketDataSerializer(paramByteBuf, version); ++ int i = localPacketDataSerializer.e(); ++ Packet localPacket = ((EnumProtocol)paramChannelHandlerContext.channel().attr(NetworkManager.c).get()).a(this.c, i, version == 47); ++ ++ if (localPacket == null) { ++ throw new IOException("Bad packet id " + i); ++ } ++ ++ localPacket.a(localPacketDataSerializer); ++ if (localPacketDataSerializer.readableBytes() > 0) { ++ throw new IOException("Packet " + ((EnumProtocol)paramChannelHandlerContext.channel().attr(NetworkManager.c).get()).a() + "/" + i + " (" + localPacket.getClass().getSimpleName() + ") was larger than I expected, found " + localPacketDataSerializer.readableBytes() + " bytes extra whilst reading packet " + i); ++ } ++ paramList.add(localPacket); ++ ++ if (a.isDebugEnabled()) ++ a.debug(b, " IN: [{}:{}] {}", new Object[] { paramChannelHandlerContext.channel().attr(NetworkManager.c).get(), Integer.valueOf(i), localPacket.getClass().getName() }); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketEncoder.java b/src/main/java/net/minecraft/server/PacketEncoder.java +new file mode 100644 +index 0000000..70a3a7b +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketEncoder.java +@@ -0,0 +1,50 @@ ++package net.minecraft.server; ++ ++import io.netty.buffer.ByteBuf; ++import io.netty.channel.Channel; ++import io.netty.channel.ChannelHandlerContext; ++import io.netty.handler.codec.MessageToByteEncoder; ++import io.netty.util.Attribute; ++import java.io.IOException; ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; ++import org.apache.logging.log4j.Marker; ++import org.apache.logging.log4j.MarkerManager; ++ ++public class PacketEncoder extends MessageToByteEncoder ++{ ++ private static final Logger a = LogManager.getLogger(); ++ private static final Marker b = MarkerManager.getMarker("PACKET_SENT", NetworkManager.b); ++ private final EnumProtocolDirection c; ++ ++ public PacketEncoder(EnumProtocolDirection paramEnumProtocolDirection) ++ { ++ this.c = paramEnumProtocolDirection; ++ } ++ ++ protected void encode(ChannelHandlerContext paramChannelHandlerContext, Packet paramPacket, ByteBuf paramByteBuf) throws Exception ++ { ++ int version = NetworkManager.getVersion(paramChannelHandlerContext.channel()); ++ Integer localInteger = ((EnumProtocol)paramChannelHandlerContext.channel().attr(NetworkManager.c).get()).a(this.c, paramPacket, version == 47); ++ ++ if (a.isDebugEnabled()) { ++ a.debug(b, "OUT: [{}:{}] {}", new Object[] { paramChannelHandlerContext.channel().attr(NetworkManager.c).get(), localInteger, paramPacket.getClass().getName() }); ++ } ++ ++ if (localInteger == null) { ++ throw new IOException("Can't serialize unregistered packet"); ++ } ++ ++ PacketDataSerializer localPacketDataSerializer = new PacketDataSerializer(paramByteBuf, version); ++ localPacketDataSerializer.b(localInteger.intValue()); ++ try ++ { ++ if ((paramPacket instanceof PacketPlayOutNamedEntitySpawn)) { ++ paramPacket = paramPacket; ++ } ++ paramPacket.b(localPacketDataSerializer); ++ } catch (Throwable localThrowable) { ++ a.error(localThrowable); ++ } ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketListenerPlayIn.java b/src/main/java/net/minecraft/server/PacketListenerPlayIn.java +new file mode 100644 +index 0000000..80c2645 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketListenerPlayIn.java +@@ -0,0 +1,58 @@ ++package net.minecraft.server; ++ ++public abstract interface PacketListenerPlayIn extends PacketListener ++{ ++ public abstract void a(PacketPlayInArmAnimation paramPacketPlayInArmAnimation); ++ ++ public abstract void a(PacketPlayInChat paramPacketPlayInChat); ++ ++ public abstract void a(PacketPlayInTabComplete paramPacketPlayInTabComplete); ++ ++ public abstract void a(PacketPlayInClientCommand paramPacketPlayInClientCommand); ++ ++ public abstract void a(PacketPlayInSettings paramPacketPlayInSettings); ++ ++ public abstract void a(PacketPlayInTransaction paramPacketPlayInTransaction); ++ ++ public abstract void a(PacketPlayInEnchantItem paramPacketPlayInEnchantItem); ++ ++ public abstract void a(PacketPlayInWindowClick paramPacketPlayInWindowClick); ++ ++ public abstract void a(PacketPlayInCloseWindow paramPacketPlayInCloseWindow); ++ ++ public abstract void a(PacketPlayInCustomPayload paramPacketPlayInCustomPayload); ++ ++ public abstract void a(PacketPlayInUseEntity paramPacketPlayInUseEntity); ++ ++ public abstract void a(PacketPlayInKeepAlive paramPacketPlayInKeepAlive); ++ ++ public abstract void a(PacketPlayInFlying paramPacketPlayInFlying); ++ ++ public abstract void a(PacketPlayInAbilities paramPacketPlayInAbilities); ++ ++ public abstract void a(PacketPlayInBlockDig paramPacketPlayInBlockDig); ++ ++ public abstract void a(PacketPlayInEntityAction paramPacketPlayInEntityAction); ++ ++ public abstract void a(PacketPlayInSteerVehicle paramPacketPlayInSteerVehicle); ++ ++ public abstract void a(PacketPlayInHeldItemSlot paramPacketPlayInHeldItemSlot); ++ ++ public abstract void a(PacketPlayInSetCreativeSlot paramPacketPlayInSetCreativeSlot); ++ ++ public abstract void a(PacketPlayInUpdateSign paramPacketPlayInUpdateSign); ++ ++ public abstract void a(PacketPlayInBlockPlace paramPacketPlayInBlockPlace); ++ ++ public abstract void a(PacketPlayInSpectate paramPacketPlayInSpectate); ++ ++ public abstract void a(PacketPlayInResourcePackStatus paramPacketPlayInResourcePackStatus); ++ ++ public abstract void a(PacketPlayInUnknownFloats paramPacketPlayInUnknownFloats); ++ ++ public abstract void a(PacketPlayInUnknownPosition paramPacketInPlayUnknownPosition); ++ ++ public abstract void a(PacketPlayInLeftClick paramPacketPlayInLeftClick); ++ ++ public abstract void a(PacketPlayInRightClick paramPacketPlayInRightClick); ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketListenerPlayOut.java b/src/main/java/net/minecraft/server/PacketListenerPlayOut.java +new file mode 100644 +index 0000000..361eebb +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketListenerPlayOut.java +@@ -0,0 +1,150 @@ ++package net.minecraft.server; ++ ++public abstract interface PacketListenerPlayOut extends PacketListener ++{ ++ public abstract void a(PacketPlayOutSpawnEntity paramPacketPlayOutSpawnEntity); ++ ++ public abstract void a(PacketPlayOutSpawnEntityExperienceOrb paramPacketPlayOutSpawnEntityExperienceOrb); ++ ++ public abstract void a(PacketPlayOutSpawnEntityWeather paramPacketPlayOutSpawnEntityWeather); ++ ++ public abstract void a(PacketPlayOutSpawnEntityLiving paramPacketPlayOutSpawnEntityLiving); ++ ++ public abstract void a(PacketPlayOutScoreboardObjective paramPacketPlayOutScoreboardObjective); ++ ++ public abstract void a(PacketPlayOutSpawnEntityPainting paramPacketPlayOutSpawnEntityPainting); ++ ++ public abstract void a(PacketPlayOutNamedEntitySpawn paramPacketPlayOutNamedEntitySpawn); ++ ++ public abstract void a(PacketPlayOutAnimation paramPacketPlayOutAnimation); ++ ++ public abstract void a(PacketPlayOutStatistic paramPacketPlayOutStatistic); ++ ++ public abstract void a(PacketPlayOutBlockBreakAnimation paramPacketPlayOutBlockBreakAnimation); ++ ++ public abstract void a(PacketPlayOutOpenSignEditor paramPacketPlayOutOpenSignEditor); ++ ++ public abstract void a(PacketPlayOutTileEntityData paramPacketPlayOutTileEntityData); ++ ++ public abstract void a(PacketPlayOutBlockAction paramPacketPlayOutBlockAction); ++ ++ public abstract void a(PacketPlayOutBlockChange paramPacketPlayOutBlockChange); ++ ++ public abstract void a(PacketPlayOutChat paramPacketPlayOutChat); ++ ++ public abstract void a(PacketPlayOutTabComplete paramPacketPlayOutTabComplete); ++ ++ public abstract void a(PacketPlayOutMultiBlockChange paramPacketPlayOutMultiBlockChange); ++ ++ public abstract void a(PacketPlayOutMap paramPacketPlayOutMap); ++ ++ public abstract void a(PacketPlayOutTransaction paramPacketPlayOutTransaction); ++ ++ public abstract void a(PacketPlayOutCloseWindow paramPacketPlayOutCloseWindow); ++ ++ public abstract void a(PacketPlayOutWindowItems paramPacketPlayOutWindowItems); ++ ++ public abstract void a(PacketPlayOutOpenWindow paramPacketPlayOutOpenWindow); ++ ++ public abstract void a(PacketPlayOutWindowData paramPacketPlayOutWindowData); ++ ++ public abstract void a(PacketPlayOutSetSlot paramPacketPlayOutSetSlot); ++ ++ public abstract void a(PacketPlayOutCustomPayload paramPacketPlayOutCustomPayload); ++ ++ public abstract void a(PacketPlayOutKickDisconnect paramPacketPlayOutKickDisconnect); ++ ++ public abstract void a(PacketPlayOutBed paramPacketPlayOutBed); ++ ++ public abstract void a(PacketPlayOutEntityStatus paramPacketPlayOutEntityStatus); ++ ++ public abstract void a(PacketPlayOutAttachEntity paramPacketPlayOutAttachEntity); ++ ++ public abstract void a(PacketPlayOutExplosion paramPacketPlayOutExplosion); ++ ++ public abstract void a(PacketPlayOutGameStateChange paramPacketPlayOutGameStateChange); ++ ++ public abstract void a(PacketPlayOutKeepAlive paramPacketPlayOutKeepAlive); ++ ++ public abstract void a(PacketPlayOutMapChunk paramPacketPlayOutMapChunk); ++ ++ public abstract void a(PacketPlayOutMapChunkBulk paramPacketPlayOutMapChunkBulk); ++ ++ public abstract void a(PacketPlayOutWorldEvent paramPacketPlayOutWorldEvent); ++ ++ public abstract void a(PacketPlayOutLogin paramPacketPlayOutLogin); ++ ++ public abstract void a(PacketPlayOutEntity paramPacketPlayOutEntity); ++ ++ public abstract void a(PacketPlayOutPosition paramPacketPlayOutPosition); ++ ++ public abstract void a(PacketPlayOutWorldParticles paramPacketPlayOutWorldParticles); ++ ++ public abstract void a(PacketPlayOutAbilities paramPacketPlayOutAbilities); ++ ++ public abstract void a(PacketPlayOutPlayerInfo paramPacketPlayOutPlayerInfo); ++ ++ public abstract void a(PacketPlayOutEntityDestroy paramPacketPlayOutEntityDestroy); ++ ++ public abstract void a(PacketPlayOutRemoveEntityEffect paramPacketPlayOutRemoveEntityEffect); ++ ++ public abstract void a(PacketPlayOutRespawn paramPacketPlayOutRespawn); ++ ++ public abstract void a(PacketPlayOutEntityHeadRotation paramPacketPlayOutEntityHeadRotation); ++ ++ public abstract void a(PacketPlayOutHeldItemSlot paramPacketPlayOutHeldItemSlot); ++ ++ public abstract void a(PacketPlayOutScoreboardDisplayObjective paramPacketPlayOutScoreboardDisplayObjective); ++ ++ public abstract void a(PacketPlayOutEntityMetadata paramPacketPlayOutEntityMetadata); ++ ++ public abstract void a(PacketPlayOutEntityVelocity paramPacketPlayOutEntityVelocity); ++ ++ public abstract void a(PacketPlayOutEntityEquipment paramPacketPlayOutEntityEquipment); ++ ++ public abstract void a(PacketPlayOutExperience paramPacketPlayOutExperience); ++ ++ public abstract void a(PacketPlayOutUpdateHealth paramPacketPlayOutUpdateHealth); ++ ++ public abstract void a(PacketPlayOutScoreboardTeam paramPacketPlayOutScoreboardTeam); ++ ++ public abstract void a(PacketPlayOutScoreboardScore paramPacketPlayOutScoreboardScore); ++ ++ public abstract void a(PacketPlayOutSpawnPosition paramPacketPlayOutSpawnPosition); ++ ++ public abstract void a(PacketPlayOutUpdateTime paramPacketPlayOutUpdateTime); ++ ++ public abstract void a(PacketPlayOutUpdateSign paramPacketPlayOutUpdateSign); ++ ++ public abstract void a(PacketPlayOutNamedSoundEffect paramPacketPlayOutNamedSoundEffect); ++ ++ public abstract void a(PacketPlayOutCollect paramPacketPlayOutCollect); ++ ++ public abstract void a(PacketPlayOutEntityTeleport paramPacketPlayOutEntityTeleport); ++ ++ public abstract void a(PacketPlayOutUpdateAttributes paramPacketPlayOutUpdateAttributes); ++ ++ public abstract void a(PacketPlayOutEntityEffect paramPacketPlayOutEntityEffect); ++ ++ public abstract void a(PacketPlayOutCombatEvent paramPacketPlayOutCombatEvent); ++ ++ public abstract void a(PacketPlayOutServerDifficulty paramPacketPlayOutServerDifficulty); ++ ++ public abstract void a(PacketPlayOutCamera paramPacketPlayOutCamera); ++ ++ public abstract void a(PacketPlayOutWorldBorder paramPacketPlayOutWorldBorder); ++ ++ public abstract void a(PacketPlayOutTitle paramPacketPlayOutTitle); ++ ++ public abstract void a(PacketPlayOutSetCompression paramPacketPlayOutSetCompression); ++ ++ public abstract void a(PacketPlayOutPlayerListHeaderFooter paramPacketPlayOutPlayerListHeaderFooter); ++ ++ public abstract void a(PacketPlayOutResourcePackSend paramPacketPlayOutResourcePackSend); ++ ++ public abstract void a(PacketPlayOutUpdateEntityNBT paramPacketPlayOutUpdateEntityNBT); ++ ++ public abstract void a(PacketPlayOutUnloadChunk paramPacketPlayOutUnloadChunk); ++ ++ public abstract void a(PacketPlayOutNewAttachEntity paramPacketPlayOutNewAttachEntity); ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java b/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java +index 28cb5e3..d892097 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java ++++ b/src/main/java/net/minecraft/server/PacketPlayInArmAnimation.java +@@ -10,6 +10,10 @@ public class PacketPlayInArmAnimation implements Packet { + + public void a(PacketDataSerializer packetdataserializer) throws IOException { + timestamp = System.currentTimeMillis(); // Spigot ++ if (packetdataserializer.version != 47) ++ { ++ packetdataserializer.e(); ++ } + } + + public void b(PacketDataSerializer packetdataserializer) throws IOException {} +diff --git a/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java b/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java +index ac5928d..3238be6 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java ++++ b/src/main/java/net/minecraft/server/PacketPlayInBlockPlace.java +@@ -32,8 +32,15 @@ public class PacketPlayInBlockPlace implements Packet { + public void a(PacketDataSerializer packetdataserializer) throws IOException { + timestamp = System.currentTimeMillis(); // CraftBukkit + this.b = packetdataserializer.c(); +- this.c = packetdataserializer.readUnsignedByte(); +- this.d = packetdataserializer.i(); ++ if (packetdataserializer.version == 47) ++ { ++ this.c = packetdataserializer.readUnsignedByte(); ++ this.d = packetdataserializer.i(); ++ } ++ else { ++ this.c = packetdataserializer.e(); ++ packetdataserializer.e(); ++ } + this.e = (float) packetdataserializer.readUnsignedByte() / 16.0F; + this.f = (float) packetdataserializer.readUnsignedByte() / 16.0F; + this.g = (float) packetdataserializer.readUnsignedByte() / 16.0F; +diff --git a/src/main/java/net/minecraft/server/PacketPlayInKeepAlive.java b/src/main/java/net/minecraft/server/PacketPlayInKeepAlive.java +new file mode 100644 +index 0000000..366479c +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInKeepAlive.java +@@ -0,0 +1,28 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInKeepAlive ++ implements Packet ++{ ++ private int a; ++ ++ public void a(PacketListenerPlayIn paramPacketListenerPlayIn) ++ { ++ paramPacketListenerPlayIn.a(this); ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ this.a = paramPacketDataSerializer.e(); ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.b(this.a); ++ } ++ ++ public int a() { ++ return this.a; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInLeftClick.java b/src/main/java/net/minecraft/server/PacketPlayInLeftClick.java +new file mode 100644 +index 0000000..c186d56 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInLeftClick.java +@@ -0,0 +1,18 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInLeftClick implements Packet { ++ ++ public PacketPlayInLeftClick() {} ++ ++ public void a(PacketDataSerializer packetdataserializer) throws IOException { ++ packetdataserializer.e(); ++ } ++ ++ public void b(PacketDataSerializer packetdataserializer) throws IOException {} ++ ++ public void a(PacketListenerPlayIn packetlistenerplayin) { ++ packetlistenerplayin.a(this); ++ } ++} +diff --git a/src/main/java/net/minecraft/server/PacketPlayInRightClick.java b/src/main/java/net/minecraft/server/PacketPlayInRightClick.java +new file mode 100644 +index 0000000..a24efd6 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInRightClick.java +@@ -0,0 +1,18 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInRightClick implements Packet { ++ ++ public PacketPlayInRightClick() {} ++ ++ public void a(PacketDataSerializer packetdataserializer) throws IOException { ++ packetdataserializer.e(); ++ } ++ ++ public void b(PacketDataSerializer packetdataserializer) throws IOException {} ++ ++ public void a(PacketListenerPlayIn packetlistenerplayin) { ++ packetlistenerplayin.a(this); ++ } ++} +diff --git a/src/main/java/net/minecraft/server/PacketPlayInSettings.java b/src/main/java/net/minecraft/server/PacketPlayInSettings.java +new file mode 100644 +index 0000000..67487f6 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInSettings.java +@@ -0,0 +1,63 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInSettings ++ implements Packet ++{ ++ public String a; ++ public int b; ++ public EntityHuman.EnumChatVisibility c; ++ public boolean d; ++ public int e; ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) ++ throws IOException ++ { ++ this.a = paramPacketDataSerializer.c(7); ++ this.b = paramPacketDataSerializer.readByte(); ++ ++ if (paramPacketDataSerializer.version == 47) ++ this.c = EntityHuman.EnumChatVisibility.a(paramPacketDataSerializer.readByte()); ++ else ++ this.c = EntityHuman.EnumChatVisibility.a(paramPacketDataSerializer.e()); ++ ++ this.d = paramPacketDataSerializer.readBoolean(); ++ ++ this.e = paramPacketDataSerializer.readUnsignedByte(); ++ ++ if (paramPacketDataSerializer.version != 47) ++ paramPacketDataSerializer.e(); ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.a(this.a); ++ paramPacketDataSerializer.writeByte(this.b); ++ paramPacketDataSerializer.writeByte(this.c.a()); ++ paramPacketDataSerializer.writeBoolean(this.d); ++ paramPacketDataSerializer.writeByte(this.e); ++ } ++ ++ public void a(PacketListenerPlayIn paramPacketListenerPlayIn) ++ { ++ paramPacketListenerPlayIn.a(this); ++ } ++ ++ public String a() { ++ return this.a; ++ } ++ ++ public EntityHuman.EnumChatVisibility c() ++ { ++ return this.c; ++ } ++ ++ public boolean d() { ++ return this.d; ++ } ++ ++ public int e() { ++ return this.e; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInTabComplete.java b/src/main/java/net/minecraft/server/PacketPlayInTabComplete.java +new file mode 100644 +index 0000000..b8947f4 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInTabComplete.java +@@ -0,0 +1,58 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++import org.apache.commons.lang3.StringUtils; ++ ++public class PacketPlayInTabComplete ++ implements Packet ++{ ++ private String a; ++ private BlockPosition b; ++ ++ public PacketPlayInTabComplete() ++ { ++ } ++ ++ public PacketPlayInTabComplete(String paramString) ++ { ++ this(paramString, null); ++ } ++ ++ public PacketPlayInTabComplete(String paramString, BlockPosition paramBlockPosition) { ++ this.a = paramString; ++ this.b = paramBlockPosition; ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ this.a = paramPacketDataSerializer.c(32767); ++ if (paramPacketDataSerializer.version > 47) ++ paramPacketDataSerializer.readBoolean(); ++ boolean bool = paramPacketDataSerializer.readBoolean(); ++ if (bool) ++ this.b = paramPacketDataSerializer.c(); ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) ++ throws IOException ++ { ++ paramPacketDataSerializer.a(StringUtils.substring(this.a, 0, 32767)); ++ boolean bool = this.b != null; ++ paramPacketDataSerializer.writeBoolean(bool); ++ if (bool) ++ paramPacketDataSerializer.a(this.b); ++ } ++ ++ public void a(PacketListenerPlayIn paramPacketListenerPlayIn) ++ { ++ paramPacketListenerPlayIn.a(this); ++ } ++ ++ public String a() { ++ return this.a; ++ } ++ ++ public BlockPosition b() { ++ return this.b; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInUnknownFloats.java b/src/main/java/net/minecraft/server/PacketPlayInUnknownFloats.java +new file mode 100644 +index 0000000..ace5a60 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInUnknownFloats.java +@@ -0,0 +1,39 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInUnknownFloats ++ implements Packet ++{ ++ public float a; ++ public float b; ++ ++ public PacketPlayInUnknownFloats() ++ { ++ } ++ ++ public void a(PacketDataSerializer dataSerializer) throws IOException ++ { ++ this.a = dataSerializer.readFloat(); ++ this.b = dataSerializer.readFloat(); ++ } ++ ++ public void b(PacketDataSerializer dataSerializer) throws IOException ++ { ++ dataSerializer.writeFloat(this.a); ++ dataSerializer.writeFloat(this.b); ++ } ++ ++ public void a(PacketListenerPlayIn listenerPlayIn) ++ { ++ listenerPlayIn.a(this); ++ } ++ ++ public float a() { ++ return this.a; ++ } ++ ++ public float b() { ++ return this.b; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInUnknownPosition.java b/src/main/java/net/minecraft/server/PacketPlayInUnknownPosition.java +new file mode 100644 +index 0000000..af5883a +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInUnknownPosition.java +@@ -0,0 +1,60 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInUnknownPosition ++ implements Packet ++{ ++ public double a; ++ public double b; ++ public double c; ++ public float d; ++ public float e; ++ ++ public PacketPlayInUnknownPosition() ++ { ++ } ++ ++ public void a(PacketDataSerializer dataSerializer) throws IOException ++ { ++ this.a = dataSerializer.readDouble(); ++ this.b = dataSerializer.readDouble(); ++ this.c = dataSerializer.readDouble(); ++ this.d = dataSerializer.readFloat(); ++ this.e = dataSerializer.readFloat(); ++ } ++ ++ public void b(PacketDataSerializer dataSerializer) throws IOException ++ { ++ dataSerializer.writeDouble(this.a); ++ dataSerializer.writeDouble(this.b); ++ dataSerializer.writeDouble(this.c); ++ dataSerializer.writeFloat(this.d); ++ dataSerializer.writeFloat(this.e); ++ } ++ ++ public void a(PacketListenerPlayIn listenerPlayIn) ++ { ++ listenerPlayIn.a(this); ++ } ++ ++ public double a() { ++ return this.a; ++ } ++ ++ public double b() { ++ return this.b; ++ } ++ ++ public double c() { ++ return this.c; ++ } ++ ++ public float d() { ++ return this.d; ++ } ++ ++ public float e() { ++ return this.e; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInUpdateSign.java b/src/main/java/net/minecraft/server/PacketPlayInUpdateSign.java +new file mode 100644 +index 0000000..7b8f6dc +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInUpdateSign.java +@@ -0,0 +1,58 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++import org.bukkit.craftbukkit.util.CraftChatMessage; ++ ++public class PacketPlayInUpdateSign ++ implements Packet ++{ ++ private BlockPosition a; ++ private IChatBaseComponent[] b; ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) ++ throws IOException ++ { ++ this.a = paramPacketDataSerializer.c(); ++ this.b = new IChatBaseComponent[4]; ++ for (int i = 0; i < 4; i++) { ++ if (paramPacketDataSerializer.version == 47) { ++ String str = paramPacketDataSerializer.c(384); ++ IChatBaseComponent localIChatBaseComponent = IChatBaseComponent.ChatSerializer.a(str); ++ this.b[i] = localIChatBaseComponent; ++ } ++ else ++ { ++ b[i] = CraftChatMessage.fromString(paramPacketDataSerializer.c(384))[0]; ++ } ++ } ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.a(this.a); ++ for (int i = 0; i < 4; i++) { ++ IChatBaseComponent localIChatBaseComponent = this.b[i]; ++ if (paramPacketDataSerializer.version == 47) { ++ String str = IChatBaseComponent.ChatSerializer.a(localIChatBaseComponent); ++ paramPacketDataSerializer.a(str); ++ } ++ else ++ { ++ paramPacketDataSerializer.a(CraftChatMessage.fromComponent(localIChatBaseComponent)); ++ } ++ } ++ } ++ ++ public void a(PacketListenerPlayIn paramPacketListenerPlayIn) ++ { ++ paramPacketListenerPlayIn.a(this); ++ } ++ ++ public BlockPosition a() { ++ return this.a; ++ } ++ ++ public IChatBaseComponent[] b() { ++ return this.b; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java b/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java +index 40c4e2d..3969fa9 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java ++++ b/src/main/java/net/minecraft/server/PacketPlayInUseEntity.java +@@ -16,6 +16,10 @@ public class PacketPlayInUseEntity + this.action = ((EnumEntityUseAction)paramPacketDataSerializer.a(EnumEntityUseAction.class)); + if (this.action == EnumEntityUseAction.INTERACT_AT) + this.c = new Vec3D(paramPacketDataSerializer.readFloat(), paramPacketDataSerializer.readFloat(), paramPacketDataSerializer.readFloat()); ++ if (this.action != EnumEntityUseAction.ATTACK && paramPacketDataSerializer.version != 47) ++ { ++ paramPacketDataSerializer.e(); ++ } + } + + public void b(PacketDataSerializer paramPacketDataSerializer) +diff --git a/src/main/java/net/minecraft/server/PacketPlayInWindowClick.java b/src/main/java/net/minecraft/server/PacketPlayInWindowClick.java +new file mode 100644 +index 0000000..0713db5 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayInWindowClick.java +@@ -0,0 +1,65 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayInWindowClick ++ implements Packet ++{ ++ private int a; ++ private int slot; ++ private int button; ++ private short d; ++ private ItemStack item; ++ private int shift; ++ ++ public void a(PacketListenerPlayIn paramPacketListenerPlayIn) ++ { ++ paramPacketListenerPlayIn.a(this); ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ this.a = paramPacketDataSerializer.readByte(); ++ this.slot = paramPacketDataSerializer.readShort(); ++ this.button = paramPacketDataSerializer.readByte(); ++ this.d = paramPacketDataSerializer.readShort(); ++ this.shift = paramPacketDataSerializer.e(); ++ ++ this.item = paramPacketDataSerializer.i(); ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.writeByte(this.a); ++ paramPacketDataSerializer.writeShort(this.slot); ++ paramPacketDataSerializer.writeByte(this.button); ++ paramPacketDataSerializer.writeShort(this.d); ++ paramPacketDataSerializer.writeByte(this.shift); ++ ++ paramPacketDataSerializer.a(this.item); ++ } ++ ++ public int a() { ++ return this.a; ++ } ++ ++ public int b() { ++ return this.slot; ++ } ++ ++ public int c() { ++ return this.button; ++ } ++ ++ public short d() { ++ return this.d; ++ } ++ ++ public ItemStack e() { ++ return this.item; ++ } ++ ++ public int f() { ++ return this.shift; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutAttachEntity.java b/src/main/java/net/minecraft/server/PacketPlayOutAttachEntity.java +index 314a2de..23a406f 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutAttachEntity.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutAttachEntity.java +@@ -31,7 +31,8 @@ public class PacketPlayOutAttachEntity implements Packet + { + packetdataserializer.writeInt(this.b); + packetdataserializer.writeInt(this.c); +- packetdataserializer.writeByte(this.a); ++ if (packetdataserializer.version == 47) ++ packetdataserializer.writeByte(this.a); + } + + public void a(PacketListenerPlayOut packetlistenerplayout) +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutCombatEvent.java b/src/main/java/net/minecraft/server/PacketPlayOutCombatEvent.java +new file mode 100644 +index 0000000..4622309 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayOutCombatEvent.java +@@ -0,0 +1,80 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++import org.bukkit.craftbukkit.util.CraftChatMessage; ++ ++public class PacketPlayOutCombatEvent ++ implements Packet ++{ ++ public EnumCombatEventType a; ++ public int b; ++ public int c; ++ public int d; ++ public String e; ++ ++ public PacketPlayOutCombatEvent() ++ { ++ } ++ ++ public PacketPlayOutCombatEvent(CombatTracker paramCombatTracker, EnumCombatEventType paramEnumCombatEventType) ++ { ++ this.a = paramEnumCombatEventType; ++ ++ EntityLiving localEntityLiving = paramCombatTracker.c(); ++ ++ switch (paramEnumCombatEventType.ordinal()) { ++ case 1: ++ this.d = paramCombatTracker.f(); ++ this.c = (localEntityLiving == null ? -1 : localEntityLiving.getId()); ++ break; ++ case 2: ++ this.b = paramCombatTracker.h().getId(); ++ this.c = (localEntityLiving == null ? -1 : localEntityLiving.getId()); ++ this.e = paramCombatTracker.b().c(); ++ } ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) ++ throws IOException ++ { ++ this.a = ((EnumCombatEventType)paramPacketDataSerializer.a(EnumCombatEventType.class)); ++ ++ if (this.a == EnumCombatEventType.END_COMBAT) { ++ this.d = paramPacketDataSerializer.e(); ++ this.c = paramPacketDataSerializer.readInt(); ++ } else if (this.a == EnumCombatEventType.ENTITY_DIED) { ++ this.b = paramPacketDataSerializer.e(); ++ this.c = paramPacketDataSerializer.readInt(); ++ this.e = paramPacketDataSerializer.c(32767); ++ } ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.a(this.a); ++ ++ if (this.a == EnumCombatEventType.END_COMBAT) { ++ paramPacketDataSerializer.b(this.d); ++ paramPacketDataSerializer.writeInt(this.c); ++ } else if (this.a == EnumCombatEventType.ENTITY_DIED) { ++ paramPacketDataSerializer.b(this.b); ++ paramPacketDataSerializer.writeInt(this.c); ++ if (paramPacketDataSerializer.version == 47) ++ paramPacketDataSerializer.a(this.e); ++ else ++ { ++ paramPacketDataSerializer.a(CraftChatMessage.fromString(this.e)[0]); ++ } ++ } ++ } ++ ++ public void a(PacketListenerPlayOut paramPacketListenerPlayOut) ++ { ++ paramPacketListenerPlayOut.a(this); ++ } ++ ++ public static enum EnumCombatEventType ++ { ++ ENTER_COMBAT, END_COMBAT, ENTITY_DIED; ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutCustomPayload.java b/src/main/java/net/minecraft/server/PacketPlayOutCustomPayload.java +new file mode 100644 +index 0000000..29b1e5c +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayOutCustomPayload.java +@@ -0,0 +1,45 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayOutCustomPayload ++ implements Packet ++{ ++ public String a; ++ public PacketDataSerializer b; ++ ++ public PacketPlayOutCustomPayload() ++ { ++ } ++ ++ public PacketPlayOutCustomPayload(String paramString, PacketDataSerializer paramPacketDataSerializer) ++ { ++ this.a = paramString; ++ this.b = paramPacketDataSerializer; ++ ++ if (paramPacketDataSerializer.writerIndex() > 1048576) ++ throw new IllegalArgumentException("Payload may not be larger than 1048576 bytes"); ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) ++ throws IOException ++ { ++ this.a = paramPacketDataSerializer.c(20); ++ int i = paramPacketDataSerializer.readableBytes(); ++ if ((i < 0) || (i > 1048576)) { ++ throw new IOException("Payload may not be larger than 1048576 bytes"); ++ } ++ this.b = new PacketDataSerializer(paramPacketDataSerializer.readBytes(i)); ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.a(this.a); ++ paramPacketDataSerializer.writeBytes(this.b); ++ } ++ ++ public void a(PacketListenerPlayOut paramPacketListenerPlayOut) ++ { ++ paramPacketListenerPlayOut.a(this); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutEntityEquipment.java b/src/main/java/net/minecraft/server/PacketPlayOutEntityEquipment.java +index ecc2e78..bb41d9d 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutEntityEquipment.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutEntityEquipment.java +@@ -24,7 +24,11 @@ public class PacketPlayOutEntityEquipment implements Packet ++{ ++ public int a; ++ public byte b; ++ public MapIcon[] c; ++ public int d; ++ public int e; ++ public int f; ++ public int g; ++ public byte[] h; ++ ++ public PacketPlayOutMap() ++ { ++ } ++ ++ public PacketPlayOutMap(int paramInt1, byte paramByte, Collection paramCollection, byte[] paramArrayOfByte, int paramInt2, int paramInt3, int paramInt4, int paramInt5) ++ { ++ this.a = paramInt1; ++ this.b = paramByte; ++ this.c = ((MapIcon[])paramCollection.toArray(new MapIcon[paramCollection.size()])); ++ this.d = paramInt2; ++ this.e = paramInt3; ++ this.f = paramInt4; ++ this.g = paramInt5; ++ ++ this.h = new byte[paramInt4 * paramInt5]; ++ for (int i = 0; i < paramInt4; i++) ++ for (int j = 0; j < paramInt5; j++) ++ this.h[(i + j * paramInt4)] = paramArrayOfByte[(paramInt2 + i + (paramInt3 + j) * 128)]; ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) ++ throws IOException ++ { ++ this.a = paramPacketDataSerializer.e(); ++ this.b = paramPacketDataSerializer.readByte(); ++ this.c = new MapIcon[paramPacketDataSerializer.e()]; ++ for (int i = 0; i < this.c.length; i++) { ++ int j = (short)paramPacketDataSerializer.readByte(); ++ this.c[i] = new MapIcon((byte)(j >> 4 & 0xF), paramPacketDataSerializer.readByte(), paramPacketDataSerializer.readByte(), (byte)(j & 0xF)); ++ } ++ this.f = paramPacketDataSerializer.readUnsignedByte(); ++ if (this.f > 0) { ++ this.g = paramPacketDataSerializer.readUnsignedByte(); ++ this.d = paramPacketDataSerializer.readUnsignedByte(); ++ this.e = paramPacketDataSerializer.readUnsignedByte(); ++ this.h = paramPacketDataSerializer.a(); ++ } ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.b(this.a); ++ paramPacketDataSerializer.writeByte(this.b); ++ paramPacketDataSerializer.b(this.c.length); ++ if (paramPacketDataSerializer.version != 47) ++ { ++ paramPacketDataSerializer.writeBoolean(this.c.length > 0); ++ } ++ for (MapIcon localMapIcon : this.c) { ++ paramPacketDataSerializer.writeByte((localMapIcon.getType() & 0xF) << 4 | localMapIcon.getRotation() & 0xF); ++ paramPacketDataSerializer.writeByte(localMapIcon.getX()); ++ paramPacketDataSerializer.writeByte(localMapIcon.getY()); ++ } ++ paramPacketDataSerializer.writeByte(this.f); ++ if (this.f > 0) { ++ paramPacketDataSerializer.writeByte(this.g); ++ paramPacketDataSerializer.writeByte(this.d); ++ paramPacketDataSerializer.writeByte(this.e); ++ paramPacketDataSerializer.a(this.h); ++ } ++ } ++ ++ public void a(PacketListenerPlayOut paramPacketListenerPlayOut) ++ { ++ paramPacketListenerPlayOut.a(this); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +index c72526a..e85c71c 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutMapChunk.java +@@ -4,6 +4,8 @@ import com.google.common.collect.Lists; + import java.io.IOException; + import java.util.ArrayList; + import java.util.Iterator; ++import io.netty.buffer.ByteBuf; ++import io.netty.buffer.Unpooled; + + public class PacketPlayOutMapChunk implements Packet { + +@@ -13,15 +15,24 @@ public class PacketPlayOutMapChunk implements Packet { + public boolean d; + public Chunk mapChunk; + ++ public int size9; ++ public byte[] bytes9; ++ + public PacketPlayOutMapChunk() {} + + public PacketPlayOutMapChunk(Chunk chunk, boolean flag, int i) { + this.a = chunk.locX; + this.b = chunk.locZ; + this.d = flag; +- this.c = a(chunk, flag, !chunk.getWorld().worldProvider.o(), i); ++ ++ boolean world = !chunk.getWorld().worldProvider.o(); ++ ++ this.c = a(chunk, flag, world, i); + chunk.world.spigotConfig.antiXrayInstance.obfuscateSync(chunk.locX, chunk.locZ, c.b, c.a, chunk.world); + mapChunk = chunk; ++ ++ this.bytes9 = new byte[a9(chunk, flag, world, i)]; ++ this.size9 = a9(new PacketDataSerializer(this.f()), chunk, flag, world, i); + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { +@@ -37,8 +48,16 @@ public class PacketPlayOutMapChunk implements Packet { + packetdataserializer.writeInt(this.a); + packetdataserializer.writeInt(this.b); + packetdataserializer.writeBoolean(this.d); ++ ++ if (packetdataserializer.version == 47){ + packetdataserializer.writeShort((short) (this.c.b & '\uffff')); + packetdataserializer.a(this.c.a); ++ } else ++ { ++ packetdataserializer.b(this.size9); ++ packetdataserializer.b(this.bytes9.length); ++ packetdataserializer.writeBytes(this.bytes9); ++ } + } + + public void a(PacketListenerPlayOut packetlistenerplayout) { +@@ -119,4 +138,52 @@ public class PacketPlayOutMapChunk implements Packet { + + public ChunkMap() {} + } ++ private ByteBuf f() { ++ ByteBuf byteBuf = Unpooled.wrappedBuffer(this.bytes9); ++ byteBuf.writerIndex(0); ++ return byteBuf; ++ } ++ ++ public static int a9(PacketDataSerializer dataSerializer, Chunk chunk, boolean bl, boolean bl2, int n) { ++ int n2 = 0; ++ ChunkSection[] sectionArray = chunk.getSections(); ++ ++ for (int i = 0; i < sectionArray.length; ++i) { ++ ChunkSection section = sectionArray[i]; ++ if (section == null || bl && section.a()) continue; ++ if ((n & 1 << i) == 0) continue; ++ n2|=1 << i; ++ ++ section.writeSerializer(dataSerializer); ++ ++ dataSerializer.writeBytes(section.getEmittedLightArray().a()); ++ if (!bl2) continue; ++ dataSerializer.writeBytes(section.getSkyLightArray().a()); ++ } ++ if (bl) { ++ dataSerializer.writeBytes(chunk.getBiomeIndex()); ++ } ++ return n2; ++ } ++ ++ protected static int a9(Chunk chunk, boolean bl, boolean bl2, int n) { ++ int n2 = 0; ++ ChunkSection[] sectionArray = chunk.getSections(); ++ ++ for (int i = 0; i < sectionArray.length; ++i) { ++ ChunkSection section = sectionArray[i]; ++ if (section == null || bl && section.a()) continue; ++ if ((n & 1 << i) == 0) continue; ++ ++ n2 += section.getLength(); ++ ++ n2+=section.getEmittedLightArray().a().length; ++ if (!bl2) continue; ++ n2+=section.getSkyLightArray().a().length; ++ } ++ if (bl) { ++ n2+=chunk.getBiomeIndex().length; ++ } ++ return n2; ++ } + } +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutNamedEntitySpawn.java b/src/main/java/net/minecraft/server/PacketPlayOutNamedEntitySpawn.java +index 277d1f2..340787a 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutNamedEntitySpawn.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutNamedEntitySpawn.java +@@ -53,7 +53,8 @@ public class PacketPlayOutNamedEntitySpawn implements Packet sounds = new HashMap(); ++ ++ static { ++ sounds.put("ambient.cave.cave", "ambient.cave"); ++ sounds.put("ambient.weather.rain", "weather.rain.above"); ++ sounds.put("ambient.weather.thunder", "entity.lightning.thunder"); ++ sounds.put("dig.cloth", "block.cloth.place"); ++ sounds.put("dig.grass", "block.grass.break"); ++ sounds.put("dig.gravel", "block.gravel.break"); ++ sounds.put("dig.sand", "block.sand.place"); ++ sounds.put("dig.snow", "block.snow.place"); ++ sounds.put("dig.stone", "block.glass.place"); ++ sounds.put("dig.wood", "block.wood.place"); ++ sounds.put("fire.fire", "entity.blaze.burn"); ++ sounds.put("fire.ignite", "item.flintandsteel.use"); ++ sounds.put("fireworks.blast", "entity.firework.blast"); ++ sounds.put("fireworks.blast_far", "entity.firework.blast_far"); ++ sounds.put("fireworks.largeBlast", "entity.firework.large_blast"); ++ sounds.put("fireworks.largeBlast_far", "entity.firework.large_blast_far"); ++ sounds.put("fireworks.launch", "entity.firework.launch"); ++ sounds.put("fireworks.twinkle", "entity.firework.twinkle"); ++ sounds.put("fireworks.twinkle_far", "entity.firework.twinkle_far"); ++ sounds.put("game.hostile.swim", "entity.player.swim"); ++ sounds.put("game.neutral.die", "entity.player.hurt"); ++ sounds.put("game.neutral.hurt.fall.small", "entity.generic.small_fall"); ++ sounds.put("game.neutral.swim.splash", "entity.generic.splash"); ++ sounds.put("game.player.hurt.fall.big", "entity.generic.big_fall"); ++ sounds.put("game.potion.smash", "block.glass.break"); ++ sounds.put("game.tnt.primed", "entity.tnt.primed"); ++ sounds.put("item.fireCharge.use", "item.firecharge.use"); ++ sounds.put("liquid.lava", "block.lava.ambient"); ++ sounds.put("liquid.lavapop", "block.lava.pop"); ++ sounds.put("liquid.water", "block.water.ambient"); ++ sounds.put("minecart.base", "entity.minecart.riding"); ++ sounds.put("minecart.inside", "entity.minecart.inside"); ++ sounds.put("mob.bat.death", "entity.bat.death"); ++ sounds.put("mob.bat.hurt", "entity.bat.hurt"); ++ sounds.put("mob.bat.idle", "entity.bat.ambient"); ++ sounds.put("mob.bat.takeoff", "entity.bat.takeoff"); ++ sounds.put("mob.blaze.breathe", "entity.blaze.ambient"); ++ sounds.put("mob.blaze.death", "entity.blaze.death"); ++ sounds.put("mob.blaze.hit", "entity.blaze.hurt"); ++ sounds.put("mob.cat.hitt", "entity.cat.hurt"); ++ sounds.put("mob.cat.meow", "entity.cat.ambient"); ++ sounds.put("mob.cat.purr", "entity.cat.purr"); ++ sounds.put("mob.cat.purreow", "entity.cat.purreow"); ++ sounds.put("mob.chicken.hurt", "entity.chicken.hurt"); ++ sounds.put("mob.chicken.plop", "entity.chicken.egg"); ++ sounds.put("mob.chicken.say", "entity.chicken.ambient"); ++ sounds.put("mob.chicken.step", "entity.chicken.step"); ++ sounds.put("mob.cow.hurt", "entity.cow.hurt"); ++ sounds.put("mob.cow.say", "entity.cow.ambient"); ++ sounds.put("mob.cow.step", "entity.cow.step"); ++ sounds.put("mob.creeper.death", "entity.creeper.death"); ++ sounds.put("mob.creeper.say", "entity.creeper.hurt"); ++ sounds.put("mob.enderdragon.end", "entity.enderdragon.death"); ++ sounds.put("mob.enderdragon.growl", "entity.enderdragon.growl"); ++ sounds.put("mob.enderdragon.hit", "entity.enderdragon.hurt"); ++ sounds.put("mob.enderdragon.wings", "entity.enderdragon.flap"); ++ sounds.put("mob.endermen.death", "entity.endermen.death"); ++ sounds.put("mob.endermen.hit", "entity.endermen.hurt"); ++ sounds.put("mob.endermen.idle", "entity.endermen.ambient"); ++ sounds.put("mob.endermen.portal", "entity.endermen.teleport"); ++ sounds.put("mob.endermen.scream", "entity.endermen.scream"); ++ sounds.put("mob.endermen.stare", "entity.endermen.stare"); ++ sounds.put("mob.ghast.charge", "entity.ghast.warn"); ++ sounds.put("mob.ghast.death", "entity.ghast.death"); ++ sounds.put("mob.ghast.moan", "entity.ghast.ambient"); ++ sounds.put("mob.ghast.scream", "entity.ghast.hurt"); ++ sounds.put("mob.guardian.attack", "entity.guardian.attack"); ++ sounds.put("mob.guardian.curse", "entity.elder_guardian.curse"); ++ sounds.put("mob.guardian.death", "entity.guardian.death"); ++ sounds.put("mob.guardian.elder.death", "entity.elder_guardian.death"); ++ sounds.put("mob.guardian.elder.hit", "entity.elder_guardian.hurt"); ++ sounds.put("mob.guardian.elder.idle", "entity.elder_guardian.ambient"); ++ sounds.put("mob.guardian.flop", "entity.guardian.flop"); ++ sounds.put("mob.guardian.hit", "entity.guardian.hurt"); ++ sounds.put("mob.guardian.idle", "entity.guardian.ambient"); ++ sounds.put("mob.guardian.land.death", "entity.guardian.death_land"); ++ sounds.put("mob.guardian.land.hit", "entity.elder_guardian.hurt_land"); ++ sounds.put("mob.guardian.land.idle", "entity.elder_guardian.ambient_land"); ++ sounds.put("mob.horse.angry", "entity.horse.angry"); ++ sounds.put("mob.horse.armor", "entity.horse.armor"); ++ sounds.put("mob.horse.breathe", "entity.horse.breathe"); ++ sounds.put("mob.horse.death", "entity.horse.death"); ++ sounds.put("mob.horse.donkey.angry", "entity.donkey.angry"); ++ sounds.put("mob.horse.donkey.death", "entity.mule.death"); ++ sounds.put("mob.horse.donkey.hit", "entity.donkey.hurt"); ++ sounds.put("mob.horse.donkey.idle", "entity.donkey.ambient"); ++ sounds.put("mob.horse.gallop", "entity.horse.gallop"); ++ sounds.put("mob.horse.hit", "entity.horse.hurt"); ++ sounds.put("mob.horse.idle", "entity.horse.ambient"); ++ sounds.put("mob.horse.jump", "entity.horse.jump"); ++ sounds.put("mob.horse.land", "entity.horse.land"); ++ sounds.put("mob.horse.leather", "entity.horse.saddle"); ++ sounds.put("mob.horse.skeleton.death", "entity.skeleton_horse.death"); ++ sounds.put("mob.horse.skeleton.hit", "entity.skeleton_horse.hurt"); ++ sounds.put("mob.horse.skeleton.idle", "entity.skeleton_horse.ambient"); ++ sounds.put("mob.horse.soft", "entity.horse.step"); ++ sounds.put("mob.horse.wood", "entity.horse.step_wood"); ++ sounds.put("mob.horse.zombie.death", "entity.zombie_horse.death"); ++ sounds.put("mob.horse.zombie.hit", "entity.zombie_horse.hurt"); ++ sounds.put("mob.horse.zombie.idle", "entity.zombie_horse.ambient"); ++ sounds.put("mob.irongolem.death", "entity.irongolem.death"); ++ sounds.put("mob.irongolem.hit", "entity.irongolem.hurt"); ++ sounds.put("mob.irongolem.throw", "entity.irongolem.attack"); ++ sounds.put("mob.irongolem.walk", "entity.irongolem.step"); ++ sounds.put("mob.magmacube.big", "entity.magmacube.squish"); ++ sounds.put("mob.magmacube.jump", "entity.magmacube.jump"); ++ sounds.put("mob.magmacube.small", "entity.small_magmacube.squish"); ++ sounds.put("mob.pig.death", "entity.pig.death"); ++ sounds.put("mob.pig.say", "entity.pig.hurt"); ++ sounds.put("mob.pig.step", "entity.pig.step"); ++ sounds.put("mob.rabbit.death", "entity.rabbit.death"); ++ sounds.put("mob.rabbit.hop", "entity.rabbit.jump"); ++ sounds.put("mob.rabbit.hurt", "entity.rabbit.hurt"); ++ sounds.put("mob.rabbit.idle", "entity.rabbit.ambient"); ++ sounds.put("mob.sheep.say", "entity.sheep.death"); ++ sounds.put("mob.sheep.shear", "entity.sheep.shear"); ++ sounds.put("mob.sheep.step", "entity.sheep.step"); ++ sounds.put("mob.silverfish.hit", "entity.endermite.hurt"); ++ sounds.put("mob.silverfish.kill", "entity.silverfish.death"); ++ sounds.put("mob.silverfish.say", "entity.silverfish.ambient"); ++ sounds.put("mob.silverfish.step", "entity.endermite.step"); ++ sounds.put("mob.skeleton.death", "entity.skeleton.death"); ++ sounds.put("mob.skeleton.hurt", "entity.skeleton.hurt"); ++ sounds.put("mob.skeleton.say", "entity.skeleton.ambient"); ++ sounds.put("mob.skeleton.step", "entity.skeleton.step"); ++ sounds.put("mob.slime.attack", "entity.slime.attack"); ++ sounds.put("mob.slime.big", "block.slime.place"); ++ sounds.put("mob.slime.small", "block.slime.fall"); ++ sounds.put("mob.spider.death", "entity.spider.death"); ++ sounds.put("mob.spider.say", "entity.spider.ambient"); ++ sounds.put("mob.spider.step", "entity.spider.step"); ++ sounds.put("mob.villager.death", "entity.villager.death"); ++ sounds.put("mob.villager.haggle", "entity.villager.trading"); ++ sounds.put("mob.villager.hit", "entity.villager.hurt"); ++ sounds.put("mob.villager.idle", "entity.villager.ambient"); ++ sounds.put("mob.villager.no", "entity.villager.no"); ++ sounds.put("mob.villager.yes", "entity.villager.yes"); ++ sounds.put("mob.wither.death", "entity.wither.death"); ++ sounds.put("mob.wither.hurt", "entity.wither.hurt"); ++ sounds.put("mob.wither.idle", "entity.wither.ambient"); ++ sounds.put("mob.wither.shoot", "entity.wither.shoot"); ++ sounds.put("mob.wither.spawn", "entity.wither.spawn"); ++ sounds.put("mob.wolf.bark", "entity.wolf.ambient"); ++ sounds.put("mob.wolf.death", "entity.wolf.death"); ++ sounds.put("mob.wolf.growl", "entity.wolf.growl"); ++ sounds.put("mob.wolf.hurt", "entity.wolf.hurt"); ++ sounds.put("mob.wolf.panting", "entity.wolf.pant"); ++ sounds.put("mob.wolf.shake", "entity.wolf.shake"); ++ sounds.put("mob.wolf.step", "entity.wolf.step"); ++ sounds.put("mob.wolf.whine", "entity.wolf.whine"); ++ sounds.put("mob.zombie.death", "entity.zombie.death"); ++ sounds.put("mob.zombie.hurt", "entity.zombie.hurt"); ++ sounds.put("mob.zombie.infect", "entity.zombie.infect"); ++ sounds.put("mob.zombie.metal", "entity.zombie.attack_iron_door"); ++ sounds.put("mob.zombie.remedy", "entity.zombie.cure"); ++ sounds.put("mob.zombie.say", "entity.zombie.ambient"); ++ sounds.put("mob.zombie.step", "entity.zombie.step"); ++ sounds.put("mob.zombie.unfect", "entity.zombie.unfect"); ++ sounds.put("mob.zombie.wood", "entity.zombie.attack_door_wood"); ++ sounds.put("mob.zombie.woodbreak", "entity.zombie.break_door_wood"); ++ sounds.put("mob.zombiepig.zpig", "entity.zombie_pig.ambient"); ++ sounds.put("mob.zombiepig.zpigangry", "entity.zombie_pig.angry"); ++ sounds.put("mob.zombiepig.zpigdeath", "entity.zombie_pig.death"); ++ sounds.put("mob.zombiepig.zpighurt", "entity.zombie_pig.hurt"); ++ sounds.put("music.game", "music.game"); ++ sounds.put("music.game.creative", "music.creative"); ++ sounds.put("music.game.end", "music.end"); ++ sounds.put("music.game.end.credits", "music.credits"); ++ sounds.put("music.game.end.dragon", "music.dragon"); ++ sounds.put("music.game.nether", "music.nether"); ++ sounds.put("music.menu", "music.menu"); ++ sounds.put("note.bassattack", "block.note.bass"); ++ sounds.put("note.bd", "block.note.basedrum"); ++ sounds.put("note.harp", "block.note.harp"); ++ sounds.put("note.hat", "block.note.hat"); ++ sounds.put("note.snare", "block.note.snare"); ++ sounds.put("portal.portal", "block.portal.ambient"); ++ sounds.put("portal.travel", "block.portal.travel"); ++ sounds.put("portal.trigger", "block.portal.trigger"); ++ sounds.put("random.anvil_break", "block.anvil.destroy"); ++ sounds.put("random.anvil_land", "block.anvil.place"); ++ sounds.put("random.anvil_use", "block.anvil.use"); ++ sounds.put("random.bow", "entity.firework.shoot"); ++ sounds.put("random.bowhit", "block.tripwire.detach"); ++ sounds.put("random.break", "entity.item.break"); ++ sounds.put("random.burp", "entity.player.burp"); ++ sounds.put("random.chestclosed", "block.enderchest.close"); ++ sounds.put("random.chestopen", "block.chest.open"); ++ sounds.put("random.click", "block.stone_pressureplate.click_on"); ++ sounds.put("random.door_close", "block.trapdoor.open"); ++ sounds.put("random.drink", "entity.generic.drink"); ++ sounds.put("random.eat", "entity.generic.eat"); ++ sounds.put("random.explode", "entity.lightning.impact"); ++ sounds.put("random.fizz", "entity.generic.extinguish_fire"); ++ sounds.put("random.levelup", "entity.player.levelup"); ++ sounds.put("random.orb", "entity.experience_orb.touch"); ++ sounds.put("random.pop", "entity.item.pickup"); ++ sounds.put("random.splash", "entity.bobber.splash"); ++ sounds.put("random.successful_hit", "entity.arrow.successful_hit"); ++ sounds.put("random.wood_click", "block.wood_button.click_off"); ++ sounds.put("records.11", "record.11"); ++ sounds.put("records.13", "record.13"); ++ sounds.put("records.blocks", "record.blocks"); ++ sounds.put("records.cat", "record.cat"); ++ sounds.put("records.chirp", "record.chirp"); ++ sounds.put("records.far", "record.far"); ++ sounds.put("records.mall", "record.mall"); ++ sounds.put("records.mellohi", "record.mellohi"); ++ sounds.put("records.stal", "record.stal"); ++ sounds.put("records.strad", "record.strad"); ++ sounds.put("records.wait", "record.wait"); ++ sounds.put("records.ward", "record.ward"); ++ sounds.put("step.cloth", "block.cloth.fall"); ++ sounds.put("step.grass", "block.grass.step"); ++ sounds.put("step.gravel", "block.gravel.hit"); ++ sounds.put("step.ladder", "block.ladder.hit"); ++ sounds.put("step.sand", "block.sand.hit"); ++ sounds.put("step.snow", "block.snow.fall"); ++ sounds.put("step.stone", "block.stone.hit"); ++ sounds.put("step.wood", "block.wood.step"); ++ sounds.put("tile.piston.in", "block.piston.contract"); ++ sounds.put("tile.piston.out", "block.piston.extend"); ++ } ++ + public String a; + public int b; + public int c; +@@ -16,12 +245,13 @@ public class PacketPlayOutNamedSoundEffect + { + c = 0x7fffffff; + } +- ++ private static HashMap so = new HashMap(); + public PacketPlayOutNamedSoundEffect(String s, double d1, double d2, double d3, + float f1, float f2) + { + c = 0x7fffffff; + Validate.notNull(s, "name", new Object[0]); ++ if (!so.containsKey(s) || so.get(s) < System.currentTimeMillis()){so.put(s, System.currentTimeMillis() + 60000); System.out.print("Sound: " + s);} + a = s; + b = (int)(d1 * 8D); + c = (int)(d2 * 8D); +@@ -43,7 +273,11 @@ public class PacketPlayOutNamedSoundEffect + + public void b(PacketDataSerializer packetdataserializer) + { +- packetdataserializer.a(a); ++ String toPlay = a; ++ if (packetdataserializer.version > 47 && sounds.containsKey(toPlay)) ++ toPlay = sounds.get(toPlay); ++ ++ packetdataserializer.a(toPlay); + packetdataserializer.writeInt(b); + packetdataserializer.writeInt(c); + packetdataserializer.writeInt(d); +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutNewAttachEntity.java b/src/main/java/net/minecraft/server/PacketPlayOutNewAttachEntity.java +new file mode 100644 +index 0000000..2467252 +--- /dev/null ++++ b/src/main/java/net/minecraft/server/PacketPlayOutNewAttachEntity.java +@@ -0,0 +1,56 @@ ++package net.minecraft.server; ++ ++import java.io.IOException; ++ ++public class PacketPlayOutNewAttachEntity implements Packet ++{ ++ public int a; ++ public int[] b; ++ ++ public PacketPlayOutNewAttachEntity() ++ { ++ } ++ ++ public PacketPlayOutNewAttachEntity(Entity vehicle, Entity[] riding) ++ { ++ this.a = vehicle.getId(); ++ this.b = new int[riding.length]; ++ ++ for (int i=0; i ++{ ++ public enum EnumPlayerTeleportFlags ++ { ++ ++ X(0), Y(1), Z(2), Y_ROT(3), X_ROT(4); ++ ++ private int f; ++ ++ private EnumPlayerTeleportFlags(int j) ++ { ++ f = j; ++ } ++ ++ private int a() ++ { ++ return 1 << f; ++ } ++ ++ private boolean b(int i) ++ { ++ return (i & a()) == a(); ++ } ++ ++ public static Set a(int i) ++ { ++ EnumSet enumset = EnumSet.noneOf(PacketPlayOutPosition.EnumPlayerTeleportFlags.class); ++ int j = values().length; ++ for(int k = 0; k < j; k++) ++ { ++ EnumPlayerTeleportFlags enumplayerteleportflags = values()[k]; ++ if(enumplayerteleportflags.b(i)) ++ enumset.add(enumplayerteleportflags); ++ } ++ ++ return enumset; ++ } ++ ++ public static int a(Set set) ++ { ++ int i = 0; ++ for(Iterator iterator = set.iterator(); iterator.hasNext();) ++ { ++ EnumPlayerTeleportFlags enumplayerteleportflags = (EnumPlayerTeleportFlags)iterator.next(); ++ i |= enumplayerteleportflags.a(); ++ } ++ ++ return i; ++ } ++ } ++ ++ public double a; ++ public double b; ++ public double c; ++ public float d; ++ public float e; ++ public Set f; ++ ++ public PacketPlayOutPosition() ++ { ++ } ++ ++ public PacketPlayOutPosition(double d1, double d2, double d3, float f1, ++ float f2, Set set) ++ { ++ a = d1; ++ b = d2; ++ c = d3; ++ d = f1; ++ e = f2; ++ f = set; ++ } ++ ++ public void a(PacketDataSerializer packetdataserializer) ++ throws IOException ++ { ++ a = packetdataserializer.readDouble(); ++ b = packetdataserializer.readDouble(); ++ c = packetdataserializer.readDouble(); ++ d = packetdataserializer.readFloat(); ++ e = packetdataserializer.readFloat(); ++ f = EnumPlayerTeleportFlags.a(packetdataserializer.readUnsignedByte()); ++ } ++ ++ public void b(PacketDataSerializer packetdataserializer) ++ throws IOException ++ { ++ packetdataserializer.writeDouble(a); ++ packetdataserializer.writeDouble(b); ++ packetdataserializer.writeDouble(c); ++ packetdataserializer.writeFloat(d); ++ packetdataserializer.writeFloat(e); ++ packetdataserializer.writeByte(EnumPlayerTeleportFlags.a(f)); ++ if (packetdataserializer.version != 47) ++ packetdataserializer.b(0); ++ } ++ ++ public void a(PacketListenerPlayOut packetlistenerplayout) ++ { ++ packetlistenerplayout.a(this); ++ } ++} +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java b/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java +index f300bfc..7ef913f 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutScoreboardTeam.java +@@ -12,6 +12,7 @@ public class PacketPlayOutScoreboardTeam + public String c = ""; + public String d = ""; + public String e = ScoreboardTeamBase.EnumNameTagVisibility.ALWAYS.e; ++ public String collision = "never"; + public int f = -1; + public Collection g = Lists.newArrayList(); + public int h; +@@ -85,6 +86,10 @@ public class PacketPlayOutScoreboardTeam + paramPacketDataSerializer.a(this.c); + paramPacketDataSerializer.a(this.d); + paramPacketDataSerializer.writeByte(this.i); ++ if (paramPacketDataSerializer.version != 47) ++ { ++ paramPacketDataSerializer.a(collision); ++ } + paramPacketDataSerializer.a(this.e); + paramPacketDataSerializer.writeByte(this.f); + } +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntity.java b/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntity.java +index 56eeff6..0c60066 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntity.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntity.java +@@ -1,6 +1,7 @@ + package net.minecraft.server; + + import java.io.IOException; ++import java.util.UUID; + + public class PacketPlayOutSpawnEntity implements Packet { + +@@ -15,6 +16,7 @@ public class PacketPlayOutSpawnEntity implements Packet { + public int i; + public int j; + public int k; ++ public UUID uuid; + + public PacketPlayOutSpawnEntity() {} + +@@ -31,6 +33,8 @@ public class PacketPlayOutSpawnEntity implements Packet { + this.i = MathHelper.d((entity.isFakeHead() ? entity.fakeYaw : entity.yaw) * 256.0F / 360.0F); + this.j = i; + this.k = j; ++ this.uuid = entity.getUniqueID(); ++ + if (j > 0) { + double d0 = entity.motX; + double d1 = entity.motY; +@@ -65,7 +69,6 @@ public class PacketPlayOutSpawnEntity implements Packet { + this.f = (int) (d1 * 8000.0D); + this.g = (int) (d2 * 8000.0D); + } +- + } + + public void a(PacketDataSerializer packetdataserializer) throws IOException { +@@ -87,6 +90,8 @@ public class PacketPlayOutSpawnEntity implements Packet { + + public void b(PacketDataSerializer packetdataserializer) throws IOException { + packetdataserializer.b(this.a); ++ if (packetdataserializer.version != 47) ++ packetdataserializer.a(this.uuid); + packetdataserializer.writeByte(this.j); + packetdataserializer.writeInt(this.b); + packetdataserializer.writeInt(this.c); +@@ -94,7 +99,7 @@ public class PacketPlayOutSpawnEntity implements Packet { + packetdataserializer.writeByte(this.h); + packetdataserializer.writeByte(this.i); + packetdataserializer.writeInt(this.k); +- if (this.k > 0) { ++ if (packetdataserializer.version != 47 || this.k > 0) { + packetdataserializer.writeShort(this.e); + packetdataserializer.writeShort(this.f); + packetdataserializer.writeShort(this.g); +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntityLiving.java b/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntityLiving.java +index 286ad09..9da448e 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntityLiving.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutSpawnEntityLiving.java +@@ -2,6 +2,7 @@ package net.minecraft.server; + + import java.io.IOException; + import java.util.List; ++import java.util.UUID; + + public class PacketPlayOutSpawnEntityLiving implements Packet { + +@@ -18,6 +19,7 @@ public class PacketPlayOutSpawnEntityLiving implements Packet m; ++ public UUID uuid; + + public PacketPlayOutSpawnEntityLiving() {} + +@@ -34,6 +36,7 @@ public class PacketPlayOutSpawnEntityLiving implements Packet ++{ ++ public int a; ++ public int b; ++ ++ public PacketPlayOutUnloadChunk() ++ { ++ } ++ ++ public PacketPlayOutUnloadChunk(int paramInt1, int paramInt2) ++ { ++ this.a = paramInt1; ++ this.b = paramInt2; ++ } ++ ++ public void a(PacketListenerPlayOut paramPacketListenerPlayOut) ++ { ++ paramPacketListenerPlayOut.a(this); ++ } ++ ++ public void a(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ } ++ ++ public void b(PacketDataSerializer paramPacketDataSerializer) throws IOException ++ { ++ paramPacketDataSerializer.writeInt(this.a); ++ paramPacketDataSerializer.writeInt(this.b); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/PacketPlayOutUpdateSign.java b/src/main/java/net/minecraft/server/PacketPlayOutUpdateSign.java +index ebf08f6..9a3b275 100644 +--- a/src/main/java/net/minecraft/server/PacketPlayOutUpdateSign.java ++++ b/src/main/java/net/minecraft/server/PacketPlayOutUpdateSign.java +@@ -6,6 +6,7 @@ + package net.minecraft.server; + + import java.io.IOException; ++import org.bukkit.craftbukkit.util.CraftChatMessage; + + // Referenced classes of package net.minecraft.server.v1_8_R3: + // Packet, IChatBaseComponent, PacketDataSerializer, PacketListenerPlayOut, +@@ -14,6 +15,9 @@ import java.io.IOException; + public class PacketPlayOutUpdateSign + implements Packet + { ++ public World a; ++ public BlockPosition b; ++ public IChatBaseComponent c[]; + + public PacketPlayOutUpdateSign() + { +@@ -34,7 +38,12 @@ public class PacketPlayOutUpdateSign + b = packetdataserializer.c(); + c = new IChatBaseComponent[4]; + for(int i = 0; i < 4; i++) +- c[i] = packetdataserializer.d(); ++ { ++ if (packetdataserializer.version == 47) ++ c[i] = packetdataserializer.d(); ++ else ++ c[i] = CraftChatMessage.fromString(packetdataserializer.c(50))[0]; ++ } + + } + +@@ -43,7 +52,16 @@ public class PacketPlayOutUpdateSign + { + packetdataserializer.a(b); + for(int i = 0; i < 4; i++) +- packetdataserializer.a(c[i]); ++ { ++ if (packetdataserializer.version == 47) ++ { ++ packetdataserializer.a(c[i]); ++ } ++ else ++ { ++ packetdataserializer.a(c[i]); ++ } ++ } + + } + +@@ -56,8 +74,4 @@ public class PacketPlayOutUpdateSign + { + a((PacketListenerPlayOut)packetlistener); + } +- +- public World a; +- public BlockPosition b; +- public IChatBaseComponent c[]; + } +diff --git a/src/main/java/net/minecraft/server/PacketStatusListener.java b/src/main/java/net/minecraft/server/PacketStatusListener.java +index e4bff04..ea99925 100644 +--- a/src/main/java/net/minecraft/server/PacketStatusListener.java ++++ b/src/main/java/net/minecraft/server/PacketStatusListener.java +@@ -121,7 +121,7 @@ public class PacketStatusListener implements PacketStatusInListener { + ping.setFavicon(event.icon.value); + ping.setMOTD(new ChatComponentText(event.getMotd())); + ping.setPlayerSample(playerSample); +- ping.setServerInfo(new ServerPing.ServerData(minecraftServer.getServerModName() + " " + minecraftServer.getVersion(), 47)); // TODO: Update when protocol changes ++ ping.setServerInfo(new ServerPing.ServerData(minecraftServer.getServerModName() + " " + minecraftServer.getVersion(), networkManager.getVersion())); // TODO: Update when protocol changes + + this.networkManager.handle(new PacketStatusOutServerInfo(ping)); + // CraftBukkit end +diff --git a/src/main/java/net/minecraft/server/PlayerChunkMap.java b/src/main/java/net/minecraft/server/PlayerChunkMap.java +index abb24c8..2d8db9c 100644 +--- a/src/main/java/net/minecraft/server/PlayerChunkMap.java ++++ b/src/main/java/net/minecraft/server/PlayerChunkMap.java +@@ -386,7 +386,12 @@ public class PlayerChunkMap { + Chunk chunk = PlayerChunkMap.this.world.getChunkAt(this.location.x, this.location.z); + + if (chunk.isReady()) { +- entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunk, true, 0)); ++ if (entityplayer.playerConnection.networkManager.getVersion() > 47) ++ { ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutUnloadChunk(chunk.locX, chunk.locZ)); ++ } ++ else ++ entityplayer.playerConnection.sendPacket(new PacketPlayOutMapChunk(chunk, true, 0)); + } + + this.players.remove(entityplayer); // CraftBukkit +diff --git a/src/main/java/net/minecraft/server/PlayerConnection.java b/src/main/java/net/minecraft/server/PlayerConnection.java +index 5edef3e..a8c5b44 100644 +--- a/src/main/java/net/minecraft/server/PlayerConnection.java ++++ b/src/main/java/net/minecraft/server/PlayerConnection.java +@@ -386,7 +386,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList + f3 = packetplayinflying.e(); + } + +- this.player.l(); ++ //this.player.l(); + this.player.setLocation(this.o, this.p, this.q, f2, f3); + if (!this.checkMovement) { + return; +@@ -692,6 +692,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList + EnumDirection enumdirection = EnumDirection.fromType1(packetplayinblockplace.getFace()); + + this.player.resetIdleTimer(); ++ // Never called by 1.9 + if (packetplayinblockplace.getFace() == 255) { + if (itemstack == null) { + return; +@@ -701,41 +702,41 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList + int itemstackAmount = itemstack.count; + // Spigot start - skip the event if throttled + if (!throttled) { +- // Raytrace to look for 'rogue armswings' +- float f1 = this.player.pitch; +- float f2 = this.player.yaw; +- double d0 = this.player.locX; +- double d1 = this.player.locY + (double) this.player.getHeadHeight(); +- double d2 = this.player.locZ; +- Vec3D vec3d = new Vec3D(d0, d1, d2); +- +- float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); +- float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); +- float f5 = -MathHelper.cos(-f1 * 0.017453292F); +- float f6 = MathHelper.sin(-f1 * 0.017453292F); +- float f7 = f4 * f5; +- float f8 = f3 * f5; +- double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; +- Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); +- MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); +- +- boolean cancelled = false; +- if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { +- org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack); +- cancelled = event.useItemInHand() == Event.Result.DENY; +- } else { +- if (player.playerInteractManager.firedInteract) { +- player.playerInteractManager.firedInteract = false; +- cancelled = player.playerInteractManager.interactResult; +- } else { +- org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectposition.a(), movingobjectposition.direction, itemstack, true); ++ // Raytrace to look for 'rogue armswings' ++ float f1 = this.player.pitch; ++ float f2 = this.player.yaw; ++ double d0 = this.player.locX; ++ double d1 = this.player.locY + (double) this.player.getHeadHeight(); ++ double d2 = this.player.locZ; ++ Vec3D vec3d = new Vec3D(d0, d1, d2); ++ ++ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); ++ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); ++ float f5 = -MathHelper.cos(-f1 * 0.017453292F); ++ float f6 = MathHelper.sin(-f1 * 0.017453292F); ++ float f7 = f4 * f5; ++ float f8 = f3 * f5; ++ double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; ++ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); ++ MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); ++ ++ boolean cancelled = false; ++ if (this.networkManager.getVersion() == 47 && (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK)) { ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack); + cancelled = event.useItemInHand() == Event.Result.DENY; ++ } else { ++ if (player.playerInteractManager.firedInteract) { ++ player.playerInteractManager.firedInteract = false; ++ cancelled = player.playerInteractManager.interactResult; ++ } else { ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(player, Action.RIGHT_CLICK_BLOCK, movingobjectposition.a(), movingobjectposition.direction, itemstack, true); ++ cancelled = event.useItemInHand() == Event.Result.DENY; ++ } + } +- } + +- if (!cancelled) { +- this.player.playerInteractManager.useItem(this.player, this.player.world, itemstack); +- } ++ if (!cancelled) { ++ this.player.playerInteractManager.useItem(this.player, this.player.world, itemstack); ++ } + } + // Spigot end + +@@ -788,7 +789,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList + this.player.activeContainer.b(); + this.player.g = false; + // CraftBukkit - TODO CHECK IF NEEDED -- new if structure might not need 'always'. Kept it in for now, but may be able to remove in future +- if (!ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) { ++ if (this.networkManager.getVersion() == 47 && !ItemStack.matches(this.player.inventory.getItemInHand(), packetplayinblockplace.getItemStack()) || always) { + this.sendPacket(new PacketPlayOutSetSlot(this.player.activeContainer.windowId, slot.rawSlotIndex, this.player.inventory.getItemInHand())); + } + } +@@ -1992,7 +1993,7 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList + + itemstack1 = this.player.inventory.getItemInHand(); + if (itemstack1 != null) { +- if (itemstack.getItem() == Items.WRITTEN_BOOK && itemstack1.getItem() == Items.WRITABLE_BOOK) { ++ if (itemstack.getItem() == (networkManager.getVersion() == 47 ? Items.WRITTEN_BOOK : Items.WRITABLE_BOOK) && itemstack1.getItem() == Items.WRITABLE_BOOK) { + // CraftBukkit start + itemstack1 = new ItemStack(Items.WRITTEN_BOOK); + itemstack1.a("author", (NBTBase) (new NBTTagString(this.player.getName()))); +@@ -2247,4 +2248,65 @@ public class PlayerConnection implements PacketListenerPlayIn, IUpdatePlayerList + + } + } ++ ++ public void a(PacketPlayInUnknownFloats paramPacketPlayInUnknownFloats){System.out.print("Received unknown floats");} ++ ++ public void a(PacketPlayInUnknownPosition paramPacketPlayInUnknownPosition){System.out.print("Received unknown position");} ++ ++ public void a(PacketPlayInLeftClick paramPacketPlayInLeftClick){System.out.print("Received left click");} ++ ++ public void a(PacketPlayInRightClick paramPacketPlayInRightClick) ++ { ++ PlayerConnectionUtils.ensureMainThread(paramPacketPlayInRightClick, this, this.player.u()); ++ // CraftBukkit - if rightclick decremented the item, always send the update packet. */ ++ // this is not here for CraftBukkit's own functionality; rather it is to fix ++ // a notch bug where the item doesn't update correctly. ++ boolean always = false; ++ // CraftBukkit end ++ ++ ItemStack itemstack = this.player.inventory.getItemInHand(); ++ boolean flag = false; ++ ++ this.player.resetIdleTimer(); ++ // Never called by 1.9 ++ if (itemstack == null) { ++ return; ++ } ++ ++ // CraftBukkit start ++ int itemstackAmount = itemstack.count; ++ // Raytrace to look for 'rogue armswings' ++ float f1 = this.player.pitch; ++ float f2 = this.player.yaw; ++ double d0 = this.player.locX; ++ double d1 = this.player.locY + (double) this.player.getHeadHeight(); ++ double d2 = this.player.locZ; ++ Vec3D vec3d = new Vec3D(d0, d1, d2); ++ ++ float f3 = MathHelper.cos(-f2 * 0.017453292F - 3.1415927F); ++ float f4 = MathHelper.sin(-f2 * 0.017453292F - 3.1415927F); ++ float f5 = -MathHelper.cos(-f1 * 0.017453292F); ++ float f6 = MathHelper.sin(-f1 * 0.017453292F); ++ float f7 = f4 * f5; ++ float f8 = f3 * f5; ++ double d3 = player.playerInteractManager.getGameMode() == WorldSettings.EnumGamemode.CREATIVE ? 5.0D : 4.5D; ++ Vec3D vec3d1 = vec3d.add((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); ++ MovingObjectPosition movingobjectposition = this.player.world.rayTrace(vec3d, vec3d1, false); ++ ++ boolean cancelled = false; ++ if (movingobjectposition == null || movingobjectposition.type != MovingObjectPosition.EnumMovingObjectType.BLOCK) { ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.player, Action.RIGHT_CLICK_AIR, itemstack); ++ cancelled = event.useItemInHand() == Event.Result.DENY; ++ } ++ ++ if (!cancelled) { ++ this.player.playerInteractManager.useItem(this.player, this.player.world, itemstack); ++ } ++ // Spigot end ++ ++ // CraftBukkit - notch decrements the counter by 1 in the above method with food, ++ // snowballs and so forth, but he does it in a place that doesn't cause the ++ // inventory update packet to get sent ++ always = (itemstack.count != itemstackAmount) || itemstack.getItem() == Item.getItemOf(Blocks.WATERLILY); ++ } + } +diff --git a/src/main/java/net/minecraft/server/RegistryID.java b/src/main/java/net/minecraft/server/RegistryID.java +new file mode 100644 +index 0000000..86453bf +--- /dev/null ++++ b/src/main/java/net/minecraft/server/RegistryID.java +@@ -0,0 +1,50 @@ ++package net.minecraft.server; ++ ++import com.google.common.base.Predicates; ++import com.google.common.collect.Iterators; ++import com.google.common.collect.Lists; ++import java.util.IdentityHashMap; ++import java.util.Iterator; ++import java.util.List; ++ ++public class RegistryID ++ implements Registry ++{ ++ private final IdentityHashMap a = new IdentityHashMap(512); ++ private final List b = Lists.newArrayList(); ++ ++ public void a(T paramT, int paramInt) { ++ this.a.put(paramT, Integer.valueOf(paramInt)); ++ ++ while (this.b.size() <= paramInt) { ++ this.b.add(null); ++ } ++ ++ this.b.set(paramInt, paramT); ++ } ++ ++ public int b(T paramT) ++ { ++ Integer localInteger = (Integer)this.a.get(paramT); ++ return localInteger == null ? -1 : localInteger.intValue(); ++ } ++ ++ public final T a(int paramInt) ++ { ++ if ((paramInt >= 0) && (paramInt < this.b.size())) { ++ return this.b.get(paramInt); ++ } ++ ++ return null; ++ } ++ ++ public Iterator iterator() ++ { ++ return Iterators.filter(this.b.iterator(), Predicates.notNull()); ++ } ++ ++ public int a() ++ { ++ return this.a.size(); ++ } ++} +\ No newline at end of file +diff --git a/src/main/java/net/minecraft/server/World.java b/src/main/java/net/minecraft/server/World.java +index eca86db..e61032c 100644 +--- a/src/main/java/net/minecraft/server/World.java ++++ b/src/main/java/net/minecraft/server/World.java +@@ -1347,6 +1347,11 @@ public abstract class World implements IBlockAccess { + CrashReport crashreport; + CrashReportSystemDetails crashreportsystemdetails; + ++ for (EntityHuman player : players) ++ { ++ ((EntityPlayer) player).l(); ++ } ++ + for (i = 0; i < this.k.size(); ++i) { + entity = (Entity) this.k.get(i); + // CraftBukkit start - Fixed an NPE +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +index efbf1a8..dbc7b54 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +@@ -1,6 +1,7 @@ + package org.bukkit.craftbukkit.entity; + + import com.google.common.base.Preconditions; ++import com.google.common.primitives.Doubles; + import java.util.ArrayList; + import java.util.Collection; + import java.util.List; +@@ -234,6 +235,12 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { + // If this entity is riding another entity, we must dismount before teleporting. + entity.mount(null); + ++ if (!Doubles.isFinite(location.getX()) || !Doubles.isFinite(location.getY()) || !Doubles.isFinite(location.getZ())) ++ { ++ Thread.dumpStack(); ++ return false; ++ } ++ + // Spigot start + if (!location.getWorld().equals(getWorld())) { + entity.teleportTo(location, cause.equals(TeleportCause.NETHER_PORTAL)); +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +index 76a9bdb..473f574 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java +@@ -26,7 +26,7 @@ public class CraftFirework extends CraftEntity implements Firework { + + if (item == null) { + item = new ItemStack(Items.FIREWORKS); +- getHandle().getDataWatcher().watch(FIREWORK_ITEM_INDEX, item); ++ getHandle().setFireworkItem(item); + } + + this.item = CraftItemStack.asCraftMirror(item); +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +index e979f69..42f0a58 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +@@ -1301,7 +1301,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { + + injectScaledMaxHealth(set, true); + +- getHandle().getDataWatcher().watch(6, (float) getScaledHealth()); ++ getHandle().getDataWatcher().watch(6, (float) getScaledHealth(), getHandle().META_HEALTH, (float) getScaledHealth()); + getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateHealth(getScaledHealth(), getHandle().getFoodData().getFoodLevel(), getHandle().getFoodData().getSaturationLevel())); + getHandle().playerConnection.sendPacket(new PacketPlayOutUpdateAttributes(getHandle().getId(), set)); + +diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java +index 18da426..79bd517 100644 +--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java ++++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java +@@ -29,7 +29,7 @@ public class CraftThrownPotion extends CraftProjectile implements ThrownPotion { + // We run this method once since it will set the item stack if there is none. + getHandle().getPotionValue(); + +- return CraftItemStack.asBukkitCopy(getHandle().item); ++ return CraftItemStack.asBukkitCopy(getHandle().getItem()); + } + + public void setItem(ItemStack item) { +@@ -39,7 +39,7 @@ public class CraftThrownPotion extends CraftProjectile implements ThrownPotion { + // The ItemStack must be a potion. + Validate.isTrue(item.getType() == Material.POTION, "ItemStack must be a potion. This item stack was " + item.getType() + "."); + +- getHandle().item = CraftItemStack.asNMSCopy(item); ++ getHandle().setItem(CraftItemStack.asNMSCopy(item)); + } + + @Override +-- +1.9.5.msysgit.0 +