diff --git a/modules/API/src/main/java/com/comphenix/protocol/events/PacketContainer.java b/modules/API/src/main/java/com/comphenix/protocol/events/PacketContainer.java index 841885bd..fdf1d308 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/events/PacketContainer.java +++ b/modules/API/src/main/java/com/comphenix/protocol/events/PacketContainer.java @@ -81,6 +81,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.ClientCommand; import com.comphenix.protocol.wrappers.EnumWrappers.CombatEventType; import com.comphenix.protocol.wrappers.EnumWrappers.Difficulty; import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction; +import com.comphenix.protocol.wrappers.EnumWrappers.EnumConverter; import com.comphenix.protocol.wrappers.EnumWrappers.Hand; import com.comphenix.protocol.wrappers.EnumWrappers.ItemSlot; import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode; @@ -897,6 +898,33 @@ public class PacketContainer implements Serializable { EnumWrappers.getHandClass(), EnumWrappers.getHandConverter()); } + /** + * Retrieve a read/write structure for an enum. This allows for the use of + * user-created enums that may not exist in ProtocolLib. The specific (user + * created) enum constants must match up perfectly with their generic (NMS) + * counterparts. + * + * @param enumClass The specific Enum class + * @param nmsClass The generic Enum class + * @return The modifier + */ + public > StructureModifier getEnumModifier(Class enumClass, Class nmsClass) { + return structureModifier.withType(nmsClass, new EnumConverter(enumClass)); + } + + /** + * Retrieve a read/write structure for an enum. This method is for convenience, + * see {@link #getEnumModifier(Class, Class)} for more information. + * + * @param enumClass The specific Enum class + * @param index Index of the generic Enum + * @return The modifier + * @see #getEnumModifier(Class, Class) + */ + public > StructureModifier getEnumModifier(Class enumClass, int index) { + return getEnumModifier(enumClass, structureModifier.getField(index).getType()); + } + /** * Retrieves the ID of this packet. *

diff --git a/modules/API/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java b/modules/API/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java index fc6b7214..72ded7b0 100644 --- a/modules/API/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java +++ b/modules/API/src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java @@ -599,7 +599,7 @@ public abstract class EnumWrappers { // The common enum converter @SuppressWarnings({ "rawtypes", "unchecked" }) - private static class EnumConverter> implements EquivalentConverter { + public static class EnumConverter> implements EquivalentConverter { private Class specificType; public EnumConverter(Class specificType) { diff --git a/modules/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java b/modules/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java index d646e8f1..3d616ae1 100644 --- a/modules/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java +++ b/modules/ProtocolLib/src/test/java/com/comphenix/protocol/events/PacketContainerTest.java @@ -34,6 +34,7 @@ import net.minecraft.server.v1_9_R1.Entity; import net.minecraft.server.v1_9_R1.EntityLightning; import net.minecraft.server.v1_9_R1.MobEffect; import net.minecraft.server.v1_9_R1.MobEffectList; +import net.minecraft.server.v1_9_R1.PacketPlayOutBoss; import net.minecraft.server.v1_9_R1.PacketPlayOutUpdateAttributes; import net.minecraft.server.v1_9_R1.PacketPlayOutUpdateAttributes.AttributeSnapshot; @@ -501,6 +502,27 @@ public class PacketContainerTest { assertEquals(container.getSoundEffects().read(0), Sound.ENTITY_CAT_HISS); } + @Test + public void testGenericEnums() { + PacketContainer container = new PacketContainer(PacketType.Play.Server.BOSS); + container.getEnumModifier(Action.class, 1).write(0, Action.UPDATE_PCT); + + assertEquals(container.getEnumModifier(Action.class, PacketPlayOutBoss.Action.class).read(0), Action.UPDATE_PCT); + } + + /** + * Actions from the outbound Boss packet. Used for testing generic enums. + * @author dmulloy2 + */ + public static enum Action { + ADD, + REMOVE, + UPDATE_PCT, + UPDATE_NAME, + UPDATE_STYLE, + UPDATE_PROPERTIES; + } + private static final List BLACKLISTED = Util.asList( PacketType.Play.Client.CUSTOM_PAYLOAD, PacketType.Play.Server.CUSTOM_PAYLOAD, PacketType.Play.Server.SET_COOLDOWN