From 922fb948049d858c45efc8b33dfa16515b1d15cb Mon Sep 17 00:00:00 2001 From: "Kristian S. Stangeland" Date: Wed, 11 Dec 2013 03:55:25 +0100 Subject: [PATCH] Added support for cloing ServerPing packets. --- .../comphenix/protocol/ProtocolLibrary.java | 6 ++- .../events/SerializedOfflinePlayer.java | 4 +- .../injector/PacketFilterManager.java | 14 +++--- .../injector/packet/InterceptWritePacket.java | 9 ++-- .../packet/PacketInjectorBuilder.java | 18 +------- .../injector/packet/ProxyPacketInjector.java | 12 ++--- .../injector/player/InjectedArrayList.java | 8 ++-- .../injector/player/NetworkFieldInjector.java | 6 +-- .../player/NetworkObjectInjector.java | 10 ++--- .../player/NetworkServerInjector.java | 7 +-- .../injector/player/PlayerInjector.java | 3 +- .../player/PlayerInjectorBuilder.java | 16 +------ .../player/ProxyPlayerInjectionHandler.java | 12 ++--- .../injector/spigot/SpigotPacketInjector.java | 14 +++--- .../reflect/cloning/BukkitCloner.java | 6 ++- .../protocol/utility/EnhancerFactory.java | 44 +++++++++++++++++++ .../protocol/utility/MinecraftMethods.java | 4 +- .../wrappers/WrappedChatComponent.java | 8 ++++ .../protocol/wrappers/WrappedServerPing.java | 18 ++++++++ 19 files changed, 128 insertions(+), 91 deletions(-) create mode 100644 ProtocolLib/src/main/java/com/comphenix/protocol/utility/EnhancerFactory.java diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java index 18c62514..3bc60b31 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java @@ -51,6 +51,7 @@ import com.comphenix.protocol.metrics.Updater.UpdateResult; import com.comphenix.protocol.metrics.Updater.UpdateType; import com.comphenix.protocol.reflect.compiler.BackgroundCompiler; import com.comphenix.protocol.utility.ChatExtensions; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftVersion; import com.google.common.base.Splitter; import com.google.common.collect.Iterables; @@ -119,7 +120,7 @@ public class ProtocolLibrary extends JavaPlugin { // Executors private static ListeningScheduledExecutorService executorAsync; private static ListeningScheduledExecutorService executorSync; - + // Structure compiler private BackgroundCompiler backgroundCompiler; @@ -156,6 +157,9 @@ public class ProtocolLibrary extends JavaPlugin { // Load configuration logger = getLoggerSafely(); + // Initialize enhancer factory + EnhancerFactory.getInstance().setClassLoader(getClassLoader()); + // Initialize executors executorAsync = BukkitExecutors.newAsynchronous(this); executorSync = BukkitExecutors.newSynchronous(this); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java b/ProtocolLib/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java index 0c60ab43..d8975f9f 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/events/SerializedOfflinePlayer.java @@ -35,6 +35,8 @@ import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.entity.Player; +import com.comphenix.protocol.utility.EnhancerFactory; + /** * Represents a player object that can be serialized by Java. * @@ -208,7 +210,7 @@ class SerializedOfflinePlayer implements OfflinePlayer, Serializable { } // MORE CGLIB magic! - Enhancer ex = new Enhancer(); + Enhancer ex = EnhancerFactory.getInstance().createEnhancer(); ex.setSuperclass(Player.class); ex.setCallback(new MethodInterceptor() { @Override diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java index be3d692e..0a0be04b 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java @@ -68,6 +68,7 @@ import com.comphenix.protocol.injector.player.PlayerInjectionHandler.ConflictStr import com.comphenix.protocol.injector.spigot.SpigotPacketInjector; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FuzzyReflection; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; import com.google.common.base.Objects; @@ -232,7 +233,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok this.loginPackets = new LoginPackets(minecraftVersion); // The write packet interceptor - this.interceptWritePacket = new InterceptWritePacket(classLoader, reporter); + this.interceptWritePacket = new InterceptWritePacket(reporter); // Use the correct injection type if (MinecraftReflection.isUsingNetty()) { @@ -241,7 +242,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok this.packetInjector = nettyInjector.getPacketInjector(); } else if (builder.isNettyEnabled()) { - this.spigotInjector = new SpigotPacketInjector(classLoader, reporter, this, server); + this.spigotInjector = new SpigotPacketInjector(reporter, this, server); this.playerInjection = spigotInjector.getPlayerHandler(); this.packetInjector = spigotInjector.getPacketInjector(); @@ -249,7 +250,6 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok spigotInjector.setProxyPacketInjector(PacketInjectorBuilder.newBuilder(). invoker(this). reporter(reporter). - classLoader(classLoader). playerInjection(playerInjection). buildInjector() ); @@ -260,7 +260,6 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok invoker(this). server(server). reporter(reporter). - classLoader(classLoader). packetListeners(packetListeners). injectionFilter(isInjectionNecessary). version(builder.getMinecraftVersion()). @@ -269,7 +268,6 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok this.packetInjector = PacketInjectorBuilder.newBuilder(). invoker(this). reporter(reporter). - classLoader(classLoader). playerInjection(playerInjection). buildInjector(); } @@ -1077,9 +1075,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok Method registerEvent = FuzzyReflection.fromObject(manager).getMethodByParameters("registerEvent", eventTypes, Listener.class, eventPriority, Plugin.class); - Enhancer playerLow = new Enhancer(); - Enhancer playerEx = new Enhancer(); - Enhancer serverEx = new Enhancer(); + Enhancer playerLow = EnhancerFactory.getInstance().createEnhancer(); + Enhancer playerEx = EnhancerFactory.getInstance().createEnhancer(); + Enhancer serverEx = EnhancerFactory.getInstance().createEnhancer(); playerLow.setSuperclass(playerListener); playerLow.setClassLoader(classLoader); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/InterceptWritePacket.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/InterceptWritePacket.java index 21f0107f..cd3e1415 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/InterceptWritePacket.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/InterceptWritePacket.java @@ -15,6 +15,7 @@ import com.comphenix.protocol.events.NetworkMarker; import com.comphenix.protocol.events.PacketEvent; import com.comphenix.protocol.reflect.MethodInfo; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.collect.Maps; @@ -39,15 +40,12 @@ public class InterceptWritePacket { private boolean writePacketIntercepted; private ConcurrentMap> proxyClasses = Maps.newConcurrentMap(); - - private ClassLoader classLoader; private ErrorReporter reporter; private WritePacketModifier modifierWrite; private WritePacketModifier modifierRest; - public InterceptWritePacket(ClassLoader classLoader, ErrorReporter reporter) { - this.classLoader = classLoader; + public InterceptWritePacket(ErrorReporter reporter) { this.reporter = reporter; // Initialize modifiers @@ -57,7 +55,7 @@ public class InterceptWritePacket { private Class createProxyClass(int packetId) { // Construct the proxy object - Enhancer ex = new Enhancer(); + Enhancer ex = EnhancerFactory.getInstance().createEnhancer(); // Attempt to share callback filter if (filter == null) { @@ -80,7 +78,6 @@ public class InterceptWritePacket { ex.setCallbackFilter(filter); ex.setUseCache(false); - ex.setClassLoader(classLoader); ex.setCallbackTypes( new Class[] { WritePacketModifier.class, WritePacketModifier.class }); Class proxyClass = ex.createClass(); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketInjectorBuilder.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketInjectorBuilder.java index fb6def6a..e8977289 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketInjectorBuilder.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketInjectorBuilder.java @@ -28,23 +28,11 @@ public class PacketInjectorBuilder { public static PacketInjectorBuilder newBuilder() { return new PacketInjectorBuilder(); } - - protected ClassLoader classLoader; + protected ListenerInvoker invoker; protected ErrorReporter reporter; protected PlayerInjectionHandler playerInjection; - /** - * Set the class loader to use during class generation. - * @param classLoader - new class loader. - * @return This builder, for chaining. - */ - public PacketInjectorBuilder classLoader(@Nonnull ClassLoader classLoader) { - Preconditions.checkNotNull(classLoader, "classLoader cannot be NULL"); - this.classLoader = classLoader; - return this; - } - /** * The error reporter used by the created injector. * @param reporter - new error reporter. @@ -86,8 +74,6 @@ public class PacketInjectorBuilder { ProtocolManager manager = ProtocolLibrary.getProtocolManager(); // Initialize with default values if we can - if (classLoader == null) - classLoader = this.getClass().getClassLoader(); if (reporter == null) reporter = ProtocolLibrary.getErrorReporter(); if (invoker == null) @@ -105,6 +91,6 @@ public class PacketInjectorBuilder { */ public PacketInjector buildInjector() throws FieldAccessException { initializeDefaults(); - return new ProxyPacketInjector(classLoader, invoker, playerInjection, reporter); + return new ProxyPacketInjector(invoker, playerInjection, reporter); } } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java index 94747491..18f6446e 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java @@ -49,6 +49,7 @@ import com.comphenix.protocol.reflect.FieldUtils; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.MethodInfo; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.wrappers.WrappedIntHashMap; @@ -147,19 +148,15 @@ class ProxyPacketInjector implements PacketInjector { // Allows us to determine the sender private PlayerInjectionHandler playerInjection; - // Class loader - private ClassLoader classLoader; - // Share callback filter private CallbackFilter filter; // Determine if the read packet method was found private boolean readPacketIntercepted = false; - public ProxyPacketInjector(ClassLoader classLoader, ListenerInvoker manager, - PlayerInjectionHandler playerInjection, ErrorReporter reporter) throws FieldAccessException { + public ProxyPacketInjector(ListenerInvoker manager, PlayerInjectionHandler playerInjection, + ErrorReporter reporter) throws FieldAccessException { - this.classLoader = classLoader; this.manager = manager; this.playerInjection = playerInjection; this.reporter = reporter; @@ -211,7 +208,7 @@ class ProxyPacketInjector implements PacketInjector { if (hasPacketHandler(type)) return false; - Enhancer ex = new Enhancer(); + Enhancer ex = EnhancerFactory.getInstance().createEnhancer(); // Unfortunately, we can't easily distinguish between these two functions: // * Object lookup(int par1) @@ -255,7 +252,6 @@ class ProxyPacketInjector implements PacketInjector { ex.setSuperclass(old); ex.setCallbackFilter(filter); ex.setCallbackTypes(new Class[] { NoOp.class, ReadPacketModifier.class, ReadPacketModifier.class }); - ex.setClassLoader(classLoader); Class proxy = ex.createClass(); // Create the proxy handlers diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java index b5138290..c88b021d 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/InjectedArrayList.java @@ -29,6 +29,7 @@ import com.comphenix.protocol.error.Report; import com.comphenix.protocol.error.ReportType; import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.collect.MapMaker; @@ -55,12 +56,10 @@ class InjectedArrayList extends ArrayList { private transient PlayerInjector injector; private transient Set ignoredPackets; - private transient ClassLoader classLoader; private transient InvertedIntegerCallback callback; - public InjectedArrayList(ClassLoader classLoader, PlayerInjector injector, Set ignoredPackets) { - this.classLoader = classLoader; + public InjectedArrayList(PlayerInjector injector, Set ignoredPackets) { this.injector = injector; this.ignoredPackets = ignoredPackets; this.callback = new InvertedIntegerCallback(); @@ -135,11 +134,10 @@ class InjectedArrayList extends ArrayList { // } // ect. // } - Enhancer ex = new Enhancer(); + Enhancer ex = EnhancerFactory.getInstance().createEnhancer(); ex.setSuperclass(MinecraftReflection.getPacketClass()); ex.setInterfaces(new Class[] { FakePacket.class } ); ex.setUseCache(true); - ex.setClassLoader(classLoader); ex.setCallbackType(InvertedIntegerCallback.class); Class proxyClass = ex.createClass(); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java index b8720fb6..fd22a390 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkFieldInjector.java @@ -77,10 +77,10 @@ class NetworkFieldInjector extends PlayerInjector { // Determine if we're listening private IntegerSet sendingFilters; - public NetworkFieldInjector(ClassLoader classLoader, ErrorReporter reporter, Player player, + public NetworkFieldInjector(ErrorReporter reporter, Player player, ListenerInvoker manager, IntegerSet sendingFilters) throws IllegalAccessException { - super(classLoader, reporter, player, manager); + super(reporter, player, manager); this.sendingFilters = sendingFilters; } @@ -161,7 +161,7 @@ class NetworkFieldInjector extends PlayerInjector { synchronized(syncObject) { // The list we'll be inserting - List hackedList = new InjectedArrayList(classLoader, this, ignoredPackets); + List hackedList = new InjectedArrayList(this, ignoredPackets); // Add every previously stored packet for (Object packet : minecraftList) { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java index 0ef8b22a..992cbd32 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkObjectInjector.java @@ -41,6 +41,7 @@ import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.injector.ListenerInvoker; import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks; import com.comphenix.protocol.injector.server.TemporaryPlayerFactory; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftVersion; /** @@ -68,16 +69,16 @@ public class NetworkObjectInjector extends PlayerInjector { * Create a new network object injector. *

* Note: This class is intended to be internal. Do not use. - * @param classLoader - the class loader. * @param reporter - the error reporter. * @param player - the player Bukkit entity. * @param invoker - the packet invoker. * @param sendingFilters - list of permitted packet IDs. * @throws IllegalAccessException If reflection failed. */ - public NetworkObjectInjector(ClassLoader classLoader, ErrorReporter reporter, Player player, + public NetworkObjectInjector(ErrorReporter reporter, Player player, ListenerInvoker invoker, IntegerSet sendingFilters) throws IllegalAccessException { - super(classLoader, reporter, player, invoker); + + super(reporter, player, invoker); this.sendingFilters = sendingFilters; } @@ -194,8 +195,7 @@ public class NetworkObjectInjector extends PlayerInjector { } // Create our proxy object - Enhancer ex = new Enhancer(); - ex.setClassLoader(classLoader); + Enhancer ex = EnhancerFactory.getInstance().createEnhancer(); ex.setSuperclass(networkInterface); ex.setCallbacks(new Callback[] { queueFilter, dispatch }); ex.setCallbackFilter(callbackFilter); diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java index a5efbb11..2a975ff2 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetworkServerInjector.java @@ -41,6 +41,7 @@ import com.comphenix.protocol.reflect.ObjectWriter; import com.comphenix.protocol.reflect.VolatileField; import com.comphenix.protocol.reflect.instances.DefaultInstances; import com.comphenix.protocol.reflect.instances.ExistingGenerator; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftMethods; import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftVersion; @@ -72,11 +73,11 @@ class NetworkServerInjector extends PlayerInjector { private final ObjectWriter writer = new ObjectWriter(); public NetworkServerInjector( - ClassLoader classLoader, ErrorReporter reporter, Player player, + ErrorReporter reporter, Player player, ListenerInvoker invoker, IntegerSet sendingFilters, InjectedServerConnection serverInjection) throws IllegalAccessException { - super(classLoader, reporter, player, invoker); + super(reporter, player, invoker); this.sendingFilters = sendingFilters; this.serverInjection = serverInjection; } @@ -148,7 +149,7 @@ class NetworkServerInjector extends PlayerInjector { private boolean tryInjectManager() { Class serverClass = serverHandler.getClass(); - Enhancer ex = new Enhancer(); + Enhancer ex = EnhancerFactory.getInstance().createEnhancer(); Callback sendPacketCallback = new MethodInterceptor() { @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java index 01c85515..ede92f75 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjector.java @@ -140,8 +140,7 @@ public abstract class PlayerInjector implements SocketInjector { boolean updateOnLogin; volatile Player updatedPlayer; - public PlayerInjector(ClassLoader classLoader, ErrorReporter reporter, Player player, ListenerInvoker invoker) throws IllegalAccessException { - this.classLoader = classLoader; + public PlayerInjector(ErrorReporter reporter, Player player, ListenerInvoker invoker) throws IllegalAccessException { this.reporter = reporter; this.player = player; this.invoker = invoker; diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectorBuilder.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectorBuilder.java index 3a5ec97b..3319d5c6 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectorBuilder.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectorBuilder.java @@ -32,7 +32,6 @@ public class PlayerInjectorBuilder { // Use the static method. } - protected ClassLoader classLoader; protected ErrorReporter reporter; protected Predicate injectionFilter; protected ListenerInvoker invoker; @@ -40,17 +39,6 @@ public class PlayerInjectorBuilder { protected Server server; protected MinecraftVersion version; - /** - * Set the class loader to use during class generation. - * @param classLoader - new class loader. - * @return This builder, for chaining. - */ - public PlayerInjectorBuilder classLoader(@Nonnull ClassLoader classLoader) { - Preconditions.checkNotNull(classLoader, "classLoader cannot be NULL"); - this.classLoader = classLoader; - return this; - } - /** * The error reporter used by the created injector. * @param reporter - new error reporter. @@ -126,8 +114,6 @@ public class PlayerInjectorBuilder { ProtocolManager manager = ProtocolLibrary.getProtocolManager(); // Initialize with default values if we can - if (classLoader == null) - classLoader = this.getClass().getClassLoader(); if (reporter == null) reporter = ProtocolLibrary.getErrorReporter(); if (invoker == null) @@ -151,7 +137,7 @@ public class PlayerInjectorBuilder { initializeDefaults(); return new ProxyPlayerInjectionHandler( - classLoader, reporter, injectionFilter, + reporter, injectionFilter, invoker, packetListeners, server, version); } } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ProxyPlayerInjectionHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ProxyPlayerInjectionHandler.java index 57b8d7e4..4e34a42c 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ProxyPlayerInjectionHandler.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/ProxyPlayerInjectionHandler.java @@ -124,17 +124,13 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler { // List of packet listeners private Set packetListeners; - // The class loader we're using - private ClassLoader classLoader; - // Used to filter injection attempts private Predicate injectionFilter; public ProxyPlayerInjectionHandler( - ClassLoader classLoader, ErrorReporter reporter, Predicate injectionFilter, + ErrorReporter reporter, Predicate injectionFilter, ListenerInvoker invoker, Set packetListeners, Server server, MinecraftVersion version) { - this.classLoader = classLoader; this.reporter = reporter; this.invoker = invoker; this.injectionFilter = injectionFilter; @@ -224,11 +220,11 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler { // Construct the correct player hook switch (hook) { case NETWORK_HANDLER_FIELDS: - return new NetworkFieldInjector(classLoader, reporter, player, invoker, sendingFilters); + return new NetworkFieldInjector(reporter, player, invoker, sendingFilters); case NETWORK_MANAGER_OBJECT: - return new NetworkObjectInjector(classLoader, reporter, player, invoker, sendingFilters); + return new NetworkObjectInjector(reporter, player, invoker, sendingFilters); case NETWORK_SERVER_OBJECT: - return new NetworkServerInjector(classLoader, reporter, player, invoker, sendingFilters, serverInjection); + return new NetworkServerInjector(reporter, player, invoker, sendingFilters, serverInjection); default: throw new IllegalArgumentException("Cannot construct a player injector."); } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java index f378fda2..a2e3d165 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/SpigotPacketInjector.java @@ -43,6 +43,7 @@ import com.comphenix.protocol.reflect.FieldUtils; import com.comphenix.protocol.reflect.FuzzyReflection; import com.comphenix.protocol.reflect.MethodInfo; import com.comphenix.protocol.reflect.fuzzy.FuzzyMethodContract; +import com.comphenix.protocol.utility.EnhancerFactory; import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.collect.Iterables; @@ -98,7 +99,6 @@ public class SpigotPacketInjector implements SpigotPacketListener { private ListenerInvoker invoker; private ErrorReporter reporter; private Server server; - private ClassLoader classLoader; // The proxy packet injector private PacketInjector proxyPacketInjector; @@ -106,8 +106,7 @@ public class SpigotPacketInjector implements SpigotPacketListener { /** * Create a new spigot injector. */ - public SpigotPacketInjector(ClassLoader classLoader, ErrorReporter reporter, ListenerInvoker invoker, Server server) { - this.classLoader = classLoader; + public SpigotPacketInjector(ErrorReporter reporter, ListenerInvoker invoker, Server server) { this.reporter = reporter; this.invoker = invoker; this.server = server; @@ -220,8 +219,7 @@ public class SpigotPacketInjector implements SpigotPacketListener { // Don't care for everything else callbacks[2] = NoOp.INSTANCE; - Enhancer enhancer = new Enhancer(); - enhancer.setClassLoader(classLoader); + Enhancer enhancer = EnhancerFactory.getInstance().createEnhancer(); enhancer.setSuperclass(getSpigotListenerClass()); enhancer.setCallbacks(callbacks); enhancer.setCallbackFilter(new CallbackFilter() { @@ -316,7 +314,7 @@ public class SpigotPacketInjector implements SpigotPacketListener { try { NetworkObjectInjector created = new NetworkObjectInjector( - classLoader, filterImpossibleWarnings(reporter), null, invoker, null); + filterImpossibleWarnings(reporter), null, invoker, null); created.initializePlayer(player); @@ -344,7 +342,7 @@ public class SpigotPacketInjector implements SpigotPacketListener { // Inject the network manager try { NetworkObjectInjector created = new NetworkObjectInjector( - classLoader, filterImpossibleWarnings(reporter), null, invoker, null); + filterImpossibleWarnings(reporter), null, invoker, null); if (MinecraftReflection.isLoginHandler(connection)) { created.initialize(connection); @@ -501,7 +499,7 @@ public class SpigotPacketInjector implements SpigotPacketListener { void injectPlayer(Player player) { try { NetworkObjectInjector dummy = new NetworkObjectInjector( - classLoader, filterImpossibleWarnings(reporter), player, invoker, null); + filterImpossibleWarnings(reporter), player, invoker, null); dummy.initializePlayer(player); // Save this player for the network manager diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/cloning/BukkitCloner.java b/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/cloning/BukkitCloner.java index 63456619..56ac26e9 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/cloning/BukkitCloner.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/reflect/cloning/BukkitCloner.java @@ -22,6 +22,7 @@ import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.wrappers.BukkitConverters; import com.comphenix.protocol.wrappers.ChunkPosition; import com.comphenix.protocol.wrappers.WrappedDataWatcher; +import com.comphenix.protocol.wrappers.WrappedServerPing; /** * Represents an object that can clone a specific list of Bukkit- and Minecraft-related objects. @@ -31,7 +32,7 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher; public class BukkitCloner implements Cloner { // List of classes we support private Class[] clonableClasses = { MinecraftReflection.getItemStackClass(), MinecraftReflection.getChunkPositionClass(), - MinecraftReflection.getDataWatcherClass() }; + MinecraftReflection.getDataWatcherClass(), MinecraftReflection.getServerPingClass() }; private int findMatchingClass(Class type) { // See if is a subclass of any of our supported superclasses @@ -66,6 +67,9 @@ public class BukkitCloner implements Cloner { case 2: EquivalentConverter dataConverter = BukkitConverters.getDataWatcherConverter(); return dataConverter.getGeneric(clonableClasses[2], dataConverter.getSpecific(source).deepClone()); + case 3: + EquivalentConverter serverConverter = BukkitConverters.getWrappedServerPingConverter(); + return serverConverter.getGeneric(clonableClasses[3], serverConverter.getSpecific(source).deepClone()); default: throw new IllegalArgumentException("Cannot clone objects of type " + source.getClass()); } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/EnhancerFactory.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/EnhancerFactory.java new file mode 100644 index 00000000..c64fb1e8 --- /dev/null +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/EnhancerFactory.java @@ -0,0 +1,44 @@ +package com.comphenix.protocol.utility; + +import net.sf.cglib.proxy.Enhancer; + +/** + * Represents a shared enchancer factory. + * @author Kristian + */ +public class EnhancerFactory { + private static EnhancerFactory INSTANCE = new EnhancerFactory(); + + // The current class loader + private ClassLoader loader = EnhancerFactory.class.getClassLoader(); + + public static EnhancerFactory getInstance() { + return INSTANCE; + } + + /** + * Create a new CGLib enhancer. + * @return The new enhancer. + */ + public Enhancer createEnhancer() { + Enhancer enhancer = new Enhancer(); + enhancer.setClassLoader(loader); + return enhancer; + } + + /** + * Set the current class loader to use when constructing enhancers. + * @param loader - the class loader + */ + public void setClassLoader(ClassLoader loader) { + this.loader = loader; + } + + /** + * Get the current class loader we are using. + * @return The current class loader. + */ + public ClassLoader getClassLoader() { + return loader; + } +} diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java index 3141d7c5..e57e79c6 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/utility/MinecraftMethods.java @@ -5,6 +5,8 @@ import java.lang.reflect.Method; import java.util.List; import java.util.Map; +import org.bukkit.plugin.Plugin; + import net.minecraft.util.io.netty.buffer.ByteBuf; import net.minecraft.util.io.netty.buffer.UnpooledByteBufAllocator; import net.minecraft.util.io.netty.channel.ChannelHandlerContext; @@ -161,7 +163,7 @@ public class MinecraftMethods { // Initialize the methods if (packetReadByteBuf == null || packetWriteByteBuf == null) { // This object will allow us to detect which methods were called - Enhancer enhancer = new Enhancer(); + Enhancer enhancer = EnhancerFactory.getInstance().createEnhancer(); enhancer.setSuperclass(MinecraftReflection.getPacketDataSerializerClass()); enhancer.setCallback(new MethodInterceptor() { @Override diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java index 2bfd732c..00567d97 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedChatComponent.java @@ -97,6 +97,14 @@ public class WrappedChatComponent extends AbstractWrapper { this.cache = obj; } + /** + * Retrieve a deep copy of the current chat component. + * @return A copy of the current component. + */ + public WrappedChatComponent deepClone() { + return fromJson(getJson()); + } + @Override public boolean equals(Object obj) { if (obj == this) diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java index d4ccb06c..f3d5460d 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/wrappers/WrappedServerPing.java @@ -234,6 +234,24 @@ public class WrappedServerPing extends AbstractWrapper { VERSION_PROTOCOL.set(version, protocol); } + /** + * Retrieve a deep copy of the current wrapper object. + * @return The current object. + */ + public WrappedServerPing deepClone() { + WrappedServerPing copy = new WrappedServerPing(); + WrappedChatComponent motd = getMotD(); + + copy.setPlayers(getPlayers()); + copy.setFavicon(getFavicon()); + copy.setMotD(motd != null ? motd.deepClone() : null); + copy.setPlayersMaximum(getPlayersMaximum()); + copy.setPlayersOnline(getPlayersOnline()); + copy.setVersionName(getVersionName()); + copy.setVersionProtocol(getVersionProtocol()); + return copy; + } + /** * Represents a compressed favicon. * @author Kristian