Skip to content

Commit e915fd0

Browse files
committed
Fix player action enum compatibility with 1.14 and below
1 parent 6f8b237 commit e915fd0

File tree

2 files changed

+46
-33
lines changed

2 files changed

+46
-33
lines changed

src/main/java/com/comphenix/protocol/wrappers/EnumWrappers.java

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
* Represents a generic enum converter.
2323
* @author Kristian
2424
*/
25+
@SuppressWarnings({"unchecked","rawtypes"})
2526
public abstract class EnumWrappers {
2627
public enum ClientCommand {
2728
PERFORM_RESPAWN,
@@ -161,8 +162,8 @@ public enum PlayerDigType {
161162
}
162163

163164
public enum PlayerAction implements AliasedEnum {
164-
PRESS_SHIFT_KEY("START_SNEAKING"),
165-
RELEASE_SHIFT_KEY("STOP_SNEAKING"),
165+
START_SNEAKING("PRESS_SHIFT_KEY"),
166+
STOP_SNEAKING("RELEASE_SHIFT_KEY"),
166167
STOP_SLEEPING,
167168
START_SPRINTING,
168169
STOP_SPRINTING,
@@ -677,8 +678,9 @@ public static <T extends Enum<T>> EquivalentConverter<T> getGenericConverter(Cla
677678
return new EnumConverter<>(null, specificType);
678679
}
679680

680-
// The common enum converter
681-
@SuppressWarnings({ "rawtypes", "unchecked" })
681+
/**
682+
* The common Enum converter
683+
*/
682684
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
683685
private Class<?> genericType;
684686
private Class<T> specificType;
@@ -712,62 +714,68 @@ public interface AliasedEnum {
712714
String[] getAliases();
713715
}
714716

717+
/**
718+
* Enums whose name has changed across NMS versions. Enums using this must also implement {@link AliasedEnum}
719+
*/
715720
public static class AliasedEnumConverter<T extends Enum<T> & AliasedEnum> implements EquivalentConverter<T> {
716721
private Class<?> genericType;
717722
private Class<T> specificType;
718723

724+
private Map<T, Object> genericMap = new ConcurrentHashMap<>();
725+
private Map<Object, T> specificMap = new ConcurrentHashMap<>();
726+
719727
public AliasedEnumConverter(Class<?> genericType, Class<T> specificType) {
720728
this.genericType = genericType;
721729
this.specificType = specificType;
722730
}
723731

724732
@Override
725733
public T getSpecific(Object generic) {
726-
String name = ((Enum) generic).name();
727-
728-
try {
729-
return Enum.valueOf(specificType, name);
730-
} catch (Exception ex) {
731-
// TODO would caching help much, if at all?
732-
for (T elem : specificType.getEnumConstants()) {
733-
for (String alias : elem.getAliases()) {
734-
if (alias.equals(name)) {
735-
return elem;
734+
return specificMap.computeIfAbsent(generic, x -> {
735+
String name = ((Enum) generic).name();
736+
737+
try {
738+
return Enum.valueOf(specificType, name);
739+
} catch (Exception ex) {
740+
for (T elem : specificType.getEnumConstants()) {
741+
for (String alias : elem.getAliases()) {
742+
if (alias.equals(name)) {
743+
return elem;
744+
}
736745
}
737746
}
738747
}
739-
}
740748

741-
throw new IllegalArgumentException("Unknown enum constant " + name);
749+
throw new IllegalArgumentException("Unknown enum constant " + name);
750+
});
742751
}
743752

744753
@Override
745754
public Object getGeneric(T specific) {
746-
String name = specific.name();
747-
748-
try {
749-
return Enum.valueOf((Class) genericType, specific.name());
750-
} catch (Exception ex) {
751-
for (Object elem : genericType.getEnumConstants()) {
752-
for (String alias : specific.getAliases()) {
753-
if (alias.equals(name)) {
754-
return elem;
755+
return genericMap.computeIfAbsent(specific, x -> {
756+
String name = specific.name();
757+
758+
try {
759+
return Enum.valueOf((Class) genericType, specific.name());
760+
} catch (Exception ex) {
761+
for (Object rawElem : genericType.getEnumConstants()) {
762+
Enum elem = (Enum) rawElem;
763+
for (String alias : specific.getAliases()) {
764+
if (alias.equals(elem.name())) {
765+
return elem;
766+
}
755767
}
756768
}
757769
}
758-
}
759770

760-
throw new IllegalArgumentException("Unknown enum constant " + name);
771+
throw new IllegalArgumentException("Unknown enum constant " + name);
772+
});
761773
}
762774

763775
@Override
764776
public Class<T> getSpecificType() {
765777
return specificType;
766778
}
767-
768-
void setGenericType(Class<?> genericType) {
769-
this.genericType = genericType;
770-
}
771779
}
772780

773781
/**

src/test/java/com/comphenix/protocol/events/PacketContainerTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -456,9 +456,14 @@ public void testPotionEffect() {
456456
@Test
457457
public void testPlayerAction() {
458458
PacketContainer container = new PacketContainer(PacketType.Play.Client.ENTITY_ACTION);
459-
container.getPlayerActions().write(0, EnumWrappers.PlayerAction.PRESS_SHIFT_KEY);
460459

461-
assertEquals(container.getPlayerActions().read(0), EnumWrappers.PlayerAction.PRESS_SHIFT_KEY);
460+
// no change across nms versions
461+
container.getPlayerActions().write(0, EnumWrappers.PlayerAction.OPEN_INVENTORY);
462+
assertEquals(container.getPlayerActions().read(0), EnumWrappers.PlayerAction.OPEN_INVENTORY);
463+
464+
// changed in 1.15
465+
container.getPlayerActions().write(0, EnumWrappers.PlayerAction.START_SNEAKING);
466+
assertEquals(container.getPlayerActions().read(0), EnumWrappers.PlayerAction.START_SNEAKING);
462467
}
463468

464469
@Test

0 commit comments

Comments
 (0)