mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2025-01-20 23:31:35 +01:00
Fix EntityUseAction & Hand read for minecraft 1.17 (#1230)
This commit is contained in:
parent
1c2bc274dd
commit
0a32f24f08
@ -744,6 +744,17 @@ public class PacketContainer implements Serializable {
|
||||
EnumWrappers.getEntityUseActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a read/write structure for the EntityUseAction class in the UseEntity packet sent by the client for
|
||||
* 1.17 and above.
|
||||
* @return A modifier for EntityUseAction class fields.
|
||||
*/
|
||||
public StructureModifier<WrappedEnumEntityUseAction> getEnumEntityUseActions() {
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getEnumEntityUseActionClass(),
|
||||
WrappedEnumEntityUseAction.CONVERTER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the NativeGameMode enum in 1.7.2.
|
||||
* @return A modifier for NativeGameMode enum fields.
|
||||
|
@ -289,6 +289,7 @@ public final class Accessors {
|
||||
* @return The method accessor.
|
||||
*/
|
||||
public static ConstructorAccessor getConstructorAccessor(final Constructor<?> constructor) {
|
||||
constructor.setAccessible(true); // let us in even if we are not allowed to
|
||||
return new DefaultConstrutorAccessor(constructor);
|
||||
}
|
||||
|
||||
|
@ -27,10 +27,8 @@ import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
@ -57,6 +55,7 @@ import com.comphenix.protocol.reflect.ClassAnalyser;
|
||||
import com.comphenix.protocol.reflect.ClassAnalyser.AsmMethod;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.AbstractFuzzyMatcher;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyClassContract;
|
||||
@ -65,6 +64,7 @@ import com.comphenix.protocol.reflect.fuzzy.FuzzyMatchers;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException;
|
||||
import com.comphenix.protocol.utility.RemappedClassSource.RemapperUnavailableException.Reason;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtType;
|
||||
import com.google.common.base.Joiner;
|
||||
@ -1793,6 +1793,52 @@ public class MinecraftReflection {
|
||||
"PacketPlayOutPlayerInfo$PlayerInfoData", "PlayerInfoData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the entity use action class in 1.17.
|
||||
* @return The EntityUseAction class
|
||||
*/
|
||||
public static Class<?> getEnumEntityUseActionClass() {
|
||||
Class<?> packetClass = PacketType.Play.Client.USE_ENTITY.getPacketClass();
|
||||
return FuzzyReflection.fromClass(packetClass, true).getFieldByType("^.*(EnumEntityUseAction)").getType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a method accessor to get the actual use action out of the wrapping EnumEntityUseAction in 1.17.
|
||||
* @return a method accessor to get the actual use action
|
||||
*/
|
||||
public static MethodAccessor getEntityUseActionEnumMethodAccessor() {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromClass(MinecraftReflection.getEnumEntityUseActionClass(), true);
|
||||
return Accessors.getMethodAccessor(fuzzy.getMethod(FuzzyMethodContract.newBuilder()
|
||||
.returnTypeExact(EnumWrappers.getEntityUseActionClass())
|
||||
.build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field accessor for the hand in the wrapping EnumEntityUseAction in 1.17.
|
||||
*
|
||||
* @param enumEntityUseAction the object instance of the action, the field is not present in attack.
|
||||
* @return a field accessor for the hand in the wrapping EnumEntityUseAction
|
||||
*/
|
||||
public static FieldAccessor getHandEntityUseActionEnumFieldAccessor(Object enumEntityUseAction) {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromObject(enumEntityUseAction, true);
|
||||
return Accessors.getFieldAccessor(fuzzy.getField(FuzzyFieldContract.newBuilder()
|
||||
.typeExact(EnumWrappers.getHandClass())
|
||||
.build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field accessor for the vec3d in the wrapping EnumEntityUseAction in 1.17.
|
||||
*
|
||||
* @param enumEntityUseAction the object instance of the action, the field is not present in attack.
|
||||
* @return a field accessor for the hand in the wrapping EnumEntityUseAction
|
||||
*/
|
||||
public static FieldAccessor getVec3EntityUseActionEnumFieldAccessor(Object enumEntityUseAction) {
|
||||
FuzzyReflection fuzzy = FuzzyReflection.fromObject(enumEntityUseAction, true);
|
||||
return Accessors.getFieldAccessor(fuzzy.getField(FuzzyFieldContract.newBuilder()
|
||||
.typeExact(MinecraftReflection.getVec3DClass())
|
||||
.build()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given object is a PlayerInfoData.
|
||||
* @param obj - the given object.
|
||||
|
@ -10,6 +10,7 @@ import com.comphenix.protocol.ProtocolLogger;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
@ -481,7 +482,6 @@ public abstract class EnumWrappers {
|
||||
DIFFICULTY_CLASS = getEnum(PacketType.Play.Server.LOGIN.getPacketClass(), 1);
|
||||
}
|
||||
|
||||
ENTITY_USE_ACTION_CLASS = getEnum(PacketType.Play.Client.USE_ENTITY.getPacketClass(), 0);
|
||||
GAMEMODE_CLASS = getEnum(PacketType.Play.Server.LOGIN.getPacketClass(), 0);
|
||||
RESOURCE_PACK_STATUS_CLASS = getEnum(PacketType.Play.Client.RESOURCE_PACK_STATUS.getPacketClass(), 0);
|
||||
PLAYER_INFO_ACTION_CLASS = getEnum(PacketType.Play.Server.PLAYER_INFO.getPacketClass(), 0);
|
||||
@ -501,7 +501,16 @@ public abstract class EnumWrappers {
|
||||
ITEM_SLOT_CLASS = getEnum(PacketType.Play.Server.ENTITY_EQUIPMENT.getPacketClass(), 0);
|
||||
}
|
||||
|
||||
// In 1.17 the hand and use action class is no longer a field in the packet
|
||||
if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
|
||||
HAND_CLASS = MinecraftReflection.getMinecraftClass("world.EnumHand");
|
||||
// class is named 'b' in the packet but class order differs in spigot and paper so we can only use the first method's return type (safest way)
|
||||
ENTITY_USE_ACTION_CLASS = MinecraftReflection.getEnumEntityUseActionClass().getMethods()[0].getReturnType();
|
||||
} else {
|
||||
HAND_CLASS = getEnum(PacketType.Play.Client.USE_ENTITY.getPacketClass(), 1);
|
||||
ENTITY_USE_ACTION_CLASS = getEnum(PacketType.Play.Client.USE_ENTITY.getPacketClass(), 0);
|
||||
}
|
||||
|
||||
DIRECTION_CLASS = getEnum(PacketType.Play.Server.SPAWN_ENTITY_PAINTING.getPacketClass(), 0);
|
||||
CHAT_TYPE_CLASS = getEnum(PacketType.Play.Server.CHAT.getPacketClass(), 0);
|
||||
ENTITY_POSE_CLASS = MinecraftReflection.getNullableNMS("world.entity.EntityPose", "EntityPose");
|
||||
@ -510,7 +519,6 @@ public abstract class EnumWrappers {
|
||||
associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter());
|
||||
associate(CHAT_VISIBILITY_CLASS, ChatVisibility.class, getChatVisibilityConverter());
|
||||
associate(DIFFICULTY_CLASS, Difficulty.class, getDifficultyConverter());
|
||||
associate(ENTITY_USE_ACTION_CLASS, EntityUseAction.class, getEntityUseActionConverter());
|
||||
associate(GAMEMODE_CLASS, NativeGameMode.class, getGameModeConverter());
|
||||
associate(RESOURCE_PACK_STATUS_CLASS, ResourcePackStatus.class, getResourcePackStatusConverter());
|
||||
associate(PLAYER_INFO_ACTION_CLASS, PlayerInfoAction.class, getPlayerInfoActionConverter());
|
||||
@ -523,15 +531,14 @@ public abstract class EnumWrappers {
|
||||
associate(PARTICLE_CLASS, Particle.class, getParticleConverter());
|
||||
associate(SOUND_CATEGORY_CLASS, SoundCategory.class, getSoundCategoryConverter());
|
||||
associate(ITEM_SLOT_CLASS, ItemSlot.class, getItemSlotConverter());
|
||||
associate(HAND_CLASS, Hand.class, getHandConverter());
|
||||
associate(DIRECTION_CLASS, Direction.class, getDirectionConverter());
|
||||
associate(CHAT_TYPE_CLASS, ChatType.class, getChatTypeConverter());
|
||||
associate(HAND_CLASS, Hand.class, getHandConverter());
|
||||
associate(ENTITY_USE_ACTION_CLASS, EntityUseAction.class, getEntityUseActionConverter());
|
||||
|
||||
if (ENTITY_POSE_CLASS != null) {
|
||||
associate(ENTITY_POSE_CLASS, EntityPose.class, getEntityPoseConverter());
|
||||
}
|
||||
|
||||
INITIALIZED = true;
|
||||
}
|
||||
|
||||
private static void associate(Class<?> nativeClass, Class<?> wrapperClass, EquivalentConverter<?> converter) {
|
||||
|
@ -0,0 +1,200 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.reflect.fuzzy.FuzzyFieldContract;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Hand;
|
||||
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
/**
|
||||
* Represents an entity used action used in the UseEntity packet sent by the client.
|
||||
* @author derklaro
|
||||
*/
|
||||
public class WrappedEnumEntityUseAction extends AbstractWrapper implements ClonableWrapper {
|
||||
|
||||
public static final EquivalentConverter<WrappedEnumEntityUseAction> CONVERTER = Converters.handle(AbstractWrapper::getHandle,
|
||||
WrappedEnumEntityUseAction::fromHandle, WrappedEnumEntityUseAction.class);
|
||||
|
||||
private static final Class<?> PACKET_CLASS = PacketType.Play.Client.USE_ENTITY.getPacketClass();
|
||||
private static final Class<?>[] DECLARED_CLASSES = PACKET_CLASS.getDeclaredClasses();
|
||||
|
||||
private static final Class<?> HANDLE_TYPE = MinecraftReflection.getEnumEntityUseActionClass();
|
||||
private static final MethodAccessor ACTION_USE = MinecraftReflection.getEntityUseActionEnumMethodAccessor();
|
||||
|
||||
private static final ConstructorAccessor INTERACT = useAction(EnumWrappers.getHandClass());
|
||||
private static final ConstructorAccessor INTERACT_AT = useAction(EnumWrappers.getHandClass(),
|
||||
MinecraftReflection.getVec3DClass());
|
||||
|
||||
private static final Object ATTACK = Accessors.getFieldAccessor(FuzzyReflection.fromClass(PACKET_CLASS, true)
|
||||
.getField(FuzzyFieldContract.newBuilder()
|
||||
.requireModifier(Modifier.STATIC)
|
||||
.typeExact(MinecraftReflection.getEnumEntityUseActionClass())
|
||||
.build())
|
||||
).get(null);
|
||||
private static final WrappedEnumEntityUseAction ATTACK_WRAPPER = new WrappedEnumEntityUseAction(ATTACK);
|
||||
|
||||
private final EntityUseAction action;
|
||||
// these fields are only available for interact & interact_at
|
||||
private FieldAccessor handAccessor;
|
||||
private FieldAccessor positionAccessor;
|
||||
|
||||
/**
|
||||
* Construct a new wrapper for the entity use action class in the UseEntity packet.
|
||||
* @param handle - the NMS handle.
|
||||
*/
|
||||
private WrappedEnumEntityUseAction(Object handle) {
|
||||
super(HANDLE_TYPE);
|
||||
setHandle(handle);
|
||||
|
||||
action = EnumWrappers.getEntityUseActionConverter().getSpecific(ACTION_USE.invoke(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a constructor of a declared class in the UseEntity class. Used to find the action class implementations.
|
||||
* @param parameterTypes - the types the constructor of the class must have.
|
||||
* @return a constructor for a matching class.
|
||||
* @throws IllegalArgumentException if no constructor was found.
|
||||
*/
|
||||
private static ConstructorAccessor useAction(Class<?>... parameterTypes) {
|
||||
for (Class<?> subClass : DECLARED_CLASSES) {
|
||||
ConstructorAccessor accessor = Accessors.getConstructorAccessorOrNull(subClass, parameterTypes);
|
||||
if (accessor != null) {
|
||||
return accessor;
|
||||
}
|
||||
}
|
||||
throw new IllegalArgumentException(
|
||||
"No constructor with " + Arrays.toString(parameterTypes) + " in " + PACKET_CLASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a new wrapper for the entity use action class in the UseEntity packet.
|
||||
* @param handle - the NMS handle.
|
||||
* @return the created wrapper.
|
||||
*/
|
||||
public static WrappedEnumEntityUseAction fromHandle(Object handle) {
|
||||
return new WrappedEnumEntityUseAction(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the jvm static action for attacking an entity.
|
||||
* @return the action for an entity attack.
|
||||
*/
|
||||
public static WrappedEnumEntityUseAction attack() {
|
||||
return ATTACK_WRAPPER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an action for interacting with an entity.
|
||||
* @param hand - the hand used for the interact.
|
||||
* @return the action for an interact.
|
||||
*/
|
||||
public static WrappedEnumEntityUseAction interact(Hand hand) {
|
||||
Object handle = INTERACT.invoke(EnumWrappers.getHandConverter().getGeneric(hand));
|
||||
return new WrappedEnumEntityUseAction(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an action for interacting with an entity at a specific location.
|
||||
* @param hand - the hand used for the interact.
|
||||
* @param vector - the position of the interact.
|
||||
* @return the action for an interact_at.
|
||||
*/
|
||||
public static WrappedEnumEntityUseAction interactAt(Hand hand, Vector vector) {
|
||||
Object handle = INTERACT_AT.invoke(EnumWrappers.getHandConverter().getGeneric(hand),
|
||||
BukkitConverters.getVectorConverter().getGeneric(vector));
|
||||
return new WrappedEnumEntityUseAction(handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the action used for the interact.
|
||||
* @return the interact action.
|
||||
*/
|
||||
public EntityUseAction getAction() {
|
||||
return action;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the hand used for the interact. Only available if this represents interact or interact_at.
|
||||
* @return the hand used for the interact.
|
||||
* @throws IllegalArgumentException if called for attack.
|
||||
*/
|
||||
public Hand getHand() {
|
||||
return EnumWrappers.getHandConverter().getSpecific(getHandAccessor().get(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the hand used for the interact.
|
||||
* @param hand the used hand.
|
||||
* @throws IllegalArgumentException if called for attack.
|
||||
*/
|
||||
public void setHand(Hand hand) {
|
||||
getHandAccessor().set(handle, EnumWrappers.getHandConverter().getGeneric(hand));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the position of the interact. Only available if this represents interact_at.
|
||||
* @return the position of the interact.
|
||||
* @throws IllegalArgumentException if called for attack or interact.
|
||||
*/
|
||||
public Vector getPosition() {
|
||||
return BukkitConverters.getVectorConverter().getSpecific(getPositionAccessor().get(handle));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the position of the interact.
|
||||
* @param position the position.
|
||||
* @throws IllegalArgumentException if called for attack or interact.
|
||||
*/
|
||||
public void setPosition(Vector position) {
|
||||
getPositionAccessor().set(handle, BukkitConverters.getVectorConverter().getGeneric(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public WrappedEnumEntityUseAction deepClone() {
|
||||
switch (action) {
|
||||
case ATTACK:
|
||||
return WrappedEnumEntityUseAction.attack();
|
||||
case INTERACT:
|
||||
return WrappedEnumEntityUseAction.interact(getHand());
|
||||
case INTERACT_AT:
|
||||
return WrappedEnumEntityUseAction.interactAt(getHand(), getPosition());
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid EntityUseAction: " + action);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field accessor for the hand in the interact and interact_at type.
|
||||
* @return a field accessor for the hand field.
|
||||
* @throws IllegalArgumentException if called for attack.
|
||||
*/
|
||||
private FieldAccessor getHandAccessor() {
|
||||
if (handAccessor == null) {
|
||||
handAccessor = MinecraftReflection.getHandEntityUseActionEnumFieldAccessor(handle);
|
||||
}
|
||||
return handAccessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a field accessor for the position in the interact_at type.
|
||||
* @return a field accessor for the position field.
|
||||
* @throws IllegalArgumentException if called for attack or interact.
|
||||
*/
|
||||
public FieldAccessor getPositionAccessor() {
|
||||
if (positionAccessor == null) {
|
||||
positionAccessor = MinecraftReflection.getVec3EntityUseActionEnumFieldAccessor(handle);
|
||||
}
|
||||
return positionAccessor;
|
||||
}
|
||||
}
|
@ -16,6 +16,8 @@
|
||||
*/
|
||||
package com.comphenix.protocol.events;
|
||||
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Hand;
|
||||
import java.lang.reflect.Array;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
@ -585,6 +587,51 @@ public class PacketContainerTest {
|
||||
assertTrue(packet.getGameStateIDs().read(0) == 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUseEntity() {
|
||||
PacketContainer packet = new PacketContainer(PacketType.Play.Client.USE_ENTITY);
|
||||
|
||||
WrappedEnumEntityUseAction action;
|
||||
WrappedEnumEntityUseAction clone;
|
||||
// test attack
|
||||
packet.getEnumEntityUseActions().write(0, WrappedEnumEntityUseAction.attack());
|
||||
action = packet.getEnumEntityUseActions().read(0);
|
||||
// attack's handle should always be the same
|
||||
assertEquals(WrappedEnumEntityUseAction.attack(), action);
|
||||
assertEquals(EntityUseAction.ATTACK, action.getAction());
|
||||
// hand & position should not be available
|
||||
assertThrows(IllegalArgumentException.class, action::getHand);
|
||||
assertThrows(IllegalArgumentException.class, action::getPosition);
|
||||
// test cloning
|
||||
clone = action.deepClone();
|
||||
assertSame(WrappedEnumEntityUseAction.attack(), clone);
|
||||
|
||||
// test interact
|
||||
packet.getEnumEntityUseActions().write(0, WrappedEnumEntityUseAction.interact(Hand.OFF_HAND));
|
||||
action = packet.getEnumEntityUseActions().read(0);
|
||||
assertEquals(EntityUseAction.INTERACT, action.getAction());
|
||||
assertEquals(Hand.OFF_HAND, action.getHand());
|
||||
// position should not be available
|
||||
assertThrows(IllegalArgumentException.class, action::getPosition);
|
||||
// test cloning
|
||||
clone = action.deepClone();
|
||||
assertEquals(EntityUseAction.INTERACT, clone.getAction());
|
||||
assertEquals(Hand.OFF_HAND, clone.getHand());
|
||||
|
||||
// test interact_at
|
||||
Vector position = new Vector(1, 199, 4);
|
||||
packet.getEnumEntityUseActions().write(0, WrappedEnumEntityUseAction.interactAt(Hand.MAIN_HAND, position));
|
||||
action = packet.getEnumEntityUseActions().read(0);
|
||||
assertEquals(EntityUseAction.INTERACT_AT, action.getAction());
|
||||
assertEquals(Hand.MAIN_HAND, action.getHand());
|
||||
assertEquals(position, action.getPosition());
|
||||
// test cloning
|
||||
clone = action.deepClone();
|
||||
assertEquals(EntityUseAction.INTERACT_AT, clone.getAction());
|
||||
assertEquals(Hand.MAIN_HAND, clone.getHand());
|
||||
assertEquals(position, clone.getPosition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Actions from the outbound Boss packet. Used for testing generic enums.
|
||||
* @author dmulloy2
|
||||
|
@ -150,4 +150,10 @@ public class MinecraftReflectionTest {
|
||||
public void testGameProfile() {
|
||||
assertEquals(GameProfile.class, MinecraftReflection.getGameProfileClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnumEntityUseAction() {
|
||||
// this class is package-private in PacketPlayInUseEntity, so we can only check if no exception is thrown during retrieval
|
||||
MinecraftReflection.getEnumEntityUseActionClass();
|
||||
}
|
||||
}
|
||||
|
@ -12,12 +12,11 @@ import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.network.EnumProtocol;
|
||||
import net.minecraft.network.protocol.game.PacketPlayInClientCommand.EnumClientCommand;
|
||||
import net.minecraft.world.EnumHand;
|
||||
import net.minecraft.world.EnumDifficulty;
|
||||
import net.minecraft.world.entity.player.EnumChatVisibility;
|
||||
import net.minecraft.world.level.EnumGamemode;
|
||||
@ -28,7 +27,8 @@ public class EnumWrappersTest {
|
||||
public EnumClientCommand command;
|
||||
public EnumChatVisibility visibility;
|
||||
public EnumDifficulty difficulty;
|
||||
// public EnumEntityUseAction action;
|
||||
public EnumHand hand;
|
||||
// public EnumEntityUseAction action; // moved to PacketPlayInUseEntity but is private
|
||||
public EnumGamemode mode;
|
||||
}
|
||||
|
||||
@ -44,6 +44,7 @@ public class EnumWrappersTest {
|
||||
obj.command = EnumClientCommand.b;
|
||||
obj.visibility = EnumChatVisibility.c;
|
||||
obj.difficulty = EnumDifficulty.d;
|
||||
obj.hand = EnumHand.b;
|
||||
// obj.action = EnumEntityUseAction.INTERACT;
|
||||
obj.mode = EnumGamemode.e;
|
||||
|
||||
@ -51,6 +52,7 @@ public class EnumWrappersTest {
|
||||
assertEquals(obj.command, roundtrip(obj, "command", EnumWrappers.getClientCommandConverter()) );
|
||||
assertEquals(obj.visibility, roundtrip(obj, "visibility", EnumWrappers.getChatVisibilityConverter()) );
|
||||
assertEquals(obj.difficulty, roundtrip(obj, "difficulty", EnumWrappers.getDifficultyConverter()) );
|
||||
assertEquals(obj.hand, roundtrip(obj, "hand", EnumWrappers.getHandConverter()) );
|
||||
// assertEquals(obj.action, roundtrip(obj, "action", EnumWrappers.getEntityUseActionConverter()) );
|
||||
assertEquals(obj.mode, roundtrip(obj, "mode", EnumWrappers.getGameModeConverter()) );
|
||||
}
|
||||
@ -65,7 +67,7 @@ public class EnumWrappersTest {
|
||||
}
|
||||
|
||||
private static final Set<String> KNOWN_INVALID = Sets.newHashSet(
|
||||
"Particle", "WorldBorderAction", "CombatEventType", "EntityUseAction", "TitleAction", "Hand"
|
||||
"Particle", "WorldBorderAction", "CombatEventType", "TitleAction"
|
||||
);
|
||||
|
||||
@Test
|
||||
|
Loading…
Reference in New Issue
Block a user