Dieser Commit ist enthalten in:
Ursprung
04b03ce06d
Commit
cbbafd7c09
@ -7,6 +7,7 @@ import org.bukkit.Bukkit;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.util.Arrays;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@ -135,15 +136,16 @@ public final class Reflection {
|
||||
return getField(getClass(className), fieldType, index);
|
||||
}
|
||||
|
||||
// Common method
|
||||
private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index) {
|
||||
public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index, Class<?>... parameters) {
|
||||
return getField(target, null, fieldType, index, parameters);
|
||||
}
|
||||
|
||||
private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index, Class<?>... parameters) {
|
||||
for (final Field field : target.getDeclaredFields()) {
|
||||
if ((name == null || field.getName().equals(name)) && fieldType.isAssignableFrom(field.getType()) && index-- <= 0) {
|
||||
if(matching(field, name, fieldType, parameters) && index-- <= 0) {
|
||||
field.setAccessible(true);
|
||||
|
||||
// A function for retrieving a specific field value
|
||||
return new FieldAccessor<T>() {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public T get(Object target) {
|
||||
@ -179,6 +181,24 @@ public final class Reflection {
|
||||
throw new IllegalArgumentException("Cannot find field with type " + fieldType);
|
||||
}
|
||||
|
||||
private static <T> boolean matching(Field field, String name, Class<T> fieldType, Class<?>... parameters) {
|
||||
if(name != null && !field.getName().equals(name))
|
||||
return false;
|
||||
|
||||
if(!fieldType.isAssignableFrom(field.getType()))
|
||||
return false;
|
||||
|
||||
if(parameters.length > 0) {
|
||||
Class<?>[] arguments = (Class<?>[]) ((ParameterizedType)field.getType().getGenericSuperclass()).getActualTypeArguments();
|
||||
|
||||
for(int i = 0; i < parameters.length; i++) {
|
||||
if(arguments[i] != parameters[i])
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Search for the first publicly and privately defined method of the given name and parameter count.
|
||||
*
|
||||
|
@ -1,7 +1,6 @@
|
||||
package com.comphenix.tinyprotocol;
|
||||
|
||||
import com.comphenix.tinyprotocol.Reflection.FieldAccessor;
|
||||
import com.comphenix.tinyprotocol.Reflection.MethodInvoker;
|
||||
import de.steamwar.core.Core;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelDuplexHandler;
|
||||
@ -29,8 +28,20 @@ public class TinyProtocol implements Listener {
|
||||
//enforce init
|
||||
}
|
||||
|
||||
private static final Class<?> craftServer = Reflection.getClass("{obc}.CraftServer");
|
||||
private static final Class<?> dedicatedPlayerList = Reflection.getClass("{nms.server.dedicated}.DedicatedPlayerList");
|
||||
private static final FieldAccessor<?> getPlayerList = Reflection.getField(craftServer, dedicatedPlayerList, 0);
|
||||
private static final Class<?> playerList = Reflection.getClass("{nms.server.players}.PlayerList");
|
||||
private static final Class<?> minecraftServer = Reflection.getClass("{nms.server}.MinecraftServer");
|
||||
private static final FieldAccessor<?> getMinecraftServer = Reflection.getField(playerList, minecraftServer, 0);
|
||||
private static final Class<?> serverConnection = Reflection.getClass("{nms.server.network}.ServerConnection");
|
||||
private static final FieldAccessor<?> getServerConnection = Reflection.getField(minecraftServer, serverConnection, 0);
|
||||
private static final Class<?> networkManager = Reflection.getClass("{nms.network}.NetworkManager");
|
||||
private static final FieldAccessor<List> getConnections = Reflection.getField(serverConnection, List.class, 0, networkManager);
|
||||
|
||||
private final Plugin plugin;
|
||||
private final String handlerName;
|
||||
private final List<?> connections;
|
||||
private boolean closed;
|
||||
|
||||
private final Map<Class<?>, List<BiFunction<Player, Object, Object>>> packetFilters = new HashMap<>();
|
||||
@ -38,11 +49,9 @@ public class TinyProtocol implements Listener {
|
||||
|
||||
private TinyProtocol(final Plugin plugin) {
|
||||
this.plugin = plugin;
|
||||
|
||||
// Compute handler name
|
||||
this.handlerName = "tiny-" + plugin.getName() + "-" + ++id;
|
||||
this.connections = getConnections.get(getServerConnection.get(getMinecraftServer.get(getPlayerList.get(plugin.getServer()))));
|
||||
|
||||
// Prepare existing players
|
||||
plugin.getServer().getPluginManager().registerEvents(this, plugin);
|
||||
|
||||
for (Player player : plugin.getServer().getOnlinePlayers()) {
|
||||
@ -103,12 +112,8 @@ public class TinyProtocol implements Listener {
|
||||
}
|
||||
}
|
||||
|
||||
private static final MethodInvoker getPlayerHandle = Reflection.getMethod("{obc}.entity.CraftPlayer", "getHandle");
|
||||
private static final Class<Object> playerConnection = Reflection.getUntypedClass("{nms.server.network}.PlayerConnection");
|
||||
private static final FieldAccessor<Object> getConnection = Reflection.getField("{nms.server.level}.EntityPlayer", playerConnection, 0);
|
||||
private static final Class<Object> networkManager = Reflection.getUntypedClass("{nms.network}.NetworkManager");
|
||||
private static final FieldAccessor<Object> getManager = Reflection.getField(playerConnection, networkManager, 0);
|
||||
private static final FieldAccessor<Channel> getChannel = Reflection.getField(networkManager, Channel.class, 0);
|
||||
private static final FieldAccessor<UUID> getUUID = Reflection.getField(networkManager, UUID.class, 0);
|
||||
|
||||
private final class PacketInterceptor extends ChannelDuplexHandler {
|
||||
private final Player player;
|
||||
@ -117,9 +122,7 @@ public class TinyProtocol implements Listener {
|
||||
private PacketInterceptor(Player player) {
|
||||
this.player = player;
|
||||
|
||||
Object connection = getConnection.get(getPlayerHandle.invoke(player));
|
||||
Object manager = getManager.get(connection);
|
||||
channel = getChannel.get(manager);
|
||||
channel = getChannel.get(connections.stream().filter(connection -> player.getUniqueId().equals(getUUID.get(connection))).findAny().orElseThrow(() -> new SecurityException("Could not find channel for player " + player.getName())));
|
||||
|
||||
synchronized (playerInterceptors) {
|
||||
playerInterceptors.put(player, this);
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren