From 140edabb4e90f69602c5726a68526f1c8bdeb14b Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Tue, 18 Sep 2012 02:04:26 +0200 Subject: [PATCH] Fixed packet constructor and tons of other bugs. --- .../comphenix/protocol/ProtocolManager.java | 4 +-- .../protocol/events/PacketContainer.java | 31 +++++++++++++++++++ .../protocol/injector/PacketConstructor.java | 9 ++++-- .../injector/PacketFilterManager.java | 11 +++++-- .../protocol/reflect/EquivalentConverter.java | 1 + .../protocol/reflect/StructureModifier.java | 29 ++++++++++++----- 6 files changed, 70 insertions(+), 15 deletions(-) diff --git a/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java b/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java index 485ec3ae..337d13c2 100644 --- a/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java +++ b/ProtocolLib/src/com/comphenix/protocol/ProtocolManager.java @@ -128,10 +128,10 @@ public interface ProtocolManager { /** * Construct a packet using the special builtin Minecraft constructors. * @param id - the packet ID. - * @param argumentTypes - type of each argument to pass to Minecraft. + * @param argumentTypes - arguments that will be passed to the constructor. * @return The packet constructor. */ - public PacketConstructor createPacketConstructor(int id, Class... argumentTypes); + public PacketConstructor createPacketConstructor(int id, Object... arguments); /** * Retrieves a immutable set containing the ID of the sent server packets that will be observed by listeners. diff --git a/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java b/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java index e2a53d8e..09207da9 100644 --- a/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java +++ b/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java @@ -25,6 +25,7 @@ import org.bukkit.WorldType; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.entity.Entity; +import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import com.comphenix.protocol.injector.StructureCache; @@ -136,6 +137,11 @@ public class PacketContainer { public ItemStack getSpecific(Object generic) { return new CraftItemStack((net.minecraft.server.ItemStack) generic); } + + @Override + public Class getSpecificType() { + return ItemStack.class; + } }); } @@ -170,6 +176,11 @@ public class PacketContainer { } return result; } + + @Override + public Class getSpecificType() { + return ItemStack[].class; + } }); } @@ -199,6 +210,11 @@ public class PacketContainer { net.minecraft.server.WorldType type = (net.minecraft.server.WorldType) generic; return WorldType.getByName(type.name()); } + + @Override + public Class getSpecificType() { + return WorldType.class; + } }); } @@ -216,6 +232,7 @@ public class PacketContainer { final Object worldServer = ((CraftWorld) world).getHandle(); final Class nmsEntityClass = net.minecraft.server.Entity.class; + final World worldCopy = world; if (getEntity == null) getEntity = FuzzyReflection.fromObject(worldServer).getMethodByParameters( @@ -234,11 +251,20 @@ public class PacketContainer { try { net.minecraft.server.Entity nmsEntity = (net.minecraft.server.Entity) getEntity.invoke(worldServer, generic); + Integer id = (Integer) generic; // Attempt to get the Bukkit entity if (nmsEntity != null) { return nmsEntity.getBukkitEntity(); } else { + // Maybe it's a player that's just logged in? Try a search + for (Player player : worldCopy.getPlayers()) { + if (player.getEntityId() == id) { + return player; + } + } + + System.out.println("Entity doesn't exist."); return null; } @@ -250,6 +276,11 @@ public class PacketContainer { throw new RuntimeException("Error occured in Minecraft method.", e.getCause()); } } + + @Override + public Class getSpecificType() { + return Entity.class; + } }); } diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PacketConstructor.java b/ProtocolLib/src/com/comphenix/protocol/injector/PacketConstructor.java index 1f9d7701..048f77d6 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/PacketConstructor.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PacketConstructor.java @@ -26,7 +26,7 @@ public class PacketConstructor { *

* Remember to call withPacket(). */ - public static PacketConstructor DEFAUALT = new PacketConstructor(null); + public static PacketConstructor DEFAULT = new PacketConstructor(null); // The constructor method that's actually responsible for creating the packet private Constructor constructorMethod; @@ -79,7 +79,7 @@ public class PacketConstructor { for (Unwrapper unwrapper : unwrappers) { for (int i = 0; i < types.length; i++) { - Class result =unwrapper.unwrapType(types[i]); + Class result = unwrapper.unwrapType(types[i]); // Update type we're searching for if (result != null) { @@ -141,9 +141,12 @@ public class PacketConstructor { return false; } } + + return true; } - return true; + // Parameter count must match + return false; } public static class BukkitUnwrapper implements Unwrapper { diff --git a/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java b/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java index 675ab21a..bae212c8 100644 --- a/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java +++ b/ProtocolLib/src/com/comphenix/protocol/injector/PacketFilterManager.java @@ -326,8 +326,15 @@ public final class PacketFilterManager implements ProtocolManager { } @Override - public PacketConstructor createPacketConstructor(int id, Class... argumentTypes) { - return PacketConstructor.DEFAUALT.withPacket(id, argumentTypes); + public PacketConstructor createPacketConstructor(int id, Object... arguments) { + Class[] types = new Class[arguments.length]; + + // Initialize types + for (int i = 0; i < arguments.length; i++) { + types[i] = arguments[i] != null ? arguments[i].getClass() : Object.class; + } + + return PacketConstructor.DEFAULT.withPacket(id, types); } @Override diff --git a/ProtocolLib/src/com/comphenix/protocol/reflect/EquivalentConverter.java b/ProtocolLib/src/com/comphenix/protocol/reflect/EquivalentConverter.java index 3ffa65ff..79f37696 100644 --- a/ProtocolLib/src/com/comphenix/protocol/reflect/EquivalentConverter.java +++ b/ProtocolLib/src/com/comphenix/protocol/reflect/EquivalentConverter.java @@ -26,4 +26,5 @@ package com.comphenix.protocol.reflect; public interface EquivalentConverter { public TType getSpecific(Object generic); public Object getGeneric(TType specific); + public Class getSpecificType(); } diff --git a/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java b/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java index aa6aea67..0f9aed1f 100644 --- a/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java +++ b/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java @@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableList; @SuppressWarnings("rawtypes") public class StructureModifier { - + // Object and its type private Class targetType; private Object target; @@ -220,12 +220,8 @@ public class StructureModifier { StructureModifier result = subtypeCache.get(fieldType); - if (this.fieldType.equals(fieldType)) { - - // We're dealing with the exact field type. - return withConverter(converter); - - } else if (result == null) { + // Do we need to update the cache? + if (result == null) { List filtered = new ArrayList(); Set defaults = new HashSet(); @@ -248,7 +244,24 @@ public class StructureModifier { } // Add the target too - return result.withTarget(target); + result = result.withTarget(target); + + // And the converter, if it's needed + if (!sameConverter(result.converter, converter)) { + result = result.withConverter(converter); + } + + return result; + } + + private boolean sameConverter(EquivalentConverter a, EquivalentConverter b) { + // Compare the converter types + if (a == null) + return b == null; + else if (b == null) + return a == null; + else + return a.getSpecificType().equals(b.getSpecificType()); } /**