Merge remote-tracking branch 'origin/master'

This commit is contained in:
Kristian S. Stangeland 2013-04-02 14:30:14 +02:00
commit 5720994a31
8 changed files with 140 additions and 4 deletions

View File

@ -696,6 +696,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
try {
// Let's clean up the other injection first.
playerInjection.uninjectPlayer(event.getPlayer().getAddress());
playerInjection.updatePlayer(event.getPlayer());
} catch (Exception e) {
reporter.reportDetailed(PacketFilterManager.this, "Unable to uninject net handler for player.", e, event);
}

View File

@ -129,6 +129,12 @@ public interface PlayerInjectionHandler {
public abstract void recieveClientPacket(Player player, Object mcPacket)
throws IllegalAccessException, InvocationTargetException;
/**
* Ensure that packet readers are informed of this player reference.
* @param player - the player to update.
*/
public abstract void updatePlayer(Player player);
/**
* Determine if the given listeners are valid.
* @param version - the current Minecraft version, or NULL if unknown.

View File

@ -642,10 +642,7 @@ abstract class PlayerInjector implements SocketInjector {
// Do nothing
}
/**
* Set the real Bukkit player that we will use.
* @param updatedPlayer - the real Bukkit player.
*/
@Override
public void setUpdatedPlayer(Player updatedPlayer) {
this.updatedPlayer = updatedPlayer;
}

View File

@ -42,6 +42,7 @@ import com.comphenix.protocol.injector.ListenerInvoker;
import com.comphenix.protocol.injector.PlayerLoggedOutException;
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
import com.comphenix.protocol.injector.server.AbstractInputStreamLookup;
import com.comphenix.protocol.injector.server.BukkitSocketInjector;
import com.comphenix.protocol.injector.server.InputStreamLookupBuilder;
import com.comphenix.protocol.injector.server.SocketInjector;
import com.comphenix.protocol.utility.MinecraftReflection;
@ -416,6 +417,18 @@ class ProxyPlayerInjectionHandler implements PlayerInjectionHandler {
}
}
@Override
public void updatePlayer(Player player) {
SocketInjector injector = inputStreamLookup.peekSocketInjector(player.getAddress());
if (injector != null) {
injector.setUpdatedPlayer(player);
} else {
inputStreamLookup.setSocketInjector(player.getAddress(),
new BukkitSocketInjector(player));
}
}
/**
* Unregisters the given player.
* @param player - player to unregister.

View File

@ -0,0 +1,103 @@
package com.comphenix.protocol.injector.server;
import java.lang.reflect.InvocationTargetException;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.bukkit.entity.Player;
public class BukkitSocketInjector implements SocketInjector {
/**
* Represents a single send packet command.
* @author Kristian
*/
static class SendPacketCommand {
private final Object packet;
private final boolean filtered;
public SendPacketCommand(Object packet, boolean filtered) {
this.packet = packet;
this.filtered = filtered;
}
public Object getPacket() {
return packet;
}
public boolean isFiltered() {
return filtered;
}
}
private Player player;
// Queue of server packets
private List<SendPacketCommand> syncronizedQueue = Collections.synchronizedList(new ArrayList<SendPacketCommand>());
/**
* Represents a temporary socket injector.
* @param temporaryPlayer -
*/
public BukkitSocketInjector(Player player) {
if (player == null)
throw new IllegalArgumentException("Player cannot be NULL.");
this.player = player;
}
@Override
public Socket getSocket() throws IllegalAccessException {
throw new UnsupportedOperationException("Cannot get socket from Bukkit player.");
}
@Override
public SocketAddress getAddress() throws IllegalAccessException {
return player.getAddress();
}
@Override
public void disconnect(String message) throws InvocationTargetException {
player.kickPlayer(message);
}
@Override
public void sendServerPacket(Object packet, boolean filtered)
throws InvocationTargetException {
SendPacketCommand command = new SendPacketCommand(packet, filtered);
// Queue until we can find something better
syncronizedQueue.add(command);
}
@Override
public Player getPlayer() {
return player;
}
@Override
public Player getUpdatedPlayer() {
return player;
}
@Override
public void transferState(SocketInjector delegate) {
// Transmit all queued packets to a different injector.
try {
synchronized(syncronizedQueue) {
for (SendPacketCommand command : syncronizedQueue) {
delegate.sendServerPacket(command.getPacket(), command.isFiltered());
}
syncronizedQueue.clear();
}
} catch (InvocationTargetException e) {
throw new RuntimeException("Unable to transmit packets to " + delegate + " from old injector.", e);
}
}
@Override
public void setUpdatedPlayer(Player updatedPlayer) {
this.player = updatedPlayer;
}
}

View File

@ -58,4 +58,10 @@ public interface SocketInjector {
* @param delegate - the new injector.
*/
public abstract void transferState(SocketInjector delegate);
/**
* Set the real Bukkit player that we will use.
* @param updatedPlayer - the real Bukkit player.
*/
public abstract void setUpdatedPlayer(Player updatedPlayer);
}

View File

@ -119,4 +119,9 @@ class DummyPlayerHandler implements PlayerInjectionHandler {
public void postWorldLoaded() {
// Do nothing
}
@Override
public void updatePlayer(Player player) {
// Do nothing
}
}

View File

@ -198,6 +198,11 @@ public class BackgroundCompiler {
synchronized (listenerLock) {
list = listeners.get(key);
// Prevent ConcurrentModificationExceptions
if (list != null) {
list = Lists.newArrayList(list);
}
}
// Only execute the listeners if there is a list