From 670e8f034c0ec6817c55222f3a9e0c022925d03a Mon Sep 17 00:00:00 2001 From: Dan Mulloy Date: Sat, 29 Nov 2014 11:58:43 -0500 Subject: [PATCH] Fix players being disconnected on login --- ProtocolLib/pom.xml | 2 +- .../protocol/annotations/Spigot.java | 27 -- .../injector/netty/ChannelInjector.java | 36 +- .../protocol/wrappers/WrappedDataWatcher.java | 316 ++++++++---------- .../wrappers/WrappedWatchableObject.java | 88 +++-- 5 files changed, 196 insertions(+), 273 deletions(-) delete mode 100644 ProtocolLib/src/main/java/com/comphenix/protocol/annotations/Spigot.java diff --git a/ProtocolLib/pom.xml b/ProtocolLib/pom.xml index 72c344aa..c95f4d50 100644 --- a/ProtocolLib/pom.xml +++ b/ProtocolLib/pom.xml @@ -3,7 +3,7 @@ 4.0.0 com.comphenix.protocol ProtocolLib - 3.6.1-SNAPSHOT + 3.6.2-SNAPSHOT ProtocolLib Provides read/write access to the Minecraft protocol. diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/annotations/Spigot.java b/ProtocolLib/src/main/java/com/comphenix/protocol/annotations/Spigot.java deleted file mode 100644 index accfa9fe..00000000 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/annotations/Spigot.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.comphenix.protocol.annotations; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Indicate that this API and its descendants are only valid on Spigot. - * @author Kristian - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PACKAGE, - ElementType.PARAMETER, ElementType.TYPE, ElementType.FIELD}) -public @interface Spigot { - /** - * The minimum build number of Spigot where this is valid. - * @return The minimum build. - */ - int minimumBuild(); - - /** - * The maximum build number of Spigot where this is valid, or Integer.MAX_VALUE if not set. - * @return The maximum build number. - */ - int maximumBuild() default Integer.MAX_VALUE; -} \ No newline at end of file diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java index bedf8fad..93e680aa 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/ChannelInjector.java @@ -34,7 +34,6 @@ import org.bukkit.entity.Player; import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.ProtocolLibrary; -import com.comphenix.protocol.annotations.Spigot; import com.comphenix.protocol.error.Report; import com.comphenix.protocol.error.ReportType; import com.comphenix.protocol.events.ConnectionSide; @@ -82,9 +81,6 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector { // For retrieving the protocol private static FieldAccessor PROTOCOL_ACCESSOR; - // Current version - private static volatile MethodAccessor PROTOCOL_VERSION; - // The factory that created this injector private InjectionFactory factory; @@ -171,27 +167,9 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector { * Get the version of the current protocol. * @return The version. */ - @Spigot(minimumBuild = 1628) @Override public int getProtocolVersion() { - MethodAccessor accessor = PROTOCOL_VERSION; - - if (accessor == null) { - try { - accessor = Accessors.getMethodAccessor(networkManager.getClass(), "getVersion"); - - } catch (RuntimeException e) { - // Notify user - ProtocolLibrary.getErrorReporter().reportWarning( - this, Report.newBuilder(REPORT_CANNOT_FIND_GET_VERSION).error(e)); - - // Fallback method - accessor = Accessors.getConstantAccessor( - MinecraftProtocolVersion.getCurrentVersion(), null); - } - PROTOCOL_VERSION = accessor; - } - return (Integer) accessor.invoke(networkManager); + return MinecraftProtocolVersion.getCurrentVersion(); } @Override @@ -271,13 +249,13 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector { // Intercept all write methods channelField.setValue(new ChannelProxy(originalChannel, MinecraftReflection.getPacketClass()) { - // Compatibility with Spigot 1.8 protocol hack + // Compatibility with Spigot 1.8 private final PipelineProxy pipelineProxy = new PipelineProxy(originalChannel.pipeline(), this) { @Override public ChannelPipeline addBefore(String baseName, String name, ChannelHandler handler) { // Correct the position of the decoder if ("decoder".equals(baseName)) { - if (super.get("protocol_lib_decoder") != null && guessSpigotHandler(handler)) { + if (super.get("protocol_lib_decoder") != null && guessCompression(handler)) { super.addBefore("protocol_lib_decoder", name, handler); return this; } @@ -366,15 +344,13 @@ class ChannelInjector extends ByteToMessageDecoder implements Injector { } /** - * Determine if the given object is a Spigot channel handler. + * Determine if the given object is a compressor or decompressor. * @param handler - object to test. * @return TRUE if it is, FALSE if not or unknown. */ - private boolean guessSpigotHandler(ChannelHandler handler) { + private boolean guessCompression(ChannelHandler handler) { String className = handler != null ? handler.getClass().getCanonicalName() : null; - - return "org.spigotmc.SpigotDecompressor".equals(className) || - "org.spigotmc.SpigotCompressor".equals(className); + return className.contains("PacketCompressor") || className.contains("PacketDecompressor"); } /** diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java index a3f922e0..bd59d58d 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedDataWatcher.java @@ -37,22 +37,18 @@ import javax.annotation.Nullable; import org.bukkit.entity.Entity; import org.bukkit.inventory.ItemStack; -import com.comphenix.protocol.annotations.Spigot; import com.comphenix.protocol.injector.BukkitUnwrapper; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FieldUtils; 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.ReadOnlyFieldAccessor; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.wrappers.collection.ConvertedMap; import com.google.common.base.Function; import com.google.common.base.Objects; -import com.google.common.base.Preconditions; import com.google.common.collect.Iterators; -import com.google.common.collect.Maps; /** * Wraps a DataWatcher that is used to transmit arbitrary key-value pairs with a given entity. @@ -60,129 +56,127 @@ import com.google.common.collect.Maps; * @author Kristian */ public class WrappedDataWatcher extends AbstractWrapper implements Iterable { - /** - * Every custom watchable type in Spigot #1628 and above. - * @author Kristian - */ - @Spigot(minimumBuild = 1628) - public enum CustomType { - BYTE_SHORT("org.spigotmc.ProtocolData$ByteShort", 0, short.class), - DUAL_BYTE("org.spigotmc.ProtocolData$DualByte", 0, byte.class, byte.class), - HIDDEN_BYTE("org.spigotmc.ProtocolData$HiddenByte", 0, byte.class), - INT_BYTE("org.spigotmc.ProtocolData$IntByte", 2, int.class, byte.class), - DUAL_INT("org.spigotmc.ProtocolData$DualInt", 2, int.class, int.class); - - private Class spigotClass; - private ConstructorAccessor constructor; - private FieldAccessor secondaryValue; - private int typeId; - - private CustomType(String className, int typeId, Class... parameters) { - try { - this.spigotClass = Class.forName(className); - this.constructor = Accessors.getConstructorAccessor(spigotClass, parameters); - this.secondaryValue = parameters.length > 1 ? Accessors.getFieldAccessor(spigotClass, "value2", true) : null; - - } catch (ClassNotFoundException e) { - System.out.println("[ProtocolLib] Unable to find " + className); - this.spigotClass = null; - } - this.typeId = typeId; - } - - /** - * Construct a new instance of this Spigot type. - * @param value - the value. Cannot be NULL. - * @return The instance to construct. - */ - Object newInstance(Object value) { - return newInstance(value, null); - } - - /** - * Construct a new instance of this Spigot type. - *

- * The secondary value may be NULL if this custom type does not contain a secondary value. - * @param value - the value. - * @param secondary - optional secondary value. - * @return - */ - Object newInstance(Object value, Object secondary) { - Preconditions.checkNotNull(value, "value cannot be NULL."); - - if (hasSecondary()) { - return constructor.invoke(value, secondary); - } else { - if (secondary != null) { - throw new IllegalArgumentException("Cannot construct " + this + " with a secondary value"); - } - return constructor.invoke(value); - } - } - - /** - * Set the secondary value of a given type. - * @param instance - the instance. - * @param secondary - the secondary value. - */ - void setSecondary(Object instance, Object secondary) { - if (!hasSecondary()) { - throw new IllegalArgumentException(this + " does not have a secondary value."); - } - secondaryValue.set(instance, secondary); - } - - /** - * Get the secondary value of a type. - * @param instance - the instance. - * @return The secondary value. - */ - Object getSecondary(Object instance) { - if (!hasSecondary()) { - throw new IllegalArgumentException(this + " does not have a secondary value."); - } - return secondaryValue.get(instance); - } - - /** - * Determine if this type has a secondary value. - * @return TRUE if it does, FALSE otherwise. - */ - public boolean hasSecondary() { - return secondaryValue != null; - } - - /** - * Underlying Spigot class. - * @return The class. - */ - public Class getSpigotClass() { - return spigotClass; - } - - /** - * The equivalent type ID. - * @return The equivalent ID. - */ - public int getTypeId() { - return typeId; - } - - /** - * Retrieve the custom Spigot type of a value. - * @param value - the value. - * @return The Spigot type, or NULL if not found. - */ - @Spigot(minimumBuild = 1628) - public static CustomType fromValue(Object value) { - for (CustomType type : CustomType.values()) { - if (type.getSpigotClass().isInstance(value)) { - return type; - } - } - return null; - } - } +// /** +// * Every custom watchable type in Spigot #1628 and above. +// * @author Kristian +// */ +// public enum CustomType { +// BYTE_SHORT("org.spigotmc.ProtocolData$ByteShort", 0, short.class), +// DUAL_BYTE("org.spigotmc.ProtocolData$DualByte", 0, byte.class, byte.class), +// HIDDEN_BYTE("org.spigotmc.ProtocolData$HiddenByte", 0, byte.class), +// INT_BYTE("org.spigotmc.ProtocolData$IntByte", 2, int.class, byte.class), +// DUAL_INT("org.spigotmc.ProtocolData$DualInt", 2, int.class, int.class); +// +// private Class spigotClass; +// private ConstructorAccessor constructor; +// private FieldAccessor secondaryValue; +// private int typeId; +// +// private CustomType(String className, int typeId, Class... parameters) { +// try { +// this.spigotClass = Class.forName(className); +// this.constructor = Accessors.getConstructorAccessor(spigotClass, parameters); +// this.secondaryValue = parameters.length > 1 ? Accessors.getFieldAccessor(spigotClass, "value2", true) : null; +// +// } catch (ClassNotFoundException e) { +// System.out.println("[ProtocolLib] Unable to find " + className); +// this.spigotClass = null; +// } +// this.typeId = typeId; +// } +// +// /** +// * Construct a new instance of this Spigot type. +// * @param value - the value. Cannot be NULL. +// * @return The instance to construct. +// */ +// Object newInstance(Object value) { +// return newInstance(value, null); +// } +// +// /** +// * Construct a new instance of this Spigot type. +// *

+// * The secondary value may be NULL if this custom type does not contain a secondary value. +// * @param value - the value. +// * @param secondary - optional secondary value. +// * @return +// */ +// Object newInstance(Object value, Object secondary) { +// Preconditions.checkNotNull(value, "value cannot be NULL."); +// +// if (hasSecondary()) { +// return constructor.invoke(value, secondary); +// } else { +// if (secondary != null) { +// throw new IllegalArgumentException("Cannot construct " + this + " with a secondary value"); +// } +// return constructor.invoke(value); +// } +// } +// +// /** +// * Set the secondary value of a given type. +// * @param instance - the instance. +// * @param secondary - the secondary value. +// */ +// void setSecondary(Object instance, Object secondary) { +// if (!hasSecondary()) { +// throw new IllegalArgumentException(this + " does not have a secondary value."); +// } +// secondaryValue.set(instance, secondary); +// } +// +// /** +// * Get the secondary value of a type. +// * @param instance - the instance. +// * @return The secondary value. +// */ +// Object getSecondary(Object instance) { +// if (!hasSecondary()) { +// throw new IllegalArgumentException(this + " does not have a secondary value."); +// } +// return secondaryValue.get(instance); +// } +// +// /** +// * Determine if this type has a secondary value. +// * @return TRUE if it does, FALSE otherwise. +// */ +// public boolean hasSecondary() { +// return secondaryValue != null; +// } +// +// /** +// * Underlying Spigot class. +// * @return The class. +// */ +// public Class getSpigotClass() { +// return spigotClass; +// } +// +// /** +// * The equivalent type ID. +// * @return The equivalent ID. +// */ +// public int getTypeId() { +// return typeId; +// } +// +// /** +// * Retrieve the custom Spigot type of a value. +// * @param value - the value. +// * @return The Spigot type, or NULL if not found. +// */ +// public static CustomType fromValue(Object value) { +// for (CustomType type : CustomType.values()) { +// if (type.getSpigotClass().isInstance(value)) { +// return type; +// } +// } +// return null; +// } +// } /** * Used to assign integer IDs to given types. @@ -434,23 +428,10 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable, Integer>) TYPE_MAP_ACCESSOR.get(null); @@ -757,17 +737,17 @@ public class WrappedDataWatcher extends AbstractWrapper implements Iterable, Integer> initializeCustom() { - Map, Integer> map = Maps.newHashMap(); - - for (CustomType type : CustomType.values()) { - if (type.getSpigotClass() != null) { - map.put(type.getSpigotClass(), type.getTypeId()); - } - } - return map; - } +// // For Spigot's bountiful update patch +// private static Map, Integer> initializeCustom() { +// Map, Integer> map = Maps.newHashMap(); +// +// for (CustomType type : CustomType.values()) { +// if (type.getSpigotClass() != null) { +// map.put(type.getSpigotClass(), type.getTypeId()); +// } +// } +// return map; +// } // TODO: Remove, as this was fixed in build #1189 of Spigot private static void initializeSpigot(FuzzyReflection fuzzy) { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedWatchableObject.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedWatchableObject.java index 4390eea0..49b5ee4f 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedWatchableObject.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedWatchableObject.java @@ -21,13 +21,11 @@ import java.lang.reflect.Constructor; import org.bukkit.inventory.ItemStack; -import com.comphenix.protocol.annotations.Spigot; import com.comphenix.protocol.reflect.EquivalentConverter; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.StructureModifier; import com.comphenix.protocol.reflect.instances.DefaultInstances; import com.comphenix.protocol.utility.MinecraftReflection; -import com.comphenix.protocol.wrappers.WrappedDataWatcher.CustomType; import com.google.common.base.Objects; /** @@ -97,17 +95,16 @@ public class WrappedWatchableObject extends AbstractWrapper { } } - /** - * Construct a custom watchable object from an index, value and custom type. - * @param index - the index. - * @param primary - non-null value of specific types. - * @param secondary - optional secondary value, if the type can store it. - * @param type - the custom Spigot type. - */ - @Spigot(minimumBuild = 1628) - public WrappedWatchableObject(int index, Object value, Object secondary, CustomType type) { - this(index, type.newInstance(value, secondary)); - } +// /** +// * Construct a custom watchable object from an index, value and custom type. +// * @param index - the index. +// * @param primary - non-null value of specific types. +// * @param secondary - optional secondary value, if the type can store it. +// * @param type - the custom Spigot type. +// */ +// public WrappedWatchableObject(int index, Object value, Object secondary, CustomType type) { +// this(index, type.newInstance(value, secondary)); +// } // Wrap a NMS object private void load(Object handle) { @@ -133,14 +130,13 @@ public class WrappedWatchableObject extends AbstractWrapper { } } - /** - * Retrieve the custom type of this object. - * @return The custom type, or NULL if not applicable. - */ - @Spigot(minimumBuild = 1628) - public CustomType getCustomType() { - return CustomType.fromValue(getValue()); - } +// /** +// * Retrieve the custom type of this object. +// * @return The custom type, or NULL if not applicable. +// */ +// public CustomType getCustomType() { +// return CustomType.fromValue(getValue()); +// } /** * Retrieve the correct super type of the current value. @@ -289,32 +285,30 @@ public class WrappedWatchableObject extends AbstractWrapper { return getWrapped(modifier.withType(Object.class).read(0)); } - /** - * Retrieve the secondary value associated with this watchable object. - *

- * This is only applicable for certain {@link CustomType}. - * @return The secondary value, or NULL if not found. - */ - @Spigot(minimumBuild = 1628) - public Object getSecondaryValue() { - CustomType type = getCustomType(); - return type != null ? type.getSecondary(getValue()) : null; - } - - /** - * Set the secondary value. - * @param secondary - the secondary value. - * @throws IllegalStateException If this watchable object does not have a secondary value. - */ - @Spigot(minimumBuild = 1628) - public void setSecondaryValue(Object secondary) { - CustomType type = getCustomType(); - - if (type == null) { - throw new IllegalStateException(this + " does not have a custom type."); - } - type.setSecondary(getValue(), secondary); - } +// /** +// * Retrieve the secondary value associated with this watchable object. +// *

+// * This is only applicable for certain {@link CustomType}. +// * @return The secondary value, or NULL if not found. +// */ +// public Object getSecondaryValue() { +// CustomType type = getCustomType(); +// return type != null ? type.getSecondary(getValue()) : null; +// } +// +// /** +// * Set the secondary value. +// * @param secondary - the secondary value. +// * @throws IllegalStateException If this watchable object does not have a secondary value. +// */ +// public void setSecondaryValue(Object secondary) { +// CustomType type = getCustomType(); +// +// if (type == null) { +// throw new IllegalStateException(this + " does not have a custom type."); +// } +// type.setSecondary(getValue(), secondary); +// } /** * Set whether or not the value must be synchronized with the client.