Ursprung
13b905e762
Commit
0e6a7a39a0
@ -46,6 +46,7 @@ import org.bukkit.World;
|
|||||||
import org.bukkit.WorldType;
|
import org.bukkit.WorldType;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.potion.PotionEffectType;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
|
||||||
import com.comphenix.protocol.PacketType;
|
import com.comphenix.protocol.PacketType;
|
||||||
@ -86,6 +87,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.PlayerDigType;
|
|||||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.ResourcePackStatus;
|
import com.comphenix.protocol.wrappers.EnumWrappers.ResourcePackStatus;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.ScoreboardAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.ScoreboardAction;
|
||||||
|
import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
|
||||||
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
|
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
|
||||||
@ -578,12 +580,11 @@ public class PacketContainer implements Serializable {
|
|||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(
|
||||||
MinecraftReflection.getWatchableObjectClass(),
|
MinecraftReflection.getDataWatcherItemClass(),
|
||||||
BukkitConverters.getWatchableObjectConverter())
|
BukkitConverters.getWatchableObjectConverter())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a read/write structure for block fields.
|
* Retrieves a read/write structure for block fields.
|
||||||
* <p>
|
* <p>
|
||||||
@ -845,6 +846,26 @@ public class PacketContainer implements Serializable {
|
|||||||
EnumWrappers.getParticleClass(), EnumWrappers.getParticleConverter());
|
EnumWrappers.getParticleClass(), EnumWrappers.getParticleConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a read/write structure for the MobEffectList class in 1.9.
|
||||||
|
* @return A modifier for MobEffectList fields.
|
||||||
|
*/
|
||||||
|
public StructureModifier<PotionEffectType> getEffectTypes() {
|
||||||
|
// Convert to and from Bukkit
|
||||||
|
return structureModifier.<PotionEffectType>withType(
|
||||||
|
MinecraftReflection.getMobEffectListClass(), BukkitConverters.getEffectTypeConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a read/write structure for the SoundCategory enum in 1.9.
|
||||||
|
* @return A modifier for SoundCategory enum fields.
|
||||||
|
*/
|
||||||
|
public StructureModifier<SoundCategory> getSoundCategories() {
|
||||||
|
// Convert to and from the enums
|
||||||
|
return structureModifier.<SoundCategory>withType(
|
||||||
|
EnumWrappers.getSoundCategoryClass(), EnumWrappers.getSoundCategoryConverter());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the ID of this packet.
|
* Retrieves the ID of this packet.
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -1341,6 +1341,11 @@ public class MinecraftReflection {
|
|||||||
return getMinecraftClass("MinecraftKey");
|
return getMinecraftClass("MinecraftKey");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class<?> getMobEffectListClass() {
|
||||||
|
// TODO Implement a fallback
|
||||||
|
return getMinecraftClass("MobEffectList");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the ServerConnection abstract class.
|
* Retrieve the ServerConnection abstract class.
|
||||||
* @return The ServerConnection class.
|
* @return The ServerConnection class.
|
||||||
|
@ -1105,7 +1105,7 @@ public class BukkitConverters {
|
|||||||
put(MinecraftReflection.getItemStackClass(), (EquivalentConverter) getItemStackConverter()).
|
put(MinecraftReflection.getItemStackClass(), (EquivalentConverter) getItemStackConverter()).
|
||||||
put(MinecraftReflection.getNBTBaseClass(), (EquivalentConverter) getNbtConverter()).
|
put(MinecraftReflection.getNBTBaseClass(), (EquivalentConverter) getNbtConverter()).
|
||||||
put(MinecraftReflection.getNBTCompoundClass(), (EquivalentConverter) getNbtConverter()).
|
put(MinecraftReflection.getNBTCompoundClass(), (EquivalentConverter) getNbtConverter()).
|
||||||
put(MinecraftReflection.getWatchableObjectClass(), (EquivalentConverter) getWatchableObjectConverter()).
|
put(MinecraftReflection.getDataWatcherItemClass(), (EquivalentConverter) getWatchableObjectConverter()).
|
||||||
put(MinecraftReflection.getMobEffectClass(), (EquivalentConverter) getPotionEffectConverter()).
|
put(MinecraftReflection.getMobEffectClass(), (EquivalentConverter) getPotionEffectConverter()).
|
||||||
put(MinecraftReflection.getNmsWorldClass(), (EquivalentConverter) getWorldConverter());
|
put(MinecraftReflection.getNmsWorldClass(), (EquivalentConverter) getWorldConverter());
|
||||||
|
|
||||||
@ -1146,4 +1146,38 @@ public class BukkitConverters {
|
|||||||
}
|
}
|
||||||
return unwrappers;
|
return unwrappers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static MethodAccessor getMobEffectId = null;
|
||||||
|
private static MethodAccessor getMobEffect = null;
|
||||||
|
|
||||||
|
public static EquivalentConverter<PotionEffectType> getEffectTypeConverter() {
|
||||||
|
return new IgnoreNullConverter<PotionEffectType>() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<PotionEffectType> getSpecificType() {
|
||||||
|
return PotionEffectType.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object getGenericValue(Class<?> genericType, PotionEffectType specific) {
|
||||||
|
if (getMobEffect == null) {
|
||||||
|
getMobEffect = Accessors.getMethodAccessor(genericType, "fromId", int.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = specific.getId();
|
||||||
|
return getMobEffect.invoke(null, id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PotionEffectType getSpecificValue(Object generic) {
|
||||||
|
Class<?> clazz = MinecraftReflection.getMobEffectListClass();
|
||||||
|
if (getMobEffectId == null) {
|
||||||
|
getMobEffectId = Accessors.getMethodAccessor(clazz, "getId", clazz);
|
||||||
|
}
|
||||||
|
|
||||||
|
int id = (int) getMobEffectId.invoke(null, generic);
|
||||||
|
return PotionEffectType.getById(id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,6 +272,40 @@ public abstract class EnumWrappers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum SoundCategory {
|
||||||
|
MASTER("master"),
|
||||||
|
MUSIC("music"),
|
||||||
|
RECORDS("record"),
|
||||||
|
WEATHER("weather"),
|
||||||
|
BLOCKS("block"),
|
||||||
|
HOSTILE("hostile"),
|
||||||
|
NEUTRAL("neutral"),
|
||||||
|
PLAYERS("player"),
|
||||||
|
AMBIENT("ambient"),
|
||||||
|
VOICE("voice");
|
||||||
|
|
||||||
|
private static final Map<String, SoundCategory> LOOKUP;
|
||||||
|
static {
|
||||||
|
LOOKUP = new HashMap<>();
|
||||||
|
for (SoundCategory category : values()) {
|
||||||
|
LOOKUP.put(category.key, category);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final String key;
|
||||||
|
private SoundCategory(String key) {
|
||||||
|
this.key = key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SoundCategory getByKey(String key) {
|
||||||
|
return LOOKUP.get(key.toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Class<?> PROTOCOL_CLASS = null;
|
private static Class<?> PROTOCOL_CLASS = null;
|
||||||
private static Class<?> CLIENT_COMMAND_CLASS = null;
|
private static Class<?> CLIENT_COMMAND_CLASS = null;
|
||||||
private static Class<?> CHAT_VISIBILITY_CLASS = null;
|
private static Class<?> CHAT_VISIBILITY_CLASS = null;
|
||||||
@ -287,6 +321,7 @@ public abstract class EnumWrappers {
|
|||||||
private static Class<?> PLAYER_ACTION_CLASS = null;
|
private static Class<?> PLAYER_ACTION_CLASS = null;
|
||||||
private static Class<?> SCOREBOARD_ACTION_CLASS = null;
|
private static Class<?> SCOREBOARD_ACTION_CLASS = null;
|
||||||
private static Class<?> PARTICLE_CLASS = null;
|
private static Class<?> PARTICLE_CLASS = null;
|
||||||
|
private static Class<?> SOUND_CATEGORY_CLASS = null;
|
||||||
|
|
||||||
private static boolean INITIALIZED = false;
|
private static boolean INITIALIZED = false;
|
||||||
private static Map<Class<?>, EquivalentConverter<?>> FROM_NATIVE = Maps.newHashMap();
|
private static Map<Class<?>, EquivalentConverter<?>> FROM_NATIVE = Maps.newHashMap();
|
||||||
@ -319,6 +354,7 @@ public abstract class EnumWrappers {
|
|||||||
PLAYER_ACTION_CLASS = getEnum(PacketType.Play.Client.ENTITY_ACTION.getPacketClass(), 0);
|
PLAYER_ACTION_CLASS = getEnum(PacketType.Play.Client.ENTITY_ACTION.getPacketClass(), 0);
|
||||||
SCOREBOARD_ACTION_CLASS = getEnum(PacketType.Play.Server.SCOREBOARD_SCORE.getPacketClass(), 0);
|
SCOREBOARD_ACTION_CLASS = getEnum(PacketType.Play.Server.SCOREBOARD_SCORE.getPacketClass(), 0);
|
||||||
PARTICLE_CLASS = getEnum(PacketType.Play.Server.WORLD_PARTICLES.getPacketClass(), 0);
|
PARTICLE_CLASS = getEnum(PacketType.Play.Server.WORLD_PARTICLES.getPacketClass(), 0);
|
||||||
|
SOUND_CATEGORY_CLASS = getEnum(PacketType.Play.Server.CUSTOM_SOUND_EFFECT.getPacketClass(), 0);
|
||||||
|
|
||||||
associate(PROTOCOL_CLASS, Protocol.class, getClientCommandConverter());
|
associate(PROTOCOL_CLASS, Protocol.class, getClientCommandConverter());
|
||||||
associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter());
|
associate(CLIENT_COMMAND_CLASS, ClientCommand.class, getClientCommandConverter());
|
||||||
@ -335,6 +371,7 @@ public abstract class EnumWrappers {
|
|||||||
associate(PLAYER_ACTION_CLASS, PlayerAction.class, getEntityActionConverter());
|
associate(PLAYER_ACTION_CLASS, PlayerAction.class, getEntityActionConverter());
|
||||||
associate(SCOREBOARD_ACTION_CLASS, ScoreboardAction.class, getUpdateScoreActionConverter());
|
associate(SCOREBOARD_ACTION_CLASS, ScoreboardAction.class, getUpdateScoreActionConverter());
|
||||||
associate(PARTICLE_CLASS, Particle.class, getParticleConverter());
|
associate(PARTICLE_CLASS, Particle.class, getParticleConverter());
|
||||||
|
associate(SOUND_CATEGORY_CLASS, SoundCategory.class, getSoundCategoryConverter());
|
||||||
INITIALIZED = true;
|
INITIALIZED = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -443,6 +480,11 @@ public abstract class EnumWrappers {
|
|||||||
return PARTICLE_CLASS;
|
return PARTICLE_CLASS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Class<?> getSoundCategoryClass() {
|
||||||
|
initialize();
|
||||||
|
return SOUND_CATEGORY_CLASS;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the converters
|
// Get the converters
|
||||||
public static EquivalentConverter<Protocol> getProtocolConverter() {
|
public static EquivalentConverter<Protocol> getProtocolConverter() {
|
||||||
return new EnumConverter<Protocol>(Protocol.class);
|
return new EnumConverter<Protocol>(Protocol.class);
|
||||||
@ -504,6 +546,10 @@ public abstract class EnumWrappers {
|
|||||||
return new EnumConverter<Particle>(Particle.class);
|
return new EnumConverter<Particle>(Particle.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static EquivalentConverter<SoundCategory> getSoundCategoryConverter() {
|
||||||
|
return new EnumConverter<SoundCategory>(SoundCategory.class);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a generic enum converter for use with StructureModifiers.
|
* Retrieve a generic enum converter for use with StructureModifiers.
|
||||||
* @param enumClass - Enum class
|
* @param enumClass - Enum class
|
||||||
|
@ -25,37 +25,61 @@ import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
|||||||
import com.google.common.base.Objects;
|
import com.google.common.base.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Represents an immutable PlayerInfoData in the PLAYER_INFO packet.
|
||||||
* @author dmulloy2
|
* @author dmulloy2
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class PlayerInfoData {
|
public class PlayerInfoData {
|
||||||
private static Constructor<?> constructor;
|
private static Constructor<?> constructor;
|
||||||
|
|
||||||
protected final WrappedGameProfile profile;
|
private final int latency;
|
||||||
protected final int ping;
|
private final NativeGameMode gameMode;
|
||||||
protected final NativeGameMode gameMode;
|
private final WrappedGameProfile profile;
|
||||||
protected final WrappedChatComponent displayName;
|
private final WrappedChatComponent displayName;
|
||||||
|
|
||||||
// This is the same order as the NMS class, minus the packet (which isn't a field)
|
// This is the same order as the NMS class, minus the packet (which isn't a field)
|
||||||
public PlayerInfoData(WrappedGameProfile profile, int ping, NativeGameMode gameMode, WrappedChatComponent displayName) {
|
public PlayerInfoData(WrappedGameProfile profile, int latency, NativeGameMode gameMode, WrappedChatComponent displayName) {
|
||||||
this.ping = ping;
|
|
||||||
this.gameMode = gameMode;
|
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
|
this.latency = latency;
|
||||||
|
this.gameMode = gameMode;
|
||||||
this.displayName = displayName;
|
this.displayName = displayName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the GameProfile of the player represented by this data.
|
||||||
|
* @return The GameProfile
|
||||||
|
*/
|
||||||
public WrappedGameProfile getProfile() {
|
public WrappedGameProfile getProfile() {
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated Replaced by {@link #getLatency()}
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public int getPing() {
|
public int getPing() {
|
||||||
return ping;
|
return latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the latency between the client and the server.
|
||||||
|
* @return The latency
|
||||||
|
*/
|
||||||
|
public int getLatency() {
|
||||||
|
return latency;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the GameMode of the player represented by this data.
|
||||||
|
* @return The GameMode
|
||||||
|
*/
|
||||||
public NativeGameMode getGameMode() {
|
public NativeGameMode getGameMode() {
|
||||||
return gameMode;
|
return gameMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the display name of the player represented by this data.
|
||||||
|
* @return The display name
|
||||||
|
*/
|
||||||
public WrappedChatComponent getDisplayName() {
|
public WrappedChatComponent getDisplayName() {
|
||||||
return displayName;
|
return displayName;
|
||||||
}
|
}
|
||||||
@ -91,7 +115,7 @@ public class PlayerInfoData {
|
|||||||
Object result = constructor.newInstance(
|
Object result = constructor.newInstance(
|
||||||
null,
|
null,
|
||||||
specific.profile.handle,
|
specific.profile.handle,
|
||||||
specific.ping,
|
specific.latency,
|
||||||
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
||||||
specific.displayName != null ? specific.displayName.handle : null
|
specific.displayName != null ? specific.displayName.handle : null
|
||||||
);
|
);
|
||||||
@ -112,7 +136,7 @@ public class PlayerInfoData {
|
|||||||
WrappedGameProfile gameProfile = gameProfiles.read(0);
|
WrappedGameProfile gameProfile = gameProfiles.read(0);
|
||||||
|
|
||||||
StructureModifier<Integer> ints = modifier.withType(int.class);
|
StructureModifier<Integer> ints = modifier.withType(int.class);
|
||||||
int ping = ints.read(0);
|
int latency = ints.read(0);
|
||||||
|
|
||||||
StructureModifier<NativeGameMode> gameModes = modifier.withType(
|
StructureModifier<NativeGameMode> gameModes = modifier.withType(
|
||||||
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
||||||
@ -122,7 +146,7 @@ public class PlayerInfoData {
|
|||||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||||
WrappedChatComponent displayName = displayNames.read(0);
|
WrappedChatComponent displayName = displayNames.read(0);
|
||||||
|
|
||||||
return new PlayerInfoData(gameProfile, ping, gameMode, displayName);
|
return new PlayerInfoData(gameProfile, latency, gameMode, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, return null
|
// Otherwise, return null
|
||||||
@ -146,7 +170,7 @@ public class PlayerInfoData {
|
|||||||
// Only compare objects of similar type
|
// Only compare objects of similar type
|
||||||
if (obj instanceof PlayerInfoData) {
|
if (obj instanceof PlayerInfoData) {
|
||||||
PlayerInfoData other = (PlayerInfoData) obj;
|
PlayerInfoData other = (PlayerInfoData) obj;
|
||||||
return profile.equals(other.profile) && ping == other.ping && gameMode == other.gameMode
|
return profile.equals(other.profile) && latency == other.latency && gameMode == other.gameMode
|
||||||
&& displayName.equals(other.displayName);
|
&& displayName.equals(other.displayName);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -154,12 +178,12 @@ public class PlayerInfoData {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(profile, ping, gameMode, displayName);
|
return Objects.hashCode(latency, gameMode, profile, displayName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("PlayerInfoData { profile=%s, ping=%s, gameMode=%s, displayName=%s }",
|
return String.format("PlayerInfoData[latency=%s, gameMode=%s, profile=%s, displayName=%s",
|
||||||
profile, ping, gameMode, displayName);
|
latency, gameMode, profile, displayName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,6 +209,7 @@ public class SimpleMinecraftClient {
|
|||||||
serializer.serializeVarInt(output, type.getCurrentId());
|
serializer.serializeVarInt(output, type.getCurrentId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
public void read(PacketType type, DataInputStream input) throws IOException {
|
public void read(PacketType type, DataInputStream input) throws IOException {
|
||||||
// Note - we don't read the packet id
|
// Note - we don't read the packet id
|
||||||
if (this.type != type) {
|
if (this.type != type) {
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren