mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-27 13:15:52 +01:00
Moved all player related injection methods into a separate package.
This should make the code a little bit clearer.
This commit is contained in:
parent
eb12808483
commit
af3e278e06
@ -10,5 +10,6 @@
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/4"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre6"/>
|
||||
<classpathentry kind="lib" path="D:/Games/Minecraft/Server Mods/1.3.2/SpoutPlugin.jar"/>
|
||||
<classpathentry kind="output" path="class"/>
|
||||
</classpath>
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
|
||||
public interface ListenerInvoker {
|
||||
|
||||
/**
|
||||
* Invokes the given packet event for every registered listener.
|
||||
* @param event - the packet event to invoke.
|
||||
*/
|
||||
public abstract void invokePacketRecieving(PacketEvent event);
|
||||
|
||||
/**
|
||||
* Invokes the given packet event for every registered listener.
|
||||
* @param event - the packet event to invoke.
|
||||
*/
|
||||
public abstract void invokePacketSending(PacketEvent event);
|
||||
|
||||
/**
|
||||
* Retrieve the associated ID of a packet.
|
||||
* @param packet - the packet.
|
||||
* @return The packet ID.
|
||||
*/
|
||||
public abstract int getPacketID(Packet packet);
|
||||
}
|
@ -17,13 +17,10 @@
|
||||
|
||||
package com.comphenix.protocol.injector;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
@ -51,12 +48,13 @@ import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.async.AsyncFilterManager;
|
||||
import com.comphenix.protocol.async.AsyncMarker;
|
||||
import com.comphenix.protocol.events.*;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
||||
import com.comphenix.protocol.reflect.FieldAccessException;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public final class PacketFilterManager implements ProtocolManager {
|
||||
public final class PacketFilterManager implements ProtocolManager, ListenerInvoker {
|
||||
|
||||
/**
|
||||
* Sets the inject hook type. Different types allow for maximum compatibility.
|
||||
@ -86,22 +84,12 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
// Create a concurrent set
|
||||
private Set<PacketListener> packetListeners =
|
||||
Collections.newSetFromMap(new ConcurrentHashMap<PacketListener, Boolean>());
|
||||
|
||||
// Player injection
|
||||
private Map<DataInputStream, Player> connectionLookup = new ConcurrentHashMap<DataInputStream, Player>();
|
||||
private Map<Player, PlayerInjector> playerInjection = new HashMap<Player, PlayerInjector>();
|
||||
|
||||
// Player injection type
|
||||
private PlayerInjectHooks playerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
|
||||
|
||||
|
||||
// Packet injection
|
||||
private PacketInjector packetInjector;
|
||||
|
||||
// Server connection injection
|
||||
private InjectedServerConnection serverInjection;
|
||||
|
||||
// Enabled packet filters
|
||||
private Set<Integer> sendingFilters = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());
|
||||
// Player injection
|
||||
private PlayerInjectionHandler playerInjection;
|
||||
|
||||
// The two listener containers
|
||||
private SortedPacketListenerList recievedListeners = new SortedPacketListenerList();
|
||||
@ -112,10 +100,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
// The default class loader
|
||||
private ClassLoader classLoader;
|
||||
|
||||
// The last successful player hook
|
||||
private PlayerInjector lastSuccessfulHook;
|
||||
|
||||
|
||||
// Error logger
|
||||
private Logger logger;
|
||||
|
||||
@ -135,9 +120,9 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
// Initialize values
|
||||
this.classLoader = classLoader;
|
||||
this.logger = logger;
|
||||
this.packetInjector = new PacketInjector(classLoader, this, connectionLookup);
|
||||
this.playerInjection = new PlayerInjectionHandler(classLoader, logger, this, server);
|
||||
this.packetInjector = new PacketInjector(classLoader, this, playerInjection);
|
||||
this.asyncFilterManager = new AsyncFilterManager(logger, server.getScheduler(), this);
|
||||
this.serverInjection = new InjectedServerConnection(logger, server);
|
||||
} catch (IllegalAccessException e) {
|
||||
logger.log(Level.SEVERE, "Unable to initialize packet injector.", e);
|
||||
}
|
||||
@ -153,7 +138,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
* @return Injection method for reading server packets.
|
||||
*/
|
||||
public PlayerInjectHooks getPlayerHook() {
|
||||
return playerHook;
|
||||
return playerInjection.getPlayerHook();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -161,18 +146,10 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
* @param playerHook - the new injection method for reading server packets.
|
||||
*/
|
||||
public void setPlayerHook(PlayerInjectHooks playerHook) {
|
||||
this.playerHook = playerHook;
|
||||
playerInjection.setPlayerHook(playerHook);
|
||||
|
||||
// Make sure the current listeners are compatible
|
||||
if (lastSuccessfulHook != null) {
|
||||
for (PacketListener listener : packetListeners) {
|
||||
try {
|
||||
checkListener(listener);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.log(Level.WARNING, "Unsupported listener.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
playerInjection.checkListener(packetListeners);
|
||||
}
|
||||
|
||||
public Logger getLogger() {
|
||||
@ -204,14 +181,14 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
verifyWhitelist(listener, sending);
|
||||
sendingListeners.addListener(listener, sending);
|
||||
enablePacketFilters(ConnectionSide.SERVER_SIDE, sending.getWhitelist());
|
||||
|
||||
// Make sure this is possible
|
||||
playerInjection.checkListener(listener);
|
||||
}
|
||||
if (hasReceiving) {
|
||||
verifyWhitelist(listener, receiving);
|
||||
recievedListeners.addListener(listener, receiving);
|
||||
enablePacketFilters(ConnectionSide.CLIENT_SIDE, receiving.getWhitelist());
|
||||
|
||||
// We don't know if we've hooked any players yet
|
||||
checkListener(listener);
|
||||
}
|
||||
|
||||
// Inform our injected hooks
|
||||
@ -234,21 +211,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a listener is valid or not.
|
||||
* @param listener - listener to check.
|
||||
* @throws IllegalStateException If the given listener's whitelist cannot be fulfilled.
|
||||
*/
|
||||
public void checkListener(PacketListener listener) {
|
||||
try {
|
||||
if (lastSuccessfulHook != null)
|
||||
lastSuccessfulHook.checkListener(listener);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Registering listener " + PacketAdapter.getPluginName(listener) + " failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void removePacketListener(PacketListener listener) {
|
||||
if (listener == null)
|
||||
@ -292,18 +255,12 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
asyncFilterManager.unregisterAsyncHandlers(plugin);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given packet event for every registered listener.
|
||||
* @param event - the packet event to invoke.
|
||||
*/
|
||||
@Override
|
||||
public void invokePacketRecieving(PacketEvent event) {
|
||||
handlePacket(recievedListeners, event, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes the given packet event for every registered listener.
|
||||
* @param event - the packet event to invoke.
|
||||
*/
|
||||
|
||||
@Override
|
||||
public void invokePacketSending(PacketEvent event) {
|
||||
handlePacket(sendingListeners, event, true);
|
||||
}
|
||||
@ -356,8 +313,8 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
for (int packetID : packets) {
|
||||
if (side.isForServer())
|
||||
sendingFilters.add(packetID);
|
||||
if (side.isForClient() && packetInjector != null)
|
||||
playerInjection.addPacketHandler(packetID);
|
||||
if (side.isForClient() && packetInjector != null)
|
||||
packetInjector.addPacketHandler(packetID);
|
||||
}
|
||||
}
|
||||
@ -373,7 +330,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
for (int packetID : packets) {
|
||||
if (side.isForServer())
|
||||
sendingFilters.remove(packetID);
|
||||
playerInjection.removePacketHandler(packetID);
|
||||
if (side.isForClient() && packetInjector != null)
|
||||
packetInjector.removePacketHandler(packetID);
|
||||
}
|
||||
@ -391,7 +348,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
if (packet == null)
|
||||
throw new IllegalArgumentException("packet cannot be NULL.");
|
||||
|
||||
getInjector(reciever).sendServerPacket(packet.getHandle(), filters);
|
||||
playerInjection.sendServerPacket(reciever, packet, filters);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -407,17 +364,21 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
if (packet == null)
|
||||
throw new IllegalArgumentException("packet cannot be NULL.");
|
||||
|
||||
PlayerInjector injector = getInjector(sender);
|
||||
Packet mcPacket = packet.getHandle();
|
||||
|
||||
// Make sure the packet isn't cancelled
|
||||
packetInjector.undoCancel(packet.getID(), mcPacket);
|
||||
|
||||
if (filters) {
|
||||
mcPacket = injector.handlePacketRecieved(mcPacket);
|
||||
PacketEvent event = packetInjector.packetRecieved(packet, sender);
|
||||
|
||||
if (!event.isCancelled())
|
||||
mcPacket = event.getPacket().getHandle();
|
||||
else
|
||||
return;
|
||||
}
|
||||
|
||||
injector.processPacket(mcPacket);
|
||||
playerInjection.processPacket(sender, mcPacket);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -448,7 +409,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
@Override
|
||||
public Set<Integer> getSendingFilters() {
|
||||
return ImmutableSet.copyOf(sendingFilters);
|
||||
return playerInjection.getSendingFilters();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -467,94 +428,9 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
*/
|
||||
public void initializePlayers(Player[] players) {
|
||||
for (Player player : players)
|
||||
injectPlayer(player);
|
||||
playerInjection.injectPlayer(player);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to construct a player hook.
|
||||
* @param player - the player to hook.
|
||||
* @param hook - the hook type.
|
||||
* @return A new player hoook
|
||||
* @throws IllegalAccessException Unable to do our reflection magic.
|
||||
*/
|
||||
protected PlayerInjector getHookInstance(Player player, PlayerInjectHooks hook) throws IllegalAccessException {
|
||||
// Construct the correct player hook
|
||||
switch (hook) {
|
||||
case NETWORK_HANDLER_FIELDS:
|
||||
return new NetworkFieldInjector(player, this, sendingFilters);
|
||||
case NETWORK_MANAGER_OBJECT:
|
||||
return new NetworkObjectInjector(player, this, sendingFilters);
|
||||
case NETWORK_SERVER_OBJECT:
|
||||
return new NetworkServerInjector(player, this, sendingFilters, serverInjection);
|
||||
default:
|
||||
throw new IllegalArgumentException("Cannot construct a player injector.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a player hook, allowing us to read server packets.
|
||||
* @param player - player to hook.
|
||||
*/
|
||||
protected void injectPlayer(Player player) {
|
||||
|
||||
PlayerInjector injector = null;
|
||||
PlayerInjectHooks currentHook = playerHook;
|
||||
boolean firstPlayer = lastSuccessfulHook == null;
|
||||
|
||||
// Don't inject if the class has closed
|
||||
if (!hasClosed && player != null && !playerInjection.containsKey(player)) {
|
||||
while (true) {
|
||||
try {
|
||||
injector = getHookInstance(player, currentHook);
|
||||
injector.injectManager();
|
||||
|
||||
DataInputStream inputStream = injector.getInputStream(false);
|
||||
|
||||
if (!player.isOnline() || inputStream == null) {
|
||||
throw new PlayerLoggedOutException();
|
||||
}
|
||||
|
||||
playerInjection.put(player, injector);
|
||||
connectionLookup.put(inputStream, player);
|
||||
break;
|
||||
|
||||
|
||||
} catch (PlayerLoggedOutException e) {
|
||||
throw e;
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
// Mark this injection attempt as a failure
|
||||
logger.log(Level.SEVERE, "Player hook " + currentHook.toString() + " failed.", e);
|
||||
|
||||
// Clean up as much as possible
|
||||
try {
|
||||
if (injector != null)
|
||||
injector.cleanupAll();
|
||||
} catch (Exception e2) {
|
||||
logger.log(Level.WARNING, "Cleaing up after player hook failed.", e);
|
||||
}
|
||||
|
||||
if (currentHook.ordinal() > 0) {
|
||||
// Choose the previous player hook type
|
||||
currentHook = PlayerInjectHooks.values()[currentHook.ordinal() - 1];
|
||||
logger.log(Level.INFO, "Switching to " + currentHook.toString() + " instead.");
|
||||
} else {
|
||||
// UTTER FAILURE
|
||||
playerInjection.put(player, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update values
|
||||
if (injector != null)
|
||||
lastSuccessfulHook = injector;
|
||||
if (currentHook != playerHook || firstPlayer)
|
||||
setPlayerHook(currentHook);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register this protocol manager on Bukkit.
|
||||
* @param manager - Bukkit plugin manager that provides player join/leave events.
|
||||
@ -567,12 +443,12 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerJoin(PlayerJoinEvent event) {
|
||||
injectPlayer(event.getPlayer());
|
||||
playerInjection.injectPlayer(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
public void onPlayerQuit(PlayerQuitEvent event) {
|
||||
uninjectPlayer(event.getPlayer());
|
||||
playerInjection.uninjectPlayer(event.getPlayer());
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
@ -591,6 +467,14 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPacketID(Packet packet) {
|
||||
if (packet == null)
|
||||
throw new IllegalArgumentException("Packet cannot be NULL.");
|
||||
|
||||
return MinecraftRegistry.getPacketToID().get(packet.getClass());
|
||||
}
|
||||
|
||||
// Yes, this is crazy.
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private void registerOld(PluginManager manager, Plugin plugin) {
|
||||
@ -632,9 +516,9 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
// Check for the correct event
|
||||
if (event instanceof PlayerJoinEvent)
|
||||
injectPlayer(((PlayerJoinEvent) event).getPlayer());
|
||||
playerInjection.injectPlayer(((PlayerJoinEvent) event).getPlayer());
|
||||
else if (event instanceof PlayerQuitEvent)
|
||||
uninjectPlayer(((PlayerQuitEvent) event).getPlayer());
|
||||
playerInjection.uninjectPlayer(((PlayerQuitEvent) event).getPlayer());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -676,37 +560,7 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void uninjectPlayer(Player player) {
|
||||
if (!hasClosed && player != null) {
|
||||
|
||||
PlayerInjector injector = playerInjection.get(player);
|
||||
|
||||
if (injector != null) {
|
||||
DataInputStream input = injector.getInputStream(true);
|
||||
injector.cleanupAll();
|
||||
|
||||
playerInjection.remove(player);
|
||||
connectionLookup.remove(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PlayerInjector getInjector(Player player) {
|
||||
if (!playerInjection.containsKey(player)) {
|
||||
// What? Try to inject again.
|
||||
injectPlayer(player);
|
||||
}
|
||||
|
||||
PlayerInjector injector = playerInjection.get(player);
|
||||
|
||||
// Check that the injector was sucessfully added
|
||||
if (injector != null)
|
||||
return injector;
|
||||
else
|
||||
throw new IllegalArgumentException("Player has no injected handler.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the current plugin class loader.
|
||||
* @return Class loader.
|
||||
@ -722,28 +576,19 @@ public final class PacketFilterManager implements ProtocolManager {
|
||||
|
||||
public void close() {
|
||||
// Guard
|
||||
if (hasClosed || playerInjection == null)
|
||||
if (hasClosed)
|
||||
return;
|
||||
|
||||
// Remove everything
|
||||
for (PlayerInjector injection : playerInjection.values()) {
|
||||
if (injection != null) {
|
||||
injection.cleanupAll();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove packet handlers
|
||||
if (packetInjector != null)
|
||||
packetInjector.cleanupAll();
|
||||
|
||||
// Remove server handler
|
||||
serverInjection.cleanupAll();
|
||||
playerInjection.close();
|
||||
hasClosed = true;
|
||||
|
||||
// Remove listeners
|
||||
packetListeners.clear();
|
||||
playerInjection.clear();
|
||||
connectionLookup.clear();
|
||||
|
||||
// Clean up async handlers. We have to do this last.
|
||||
asyncFilterManager.cleanupAll();
|
||||
|
@ -33,6 +33,7 @@ import net.sf.cglib.proxy.Enhancer;
|
||||
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.injector.player.PlayerInjectionHandler;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
|
||||
@ -48,10 +49,10 @@ class PacketInjector {
|
||||
private static Object intHashMap;
|
||||
|
||||
// The packet filter manager
|
||||
private PacketFilterManager manager;
|
||||
private ListenerInvoker manager;
|
||||
|
||||
// Allows us to determine the sender
|
||||
private Map<DataInputStream, Player> playerLookup;
|
||||
private PlayerInjectionHandler playerInjection;
|
||||
|
||||
// Allows us to look up read packet injectors
|
||||
private Map<Integer, ReadPacketModifier> readModifier;
|
||||
@ -59,12 +60,12 @@ class PacketInjector {
|
||||
// Class loader
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public PacketInjector(ClassLoader classLoader, PacketFilterManager manager,
|
||||
Map<DataInputStream, Player> playerLookup) throws IllegalAccessException {
|
||||
public PacketInjector(ClassLoader classLoader, ListenerInvoker manager,
|
||||
PlayerInjectionHandler playerInjection) throws IllegalAccessException {
|
||||
|
||||
this.classLoader = classLoader;
|
||||
this.manager = manager;
|
||||
this.playerLookup = playerLookup;
|
||||
this.playerInjection = playerInjection;
|
||||
this.readModifier = new ConcurrentHashMap<Integer, ReadPacketModifier>();
|
||||
initialize();
|
||||
}
|
||||
@ -194,7 +195,18 @@ class PacketInjector {
|
||||
// Called from the ReadPacketModified monitor
|
||||
PacketEvent packetRecieved(PacketContainer packet, DataInputStream input) {
|
||||
|
||||
Player client = playerLookup.get(input);
|
||||
Player client = playerInjection.getPlayerByConnection(input);
|
||||
return packetRecieved(packet, client);
|
||||
}
|
||||
|
||||
/**
|
||||
* Let the packet listeners process the given packet.
|
||||
* @param packet - a packet to process.
|
||||
* @param client - the client that sent the packet.
|
||||
* @return The resulting packet event.
|
||||
*/
|
||||
public PacketEvent packetRecieved(PacketContainer packet, Player client) {
|
||||
|
||||
PacketEvent event = PacketEvent.fromClient((Object) manager, packet, client);
|
||||
|
||||
manager.invokePacketRecieving(event);
|
||||
|
@ -1,17 +1,17 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.injector.player.NetworkFieldInjector.FakePacket;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
import net.sf.cglib.proxy.Enhancer;
|
||||
import net.sf.cglib.proxy.MethodInterceptor;
|
||||
import net.sf.cglib.proxy.MethodProxy;
|
||||
|
||||
import com.comphenix.protocol.injector.NetworkFieldInjector.FakePacket;
|
||||
|
||||
/**
|
||||
* The array list that notifies when packets are sent by the server.
|
||||
*
|
@ -1,4 +1,4 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
@ -1,4 +1,4 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -7,12 +7,14 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.comphenix.protocol.Packets;
|
||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
@ -45,13 +47,28 @@ class NetworkFieldInjector extends PlayerInjector {
|
||||
// Sync field
|
||||
private static Field syncField;
|
||||
private Object syncObject;
|
||||
|
||||
// Determine if we're listening
|
||||
private Set<Integer> sendingFilters;
|
||||
|
||||
// Used to construct proxy objects
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public NetworkFieldInjector(Player player, PacketFilterManager manager, Set<Integer> sendingFilters) throws IllegalAccessException {
|
||||
super(player, manager, sendingFilters);
|
||||
public NetworkFieldInjector(ClassLoader classLoader, Logger logger, Player player,
|
||||
ListenerInvoker manager, Set<Integer> sendingFilters) throws IllegalAccessException {
|
||||
|
||||
super(logger, player, manager);
|
||||
this.classLoader = classLoader;
|
||||
this.sendingFilters = sendingFilters;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void initialize() throws IllegalAccessException {
|
||||
protected boolean hasListener(int packetID) {
|
||||
return sendingFilters.contains(packetID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized void initialize() throws IllegalAccessException {
|
||||
super.initialize();
|
||||
|
||||
// Get the sync field as well
|
||||
@ -112,7 +129,7 @@ class NetworkFieldInjector extends PlayerInjector {
|
||||
|
||||
synchronized(syncObject) {
|
||||
// The list we'll be inserting
|
||||
List<Packet> hackedList = new InjectedArrayList(manager.getClassLoader(), this, ignoredPackets);
|
||||
List<Packet> hackedList = new InjectedArrayList(classLoader, this, ignoredPackets);
|
||||
|
||||
// Add every previously stored packet
|
||||
for (Packet packet : minecraftList) {
|
||||
@ -154,4 +171,9 @@ class NetworkFieldInjector extends PlayerInjector {
|
||||
}
|
||||
overridenLists.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInject() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
|
||||
@ -8,12 +8,14 @@ import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.comphenix.protocol.Packets;
|
||||
import com.comphenix.protocol.events.ListeningWhitelist;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
|
||||
/**
|
||||
* Injection method that overrides the NetworkHandler itself, and it's sendPacket-method.
|
||||
@ -21,10 +23,19 @@ import com.comphenix.protocol.events.PacketListener;
|
||||
* @author Kristian
|
||||
*/
|
||||
class NetworkObjectInjector extends PlayerInjector {
|
||||
public NetworkObjectInjector(Player player, PacketFilterManager manager, Set<Integer> sendingFilters) throws IllegalAccessException {
|
||||
super(player, manager, sendingFilters);
|
||||
// Determine if we're listening
|
||||
private Set<Integer> sendingFilters;
|
||||
|
||||
public NetworkObjectInjector(Logger logger, Player player, ListenerInvoker invoker, Set<Integer> sendingFilters) throws IllegalAccessException {
|
||||
super(logger, player, invoker);
|
||||
this.sendingFilters = sendingFilters;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasListener(int packetID) {
|
||||
return sendingFilters.contains(packetID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendServerPacket(Packet packet, boolean filtered) throws InvocationTargetException {
|
||||
Object networkDelegate = filtered ? networkManagerRef.getValue() : networkManagerRef.getOldValue();
|
||||
@ -107,4 +118,9 @@ class NetworkObjectInjector extends PlayerInjector {
|
||||
// Clean up
|
||||
networkManagerRef.revertValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInject() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -1,8 +1,9 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
import net.sf.cglib.proxy.Callback;
|
||||
@ -16,6 +17,7 @@ import net.sf.cglib.proxy.NoOp;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.ObjectCloner;
|
||||
@ -32,14 +34,30 @@ public class NetworkServerInjector extends PlayerInjector {
|
||||
private static Method sendPacketMethod;
|
||||
private InjectedServerConnection serverInjection;
|
||||
|
||||
public NetworkServerInjector(Player player, PacketFilterManager manager,
|
||||
Set<Integer> sendingFilters, InjectedServerConnection serverInjection) throws IllegalAccessException {
|
||||
super(player, manager, sendingFilters);
|
||||
// Determine if we're listening
|
||||
private Set<Integer> sendingFilters;
|
||||
|
||||
// Used to create proxy objects
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public NetworkServerInjector(
|
||||
ClassLoader classLoader, Logger logger, Player player,
|
||||
ListenerInvoker invoker, Set<Integer> sendingFilters,
|
||||
InjectedServerConnection serverInjection) throws IllegalAccessException {
|
||||
|
||||
super(logger, player, invoker);
|
||||
this.classLoader = classLoader;
|
||||
this.sendingFilters = sendingFilters;
|
||||
this.serverInjection = serverInjection;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize() throws IllegalAccessException {
|
||||
protected boolean hasListener(int packetID) {
|
||||
return sendingFilters.contains(packetID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() throws IllegalAccessException {
|
||||
super.initialize();
|
||||
|
||||
// Get the send packet method!
|
||||
@ -104,7 +122,7 @@ public class NetworkServerInjector extends PlayerInjector {
|
||||
};
|
||||
Callback noOpCallback = NoOp.INSTANCE;
|
||||
|
||||
ex.setClassLoader(manager.getClassLoader());
|
||||
ex.setClassLoader(classLoader);
|
||||
ex.setSuperclass(serverClass);
|
||||
ex.setCallbacks(new Callback[] { sendPacketCallback, noOpCallback });
|
||||
ex.setCallbackFilter(new CallbackFilter() {
|
||||
@ -165,4 +183,9 @@ public class NetworkServerInjector extends PlayerInjector {
|
||||
public void checkListener(PacketListener listener) {
|
||||
// We support everything
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInject() {
|
||||
return true;
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
|
||||
public class NetworkSpoutHook extends PlayerInjector {
|
||||
|
||||
public NetworkSpoutHook(Logger logger, Player player, ListenerInvoker invoker) throws IllegalAccessException {
|
||||
super(logger, player, invoker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean hasListener(int packetID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canInject() {
|
||||
return getSpout() != null;
|
||||
}
|
||||
|
||||
private Plugin getSpout() {
|
||||
// Spout must be loaded
|
||||
try {
|
||||
return Bukkit.getServer().getPluginManager().getPlugin("Spout");
|
||||
} catch (Throwable e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void injectManager() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendServerPacket(Packet packet, boolean filtered) throws InvocationTargetException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cleanupAll() {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void checkListener(PacketListener listener) {
|
||||
// We support everything Spout does
|
||||
}
|
||||
}
|
@ -0,0 +1,306 @@
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.Packet;
|
||||
|
||||
import org.bukkit.Server;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.injector.PlayerLoggedOutException;
|
||||
import com.comphenix.protocol.injector.PacketFilterManager.PlayerInjectHooks;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
|
||||
public class PlayerInjectionHandler {
|
||||
|
||||
// Server connection injection
|
||||
private InjectedServerConnection serverInjection;
|
||||
|
||||
// The last successful player hook
|
||||
private PlayerInjector lastSuccessfulHook;
|
||||
|
||||
// Player injection
|
||||
private Map<DataInputStream, Player> connectionLookup = new ConcurrentHashMap<DataInputStream, Player>();
|
||||
private Map<Player, PlayerInjector> playerInjection = new HashMap<Player, PlayerInjector>();
|
||||
|
||||
// Player injection type
|
||||
private PlayerInjectHooks playerHook = PlayerInjectHooks.NETWORK_SERVER_OBJECT;
|
||||
|
||||
// Error logger
|
||||
private Logger logger;
|
||||
|
||||
// Whether or not we're closing
|
||||
private boolean hasClosed;
|
||||
|
||||
// Used to invoke events
|
||||
private ListenerInvoker invoker;
|
||||
|
||||
// Enabled packet filters
|
||||
private Set<Integer> sendingFilters = Collections.newSetFromMap(new ConcurrentHashMap<Integer, Boolean>());
|
||||
|
||||
// The class loader we're using
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public PlayerInjectionHandler(ClassLoader classLoader, Logger logger, ListenerInvoker invoker, Server server) {
|
||||
this.classLoader = classLoader;
|
||||
this.logger = logger;
|
||||
this.invoker = invoker;
|
||||
this.serverInjection = new InjectedServerConnection(logger, server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves how the server packets are read.
|
||||
* @return Injection method for reading server packets.
|
||||
*/
|
||||
public PlayerInjectHooks getPlayerHook() {
|
||||
return playerHook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an underlying packet handler of the given ID.
|
||||
* @param packetID - packet ID to register.
|
||||
*/
|
||||
public void addPacketHandler(int packetID) {
|
||||
sendingFilters.add(packetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an underlying packet handler of ths ID.
|
||||
* @param packetID - packet ID to unregister.
|
||||
*/
|
||||
public void removePacketHandler(int packetID) {
|
||||
sendingFilters.remove(packetID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets how the server packets are read.
|
||||
* @param playerHook - the new injection method for reading server packets.
|
||||
*/
|
||||
public void setPlayerHook(PlayerInjectHooks playerHook) {
|
||||
this.playerHook = playerHook;
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to construct a player hook.
|
||||
* @param player - the player to hook.
|
||||
* @param hook - the hook type.
|
||||
* @return A new player hoook
|
||||
* @throws IllegalAccessException Unable to do our reflection magic.
|
||||
*/
|
||||
private PlayerInjector getHookInstance(Player player, PlayerInjectHooks hook) throws IllegalAccessException {
|
||||
// Construct the correct player hook
|
||||
switch (hook) {
|
||||
case NETWORK_HANDLER_FIELDS:
|
||||
return new NetworkFieldInjector(classLoader, logger, player, invoker, sendingFilters);
|
||||
case NETWORK_MANAGER_OBJECT:
|
||||
return new NetworkObjectInjector(logger, player, invoker, sendingFilters);
|
||||
case NETWORK_SERVER_OBJECT:
|
||||
return new NetworkServerInjector(classLoader, logger, player, invoker, sendingFilters, serverInjection);
|
||||
default:
|
||||
throw new IllegalArgumentException("Cannot construct a player injector.");
|
||||
}
|
||||
}
|
||||
|
||||
public Player getPlayerByConnection(DataInputStream inputStream) {
|
||||
return connectionLookup.get(inputStream);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a player hook, allowing us to read server packets.
|
||||
* @param manager - the main packet filter manager.
|
||||
* @param player - player to hook.
|
||||
*/
|
||||
public void injectPlayer(Player player) {
|
||||
|
||||
PlayerInjector injector = null;
|
||||
PlayerInjectHooks currentHook = playerHook;
|
||||
boolean firstPlayer = lastSuccessfulHook == null;
|
||||
|
||||
// Don't inject if the class has closed
|
||||
if (!hasClosed && player != null && !playerInjection.containsKey(player)) {
|
||||
while (true) {
|
||||
try {
|
||||
injector = getHookInstance(player, currentHook);
|
||||
injector.initialize();
|
||||
injector.injectManager();
|
||||
|
||||
DataInputStream inputStream = injector.getInputStream(false);
|
||||
|
||||
if (!player.isOnline() || inputStream == null) {
|
||||
throw new PlayerLoggedOutException();
|
||||
}
|
||||
|
||||
playerInjection.put(player, injector);
|
||||
connectionLookup.put(inputStream, player);
|
||||
break;
|
||||
|
||||
|
||||
} catch (PlayerLoggedOutException e) {
|
||||
throw e;
|
||||
|
||||
} catch (Exception e) {
|
||||
|
||||
// Mark this injection attempt as a failure
|
||||
logger.log(Level.SEVERE, "Player hook " + currentHook.toString() + " failed.", e);
|
||||
|
||||
// Clean up as much as possible
|
||||
try {
|
||||
if (injector != null)
|
||||
injector.cleanupAll();
|
||||
} catch (Exception e2) {
|
||||
logger.log(Level.WARNING, "Cleaing up after player hook failed.", e);
|
||||
}
|
||||
|
||||
if (currentHook.ordinal() > 0) {
|
||||
|
||||
// Choose the previous player hook type
|
||||
currentHook = PlayerInjectHooks.values()[currentHook.ordinal() - 1];
|
||||
logger.log(Level.INFO, "Switching to " + currentHook.toString() + " instead.");
|
||||
} else {
|
||||
// UTTER FAILURE
|
||||
playerInjection.put(player, null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update values
|
||||
if (injector != null)
|
||||
lastSuccessfulHook = injector;
|
||||
if (currentHook != playerHook || firstPlayer)
|
||||
setPlayerHook(currentHook);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the given player.
|
||||
* @param player - player to unregister.
|
||||
*/
|
||||
public void uninjectPlayer(Player player) {
|
||||
if (!hasClosed && player != null) {
|
||||
|
||||
PlayerInjector injector = playerInjection.get(player);
|
||||
|
||||
if (injector != null) {
|
||||
DataInputStream input = injector.getInputStream(true);
|
||||
injector.cleanupAll();
|
||||
|
||||
playerInjection.remove(player);
|
||||
connectionLookup.remove(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendServerPacket(Player reciever, PacketContainer packet, boolean filters) throws InvocationTargetException {
|
||||
getInjector(reciever).sendServerPacket(packet.getHandle(), filters);
|
||||
}
|
||||
|
||||
private PlayerInjector getInjector(Player player) {
|
||||
if (!playerInjection.containsKey(player)) {
|
||||
// What? Try to inject again.
|
||||
injectPlayer(player);
|
||||
}
|
||||
|
||||
PlayerInjector injector = playerInjection.get(player);
|
||||
|
||||
// Check that the injector was sucessfully added
|
||||
if (injector != null)
|
||||
return injector;
|
||||
else
|
||||
throw new IllegalArgumentException("Player has no injected handler.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given listeners are valid.
|
||||
* @param listeners - listeners to check.
|
||||
*/
|
||||
public void checkListener(Set<PacketListener> listeners) {
|
||||
// Make sure the current listeners are compatible
|
||||
if (lastSuccessfulHook != null) {
|
||||
for (PacketListener listener : listeners) {
|
||||
try {
|
||||
checkListener(listener);
|
||||
} catch (IllegalStateException e) {
|
||||
logger.log(Level.WARNING, "Unsupported listener.", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if a listener is valid or not.
|
||||
* @param listener - listener to check.
|
||||
* @throws IllegalStateException If the given listener's whitelist cannot be fulfilled.
|
||||
*/
|
||||
public void checkListener(PacketListener listener) {
|
||||
try {
|
||||
if (lastSuccessfulHook != null)
|
||||
lastSuccessfulHook.checkListener(listener);
|
||||
} catch (Exception e) {
|
||||
throw new IllegalStateException("Registering listener " + PacketAdapter.getPluginName(listener) + " failed", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a packet as if it were sent by the given player.
|
||||
* @param player - the sender.
|
||||
* @param mcPacket - the packet to process.
|
||||
* @throws IllegalAccessException If the reflection machinery failed.
|
||||
* @throws InvocationTargetException If the underlying method caused an error.
|
||||
*/
|
||||
public void processPacket(Player player, Packet mcPacket) throws IllegalAccessException, InvocationTargetException {
|
||||
|
||||
PlayerInjector injector = getInjector(player);
|
||||
injector.processPacket(mcPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current list of registered sending listeners.
|
||||
* @return List of the sending listeners's packet IDs.
|
||||
*/
|
||||
public Set<Integer> getSendingFilters() {
|
||||
return ImmutableSet.copyOf(sendingFilters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the current logger.
|
||||
* @return Error logger.
|
||||
*/
|
||||
public Logger getLogger() {
|
||||
return logger;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
||||
// Guard
|
||||
if (hasClosed || playerInjection == null)
|
||||
return;
|
||||
|
||||
// Remove everything
|
||||
for (PlayerInjector injection : playerInjection.values()) {
|
||||
if (injection != null) {
|
||||
injection.cleanupAll();
|
||||
}
|
||||
}
|
||||
|
||||
// Remove server handler
|
||||
serverInjection.cleanupAll();
|
||||
hasClosed = true;
|
||||
|
||||
playerInjection.clear();
|
||||
connectionLookup.clear();
|
||||
invoker = null;
|
||||
}
|
||||
}
|
@ -15,14 +15,14 @@
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.io.DataInputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.minecraft.server.EntityPlayer;
|
||||
import net.minecraft.server.Packet;
|
||||
@ -34,6 +34,7 @@ import org.bukkit.entity.Player;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.events.PacketListener;
|
||||
import com.comphenix.protocol.injector.ListenerInvoker;
|
||||
import com.comphenix.protocol.reflect.FieldUtils;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
@ -69,17 +70,18 @@ abstract class PlayerInjector {
|
||||
protected Object netHandler;
|
||||
|
||||
// The packet manager and filters
|
||||
protected PacketFilterManager manager;
|
||||
protected Set<Integer> sendingFilters;
|
||||
protected ListenerInvoker invoker;
|
||||
|
||||
// Previous data input
|
||||
protected DataInputStream cachedInput;
|
||||
|
||||
// Handle errors
|
||||
protected Logger logger;
|
||||
|
||||
public PlayerInjector(Player player, PacketFilterManager manager, Set<Integer> sendingFilters) throws IllegalAccessException {
|
||||
public PlayerInjector(Logger logger, Player player, ListenerInvoker invoker) throws IllegalAccessException {
|
||||
this.logger = logger;
|
||||
this.player = player;
|
||||
this.manager = manager;
|
||||
this.sendingFilters = sendingFilters;
|
||||
initialize();
|
||||
this.invoker = invoker;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,7 +93,11 @@ abstract class PlayerInjector {
|
||||
return craft.getHandle();
|
||||
}
|
||||
|
||||
protected void initialize() throws IllegalAccessException {
|
||||
/**
|
||||
* Initialize all fields for this player injector, if it hasn't already.
|
||||
* @throws IllegalAccessException An error has occured.
|
||||
*/
|
||||
public void initialize() throws IllegalAccessException {
|
||||
|
||||
EntityPlayer notchEntity = getEntityPlayer();
|
||||
|
||||
@ -156,12 +162,12 @@ abstract class PlayerInjector {
|
||||
return reflection.getFieldByType(".*NetServerHandler");
|
||||
|
||||
} catch (RuntimeException e) {
|
||||
manager.getLogger().log(Level.WARNING, "Server handler is a proxy type.", e);
|
||||
logger.log(Level.WARNING, "Server handler is a proxy type.", e);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (IllegalAccessException e) {
|
||||
manager.getLogger().warning("Unable to load server handler from proxy type.");
|
||||
logger.warning("Unable to load server handler from proxy type.");
|
||||
}
|
||||
|
||||
// Nope, just go with it
|
||||
@ -250,6 +256,12 @@ abstract class PlayerInjector {
|
||||
*/
|
||||
public abstract void cleanupAll();
|
||||
|
||||
/**
|
||||
* Determine if this inject method can even be attempted.
|
||||
* @return TRUE if can be attempted, though possibly with failure, FALSE otherwise.
|
||||
*/
|
||||
public abstract boolean canInject();
|
||||
|
||||
/**
|
||||
* Invoked before a new listener is registered.
|
||||
* <p>
|
||||
@ -263,16 +275,16 @@ abstract class PlayerInjector {
|
||||
* @param packet - packet to recieve.
|
||||
* @return The given packet, or the packet replaced by the listeners.
|
||||
*/
|
||||
Packet handlePacketRecieved(Packet packet) {
|
||||
public Packet handlePacketRecieved(Packet packet) {
|
||||
// Get the packet ID too
|
||||
Integer id = MinecraftRegistry.getPacketToID().get(packet.getClass());
|
||||
Integer id = invoker.getPacketID(packet);
|
||||
|
||||
// Make sure we're listening
|
||||
if (id != null && sendingFilters.contains(id)) {
|
||||
if (id != null && hasListener(id)) {
|
||||
// A packet has been sent guys!
|
||||
PacketContainer container = new PacketContainer(id, packet);
|
||||
PacketEvent event = PacketEvent.fromServer(manager, container, player);
|
||||
manager.invokePacketSending(event);
|
||||
PacketEvent event = PacketEvent.fromServer(invoker, container, player);
|
||||
invoker.invokePacketSending(event);
|
||||
|
||||
// Cancelling is pretty simple. Just ignore the packet.
|
||||
if (event.isCancelled())
|
||||
@ -285,6 +297,13 @@ abstract class PlayerInjector {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the given injector is listening for this packet ID.
|
||||
* @param packetID - packet ID to check.
|
||||
* @return TRUE if it is, FALSE oterhwise.
|
||||
*/
|
||||
protected abstract boolean hasListener(int packetID);
|
||||
|
||||
/**
|
||||
* Retrieve the current player's input stream.
|
||||
* @param cache - whether or not to cache the result of this method.
|
@ -1,4 +1,4 @@
|
||||
package com.comphenix.protocol.injector;
|
||||
package com.comphenix.protocol.injector.player;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
Loading…
Reference in New Issue
Block a user