Skip to content

Commit

Permalink
Added support for 1.18
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim203 committed Nov 27, 2021
1 parent a57bd24 commit 315efb9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 97 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,12 @@ public static Class<?> getClass(String className) {
}
}

@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);
Expand All @@ -104,16 +110,23 @@ public static Class<?> getClassOrThrow(String className) {
}

@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) {
Expand Down
87 changes: 19 additions & 68 deletions spigot/src/main/java/org/geysermc/floodgate/util/ClassNames.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -39,6 +36,7 @@
import java.lang.reflect.Method;
import java.net.SocketAddress;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;

@SuppressWarnings("PMD.SystemPrintln")
public class ClassNames {
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -82,88 +74,53 @@ 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);
checkNotNull(HANDSHAKE_HOST, "Handshake host");

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);
Expand All @@ -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");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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;
}

Expand All @@ -71,21 +63,16 @@ public static boolean addPlayer(UUID uuid, String username) {
* 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);
}
}

0 comments on commit 315efb9

Please sign in to comment.