Fixed packet constructor and tons of other bugs.

This commit is contained in:
Kristian S. Stangeland 2012-09-18 02:04:26 +02:00
parent ffbaed283a
commit 140edabb4e
6 changed files with 70 additions and 15 deletions

View File

@ -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.

View File

@ -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<ItemStack> getSpecificType() {
return ItemStack.class;
}
});
}
@ -170,6 +176,11 @@ public class PacketContainer {
}
return result;
}
@Override
public Class<ItemStack[]> 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<WorldType> 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<Entity> getSpecificType() {
return Entity.class;
}
});
}

View File

@ -26,7 +26,7 @@ public class PacketConstructor {
* <p>
* 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 {

View File

@ -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

View File

@ -26,4 +26,5 @@ package com.comphenix.protocol.reflect;
public interface EquivalentConverter<TType> {
public TType getSpecific(Object generic);
public Object getGeneric(TType specific);
public Class<TType> getSpecificType();
}

View File

@ -32,7 +32,7 @@ import com.google.common.collect.ImmutableList;
@SuppressWarnings("rawtypes")
public class StructureModifier<TField> {
// Object and its type
private Class targetType;
private Object target;
@ -220,12 +220,8 @@ public class StructureModifier<TField> {
StructureModifier<T> 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<Field> filtered = new ArrayList<Field>();
Set<Field> defaults = new HashSet<Field>();
@ -248,7 +244,24 @@ public class StructureModifier<TField> {
}
// 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());
}
/**