Allow the usage of user-created enums

Basically this will allow developers to create their own enums instead
of having to wait on me to make them. The only caveat is that enum
constants will have to match up exactly with their NMS counterparts
This commit is contained in:
Dan Mulloy 2016-04-06 22:55:14 -04:00
parent 6030992af4
commit 8c928cb237
3 changed files with 51 additions and 1 deletions

View File

@ -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 <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, Class<?> nmsClass) {
return structureModifier.<T>withType(nmsClass, new EnumConverter<T>(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 <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, int index) {
return getEnumModifier(enumClass, structureModifier.getField(index).getType());
}
/**
* Retrieves the ID of this packet.
* <p>

View File

@ -599,7 +599,7 @@ public abstract class EnumWrappers {
// The common enum converter
@SuppressWarnings({ "rawtypes", "unchecked" })
private static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
private Class<T> specificType;
public EnumConverter(Class<T> specificType) {

View File

@ -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<PacketType> BLACKLISTED = Util.asList(
PacketType.Play.Client.CUSTOM_PAYLOAD, PacketType.Play.Server.CUSTOM_PAYLOAD,
PacketType.Play.Server.SET_COOLDOWN