Retrieve the updated player entity as fast as we can.

This commit is contained in:
Kristian S. Stangeland 2012-10-16 16:42:27 +02:00
parent 09348343dd
commit 94efb38324
5 changed files with 58 additions and 7 deletions

View File

@ -87,6 +87,8 @@ public class ProtocolLibrary extends JavaPlugin {
// Worker that ensures that async packets are eventually sent
createAsyncTask(server);
addDebugListener();
// Try to enable statistics
try {
statistisc = new Statistics(this);
@ -97,6 +99,20 @@ public class ProtocolLibrary extends JavaPlugin {
}
}
private void addDebugListener() {
// DEBUG DEBUG
protocolManager.addPacketListener(new MonitorAdapter(this, ConnectionSide.BOTH, logger) {
@Override
public void onPacketReceiving(PacketEvent event) {
System.out.println("RECEIVING " + event.getPacketID() + " from " + event.getPlayer().getName());
};
@Override
public void onPacketSending(PacketEvent event) {
System.out.println("SENDING " + event.getPacketID() + " to " + event.getPlayer().getName());
}
});
}
private void createAsyncTask(Server server) {
try {
if (asyncPacketTask >= 0)

View File

@ -47,6 +47,7 @@ class NetLoginInjector {
try {
Player fakePlayer = tempPlayerFactory.createTemporaryPlayer(server);
PlayerInjector injector = injectionHandler.injectPlayer(fakePlayer, inserting, GamePhase.LOGIN);
injector.updateOnLogin = true;
// Associate the injector too
InjectContainer container = (InjectContainer) fakePlayer;

View File

@ -240,9 +240,6 @@ public class PlayerInjectionHandler {
if (previous != null) {
uninjectPlayer(previous.getPlayer());
// Update the player object too
previous.setPlayer(player);
// Remove the "hooked" network manager in our instance as well
if (previous instanceof NetworkObjectInjector) {
injector.setNetworkManager(previous.getNetworkManager(), true);

View File

@ -34,6 +34,7 @@ import net.sf.cglib.proxy.Factory;
import org.bukkit.craftbukkit.entity.CraftPlayer;
import org.bukkit.entity.Player;
import com.comphenix.protocol.Packets;
import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.events.PacketListener;
@ -63,6 +64,8 @@ abstract class PlayerInjector {
protected static Field netHandlerField;
protected static Field socketField;
private static Field entityPlayerField;
// Whether or not we're using a proxy type
private static boolean hasProxyType;
@ -101,6 +104,10 @@ abstract class PlayerInjector {
// Scheduled action on the next packet event
protected Runnable scheduledAction;
// Whether or not to update the current player on the first Packet1Login
boolean updateOnLogin;
Player updatedPlayer;
public PlayerInjector(Logger logger, Player player, ListenerInvoker invoker) throws IllegalAccessException {
this.logger = logger;
this.player = player;
@ -362,6 +369,18 @@ abstract class PlayerInjector {
return netHandler;
}
/**
* Retrieve the stored entity player from a given NetHandler.
* @param netHandler - the nethandler to retrieve it from.
* @return The stored entity player.
* @throws IllegalAccessException If the reflection failed.
*/
private EntityPlayer getEntityPlayer(Object netHandler) throws IllegalAccessException {
if (entityPlayerField == null)
entityPlayerField = FuzzyReflection.fromObject(netHandler).getFieldByType(".*EntityPlayer");
return (EntityPlayer) FieldUtils.readField(entityPlayerField, netHandler);
}
/**
* Processes the given packet as if it was transmitted by the current player.
* @param packet - packet to process.
@ -438,18 +457,33 @@ abstract class PlayerInjector {
public Packet handlePacketSending(Packet packet) {
// Get the packet ID too
Integer id = invoker.getPacketID(packet);
Player currentPlayer = player;
// Handle a single scheduled action
// Hack #1: Handle a single scheduled action
if (scheduledAction != null) {
scheduledAction.run();
scheduledAction = null;
}
// Hack #2
if (updateOnLogin) {
if (id == Packets.Server.LOGIN) {
try {
updatedPlayer = getEntityPlayer(getNetHandler()).getBukkitEntity();
} catch (IllegalAccessException e) {
logger.log(Level.WARNING, "Cannot update player in PlayerEvent.", e);
}
}
// This will only occur in the NetLoginHandler injection
if (updatedPlayer != null)
currentPlayer = updatedPlayer;
}
// Make sure we're listening
if (id != null && hasListener(id)) {
// A packet has been sent guys!
PacketContainer container = new PacketContainer(id, packet);
PacketEvent event = PacketEvent.fromServer(invoker, container, player);
PacketEvent event = PacketEvent.fromServer(invoker, container, currentPlayer);
invoker.invokePacketSending(event);
// Cancelling is pretty simple. Just ignore the packet.

View File

@ -154,6 +154,9 @@ class ReplacedArrayList<TKey> extends ArrayList<TKey> {
@Override
public void clear() {
for (TKey element : delegate())
onRemoved(element);
delegate().clear();
}