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:
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user