Archiviert
13
0

Update the player instance during PlayerLoginEvent as well.

This ensures that we at least have an OfflinePlayer when certain
packets are intercepted, instead of the TemporaryPlayer created 
by ProtocolLib.
Dieser Commit ist enthalten in:
Kristian S. Stangeland 2013-12-17 11:07:44 +01:00
Ursprung 936e0f0e82
Commit 9d972b90ac
3 geänderte Dateien mit 79 neuen und 7 gelöschten Zeilen

Datei anzeigen

@ -42,6 +42,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.event.server.PluginDisableEvent; import org.bukkit.event.server.PluginDisableEvent;
import org.bukkit.plugin.Plugin; import org.bukkit.plugin.Plugin;
@ -921,10 +922,13 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
try { try {
manager.registerEvents(new Listener() { manager.registerEvents(new Listener() {
@EventHandler(priority = EventPriority.LOWEST) @EventHandler(priority = EventPriority.LOWEST)
public void onPlayerLogin(PlayerLoginEvent event) {
PacketFilterManager.this.onPlayerLogin(event);
}
@EventHandler(priority = EventPriority.LOWEST)
public void onPrePlayerJoin(PlayerJoinEvent event) { public void onPrePlayerJoin(PlayerJoinEvent event) {
PacketFilterManager.this.onPrePlayerJoin(event); PacketFilterManager.this.onPrePlayerJoin(event);
} }
@EventHandler(priority = EventPriority.MONITOR) @EventHandler(priority = EventPriority.MONITOR)
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
PacketFilterManager.this.onPlayerJoin(event); PacketFilterManager.this.onPlayerJoin(event);
@ -946,6 +950,11 @@ public final class PacketFilterManager implements ProtocolManager, ListenerInvok
} }
} }
private void onPlayerLogin(PlayerLoginEvent event) {
System.out.println("Address: " + event.getAddress());
playerInjection.updatePlayer(event.getPlayer());
}
private void onPrePlayerJoin(PlayerJoinEvent event) { private void onPrePlayerJoin(PlayerJoinEvent event) {
playerInjection.updatePlayer(event.getPlayer()); playerInjection.updatePlayer(event.getPlayer());
} }

Datei anzeigen

@ -10,6 +10,7 @@ import java.util.NoSuchElementException;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentMap;
import net.minecraft.util.com.mojang.authlib.GameProfile;
import net.minecraft.util.io.netty.buffer.ByteBuf; import net.minecraft.util.io.netty.buffer.ByteBuf;
import net.minecraft.util.io.netty.channel.Channel; import net.minecraft.util.io.netty.channel.Channel;
import net.minecraft.util.io.netty.channel.ChannelHandler; import net.minecraft.util.io.netty.channel.ChannelHandler;
@ -24,6 +25,7 @@ import net.sf.cglib.proxy.Factory;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Protocol; import com.comphenix.protocol.PacketType.Protocol;
import com.comphenix.protocol.ProtocolLibrary; import com.comphenix.protocol.ProtocolLibrary;
import com.comphenix.protocol.error.Report; import com.comphenix.protocol.error.Report;
@ -44,6 +46,7 @@ import com.comphenix.protocol.utility.MinecraftMethods;
import com.comphenix.protocol.utility.MinecraftReflection; import com.comphenix.protocol.utility.MinecraftReflection;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import com.google.common.collect.MapMaker; import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
/** /**
* Represents a channel injector. * Represents a channel injector.
@ -53,7 +56,12 @@ class ChannelInjector extends ByteToMessageDecoder {
public static final ReportType REPORT_CANNOT_INTERCEPT_SERVER_PACKET = new ReportType("Unable to intercept a written server packet."); public static final ReportType REPORT_CANNOT_INTERCEPT_SERVER_PACKET = new ReportType("Unable to intercept a written server packet.");
public static final ReportType REPORT_CANNOT_INTERCEPT_CLIENT_PACKET = new ReportType("Unable to intercept a read client packet."); public static final ReportType REPORT_CANNOT_INTERCEPT_CLIENT_PACKET = new ReportType("Unable to intercept a read client packet.");
private static final ConcurrentMap<Player, ChannelInjector> cachedInjector = new MapMaker().weakKeys().makeMap(); private static final ConcurrentMap<Player, ChannelInjector> PLAYER_LOOKUP = Maps.newConcurrentMap();
private static final ConcurrentMap<String, ChannelInjector> NAME_LOOKUP = new MapMaker().weakValues().makeMap();
// The login packet
private static Class<?> PACKET_LOGIN_CLIENT = null;
private static FieldAccessor LOGIN_GAME_PROFILE = null;
// Saved accessors // Saved accessors
private static MethodAccessor DECODE_BUFFER; private static MethodAccessor DECODE_BUFFER;
@ -124,7 +132,7 @@ class ChannelInjector extends ByteToMessageDecoder {
* @return A new injector, or an existing injector associated with this player. * @return A new injector, or an existing injector associated with this player.
*/ */
public static ChannelInjector fromPlayer(Player player, ChannelListener listener) { public static ChannelInjector fromPlayer(Player player, ChannelListener listener) {
ChannelInjector injector = cachedInjector.get(player); ChannelInjector injector = PLAYER_LOOKUP.get(player);
// Find a temporary injector as well // Find a temporary injector as well
if (injector == null) if (injector == null)
@ -133,6 +141,11 @@ class ChannelInjector extends ByteToMessageDecoder {
return injector; return injector;
Object networkManager = MinecraftFields.getNetworkManager(player); Object networkManager = MinecraftFields.getNetworkManager(player);
// Must be a temporary Bukkit player
if (networkManager == null)
return fromName(player.getName(), player);
Channel channel = FuzzyReflection.getFieldValue(networkManager, Channel.class, true); Channel channel = FuzzyReflection.getFieldValue(networkManager, Channel.class, true);
// See if a channel has already been created // See if a channel has already been created
@ -145,7 +158,8 @@ class ChannelInjector extends ByteToMessageDecoder {
injector = new ChannelInjector(player, networkManager, channel, listener); injector = new ChannelInjector(player, networkManager, channel, listener);
} }
// Cache injector and return // Cache injector and return
cachedInjector.put(player, injector); NAME_LOOKUP.put(player.getName(), injector);
PLAYER_LOOKUP.put(player, injector);
return injector; return injector;
} }
@ -163,6 +177,24 @@ class ChannelInjector extends ByteToMessageDecoder {
return null; return null;
} }
/**
* Retrieve a cached injector from a name.
* @param address - the name.
* @return The cached injector.
* @throws IllegalArgumentException If we cannot find the corresponding injector.
*/
private static ChannelInjector fromName(String name, Player player) {
ChannelInjector injector = NAME_LOOKUP.get(name);
// We can only retrieve cached injectors
if (injector != null) {
// Update instance
injector.player = player;
return injector;
}
throw new IllegalArgumentException("Cannot inject temporary Bukkit player.");
}
/** /**
* Construct a new channel injector for the given channel. * Construct a new channel injector for the given channel.
* @param channel - the channel. * @param channel - the channel.
@ -199,7 +231,7 @@ class ChannelInjector extends ByteToMessageDecoder {
if (findChannelHandler(originalChannel, ChannelInjector.class) != null) { if (findChannelHandler(originalChannel, ChannelInjector.class) != null) {
// Invalidate cache // Invalidate cache
if (player != null) if (player != null)
cachedInjector.remove(player); PLAYER_LOOKUP.remove(player);
return false; return false;
} }
@ -287,6 +319,9 @@ class ChannelInjector extends ByteToMessageDecoder {
} catch (NoSuchElementException e) { } catch (NoSuchElementException e) {
// Ignore it - the player has logged out // Ignore it - the player has logged out
} }
// Clear cache
NAME_LOOKUP.remove(player.getName());
PLAYER_LOOKUP.remove(player);
} }
} }
} }
@ -367,6 +402,9 @@ class ChannelInjector extends ByteToMessageDecoder {
Class<?> packetClass = input.getClass(); Class<?> packetClass = input.getClass();
NetworkMarker marker = null; NetworkMarker marker = null;
// Special case!
handleLogin(packetClass, input);
if (channelListener.includeBuffer(packetClass)) { if (channelListener.includeBuffer(packetClass)) {
byteBuffer.resetReaderIndex(); byteBuffer.resetReaderIndex();
marker = new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, getBytes(byteBuffer)); marker = new NettyNetworkMarker(ConnectionSide.CLIENT_SIDE, getBytes(byteBuffer));
@ -385,6 +423,27 @@ class ChannelInjector extends ByteToMessageDecoder {
} }
} }
/**
* Invoked when we may need to handle the login packet.
* @param packetClass - the packet class.
* @param packet - the packet.
*/
protected void handleLogin(Class<?> packetClass, Object packet) {
// Initialize packet class
if (PACKET_LOGIN_CLIENT == null) {
PACKET_LOGIN_CLIENT = PacketType.Login.Client.START.getPacketClass();
LOGIN_GAME_PROFILE = Accessors.getFieldAccessor(PACKET_LOGIN_CLIENT, GameProfile.class, true);
}
// See if we are dealing with the login packet
if (PACKET_LOGIN_CLIENT.equals(packetClass)) {
GameProfile profile = (GameProfile) LOGIN_GAME_PROFILE.get(packet);
// Save the channel injector
NAME_LOOKUP.put(profile.getName(), this);
}
}
@Override @Override
public void channelActive(ChannelHandlerContext ctx) throws Exception { public void channelActive(ChannelHandlerContext ctx) throws Exception {
super.channelActive(ctx); super.channelActive(ctx);

Datei anzeigen

@ -22,7 +22,7 @@ public class MinecraftFields {
/** /**
* Retrieve the network mananger associated with a particular player. * Retrieve the network mananger associated with a particular player.
* @param player - the player. * @param player - the player.
* @return The network manager. * @return The network manager, or NULL if no network manager has been asssociated yet.
*/ */
public static Object getNetworkManager(Player player) { public static Object getNetworkManager(Player player) {
Object nmsPlayer = BukkitUnwrapper.getInstance().unwrapItem(player); Object nmsPlayer = BukkitUnwrapper.getInstance().unwrapItem(player);
@ -33,7 +33,11 @@ public class MinecraftFields {
NETWORK_ACCESSOR = Accessors.getFieldAccessor(connectionClass, networkClass, true); NETWORK_ACCESSOR = Accessors.getFieldAccessor(connectionClass, networkClass, true);
} }
// Retrieve the network manager // Retrieve the network manager
return NETWORK_ACCESSOR.get(getPlayerConnection(nmsPlayer)); final Object playerConnection = getPlayerConnection(nmsPlayer);
if (playerConnection != null)
return NETWORK_ACCESSOR.get(playerConnection);
return null;
} }
/** /**