|
4 | 4 | import java.util.HashMap;
|
5 | 5 | import java.util.Locale;
|
6 | 6 | import java.util.Map;
|
| 7 | +import java.util.concurrent.ConcurrentHashMap; |
7 | 8 |
|
8 | 9 | import com.comphenix.protocol.PacketType;
|
9 | 10 | import com.comphenix.protocol.PacketType.Protocol;
|
@@ -159,16 +160,26 @@ public enum PlayerDigType {
|
159 | 160 | SWAP_HELD_ITEMS
|
160 | 161 | }
|
161 | 162 |
|
162 |
| - public enum PlayerAction { |
163 |
| - START_SNEAKING, |
164 |
| - STOP_SNEAKING, |
| 163 | + public enum PlayerAction implements AliasedEnum { |
| 164 | + PRESS_SHIFT_KEY("START_SNEAKING"), |
| 165 | + RELEASE_SHIFT_KEY("STOP_SNEAKING"), |
165 | 166 | STOP_SLEEPING,
|
166 | 167 | START_SPRINTING,
|
167 | 168 | STOP_SPRINTING,
|
168 | 169 | START_RIDING_JUMP,
|
169 | 170 | STOP_RIDING_JUMP,
|
170 | 171 | OPEN_INVENTORY,
|
171 |
| - START_FALL_FLYING |
| 172 | + START_FALL_FLYING; |
| 173 | + |
| 174 | + String[] aliases; |
| 175 | + PlayerAction(String... aliases) { |
| 176 | + this.aliases = aliases; |
| 177 | + } |
| 178 | + |
| 179 | + @Override |
| 180 | + public String[] getAliases() { |
| 181 | + return aliases; |
| 182 | + } |
172 | 183 | }
|
173 | 184 |
|
174 | 185 | public enum ScoreboardAction {
|
@@ -617,7 +628,7 @@ public static EquivalentConverter<PlayerDigType> getPlayerDiggingActionConverter
|
617 | 628 | }
|
618 | 629 |
|
619 | 630 | public static EquivalentConverter<PlayerAction> getEntityActionConverter() {
|
620 |
| - return new EnumConverter<>(getPlayerActionClass(), PlayerAction.class); |
| 631 | + return new AliasedEnumConverter<>(getPlayerActionClass(), PlayerAction.class); |
621 | 632 | }
|
622 | 633 |
|
623 | 634 | public static EquivalentConverter<ScoreboardAction> getUpdateScoreActionConverter() {
|
@@ -697,6 +708,68 @@ void setGenericType(Class<?> genericType) {
|
697 | 708 | }
|
698 | 709 | }
|
699 | 710 |
|
| 711 | + public interface AliasedEnum { |
| 712 | + String[] getAliases(); |
| 713 | + } |
| 714 | + |
| 715 | + public static class AliasedEnumConverter<T extends Enum<T> & AliasedEnum> implements EquivalentConverter<T> { |
| 716 | + private Class<?> genericType; |
| 717 | + private Class<T> specificType; |
| 718 | + |
| 719 | + public AliasedEnumConverter(Class<?> genericType, Class<T> specificType) { |
| 720 | + this.genericType = genericType; |
| 721 | + this.specificType = specificType; |
| 722 | + } |
| 723 | + |
| 724 | + @Override |
| 725 | + 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; |
| 736 | + } |
| 737 | + } |
| 738 | + } |
| 739 | + } |
| 740 | + |
| 741 | + throw new IllegalArgumentException("Unknown enum constant " + name); |
| 742 | + } |
| 743 | + |
| 744 | + @Override |
| 745 | + 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 | + } |
| 756 | + } |
| 757 | + } |
| 758 | + } |
| 759 | + |
| 760 | + throw new IllegalArgumentException("Unknown enum constant " + name); |
| 761 | + } |
| 762 | + |
| 763 | + @Override |
| 764 | + public Class<T> getSpecificType() { |
| 765 | + return specificType; |
| 766 | + } |
| 767 | + |
| 768 | + void setGenericType(Class<?> genericType) { |
| 769 | + this.genericType = genericType; |
| 770 | + } |
| 771 | + } |
| 772 | + |
700 | 773 | /**
|
701 | 774 | * Used for classes where it's an enum in everything but name
|
702 | 775 | * @param <T> Generic type
|
|
0 commit comments