SteamWar/SpigotCore
Archiviert
13
0

Fix null connection issues
Alle Prüfungen waren erfolgreich
SteamWarCI Build successful

Dieser Commit ist enthalten in:
Lixfel 2022-08-23 12:47:53 +02:00
Ursprung 04b03ce06d
Commit cbbafd7c09
2 geänderte Dateien mit 40 neuen und 17 gelöschten Zeilen

Datei anzeigen

@ -7,6 +7,7 @@ import org.bukkit.Bukkit;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.util.Arrays; import java.util.Arrays;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -135,15 +136,16 @@ public final class Reflection {
return getField(getClass(className), fieldType, index); return getField(getClass(className), fieldType, index);
} }
// Common method public static <T> FieldAccessor<T> getField(Class<?> target, Class<T> fieldType, int index, Class<?>... parameters) {
private static <T> FieldAccessor<T> getField(Class<?> target, String name, Class<T> fieldType, int index) { 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()) { 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); field.setAccessible(true);
// A function for retrieving a specific field value
return new FieldAccessor<T>() { return new FieldAccessor<T>() {
@Override @Override
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public T get(Object target) { public T get(Object target) {
@ -179,6 +181,24 @@ public final class Reflection {
throw new IllegalArgumentException("Cannot find field with type " + fieldType); 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. * Search for the first publicly and privately defined method of the given name and parameter count.
* *

Datei anzeigen

@ -1,7 +1,6 @@
package com.comphenix.tinyprotocol; package com.comphenix.tinyprotocol;
import com.comphenix.tinyprotocol.Reflection.FieldAccessor; import com.comphenix.tinyprotocol.Reflection.FieldAccessor;
import com.comphenix.tinyprotocol.Reflection.MethodInvoker;
import de.steamwar.core.Core; import de.steamwar.core.Core;
import io.netty.channel.Channel; import io.netty.channel.Channel;
import io.netty.channel.ChannelDuplexHandler; import io.netty.channel.ChannelDuplexHandler;
@ -29,8 +28,20 @@ public class TinyProtocol implements Listener {
//enforce init //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 Plugin plugin;
private final String handlerName; private final String handlerName;
private final List<?> connections;
private boolean closed; private boolean closed;
private final Map<Class<?>, List<BiFunction<Player, Object, Object>>> packetFilters = new HashMap<>(); 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) { private TinyProtocol(final Plugin plugin) {
this.plugin = plugin; this.plugin = plugin;
// Compute handler name
this.handlerName = "tiny-" + plugin.getName() + "-" + ++id; 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); plugin.getServer().getPluginManager().registerEvents(this, plugin);
for (Player player : plugin.getServer().getOnlinePlayers()) { 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<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 class PacketInterceptor extends ChannelDuplexHandler {
private final Player player; private final Player player;
@ -117,9 +122,7 @@ public class TinyProtocol implements Listener {
private PacketInterceptor(Player player) { private PacketInterceptor(Player player) {
this.player = player; this.player = player;
Object connection = getConnection.get(getPlayerHandle.invoke(player)); 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())));
Object manager = getManager.get(connection);
channel = getChannel.get(manager);
synchronized (playerInterceptors) { synchronized (playerInterceptors) {
playerInterceptors.put(player, this); playerInterceptors.put(player, this);