diff --git a/ProtocolLib/dependency-reduced-pom.xml b/ProtocolLib/dependency-reduced-pom.xml
index a59d86f0..10c612ab 100644
--- a/ProtocolLib/dependency-reduced-pom.xml
+++ b/ProtocolLib/dependency-reduced-pom.xml
@@ -73,15 +73,6 @@
1.6
-
- org.codehaus.mojo
- findbugs-maven-plugin
- 2.5.2
-
- High
- Default
-
-
@@ -156,6 +147,19 @@
+
+
+
+ org.codehaus.mojo
+ findbugs-maven-plugin
+ 2.5.2
+
+ High
+ Default
+
+
+
+
comphenix-releases
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java
index e30fe521..d36cebe1 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/ProtocolLibrary.java
@@ -88,7 +88,7 @@ public class ProtocolLibrary extends JavaPlugin {
// Player login and logout events
protocolManager.registerEvents(manager, this);
-
+
// Worker that ensures that async packets are eventually sent
createAsyncTask(server);
//toggleDebugListener();
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 2bd87891..2aef7f5b 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java
@@ -104,9 +104,9 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
// Packet injection
private PacketInjector packetInjector;
- // Player injection
+ // Different injection types per game phase
private PlayerInjectionHandler playerInjection;
-
+
// The two listener containers
private SortedPacketListenerList recievedListeners = new SortedPacketListenerList();
private SortedPacketListenerList sendingListeners = new SortedPacketListenerList();
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 e5140ab4..d9af4827 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
@@ -98,7 +98,7 @@ class NetworkObjectInjector extends PlayerInjector {
public void injectManager() {
if (networkManager != null) {
- final Class> networkInterface = networkManagerField.getType();
+ final Class> networkInterface = networkManagerRef.getField().getType();
final Object networkDelegate = networkManagerRef.getOldValue();
if (!networkInterface.isInterface()) {
diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java
index 707bef86..23b82e2b 100644
--- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java
+++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/PlayerInjectionHandler.java
@@ -23,7 +23,6 @@ import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.Collections;
-import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@@ -65,10 +64,11 @@ public class PlayerInjectionHandler {
// Player injection
private Map addressLookup = Maps.newConcurrentMap();
private Map dataInputLookup = Maps.newConcurrentMap();
- private Map playerInjection = new HashMap();
+ private Map playerInjection = Maps.newConcurrentMap();
- // Player injection type
- private PlayerInjectHooks playerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
+ // Player injection types
+ private volatile PlayerInjectHooks loginPlayerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
+ private volatile PlayerInjectHooks playingPlayerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
// Error logger
private Logger logger;
@@ -105,9 +105,45 @@ public class PlayerInjectionHandler {
* @return Injection method for reading server packets.
*/
public PlayerInjectHooks getPlayerHook() {
- return playerHook;
+ return getPlayerHook(GamePhase.PLAYING);
+ }
+
+ /**
+ * Retrieves how the server packets are read.
+ * @param phase - the current game phase.
+ * @return Injection method for reading server packets.
+ */
+ public PlayerInjectHooks getPlayerHook(GamePhase phase) {
+ switch (phase) {
+ case LOGIN:
+ return loginPlayerHook;
+ case PLAYING:
+ return playingPlayerHook;
+ default:
+ throw new IllegalArgumentException("Cannot retrieve injection hook for both phases at the same time.");
+ }
}
+ /**
+ * Sets how the server packets are read.
+ * @param playerHook - the new injection method for reading server packets.
+ */
+ public void setPlayerHook(PlayerInjectHooks playerHook) {
+ setPlayerHook(GamePhase.PLAYING, playerHook);
+ }
+
+ /**
+ * Sets how the server packets are read.
+ * @param phase - the current game phase.
+ * @param playerHook - the new injection method for reading server packets.
+ */
+ public void setPlayerHook(GamePhase phase, PlayerInjectHooks playerHook) {
+ if (phase.hasLogin())
+ loginPlayerHook = playerHook;
+ if (phase.hasPlaying())
+ playingPlayerHook = playerHook;
+ }
+
/**
* Add an underlying packet handler of the given ID.
* @param packetID - packet ID to register.
@@ -123,15 +159,7 @@ public class PlayerInjectionHandler {
public void removePacketHandler(int packetID) {
sendingFilters.remove(packetID);
}
-
- /**
- * Sets how the server packets are read.
- * @param playerHook - the new injection method for reading server packets.
- */
- public void setPlayerHook(PlayerInjectHooks playerHook) {
- this.playerHook = playerHook;
- }
-
+
/**
* Used to construct a player hook.
* @param player - the player to hook.
@@ -214,9 +242,17 @@ public class PlayerInjectionHandler {
* @return The resulting player injector, or NULL if the injection failed.
*/
PlayerInjector injectPlayer(Player player, Object injectionPoint, GamePhase phase) {
+ // Unfortunately, due to NetLoginHandler, multiple threads may potentially call this method.
+ synchronized (player) {
+ return injectPlayerInternal(player, injectionPoint, phase);
+ }
+ }
+
+ // Unsafe variant of the above
+ private PlayerInjector injectPlayerInternal(Player player, Object injectionPoint, GamePhase phase) {
PlayerInjector injector = playerInjection.get(player);
- PlayerInjectHooks tempHook = playerHook;
+ PlayerInjectHooks tempHook = getPlayerHook(phase);
PlayerInjectHooks permanentHook = tempHook;
// The given player object may be fake, so be careful!
@@ -299,8 +335,8 @@ public class PlayerInjectionHandler {
// Update values
if (injector != null)
lastSuccessfulHook = injector;
- if (permanentHook != playerHook)
- setPlayerHook(tempHook);
+ if (permanentHook != getPlayerHook(phase))
+ setPlayerHook(phase, tempHook);
// Save last injector
playerInjection.put(player, injector);
@@ -326,14 +362,13 @@ public class PlayerInjectionHandler {
public void uninjectPlayer(Player player) {
if (!hasClosed && player != null) {
- PlayerInjector injector = playerInjection.get(player);
-
+ PlayerInjector injector = playerInjection.remove(player);
+
if (injector != null) {
DataInputStream input = injector.getInputStream(true);
InetSocketAddress address = player.getAddress();
injector.cleanupAll();
- playerInjection.remove(player);
dataInputLookup.remove(input);
if (address != null)