1
0
mirror of https://github.com/GeyserMC/Floodgate.git synced 2026-01-04 15:31:48 +00:00

Added support for 1.18

This commit is contained in:
Tim203
2021-11-27 02:25:13 +01:00
parent a57bd24216
commit 315efb9e50
3 changed files with 48 additions and 97 deletions

View File

@@ -87,6 +87,12 @@ public final class ReflectionUtils {
}
}
@Nullable
@SuppressWarnings("unchecked")
public static <T> Class<T> getCastedClass(String className) {
return (Class<T>) getClass(className);
}
public static Class<?> getClassSilently(String className) {
try {
return Class.forName(className);
@@ -104,16 +110,23 @@ public final class ReflectionUtils {
}
@Nullable
public static Constructor<?> getConstructor(Class<?> clazz, Class<?>... parameters) {
public static <T> Constructor<T> getConstructor(Class<T> clazz, boolean declared, Class<?>... parameters) {
try {
return clazz.getConstructor(parameters);
Constructor<T> constructor;
if (declared) {
constructor = clazz.getDeclaredConstructor(parameters);
} else {
constructor = clazz.getConstructor(parameters);
}
makeAccessible(constructor);
return constructor;
} catch (NoSuchMethodException e) {
return null;
}
}
@Nullable
public static Object newInstance(Constructor<?> constructor, Object... parameters) {
public static <T> T newInstance(Constructor<T> constructor, Object... parameters) {
try {
return constructor.newInstance(parameters);
} catch (IllegalAccessException | InstantiationException | InvocationTargetException e) {

View File

@@ -25,11 +25,8 @@
package org.geysermc.floodgate.util;
import static org.geysermc.floodgate.util.ReflectionUtils.getConstructor;
import static org.geysermc.floodgate.util.ReflectionUtils.getFieldOfType;
import static org.geysermc.floodgate.util.ReflectionUtils.getMethod;
import static org.geysermc.floodgate.util.ReflectionUtils.getMethodByName;
import static org.geysermc.floodgate.util.ReflectionUtils.makeAccessible;
import com.google.common.base.Preconditions;
import com.mojang.authlib.GameProfile;
@@ -39,6 +36,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.SocketAddress;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
@SuppressWarnings("PMD.SystemPrintln")
public class ClassNames {
@@ -51,7 +49,7 @@ public class ClassNames {
public static final Class<?> LOGIN_LISTENER;
public static final Class<?> LOGIN_HANDLER;
public static final Constructor<?> WHITELIST_ENTRY;
public static final Constructor<OfflinePlayer> CRAFT_OFFLINE_PLAYER_CONSTRUCTOR;
public static final Constructor<?> LOGIN_HANDLER_CONSTRUCTOR;
public static final Field SOCKET_ADDRESS;
@@ -60,12 +58,6 @@ public class ClassNames {
public static final Field PACKET_LISTENER;
public static final Method GET_PROFILE_METHOD;
public static final Method GET_SERVER;
public static final Method GET_PLAYER_LIST;
public static final Method GET_WHITELIST;
public static final Method IS_WHITELISTED;
public static final Method ADD_WHITELIST_ENTRY;
public static final Method REMOVE_WHITELIST_ENTRY;
public static final Method LOGIN_DISCONNECT;
public static final Method NETWORK_EXCEPTION_CAUGHT;
public static final Method INIT_UUID;
@@ -82,75 +74,40 @@ public class ClassNames {
GET_PROFILE_METHOD = ReflectionUtils.getMethod(craftPlayerClass, "getProfile");
checkNotNull(GET_PROFILE_METHOD, "Get profile method");
version = SPIGOT_MAPPING_PREFIX + '.';
String nmsPackage = SPIGOT_MAPPING_PREFIX + '.';
// SpigotInjector
MINECRAFT_SERVER = getClassOrFallBack(
"net.minecraft.server.MinecraftServer",
version + "MinecraftServer"
nmsPackage + "MinecraftServer"
);
SERVER_CONNECTION = getClassOrFallBack(
"net.minecraft.server.network.ServerConnection",
version + "ServerConnection"
nmsPackage + "ServerConnection"
);
// WhitelistUtils
GET_SERVER = getMethod(MINECRAFT_SERVER, MINECRAFT_SERVER, true);
checkNotNull(GET_SERVER, "Get server cannot be null");
Class<?> playerList = getClassOrFallBack(
"net.minecraft.server.players.PlayerList",
version + "PlayerList"
);
GET_PLAYER_LIST = getMethod(MINECRAFT_SERVER, playerList, true);
checkNotNull(GET_PLAYER_LIST, "Get player list");
Class<?> whitelist = getClassOrFallBack(
"net.minecraft.server.players.WhiteList",
version + "WhiteList"
);
GET_WHITELIST = getMethod(playerList, whitelist, true);
checkNotNull(GET_WHITELIST, "Get whitelist");
IS_WHITELISTED = getMethodByName(whitelist, "isWhitelisted", true);
checkNotNull(IS_WHITELISTED, "Is whitelisted");
Class<?> whitelistEntry = getClassOrFallBack(
"net.minecraft.server.players.WhiteListEntry",
version + "WhiteListEntry"
);
WHITELIST_ENTRY = getConstructor(whitelistEntry, GameProfile.class);
checkNotNull(WHITELIST_ENTRY, "Whitelist entry constructor");
Class<?> jsonList = getClassOrFallBack(
"net.minecraft.server.players.JsonList",
version + "JsonList"
);
ADD_WHITELIST_ENTRY = getMethodByName(jsonList, "add", true);
checkNotNull(ADD_WHITELIST_ENTRY, "Add whitelist entry");
REMOVE_WHITELIST_ENTRY = getMethodByName(jsonList, "remove", true);
checkNotNull(REMOVE_WHITELIST_ENTRY, "Remove whitelist entry");
Class<?> craftServerClass = ReflectionUtils.getClass(
"org.bukkit.craftbukkit." + version + ".CraftServer");
Class<OfflinePlayer> craftOfflinePlayerClass = ReflectionUtils.getCastedClass(
"org.bukkit.craftbukkit." + version + ".CraftOfflinePlayer");
CRAFT_OFFLINE_PLAYER_CONSTRUCTOR = ReflectionUtils.getConstructor(
craftOfflinePlayerClass, true, craftServerClass, GameProfile.class);
// SpigotDataHandler
Class<?> networkManager = getClassOrFallBack(
"net.minecraft.network.NetworkManager",
version + "NetworkManager"
nmsPackage + "NetworkManager"
);
SOCKET_ADDRESS = getFieldOfType(networkManager, SocketAddress.class, false);
HANDSHAKE_PACKET = getClassOrFallBack(
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol",
version + "PacketHandshakingInSetProtocol"
nmsPackage + "PacketHandshakingInSetProtocol"
);
HANDSHAKE_HOST = getFieldOfType(HANDSHAKE_PACKET, String.class);
@@ -158,12 +115,12 @@ public class ClassNames {
LOGIN_START_PACKET = getClassOrFallBack(
"net.minecraft.network.protocol.login.PacketLoginInStart",
version + "PacketLoginInStart"
nmsPackage + "PacketLoginInStart"
);
LOGIN_LISTENER = getClassOrFallBack(
"net.minecraft.server.network.LoginListener",
version + "LoginListener"
nmsPackage + "LoginListener"
);
LOGIN_PROFILE = getFieldOfType(LOGIN_LISTENER, GameProfile.class);
@@ -184,24 +141,18 @@ public class ClassNames {
Class<?> packetListenerClass = getClassOrFallBack(
"net.minecraft.network.PacketListener",
version + "PacketListener"
nmsPackage + "PacketListener"
);
PACKET_LISTENER = getFieldOfType(networkManager, packetListenerClass);
checkNotNull(PACKET_LISTENER, "Packet listener");
LOGIN_HANDLER = getClassOrFallBack(
"net.minecraft.server.network.LoginListener$LoginHandler",
version + "LoginListener$LoginHandler"
nmsPackage + "LoginListener$LoginHandler"
);
Constructor<?> loginHandlerConstructor;
try {
loginHandlerConstructor =
makeAccessible(LOGIN_HANDLER.getDeclaredConstructor(LOGIN_LISTENER));
} catch (NoSuchMethodException e) {
throw new IllegalStateException(e);
}
LOGIN_HANDLER_CONSTRUCTOR = loginHandlerConstructor;
LOGIN_HANDLER_CONSTRUCTOR =
ReflectionUtils.getConstructor(LOGIN_HANDLER, true, LOGIN_LISTENER);
checkNotNull(LOGIN_HANDLER_CONSTRUCTOR, "LoginHandler constructor");
FIRE_LOGIN_EVENTS = getMethod(LOGIN_HANDLER, "fireEvents");

View File

@@ -25,17 +25,10 @@
package org.geysermc.floodgate.util;
import static org.geysermc.floodgate.util.ClassNames.ADD_WHITELIST_ENTRY;
import static org.geysermc.floodgate.util.ClassNames.GET_PLAYER_LIST;
import static org.geysermc.floodgate.util.ClassNames.GET_SERVER;
import static org.geysermc.floodgate.util.ClassNames.GET_WHITELIST;
import static org.geysermc.floodgate.util.ClassNames.IS_WHITELISTED;
import static org.geysermc.floodgate.util.ClassNames.REMOVE_WHITELIST_ENTRY;
import static org.geysermc.floodgate.util.ClassNames.WHITELIST_ENTRY;
import com.mojang.authlib.GameProfile;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
@SuppressWarnings("ConstantConditions")
public final class WhitelistUtils {
@@ -48,17 +41,16 @@ public final class WhitelistUtils {
* @return true if the player has been whitelisted, false if the player is already whitelisted
*/
public static boolean addPlayer(UUID uuid, String username) {
Object whitelist = getWhitelist();
GameProfile profile = new GameProfile(uuid, username);
if (ReflectionUtils.castedInvoke(whitelist, IS_WHITELISTED, profile)) {
OfflinePlayer player = ReflectionUtils.newInstance(
ClassNames.CRAFT_OFFLINE_PLAYER_CONSTRUCTOR,
Bukkit.getServer(), profile
);
if (player.isWhitelisted()) {
return false;
}
Object entry = ReflectionUtils.newInstance(WHITELIST_ENTRY, profile);
ReflectionUtils.invoke(whitelist, ADD_WHITELIST_ENTRY, entry);
player.setWhitelisted(true);
return true;
}
@@ -71,21 +63,16 @@ public final class WhitelistUtils {
* whitelisted
*/
public static boolean removePlayer(UUID uuid, String username) {
Object whitelist = getWhitelist();
GameProfile profile = new GameProfile(uuid, username);
if (!(boolean) ReflectionUtils.castedInvoke(whitelist, IS_WHITELISTED, profile)) {
OfflinePlayer player = ReflectionUtils.newInstance(
ClassNames.CRAFT_OFFLINE_PLAYER_CONSTRUCTOR,
Bukkit.getServer(), profile
);
if (!player.isWhitelisted()) {
return false;
}
ReflectionUtils.invoke(whitelist, REMOVE_WHITELIST_ENTRY, profile);
player.setWhitelisted(false);
return true;
}
private static Object getWhitelist() {
Object minecraftServer = ReflectionUtils.invoke(Bukkit.getServer(), GET_SERVER);
Object playerList = ReflectionUtils.invoke(minecraftServer, GET_PLAYER_LIST);
return ReflectionUtils.invoke(playerList, GET_WHITELIST);
}
}