mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-23 19:16:14 +01:00
Improved Wrapping of PlayerInfoData and support chat session data (#2361)
* Improved Wrapping of PlayerInfoData and support chat session data * added constructor for unambiguous creation of playerinfodata without signature
This commit is contained in:
parent
448e9369de
commit
08ea2da642
@ -961,7 +961,7 @@ public abstract class AbstractStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for profile public keys in 1.9
|
||||
* Retrieve a read/write structure for profile public keys in 1.19
|
||||
* @return The Structure Modifier
|
||||
*/
|
||||
public StructureModifier<WrappedProfilePublicKey> getProfilePublicKeys() {
|
||||
@ -971,7 +971,7 @@ public abstract class AbstractStructure {
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for profile public key data in 1.9
|
||||
* Retrieve a read/write structure for profile public key data in 1.19
|
||||
* @return The Structure Modifier
|
||||
*/
|
||||
public StructureModifier<WrappedProfileKeyData> getProfilePublicKeyData() {
|
||||
@ -980,6 +980,17 @@ public abstract class AbstractStructure {
|
||||
BukkitConverters.getWrappedPublicKeyDataConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves read/write structure for remote chat session data in 1.19.3
|
||||
* @return The Structure Modifier
|
||||
*/
|
||||
public StructureModifier<WrappedRemoteChatSessionData> getRemoteChatSessionData() {
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getRemoteChatSessionDataClass(),
|
||||
BukkitConverters.getWrappedRemoteChatSessionDataConverter()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for LevelChunkPacketData in 1.18+
|
||||
*
|
||||
|
@ -1621,6 +1621,10 @@ public final class MinecraftReflection {
|
||||
return getMinecraftClass("network.chat.RemoteChatSession");
|
||||
}
|
||||
|
||||
public static Class<?> getRemoteChatSessionDataClass() {
|
||||
return getRemoteChatSessionClass().getClasses()[0];
|
||||
}
|
||||
|
||||
public static Class<?> getFastUtilClass(String className) {
|
||||
return getLibraryClass("it.unimi.dsi.fastutil." + className);
|
||||
}
|
||||
|
@ -604,6 +604,10 @@ public class BukkitConverters {
|
||||
return ignoreNull(handle(WrappedProfileKeyData::getHandle, WrappedProfileKeyData::new, WrappedProfileKeyData.class));
|
||||
}
|
||||
|
||||
public static EquivalentConverter<WrappedRemoteChatSessionData> getWrappedRemoteChatSessionDataConverter() {
|
||||
return ignoreNull(handle(WrappedRemoteChatSessionData::getHandle, WrappedRemoteChatSessionData::new, WrappedRemoteChatSessionData.class));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return converter for cryptographic signature data that are used in login and chat packets
|
||||
*/
|
||||
|
@ -30,6 +30,8 @@ import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Represents an immutable PlayerInfoData in the PLAYER_INFO packet.
|
||||
* @author dmulloy2
|
||||
@ -43,6 +45,9 @@ public class PlayerInfoData {
|
||||
private final NativeGameMode gameMode;
|
||||
private final WrappedGameProfile profile;
|
||||
private final WrappedChatComponent displayName;
|
||||
@Nullable
|
||||
private final WrappedRemoteChatSessionData remoteChatSessionData;
|
||||
@Nullable
|
||||
private final WrappedProfileKeyData profileKeyData;
|
||||
|
||||
// This is the same order as the NMS class, minus the packet (which isn't a field)
|
||||
@ -54,7 +59,35 @@ public class PlayerInfoData {
|
||||
this(profile.getUUID(), latency, true, gameMode, profile, displayName, keyData);
|
||||
}
|
||||
|
||||
public PlayerInfoData(UUID profileId, int latency, boolean listed, NativeGameMode gameMode, WrappedGameProfile profile, WrappedChatComponent displayName, WrappedProfileKeyData profileKeyData) {
|
||||
/**
|
||||
* Constructs a new PlayerInfoData for Minecraft 1.19 or later without signature data
|
||||
* @see PlayerInfoData#PlayerInfoData(UUID, int, boolean, NativeGameMode, WrappedGameProfile, WrappedChatComponent, WrappedRemoteChatSessionData)
|
||||
*
|
||||
* @param profileId the id of the profile (has to be non-null)
|
||||
* @param latency the latency in milliseconds
|
||||
* @param listed whether the player is listed in the tab list
|
||||
* @param gameMode the game mode
|
||||
* @param profile the game profile
|
||||
* @param displayName display name in tab list (optional)
|
||||
*/
|
||||
public PlayerInfoData(UUID profileId, int latency, boolean listed, NativeGameMode gameMode, WrappedGameProfile profile, WrappedChatComponent displayName) {
|
||||
this(profileId, latency, listed, gameMode, profile, displayName, (WrappedRemoteChatSessionData) null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new PlayerInfoData for Minecraft 1.19. This is incompatible on 1.19.3.
|
||||
* @see PlayerInfoData#PlayerInfoData(UUID, int, boolean, NativeGameMode, WrappedGameProfile, WrappedChatComponent, WrappedRemoteChatSessionData)
|
||||
*
|
||||
* @param profileId the id of the profile (has to be non-null)
|
||||
* @param latency the latency in milliseconds
|
||||
* @param listed whether the player is listed in the tab list
|
||||
* @param gameMode the game mode
|
||||
* @param profile the game profile
|
||||
* @param displayName display name in tab list (optional)
|
||||
* @param profileKeyData the public key for the profile or null
|
||||
*/
|
||||
@Deprecated
|
||||
public PlayerInfoData(UUID profileId, int latency, boolean listed, NativeGameMode gameMode, WrappedGameProfile profile, WrappedChatComponent displayName, @Nullable WrappedProfileKeyData profileKeyData) {
|
||||
this.profileId = profileId;
|
||||
this.latency = latency;
|
||||
this.listed = listed;
|
||||
@ -62,6 +95,29 @@ public class PlayerInfoData {
|
||||
this.profile = profile;
|
||||
this.displayName = displayName;
|
||||
this.profileKeyData = profileKeyData;
|
||||
this.remoteChatSessionData = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new PlayerInfoData for Minecraft 1.19.3 or later.
|
||||
*
|
||||
* @param profileId the id of the profile (has to be non-null)
|
||||
* @param latency the latency in milliseconds
|
||||
* @param listed whether the player is listed in the tab list
|
||||
* @param gameMode the game mode
|
||||
* @param profile the game profile
|
||||
* @param displayName display name in tab list (optional)
|
||||
* @param remoteChatSession the remote chat session for this profile or null
|
||||
*/
|
||||
public PlayerInfoData(UUID profileId, int latency, boolean listed, NativeGameMode gameMode, WrappedGameProfile profile, WrappedChatComponent displayName, @Nullable WrappedRemoteChatSessionData remoteChatSession) {
|
||||
this.profileId = profileId;
|
||||
this.latency = latency;
|
||||
this.listed = listed;
|
||||
this.gameMode = gameMode;
|
||||
this.profile = profile;
|
||||
this.displayName = displayName;
|
||||
this.profileKeyData = null;
|
||||
this.remoteChatSessionData = remoteChatSession;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,6 +125,9 @@ public class PlayerInfoData {
|
||||
* @return the id of the profile
|
||||
*/
|
||||
public UUID getProfileId() {
|
||||
if(profileId == null && profile != null) {
|
||||
return profile.getUUID(); // Ensure forward compatability
|
||||
}
|
||||
return profileId;
|
||||
}
|
||||
|
||||
@ -97,7 +156,7 @@ public class PlayerInfoData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if the player is listed on the client.
|
||||
* Gets if the player is listed on the client (since 1.19.3)
|
||||
* @return if the player is listed
|
||||
*/
|
||||
public boolean isListed() {
|
||||
@ -121,11 +180,21 @@ public class PlayerInfoData {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the profile key data of the player represented by this data, null if not present.
|
||||
* @return The profile key data
|
||||
* Returns the public key of the profile (since 1.19). Returns the public key of the remote chat session since 1.19.3
|
||||
* @return The public key of the profile.
|
||||
*/
|
||||
@Nullable
|
||||
public WrappedProfileKeyData getProfileKeyData() {
|
||||
return this.profileKeyData;
|
||||
return this.profileKeyData != null ? this.profileKeyData : (this.remoteChatSessionData != null ? this.remoteChatSessionData.getProfilePublicKey() : null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the remoteChatSessionData (since 1.19.3)
|
||||
* @return The remote chat sesion data or null
|
||||
*/
|
||||
@Nullable
|
||||
public WrappedRemoteChatSessionData getRemoteChatSessionData() {
|
||||
return this.remoteChatSessionData;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,8 +226,7 @@ public class PlayerInfoData {
|
||||
args.add(MinecraftReflection.getIChatBaseComponentClass());
|
||||
|
||||
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
|
||||
// RemoteChatSession$a...
|
||||
args.add(MinecraftReflection.getRemoteChatSessionClass().getClasses()[0]);
|
||||
args.add(MinecraftReflection.getRemoteChatSessionDataClass());
|
||||
} else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) {
|
||||
args.add(MinecraftReflection.getProfilePublicKeyDataClass());
|
||||
}
|
||||
@ -175,26 +243,28 @@ public class PlayerInfoData {
|
||||
Object gameMode = EnumWrappers.getGameModeConverter().getGeneric(specific.gameMode);
|
||||
Object displayName = specific.displayName != null ? specific.displayName.handle : null;
|
||||
|
||||
Object profile = specific.profile != null ? specific.profile.handle : null;
|
||||
if (MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
|
||||
return constructor.newInstance(
|
||||
specific.profileId,
|
||||
specific.profile.handle,
|
||||
profile,
|
||||
specific.listed,
|
||||
specific.latency,
|
||||
gameMode,
|
||||
displayName,
|
||||
null); // TODO: do we want to support this?
|
||||
specific.remoteChatSessionData != null ? BukkitConverters.getWrappedRemoteChatSessionDataConverter().getGeneric(specific.remoteChatSessionData) : null
|
||||
);
|
||||
} else if (MinecraftVersion.WILD_UPDATE.atOrAbove()) {
|
||||
return constructor.newInstance(
|
||||
specific.profile.handle,
|
||||
profile,
|
||||
specific.latency,
|
||||
gameMode,
|
||||
displayName,
|
||||
specific.profileKeyData == null ? null : specific.profileKeyData.handle);
|
||||
} else if (MinecraftVersion.CAVES_CLIFFS_1.atOrAbove()) {
|
||||
return constructor.newInstance(specific.profile.handle, specific.latency, gameMode, displayName);
|
||||
return constructor.newInstance(profile, specific.latency, gameMode, displayName);
|
||||
} else {
|
||||
return constructor.newInstance(null, specific.profile.handle, specific.latency, gameMode, displayName);
|
||||
return constructor.newInstance(null, profile, specific.latency, gameMode, displayName);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to construct PlayerInfoData.", e);
|
||||
@ -222,8 +292,18 @@ public class PlayerInfoData {
|
||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||
WrappedChatComponent displayName = displayNames.read(0);
|
||||
|
||||
if(MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
|
||||
return new PlayerInfoData(modifier.<UUID>withType(UUID.class).read(0),
|
||||
latency,
|
||||
modifier.<Boolean>withType(boolean.class).read(0),
|
||||
gameMode,
|
||||
gameProfile,
|
||||
displayName,
|
||||
modifier.withType(MinecraftReflection.getRemoteChatSessionDataClass(), BukkitConverters.getWrappedRemoteChatSessionDataConverter()).read(0)
|
||||
);
|
||||
}
|
||||
WrappedProfileKeyData key = null;
|
||||
if (MinecraftVersion.WILD_UPDATE.atOrAbove() && !MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
|
||||
if (MinecraftVersion.WILD_UPDATE.atOrAbove()) {
|
||||
StructureModifier<WrappedProfileKeyData> keyData = modifier.withType(
|
||||
MinecraftReflection.getProfilePublicKeyDataClass(), BukkitConverters.getWrappedPublicKeyDataConverter());
|
||||
key = keyData.read(0);
|
||||
@ -253,19 +333,33 @@ public class PlayerInfoData {
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof PlayerInfoData) {
|
||||
PlayerInfoData other = (PlayerInfoData) obj;
|
||||
return profile.equals(other.profile) && latency == other.latency && gameMode == other.gameMode
|
||||
&& Objects.equals(displayName, other.displayName);
|
||||
return Objects.equals(profile, other.profile)
|
||||
&& Objects.equals(profileId, other.profileId)
|
||||
&& latency == other.latency
|
||||
&& gameMode == other.gameMode
|
||||
&& Objects.equals(displayName, other.displayName)
|
||||
&& listed == other.listed
|
||||
&& Objects.equals(remoteChatSessionData, other.remoteChatSessionData)
|
||||
&& Objects.equals(profileKeyData, other.profileKeyData);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(latency, gameMode, profile, displayName);
|
||||
return Objects.hash(latency, gameMode, profile, displayName, profileKeyData, remoteChatSessionData, listed);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if(MinecraftVersion.FEATURE_PREVIEW_UPDATE.atOrAbove()) {
|
||||
return String.format("PlayerInfoData[latency=%s, listed=%b, gameMode=%s, profile=%s, displayName=%s, remoteChatSession=%s]",
|
||||
latency, listed, gameMode, profile, displayName, remoteChatSessionData);
|
||||
}
|
||||
if(MinecraftVersion.WILD_UPDATE.atOrAbove()) {
|
||||
return String.format("PlayerInfoData[latency=%s, listed=%b, gameMode=%s, profile=%s, displayName=%s, profilePublicKey=%s]",
|
||||
latency, listed, gameMode, profile, displayName, profileKeyData);
|
||||
}
|
||||
return String.format("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s]",
|
||||
latency, gameMode, profile, displayName);
|
||||
}
|
||||
|
@ -0,0 +1,96 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.ConstructorAccessor;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* A wrapper around the remote chat session.
|
||||
*
|
||||
* @since 1.19.3
|
||||
*/
|
||||
public class WrappedRemoteChatSessionData extends AbstractWrapper {
|
||||
private final static Class<?> HANDLE_TYPE = MinecraftReflection.getRemoteChatSessionDataClass();
|
||||
private static ConstructorAccessor CONSTRUCTOR;
|
||||
private StructureModifier<Object> modifier;
|
||||
|
||||
/**
|
||||
* Constructs a new profile public key wrapper directly from a nms RemoteChatSession.Data/RemoteChatSession.a object.
|
||||
*
|
||||
* @param handle the handle to create the wrapper from.
|
||||
*/
|
||||
public WrappedRemoteChatSessionData(Object handle) {
|
||||
super(HANDLE_TYPE);
|
||||
this.setHandle(handle);
|
||||
}
|
||||
|
||||
public WrappedRemoteChatSessionData(UUID sessionId, WrappedProfilePublicKey.WrappedProfileKeyData profilePublicKey) {
|
||||
super(HANDLE_TYPE);
|
||||
if (CONSTRUCTOR == null) {
|
||||
CONSTRUCTOR = Accessors.getConstructorAccessor(
|
||||
this.getHandleType(),
|
||||
UUID.class, MinecraftReflection.getProfilePublicKeyDataClass());
|
||||
}
|
||||
|
||||
this.setHandle(CONSTRUCTOR.invoke(sessionId, profilePublicKey.getHandle()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the id of the current session
|
||||
* @return session id
|
||||
*/
|
||||
public UUID getSessionID() {
|
||||
return this.modifier.<UUID>withType(UUID.class).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the id for this session
|
||||
* @param sessionId new session id
|
||||
*/
|
||||
public void setSessionID(UUID sessionId) {
|
||||
this.modifier.<UUID>withType(UUID.class).write(0, sessionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the ProfileKeyData
|
||||
* @return the public key data for this session
|
||||
*/
|
||||
public WrappedProfilePublicKey.WrappedProfileKeyData getProfilePublicKey() {
|
||||
return this.modifier.withType(MinecraftReflection.getProfilePublicKeyDataClass(), BukkitConverters.getWrappedPublicKeyDataConverter()).read(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the profile key data for this session
|
||||
* @param data ProfileKeyData
|
||||
*/
|
||||
public void setProfilePublicKey(WrappedProfilePublicKey.WrappedProfileKeyData data) {
|
||||
this.modifier.withType(MinecraftReflection.getProfilePublicKeyDataClass(), BukkitConverters.getWrappedPublicKeyDataConverter()).write(0, data);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setHandle(Object handle) {
|
||||
super.setHandle(handle);
|
||||
this.modifier = new StructureModifier<>(HANDLE_TYPE).withTarget(handle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj instanceof WrappedRemoteChatSessionData) {
|
||||
return handle.equals(((WrappedRemoteChatSessionData) obj).getHandle());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return handle.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return handle.hashCode();
|
||||
}
|
||||
}
|
@ -40,26 +40,13 @@ import com.comphenix.protocol.reflect.accessors.FieldAccessor;
|
||||
import com.comphenix.protocol.reflect.cloning.SerializableCloner;
|
||||
import com.comphenix.protocol.utility.MinecraftMethods;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.BlockPosition;
|
||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||
import com.comphenix.protocol.wrappers.ComponentConverter;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
||||
import com.comphenix.protocol.wrappers.*;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Direction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.EntityUseAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.Hand;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory;
|
||||
import com.comphenix.protocol.wrappers.MovingObjectPositionBlock;
|
||||
import com.comphenix.protocol.wrappers.Pair;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.comphenix.protocol.wrappers.WrappedBlockData;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataValue;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
|
||||
import com.comphenix.protocol.wrappers.WrappedEnumEntityUseAction;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedRegistry;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
import com.google.common.collect.Lists;
|
||||
@ -768,7 +755,7 @@ public class PacketContainerTest {
|
||||
NativeGameMode.CREATIVE,
|
||||
new WrappedGameProfile(new UUID(0, 0), "system"),
|
||||
null,
|
||||
null);
|
||||
(WrappedRemoteChatSessionData) null);
|
||||
updatePlayerInfoActions.getPlayerInfoDataLists().write(1, Collections.singletonList(data));
|
||||
|
||||
Set<EnumWrappers.PlayerInfoAction> readActions = updatePlayerInfoActions.getPlayerInfoActions().read(0);
|
||||
@ -871,7 +858,6 @@ public class PacketContainerTest {
|
||||
}
|
||||
|
||||
// gives some indication which cloning process fails as the checks itself are happening outside this method
|
||||
System.out.println("Cloning " + type);
|
||||
|
||||
// Clone the packet all three ways
|
||||
PacketContainer shallowCloned = constructed.shallowClone();
|
||||
@ -886,8 +872,8 @@ public class PacketContainerTest {
|
||||
serializedCloned.getLongs().write(0, 0L);
|
||||
}
|
||||
this.assertPacketsEqualAndSerializable(constructed, serializedCloned);
|
||||
} catch (Exception ex) {
|
||||
Assertions.fail("Unable to clone " + type, ex);
|
||||
} catch (Throwable t) {
|
||||
Assertions.fail("Unable to clone " + type, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,15 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import java.lang.reflect.Field;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import com.comphenix.protocol.wrappers.WrappedProfilePublicKey;
|
||||
import com.comphenix.protocol.wrappers.WrappedRemoteChatSessionData;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
@ -49,4 +57,17 @@ public class TestUtils {
|
||||
public static void setFinalField(Object obj, Field field, Object newValue) {
|
||||
Accessors.getFieldAccessor(field).set(obj, newValue);
|
||||
}
|
||||
|
||||
public static KeyPair generateKeyPair() throws Exception {
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
|
||||
keyPairGenerator.initialize(1024);
|
||||
return keyPairGenerator.generateKeyPair();
|
||||
}
|
||||
|
||||
public static WrappedRemoteChatSessionData creteDummyRemoteChatSessionData() throws Exception {
|
||||
byte[] signature = new byte[256];
|
||||
new Random().nextBytes(signature);
|
||||
|
||||
return new WrappedRemoteChatSessionData(UUID.randomUUID(), new WrappedProfilePublicKey.WrappedProfileKeyData(Instant.now(), TestUtils.generateKeyPair().getPublic(), signature));
|
||||
}
|
||||
}
|
||||
|
@ -1,15 +1,11 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.utility.TestUtils;
|
||||
import com.comphenix.protocol.wrappers.Either.Left;
|
||||
|
||||
import org.apache.commons.lang.builder.EqualsBuilder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
@ -20,6 +16,19 @@ import org.bukkit.inventory.meta.ItemMeta;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.security.KeyFactory;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.PublicKey;
|
||||
import java.security.spec.EncodedKeySpec;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
import java.time.Instant;
|
||||
import java.util.Random;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class BukkitConvertersTest {
|
||||
|
||||
@BeforeAll
|
||||
@ -72,4 +81,14 @@ public class BukkitConvertersTest {
|
||||
assertTrue(EqualsBuilder.reflectionEquals(container, specific)); // PacketContainer does not properly implement equals(.)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemoteChatSessionDataConverter() throws Exception {
|
||||
WrappedRemoteChatSessionData wrappedRemoteChatSessionData = TestUtils.creteDummyRemoteChatSessionData();
|
||||
Object generic = BukkitConverters.getWrappedRemoteChatSessionDataConverter().getGeneric(wrappedRemoteChatSessionData);
|
||||
|
||||
WrappedRemoteChatSessionData specific = BukkitConverters.getWrappedRemoteChatSessionDataConverter().getSpecific(generic);
|
||||
assertEquals(wrappedRemoteChatSessionData, specific);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ package com.comphenix.protocol.wrappers;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
import com.comphenix.protocol.BukkitInitialization;
|
||||
import com.comphenix.protocol.utility.TestUtils;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import java.util.UUID;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
@ -33,14 +34,19 @@ public class PlayerInfoDataTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
public void test() throws Exception {
|
||||
WrappedGameProfile profile = new WrappedGameProfile(UUID.randomUUID(), "Name");
|
||||
WrappedChatComponent displayName = WrappedChatComponent.fromText("Name's Name");
|
||||
|
||||
PlayerInfoData data = new PlayerInfoData(profile, 42, NativeGameMode.CREATIVE, displayName);
|
||||
testWriteBack(new PlayerInfoData(profile, 42, NativeGameMode.CREATIVE, displayName));
|
||||
testWriteBack(new PlayerInfoData(profile.getUUID(), 42, false, NativeGameMode.CREATIVE, profile, displayName, TestUtils.creteDummyRemoteChatSessionData()));
|
||||
testWriteBack(new PlayerInfoData(profile.getUUID(), 42, false, NativeGameMode.CREATIVE, null, null, TestUtils.creteDummyRemoteChatSessionData()));
|
||||
testWriteBack(new PlayerInfoData(profile.getUUID(), 42, true, NativeGameMode.CREATIVE, null, displayName));
|
||||
}
|
||||
|
||||
private static void testWriteBack(PlayerInfoData data) {
|
||||
Object generic = PlayerInfoData.getConverter().getGeneric(data);
|
||||
PlayerInfoData back = PlayerInfoData.getConverter().getSpecific(generic);
|
||||
|
||||
assertEquals(data, back);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user