diff --git a/src/main/java/com/comphenix/protocol/events/AbstractStructure.java b/src/main/java/com/comphenix/protocol/events/AbstractStructure.java index 87506987..f823b148 100644 --- a/src/main/java/com/comphenix/protocol/events/AbstractStructure.java +++ b/src/main/java/com/comphenix/protocol/events/AbstractStructure.java @@ -940,6 +940,7 @@ public abstract class AbstractStructure { ); } + /** * Retrieve a read/write structure for SectionPositions in 1.16.2+ * @return The Structure Modifier diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedProfilePublicKey.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedProfilePublicKey.java index 157b0f9d..bc742800 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedProfilePublicKey.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedProfilePublicKey.java @@ -11,8 +11,12 @@ import java.security.PublicKey; import java.time.Instant; import java.util.Base64; import java.util.Base64.Encoder; + +import com.comphenix.protocol.utility.MinecraftVersion; import org.bukkit.entity.Player; +import javax.annotation.Nullable; + /** * A wrapper around the profile public key. * @@ -57,7 +61,12 @@ public class WrappedProfilePublicKey extends AbstractWrapper { * @param player the player to get the key of. * @return a wrapper around the public key of the given player. */ + @Nullable public static WrappedProfilePublicKey ofPlayer(Player player) { + if(MinecraftVersion.FEATURE_PREVIEW_2.atOrAbove()) { + WrappedRemoteChatSessionData data = WrappedRemoteChatSessionData.fromPlayer(player); + return data == null ? null : new WrappedProfilePublicKey(data.getProfilePublicKey()); + } FieldAccessor accessor = PROFILE_KEY_ACCESSOR; if (accessor == null) { accessor = Accessors.getFieldAccessor(MinecraftReflection.getEntityHumanClass(), diff --git a/src/main/java/com/comphenix/protocol/wrappers/WrappedRemoteChatSessionData.java b/src/main/java/com/comphenix/protocol/wrappers/WrappedRemoteChatSessionData.java index 0d440691..a248637f 100644 --- a/src/main/java/com/comphenix/protocol/wrappers/WrappedRemoteChatSessionData.java +++ b/src/main/java/com/comphenix/protocol/wrappers/WrappedRemoteChatSessionData.java @@ -1,10 +1,16 @@ package com.comphenix.protocol.wrappers; +import com.comphenix.protocol.reflect.ExactReflection; +import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.StructureModifier; 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.utility.MinecraftReflection; +import org.bukkit.entity.Player; +import javax.annotation.Nullable; import java.util.UUID; /** @@ -16,6 +22,9 @@ public class WrappedRemoteChatSessionData extends AbstractWrapper { private final static Class HANDLE_TYPE = MinecraftReflection.getRemoteChatSessionDataClass(); private static ConstructorAccessor CONSTRUCTOR; private StructureModifier modifier; + private static MethodAccessor PLAYER_GET_HANDLE; + private static FieldAccessor REMOTE_CHAT_SESSION_FIELD; + private static MethodAccessor AS_DATA_METHOD; /** * Constructs a new profile public key wrapper directly from a nms RemoteChatSession.Data/RemoteChatSession.a object. @@ -93,4 +102,29 @@ public class WrappedRemoteChatSessionData extends AbstractWrapper { public int hashCode() { return handle.hashCode(); } + + /** + * Retrieves the current session data of the player + * @since 1.19.4 + * @return Wrapper for session data or null if not present + */ + @Nullable + public static WrappedRemoteChatSessionData fromPlayer(Player player) { + if(PLAYER_GET_HANDLE == null) { + PLAYER_GET_HANDLE = Accessors.getMethodAccessor(MinecraftReflection.getCraftPlayerClass(), "getHandle"); + } + if(REMOTE_CHAT_SESSION_FIELD == null) { + REMOTE_CHAT_SESSION_FIELD = Accessors.getFieldAccessor(MinecraftReflection.getEntityPlayerClass(), MinecraftReflection.getRemoteChatSessionClass(), true); + } + if(AS_DATA_METHOD == null) { + AS_DATA_METHOD = Accessors.getMethodAccessor(FuzzyReflection.fromClass(MinecraftReflection.getRemoteChatSessionClass(), true).getMethodListByParameters(HANDLE_TYPE).get(0)); + } + Object handle = PLAYER_GET_HANDLE.invoke(player); + Object remoteChatSession = REMOTE_CHAT_SESSION_FIELD.get(handle); + if(remoteChatSession == null) { + return null; + } + Object remoteChatSessionData = AS_DATA_METHOD.invoke(remoteChatSession); + return remoteChatSessionData == null ? null : new WrappedRemoteChatSessionData(remoteChatSessionData); + } }