Archiviert
13
0

Experimental: Correct a possible race condition with Spigot.

Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-09-28 17:22:06 +02:00
Ursprung 1b1f36c5d6
Commit 75f6cff5a5
2 geänderte Dateien mit 38 neuen und 14 gelöschten Zeilen

Datei anzeigen

@ -262,6 +262,14 @@ public abstract class PlayerInjector implements SocketInjector {
return networkManagerRef.getValue(); return networkManagerRef.getValue();
} }
/**
* Retrieve the current server handler (PlayerConnection).
* @return Current server handler.
*/
public Object getServerHandler() {
return serverHandlerRef.getValue();
}
/** /**
* Set the current network manager. * Set the current network manager.
* @param value - new network manager. * @param value - new network manager.

Datei anzeigen

@ -16,6 +16,7 @@ import org.bukkit.plugin.Plugin;
import net.sf.cglib.proxy.Callback; import net.sf.cglib.proxy.Callback;
import net.sf.cglib.proxy.CallbackFilter; import net.sf.cglib.proxy.CallbackFilter;
import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.Factory;
import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import net.sf.cglib.proxy.MethodProxy;
import net.sf.cglib.proxy.NoOp; import net.sf.cglib.proxy.NoOp;
@ -293,10 +294,32 @@ public class SpigotPacketInjector implements SpigotPacketListener {
/** /**
* Retrieve the currently registered injector for the given player. * Retrieve the currently registered injector for the given player.
* @param player - injected player. * @param player - injected player.
* @param createNew - whether or not to create a new injector if the current is missing.
* @return The injector. * @return The injector.
*/ */
NetworkObjectInjector getInjector(Player player) { NetworkObjectInjector getInjector(Player player, boolean createNew) {
return playerInjector.get(player); NetworkObjectInjector injector = playerInjector.get(player);
if (injector == null && createNew) {
// Check for temporary players ..
if ((player instanceof Factory))
throw new IllegalArgumentException("Cannot inject tempoary player " + player);
try {
NetworkObjectInjector created = new NetworkObjectInjector(
classLoader, filterImpossibleWarnings(reporter), null, invoker, null);
created.initializePlayer(player);
if (created.getNetworkManager() == null)
throw new PlayerLoggedOutException("Player " + player + " has logged out.");
injector = saveInjector(created.getNetworkManager(), created);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create dummy injector.", e);
}
}
return injector;
} }
/** /**
@ -490,7 +513,7 @@ public class SpigotPacketInjector implements SpigotPacketListener {
* @param player - the player to uninject. * @param player - the player to uninject.
*/ */
void uninjectPlayer(Player player) { void uninjectPlayer(Player player) {
final NetworkObjectInjector injector = getInjector(player); final NetworkObjectInjector injector = getInjector(player, false);
if (player != null && injector != null) { if (player != null && injector != null) {
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@ -513,7 +536,7 @@ public class SpigotPacketInjector implements SpigotPacketListener {
* @throws InvocationTargetException If anything went wrong. * @throws InvocationTargetException If anything went wrong.
*/ */
void sendServerPacket(Player reciever, PacketContainer packet, NetworkMarker marker, boolean filters) throws InvocationTargetException { void sendServerPacket(Player reciever, PacketContainer packet, NetworkMarker marker, boolean filters) throws InvocationTargetException {
NetworkObjectInjector networkObject = getInjector(reciever); NetworkObjectInjector networkObject = getInjector(reciever, true);
// If TRUE, process this packet like any other // If TRUE, process this packet like any other
if (filters) if (filters)
@ -521,10 +544,7 @@ public class SpigotPacketInjector implements SpigotPacketListener {
else else
ignoredPackets.add(packet.getHandle()); ignoredPackets.add(packet.getHandle());
if (networkObject != null) networkObject.sendServerPacket(packet.getHandle(), marker, filters);
networkObject.sendServerPacket(packet.getHandle(), marker, filters);
else
throw new PlayerLoggedOutException("Player " + reciever + " has logged out");
} }
/** /**
@ -535,15 +555,11 @@ public class SpigotPacketInjector implements SpigotPacketListener {
* @throws InvocationTargetException Minecraft threw an exception. * @throws InvocationTargetException Minecraft threw an exception.
*/ */
void processPacket(Player player, Object mcPacket) throws IllegalAccessException, InvocationTargetException { void processPacket(Player player, Object mcPacket) throws IllegalAccessException, InvocationTargetException {
NetworkObjectInjector networkObject = getInjector(player); NetworkObjectInjector networkObject = getInjector(player, true);
// We will always ignore this packet // We will always ignore this packet
ignoredPackets.add(mcPacket); ignoredPackets.add(mcPacket);
networkObject.processPacket(mcPacket);
if (networkObject != null)
networkObject.processPacket(mcPacket);
else
throw new PlayerLoggedOutException("Player " + player + " has logged out");
} }
/** /**