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 e373126d..c5b8c0ac 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/PacketFilterManager.java @@ -56,6 +56,7 @@ import com.comphenix.protocol.injector.packet.PacketInjectorBuilder; import com.comphenix.protocol.injector.packet.PacketRegistry; import com.comphenix.protocol.injector.player.PlayerInjectionHandler; import com.comphenix.protocol.injector.player.PlayerInjectorBuilder; +import com.comphenix.protocol.injector.player.PlayerInjectionHandler.ConflictStrategy; import com.comphenix.protocol.injector.spigot.SpigotPacketInjector; import com.comphenix.protocol.reflect.FieldAccessException; import com.comphenix.protocol.reflect.FuzzyReflection; @@ -620,7 +621,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok */ public void initializePlayers(Player[] players) { for (Player player : players) - playerInjection.injectPlayer(player); + playerInjection.injectPlayer(player, ConflictStrategy.OVERRIDE); } /** @@ -680,7 +681,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok private void onPlayerJoin(PlayerJoinEvent event) { try { // This call will be ignored if no listeners are registered - playerInjection.injectPlayer(event.getPlayer()); + playerInjection.injectPlayer(event.getPlayer(), ConflictStrategy.OVERRIDE); } catch (Exception e) { reporter.reportDetailed(PacketFilterManager.this, "Unable to inject player.", e, event); } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java index fc5052d6..0fc27113 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/player/NetLoginInjector.java @@ -24,6 +24,7 @@ import org.bukkit.entity.Player; import com.comphenix.protocol.error.ErrorReporter; import com.comphenix.protocol.injector.GamePhase; +import com.comphenix.protocol.injector.player.PlayerInjectionHandler.ConflictStrategy; import com.comphenix.protocol.injector.server.TemporaryPlayerFactory; import com.comphenix.protocol.utility.MinecraftReflection; import com.google.common.collect.Maps; @@ -64,7 +65,9 @@ class NetLoginInjector { return inserting; Player temporary = playerFactory.createTemporaryPlayer(server); - PlayerInjector injector = injectionHandler.injectPlayer(temporary, inserting, GamePhase.LOGIN); + // Note that we bail out if there's an existing player injector + PlayerInjector injector = injectionHandler.injectPlayer( + temporary, inserting, ConflictStrategy.BAIL_OUT, GamePhase.LOGIN); if (injector != null) { // Update injector as well 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 976bc341..8c59c15a 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 @@ -12,6 +12,23 @@ import com.comphenix.protocol.injector.GamePhase; import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks; public interface PlayerInjectionHandler { + /** + * How to handle a previously existing player injection. + * + * @author Kristian + */ + public enum ConflictStrategy { + /** + * Override it. + */ + OVERRIDE, + + /** + * Immediately exit. + */ + BAIL_OUT; + } + /** * Retrieves how the server packets are read. * @return Injection method for reading server packets. @@ -64,8 +81,9 @@ public interface PlayerInjectionHandler { *

* This call will be ignored if there's no listener that can receive the given events. * @param player - player to hook. + * @param strategy - how to handle injection conflicts. */ - public abstract void injectPlayer(Player player); + public abstract void injectPlayer(Player player, ConflictStrategy strategy); /** * Invoke special routines for handling disconnect before a player is uninjected. 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 1d95439b..35020261 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 @@ -253,12 +253,13 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler { *

* This call will be ignored if there's no listener that can receive the given events. * @param player - player to hook. + * @param strategy - how to handle previous player injections. */ @Override - public void injectPlayer(Player player) { + public void injectPlayer(Player player, ConflictStrategy strategy) { // Inject using the player instance itself if (isInjectionNecessary(GamePhase.PLAYING)) { - injectPlayer(player, player, GamePhase.PLAYING); + injectPlayer(player, player, strategy, GamePhase.PLAYING); } } @@ -281,7 +282,7 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler { * @param phase - the current game phase. * @return The resulting player injector, or NULL if the injection failed. */ - PlayerInjector injectPlayer(Player player, Object injectionPoint, GamePhase phase) { + PlayerInjector injectPlayer(Player player, Object injectionPoint, ConflictStrategy stategy, GamePhase phase) { if (player == null) throw new IllegalArgumentException("Player cannot be NULL."); if (injectionPoint == null) @@ -291,12 +292,12 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler { // Unfortunately, due to NetLoginHandler, multiple threads may potentially call this method. synchronized (player) { - return injectPlayerInternal(player, injectionPoint, phase); + return injectPlayerInternal(player, injectionPoint, stategy, phase); } } // Unsafe variant of the above - private PlayerInjector injectPlayerInternal(Player player, Object injectionPoint, GamePhase phase) { + private PlayerInjector injectPlayerInternal(Player player, Object injectionPoint, ConflictStrategy stategy, GamePhase phase) { PlayerInjector injector = playerInjection.get(player); PlayerInjectHooks tempHook = getPlayerHook(phase); PlayerInjectHooks permanentHook = tempHook; @@ -328,9 +329,14 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler { // Close any previously associated hooks before we proceed if (previous != null && !(player instanceof Factory)) { - uninjectPlayer(previous.getPlayer(), true); + switch (stategy) { + case OVERRIDE: + uninjectPlayer(previous.getPlayer(), true); + break; + case BAIL_OUT: + return null; + } } - injector.injectManager(); // Save injector diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/DummyPlayerHandler.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/DummyPlayerHandler.java index 73a1c5e2..dc6f5e9d 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/DummyPlayerHandler.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/spigot/DummyPlayerHandler.java @@ -79,7 +79,8 @@ class DummyPlayerHandler implements PlayerInjectionHandler { } @Override - public void injectPlayer(Player player) { + public void injectPlayer(Player player, ConflictStrategy strategy) { + // We don't care about strategy injector.injectPlayer(player); }