Update the player instance on login (LOWEST), not HIGHEST.
Should ensure that packet listeners recieve the most up-to-date player instance, regardless of whether or not the main thread is blocked in the player listener. No more temporary players.
Dieser Commit ist enthalten in:
Ursprung
b3322b35c1
Commit
27da638a91
@ -696,6 +696,7 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
|
|||||||
try {
|
try {
|
||||||
// Let's clean up the other injection first.
|
// Let's clean up the other injection first.
|
||||||
playerInjection.uninjectPlayer(event.getPlayer().getAddress());
|
playerInjection.uninjectPlayer(event.getPlayer().getAddress());
|
||||||
|
playerInjection.updatePlayer(event.getPlayer());
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
reporter.reportDetailed(PacketFilterManager.this, "Unable to uninject net handler for player.", e, event);
|
reporter.reportDetailed(PacketFilterManager.this, "Unable to uninject net handler for player.", e, event);
|
||||||
}
|
}
|
||||||
|
@ -129,6 +129,12 @@ public interface PlayerInjectionHandler {
|
|||||||
public abstract void recieveClientPacket(Player player, Object mcPacket)
|
public abstract void recieveClientPacket(Player player, Object mcPacket)
|
||||||
throws IllegalAccessException, InvocationTargetException;
|
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.
|
* Determine if the given listeners are valid.
|
||||||
* @param version - the current Minecraft version, or NULL if unknown.
|
* @param version - the current Minecraft version, or NULL if unknown.
|
||||||
|
@ -642,10 +642,7 @@ abstract class PlayerInjector implements SocketInjector {
|
|||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Set the real Bukkit player that we will use.
|
|
||||||
* @param updatedPlayer - the real Bukkit player.
|
|
||||||
*/
|
|
||||||
public void setUpdatedPlayer(Player updatedPlayer) {
|
public void setUpdatedPlayer(Player updatedPlayer) {
|
||||||
this.updatedPlayer = updatedPlayer;
|
this.updatedPlayer = updatedPlayer;
|
||||||
}
|
}
|
||||||
|
@ -42,6 +42,7 @@ import com.comphenix.protocol.injector.ListenerInvoker;
|
|||||||
import com.comphenix.protocol.injector.PlayerLoggedOutException;
|
import com.comphenix.protocol.injector.PlayerLoggedOutException;
|
||||||
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
|
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
|
||||||
import com.comphenix.protocol.injector.server.AbstractInputStreamLookup;
|
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.InputStreamLookupBuilder;
|
||||||
import com.comphenix.protocol.injector.server.SocketInjector;
|
import com.comphenix.protocol.injector.server.SocketInjector;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
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.
|
* Unregisters the given player.
|
||||||
* @param player - player to unregister.
|
* @param player - player to unregister.
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
@ -58,4 +58,10 @@ public interface SocketInjector {
|
|||||||
* @param delegate - the new injector.
|
* @param delegate - the new injector.
|
||||||
*/
|
*/
|
||||||
public abstract void transferState(SocketInjector delegate);
|
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);
|
||||||
}
|
}
|
@ -119,4 +119,9 @@ class DummyPlayerHandler implements PlayerInjectionHandler {
|
|||||||
public void postWorldLoaded() {
|
public void postWorldLoaded() {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updatePlayer(Player player) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren