mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-27 21:26:17 +01:00
Add wrapper for PlayerInfoData
This commit is contained in:
parent
f145d32016
commit
5f4867eb1f
@ -85,6 +85,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.ResourcePackStatus;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ScoreboardAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.comphenix.protocol.wrappers.WrappedAttribute;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
@ -650,6 +651,23 @@ public class PacketContainer implements Serializable {
|
||||
MinecraftReflection.getServerPingClass(), BukkitConverters.getWrappedServerPingConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the PlayerInfoData list fields in the following packet: <br>
|
||||
* <ul>
|
||||
* <li>{@link PacketType.Play.Server.PLAYER_INFO}</li>
|
||||
* </ul>
|
||||
* @return A modifier for PlayerInfoData list fields.
|
||||
*/
|
||||
public StructureModifier<List<PlayerInfoData>> getPlayerInfoDataLists() {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getPlayerInfoDataClass(),
|
||||
PlayerInfoData.getConverter())
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the Protocol enum in 1.7.2.
|
||||
* @return A modifier for Protocol enum fields.
|
||||
|
@ -1896,6 +1896,24 @@ public class MinecraftReflection {
|
||||
return unwrapper.unwrapItem(stack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the PlayerInfoData class in 1.8.
|
||||
* @return The PlayerInfoData class
|
||||
*/
|
||||
public static Class<?> getPlayerInfoDataClass() {
|
||||
return getMinecraftClass("PlayerInfoData");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given object is a PlayerInfoData.
|
||||
* @param obj - the given object.
|
||||
* @return TRUE if it is, FALSE otherwise.
|
||||
*/
|
||||
public static boolean isPlayerInfoData(Object obj) {
|
||||
Class<?> clazz = getPlayerInfoDataClass();
|
||||
return clazz != null && obj.getClass().equals(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given class by name.
|
||||
* @param className - name of the class.
|
||||
|
@ -0,0 +1,144 @@
|
||||
/**
|
||||
* (c) 2014 dmulloy2
|
||||
*/
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.google.common.base.Objects;
|
||||
|
||||
/**
|
||||
* @author dmulloy2
|
||||
*/
|
||||
|
||||
public class PlayerInfoData {
|
||||
private static Constructor<?> constructor;
|
||||
|
||||
protected final int ping;
|
||||
protected final NativeGameMode gameMode;
|
||||
protected final WrappedGameProfile profile;
|
||||
protected final WrappedChatComponent displayName;
|
||||
|
||||
public PlayerInfoData(int ping, NativeGameMode gameMode, WrappedGameProfile profile, WrappedChatComponent displayName) {
|
||||
this.ping = ping;
|
||||
this.gameMode = gameMode;
|
||||
this.profile = profile;
|
||||
this.displayName = displayName;
|
||||
}
|
||||
|
||||
public int getPing() {
|
||||
return ping;
|
||||
}
|
||||
|
||||
public NativeGameMode getGameMode() {
|
||||
return gameMode;
|
||||
}
|
||||
|
||||
public WrappedGameProfile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
public WrappedChatComponent getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to convert between NMS PlayerInfoData and the wrapper instance.
|
||||
* @return A new converter.
|
||||
*/
|
||||
public static EquivalentConverter<PlayerInfoData> getConverter() {
|
||||
return new EquivalentConverter<PlayerInfoData>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, PlayerInfoData specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
constructor = MinecraftReflection.getPlayerInfoDataClass().getConstructor(
|
||||
int.class,
|
||||
EnumWrappers.getGameModeClass(),
|
||||
MinecraftReflection.getGameProfileClass(),
|
||||
MinecraftReflection.getIChatBaseComponentClass()
|
||||
);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot find PlayerInfoData constructor.", e);
|
||||
}
|
||||
}
|
||||
|
||||
// Construct the underlying PlayerInfoData
|
||||
try {
|
||||
Object result = constructor.newInstance(
|
||||
specific.ping,
|
||||
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
||||
specific.profile.handle,
|
||||
specific.displayName.handle
|
||||
);
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Cannot construct BlockPosition.", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PlayerInfoData getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isPlayerInfoData(generic)) {
|
||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false)
|
||||
.withTarget(generic);
|
||||
|
||||
StructureModifier<Integer> ints = modifier.withType(int.class);
|
||||
int ping = ints.read(0);
|
||||
|
||||
StructureModifier<NativeGameMode> gameModes = modifier.withType(
|
||||
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
||||
NativeGameMode gameMode = gameModes.read(0);
|
||||
|
||||
StructureModifier<WrappedGameProfile> gameProfiles = modifier.withType(
|
||||
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
|
||||
WrappedGameProfile gameProfile = gameProfiles.read(0);
|
||||
|
||||
StructureModifier<WrappedChatComponent> displayNames = modifier.withType(
|
||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||
WrappedChatComponent displayName = displayNames.read(0);
|
||||
|
||||
return new PlayerInfoData(ping, gameMode, gameProfile, displayName);
|
||||
}
|
||||
|
||||
// Otherwise, return NULL
|
||||
return null;
|
||||
}
|
||||
|
||||
// Thanks Java Generics!
|
||||
@Override
|
||||
public Class<PlayerInfoData> getSpecificType() {
|
||||
return PlayerInfoData.class;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
// Fast checks
|
||||
if (this == obj) return true;
|
||||
if (obj == null) return false;
|
||||
|
||||
// Only compare objects of similar type
|
||||
if (obj instanceof PlayerInfoData) {
|
||||
PlayerInfoData other = (PlayerInfoData) obj;
|
||||
return ping == other.ping && gameMode == other.gameMode
|
||||
&& profile.equals(other.profile) && displayName.equals(other.displayName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hashCode(ping, gameMode, profile, displayName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("PlayerInfoData[ping=%s,gameMode=%s,profile=%s,displayName=%s]", ping, gameMode, profile, displayName);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user