diff --git a/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java b/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java index 49bcea17..9b6f3d1b 100644 --- a/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java +++ b/ProtocolLib/src/com/comphenix/protocol/events/PacketContainer.java @@ -1,5 +1,6 @@ package com.comphenix.protocol.events; +import org.bukkit.WorldType; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; @@ -22,6 +23,17 @@ public class PacketContainer { // Current structure modifier protected StructureModifier structureModifier; + // Check whether or not certain classes exists + private static boolean hasWorldType = false; + + static { + try { + Class.forName("net.minecraft.server.WorldType"); + hasWorldType = true; + } catch (ClassNotFoundException e) { + } + } + /** * Creates a packet container for a new packet. * @param id - ID of the packet to create. @@ -70,10 +82,22 @@ public class PacketContainer { return structureModifier; } - public StructureModifier getPrimitiveModifier(Class primitiveType) { + /** + * Retrieves a read/write structure for every field with the given type. + * @param primitiveType - the type to find. + * @return A modifier for this specific type. + */ + public StructureModifier getSpecificModifier(Class primitiveType) { return structureModifier.withType(primitiveType); } + /** + * Retrieves a read/write structure for ItemStack. + *

+ * This modifier will automatically marshall between the Bukkit ItemStack and the + * internal Minecraft ItemStack. + * @return A modifier for ItemStack fields. + */ public StructureModifier getItemModifier() { // Convert from and to the Bukkit wrapper return structureModifier.withType(net.minecraft.server.ItemStack.class, new EquivalentConverter() { @@ -88,6 +112,13 @@ public class PacketContainer { }); } + /** + * Retrieves a read/write structure for arrays of ItemStacks. + *

+ * This modifier will automatically marshall between the Bukkit ItemStack and the + * internal Minecraft ItemStack. + * @return A modifier for ItemStack array fields. + */ public StructureModifier getItemArrayModifier() { // Convert to and from the Bukkit wrapper return structureModifier.withType(net.minecraft.server.ItemStack[].class, new EquivalentConverter() { @@ -115,6 +146,35 @@ public class PacketContainer { }); } + /** + * Retrieves a read/write structure for the world type enum. + *

+ * This modifier will automatically marshall between the Bukkit world type and the + * internal Minecraft world type. + * @return A modifier for world type fields. + */ + public StructureModifier getWorldTypeModifier() { + + if (!hasWorldType) { + // We couldn't find the Minecraft equivalent + return structureModifier.withType(null); + } + + // Convert to and from the Bukkit wrapper + return structureModifier.withType(net.minecraft.server.WorldType.class, new EquivalentConverter() { + @Override + public Object getGeneric(WorldType specific) { + return net.minecraft.server.WorldType.getType(specific.getName()); + } + + @Override + public WorldType getSpecific(Object generic) { + net.minecraft.server.WorldType type = (net.minecraft.server.WorldType) generic; + return WorldType.getByName(type.name()); + } + }); + } + /** * Retrieves the ID of this packet. * @return Packet ID. diff --git a/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java b/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java index e7d76219..39d1b0ce 100644 --- a/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java +++ b/ProtocolLib/src/com/comphenix/protocol/reflect/StructureModifier.java @@ -186,7 +186,7 @@ public class StructureModifier { StructureModifier result = subtypeCache.get(fieldType); - if (fieldType.equals(this.fieldType)) { + if (this.fieldType.equals(fieldType)) { // We're dealing with the exact field type. return withConverter(converter); @@ -196,7 +196,7 @@ public class StructureModifier { Set defaults = new HashSet(); for (Field field : data) { - if (fieldType.isAssignableFrom(field.getType())) { + if (fieldType != null && fieldType.isAssignableFrom(field.getType())) { filtered.add(field); if (defaultFields.contains(field)) @@ -208,7 +208,9 @@ public class StructureModifier { result = new StructureModifier(); result.initialize(targetType, fieldType, filtered, defaults, converter, new HashMap()); - subtypeCache.put(fieldType, result); + + if (fieldType != null) + subtypeCache.put(fieldType, result); } // Add the target too