getPacketHandlers();
+
+ /**
+ * Let the packet listeners process the given packet.
+ * @param packet - a packet to process.
+ * @param client - the client that sent the packet.
+ * @return The resulting packet event.
+ */
+ public abstract PacketEvent packetRecieved(PacketContainer packet, Player client);
+
+ /**
+ * Perform any necessary cleanup before unloading ProtocolLib.
+ */
+ public abstract void cleanupAll();
+}
\ No newline at end of file
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
new file mode 100644
index 00000000..c3720b77
--- /dev/null
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketInjectorBuilder.java
@@ -0,0 +1,109 @@
+package com.comphenix.protocol.injector.packet;
+
+import javax.annotation.Nonnull;
+
+import com.comphenix.protocol.ProtocolLibrary;
+import com.comphenix.protocol.ProtocolManager;
+import com.comphenix.protocol.error.ErrorReporter;
+import com.comphenix.protocol.injector.ListenerInvoker;
+import com.comphenix.protocol.injector.PacketFilterManager;
+import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
+import com.google.common.base.Preconditions;
+
+/**
+ * A builder responsible for creating incoming packet injectors.
+ *
+ * @author Kristian
+ */
+public class PacketInjectorBuilder {
+ protected PacketInjectorBuilder() {
+ // No need to construct this
+ }
+
+ /**
+ * Retrieve a new packet injector builder.
+ * @return Injector builder.
+ */
+ 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.
+ * @return This builder, for chaining.
+ */
+ public PacketInjectorBuilder reporter(@Nonnull ErrorReporter reporter) {
+ Preconditions.checkNotNull(reporter, "reporter cannot be NULL");
+ this.reporter = reporter;
+ return this;
+ }
+
+ /**
+ * The packet stream invoker.
+ * @param invoker - the invoker.
+ * @return This builder, for chaining.
+ */
+ public PacketInjectorBuilder invoker(@Nonnull ListenerInvoker invoker) {
+ Preconditions.checkNotNull(invoker, "invoker cannot be NULL");
+ this.invoker = invoker;
+ return this;
+ }
+
+ /**
+ * The packet stream invoker.
+ * @param invoker - the invoker.
+ * @return This builder, for chaining.
+ */
+ @Nonnull
+ public PacketInjectorBuilder playerInjection(@Nonnull PlayerInjectionHandler playerInjection) {
+ Preconditions.checkNotNull(playerInjection, "playerInjection cannot be NULL");
+ this.playerInjection = playerInjection;
+ return this;
+ }
+
+ /**
+ * Called before an object is created with this builder.
+ */
+ private void initializeDefaults() {
+ 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)
+ invoker = (PacketFilterManager) manager;
+ if (playerInjection == null)
+ throw new IllegalStateException("Player injection parameter must be initialized.");
+ }
+
+ /**
+ * Create a packet injector using the provided fields or the default values.
+ *
+ * Note that any non-null builder parameters must be set.
+ * @return The created injector.
+ * @throws IllegalAccessException If anything goes wrong in terms of reflection.
+ */
+ public PacketInjector buildInjector() throws IllegalAccessException {
+ initializeDefaults();
+ return new ProxyPacketInjector(classLoader, invoker, playerInjection, reporter);
+ }
+}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/MinecraftRegistry.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java
similarity index 97%
rename from ProtocolLib/src/main/java/com/comphenix/protocol/injector/MinecraftRegistry.java
rename to ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java
index 7ad014cb..73f4e587 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/MinecraftRegistry.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/PacketRegistry.java
@@ -15,7 +15,7 @@
* 02111-1307 USA
*/
-package com.comphenix.protocol.injector;
+package com.comphenix.protocol.injector.packet;
import java.lang.reflect.Field;
import java.util.HashMap;
@@ -33,12 +33,12 @@ import com.google.common.base.Objects;
import com.google.common.collect.ImmutableSet;
/**
- * Static registries in Minecraft.
+ * Static packet registry in Minecraft.
*
* @author Kristian
*/
@SuppressWarnings("rawtypes")
-class MinecraftRegistry {
+public class PacketRegistry {
// Fuzzy reflection
private static FuzzyReflection packetRegistry;
@@ -174,7 +174,7 @@ class MinecraftRegistry {
for (Map.Entry entry : getPacketToID().entrySet()) {
if (Objects.equal(entry.getValue(), packetID)) {
// Attempt to get the vanilla class here too
- if (!forceVanilla || entry.getKey().getName().startsWith("net.minecraft.server"))
+ if (!forceVanilla || MinecraftReflection.isMinecraftClass(entry.getKey()))
return removeEnhancer(entry.getKey(), forceVanilla);
}
}
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java
similarity index 84%
rename from ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketInjector.java
rename to ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java
index 0a83c8ec..bd3274a8 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketInjector.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ProxyPacketInjector.java
@@ -15,7 +15,7 @@
* 02111-1307 USA
*/
-package com.comphenix.protocol.injector;
+package com.comphenix.protocol.injector.packet;
import java.io.DataInputStream;
import java.lang.reflect.Field;
@@ -33,6 +33,7 @@ import net.sf.cglib.proxy.Enhancer;
import com.comphenix.protocol.error.ErrorReporter;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
+import com.comphenix.protocol.injector.ListenerInvoker;
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
import com.comphenix.protocol.reflect.FieldUtils;
import com.comphenix.protocol.reflect.FuzzyReflection;
@@ -43,7 +44,7 @@ import com.comphenix.protocol.utility.MinecraftReflection;
*
* @author Kristian
*/
-class PacketInjector {
+class ProxyPacketInjector implements PacketInjector {
// The "put" method that associates a packet ID with a packet class
private static Method putMethod;
@@ -64,7 +65,7 @@ class PacketInjector {
// Class loader
private ClassLoader classLoader;
- public PacketInjector(ClassLoader classLoader, ListenerInvoker manager,
+ public ProxyPacketInjector(ClassLoader classLoader, ListenerInvoker manager,
PlayerInjectionHandler playerInjection, ErrorReporter reporter) throws IllegalAccessException {
this.classLoader = classLoader;
@@ -80,6 +81,7 @@ class PacketInjector {
* @param id - the id of the packet.
* @param packet - packet to uncancel.
*/
+ @Override
public void undoCancel(Integer id, Object packet) {
ReadPacketModifier modifier = readModifier.get(id);
@@ -93,7 +95,7 @@ class PacketInjector {
if (intHashMap == null) {
// We're looking for the first static field with a Minecraft-object. This should be a IntHashMap.
Field intHashMapField = FuzzyReflection.fromClass(MinecraftReflection.getPacketClass(), true).
- getFieldByType(MinecraftReflection.MINECRAFT_OBJECT);
+ getFieldByType(MinecraftReflection.getMinecraftObjectRegex());
try {
intHashMap = FieldUtils.readField(intHashMapField, (Object) null, true);
@@ -106,6 +108,7 @@ class PacketInjector {
}
}
+ @Override
@SuppressWarnings("rawtypes")
public boolean addPacketHandler(int packetID) {
if (hasPacketHandler(packetID))
@@ -118,17 +121,17 @@ class PacketInjector {
// * Object removeObject(int par1)
// So, we'll use the classMapToInt registry instead.
- Map overwritten = MinecraftRegistry.getOverwrittenPackets();
- Map previous = MinecraftRegistry.getPreviousPackets();
- Map registry = MinecraftRegistry.getPacketToID();
- Class old = MinecraftRegistry.getPacketClassFromID(packetID);
+ Map overwritten = PacketRegistry.getOverwrittenPackets();
+ Map previous = PacketRegistry.getPreviousPackets();
+ Map registry = PacketRegistry.getPacketToID();
+ Class old = PacketRegistry.getPacketClassFromID(packetID);
// If this packet is not known
if (old == null) {
throw new IllegalStateException("Packet ID " + packetID + " is not a valid packet ID in this version.");
}
// Check for previous injections
- if (!old.getName().startsWith("net.minecraft.")) {
+ if (!MinecraftReflection.isMinecraftClass(old)) {
throw new IllegalStateException("Packet " + packetID + " has already been injected.");
}
@@ -162,19 +165,20 @@ class PacketInjector {
}
}
+ @Override
@SuppressWarnings("rawtypes")
public boolean removePacketHandler(int packetID) {
if (!hasPacketHandler(packetID))
return false;
- Map registry = MinecraftRegistry.getPacketToID();
- Map previous = MinecraftRegistry.getPreviousPackets();
- Map overwritten = MinecraftRegistry.getOverwrittenPackets();
+ Map registry = PacketRegistry.getPacketToID();
+ Map previous = PacketRegistry.getPreviousPackets();
+ Map overwritten = PacketRegistry.getOverwrittenPackets();
// Use the old class definition
try {
Class old = previous.get(packetID);
- Class proxy = MinecraftRegistry.getPacketClassFromID(packetID);
+ Class proxy = PacketRegistry.getPacketClassFromID(packetID);
putMethod.invoke(intHashMap, packetID, old);
previous.remove(packetID);
@@ -193,16 +197,18 @@ class PacketInjector {
}
}
+ @Override
public boolean hasPacketHandler(int packetID) {
- return MinecraftRegistry.getPreviousPackets().containsKey(packetID);
+ return PacketRegistry.getPreviousPackets().containsKey(packetID);
}
+ @Override
public Set getPacketHandlers() {
- return MinecraftRegistry.getPreviousPackets().keySet();
+ return PacketRegistry.getPreviousPackets().keySet();
}
// Called from the ReadPacketModified monitor
- PacketEvent packetRecieved(PacketContainer packet, DataInputStream input) {
+ public PacketEvent packetRecieved(PacketContainer packet, DataInputStream input) {
try {
Player client = playerInjection.getPlayerByConnection(input);
@@ -225,18 +231,19 @@ class PacketInjector {
* @param client - the client that sent the packet.
* @return The resulting packet event.
*/
+ @Override
public PacketEvent packetRecieved(PacketContainer packet, Player client) {
-
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, client);
manager.invokePacketRecieving(event);
return event;
}
+ @Override
@SuppressWarnings("rawtypes")
public synchronized void cleanupAll() {
- Map overwritten = MinecraftRegistry.getOverwrittenPackets();
- Map previous = MinecraftRegistry.getPreviousPackets();
+ Map overwritten = PacketRegistry.getOverwrittenPackets();
+ Map previous = PacketRegistry.getPreviousPackets();
// Remove every packet handler
for (Integer id : previous.keySet().toArray(new Integer[0])) {
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/ReadPacketModifier.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ReadPacketModifier.java
similarity index 96%
rename from ProtocolLib/src/main/java/com/comphenix/protocol/injector/ReadPacketModifier.java
rename to ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ReadPacketModifier.java
index ceb702c6..00eacf9c 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/ReadPacketModifier.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/packet/ReadPacketModifier.java
@@ -15,7 +15,7 @@
* 02111-1307 USA
*/
-package com.comphenix.protocol.injector;
+package com.comphenix.protocol.injector.packet;
import java.io.DataInputStream;
import java.lang.reflect.Method;
@@ -41,7 +41,7 @@ class ReadPacketModifier implements MethodInterceptor {
private static final Object CANCEL_MARKER = new Object();
// Common for all packets of the same type
- private PacketInjector packetInjector;
+ private ProxyPacketInjector packetInjector;
private int packetID;
// Report errors
@@ -50,7 +50,7 @@ class ReadPacketModifier implements MethodInterceptor {
// Whether or not a packet has been cancelled
private static Map