Fixed all stupid NMS changes for 1.20.6+
This commit is contained in:
parent
bd6a24a242
commit
3f382583a7
4 changed files with 75 additions and 24 deletions
|
@ -34,7 +34,6 @@ import java.util.Set;
|
||||||
import java.util.concurrent.CopyOnWriteArrayList;
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import static com.cryptomorin.xseries.reflection.XReflection.*;
|
import static com.cryptomorin.xseries.reflection.XReflection.*;
|
||||||
import static com.cryptomorin.xseries.reflection.minecraft.MinecraftConnection.getHandle;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The {@link MapManager} manages all the maps. It also contains functions for wrapping.
|
* The {@link MapManager} manages all the maps. It also contains functions for wrapping.
|
||||||
|
|
|
@ -297,7 +297,17 @@ public class MapWrapper extends AbstractMapWrapper {
|
||||||
if (supports(20, 4)) {
|
if (supports(20, 4)) {
|
||||||
Object mapIdComponent = ReflectionUtil.getDeclaredField(getNMSClass("core.component", "DataComponents"), "B");
|
Object mapIdComponent = ReflectionUtil.getDeclaredField(getNMSClass("core.component", "DataComponents"), "B");
|
||||||
Object mapId1 = ReflectionUtil.callConstructor(getNMSClass("world.level.saveddata.maps", "MapId"), mapId);
|
Object mapId1 = ReflectionUtil.callConstructor(getNMSClass("world.level.saveddata.maps", "MapId"), mapId);
|
||||||
ReflectionUtil.callMethod(nmsStack, "b", mapIdComponent, mapId1);
|
|
||||||
|
// Use generic reflection because of generics
|
||||||
|
// <T> T ItemStack#b(DataComponentType<? super T> dataComponentType, T t)
|
||||||
|
try {
|
||||||
|
Method m = nmsStack.getClass().getMethod("b", getNMSClass("core.component", "DataComponentType"), Object.class);
|
||||||
|
m.setAccessible(true);
|
||||||
|
m.invoke(nmsStack, mapIdComponent, mapId1);
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
} else if (supports(13)) {
|
} else if (supports(13)) {
|
||||||
String nbtObjectName;
|
String nbtObjectName;
|
||||||
if (supports(20)) { //1.20
|
if (supports(20)) { //1.20
|
||||||
|
|
|
@ -30,14 +30,18 @@ import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
import org.bukkit.util.Vector;
|
import org.bukkit.util.Vector;
|
||||||
|
import sun.misc.Unsafe;
|
||||||
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
import tech.sbdevelopment.mapreflectionapi.MapReflectionAPI;
|
||||||
import tech.sbdevelopment.mapreflectionapi.api.events.CreativeInventoryMapUpdateEvent;
|
import tech.sbdevelopment.mapreflectionapi.api.events.CreativeInventoryMapUpdateEvent;
|
||||||
import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent;
|
import tech.sbdevelopment.mapreflectionapi.api.events.MapCancelEvent;
|
||||||
import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent;
|
import tech.sbdevelopment.mapreflectionapi.api.events.MapInteractEvent;
|
||||||
import tech.sbdevelopment.mapreflectionapi.utils.ReflectionUtil;
|
import tech.sbdevelopment.mapreflectionapi.utils.ReflectionUtil;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import static com.cryptomorin.xseries.reflection.minecraft.MinecraftConnection.getConnection;
|
||||||
import static com.cryptomorin.xseries.reflection.minecraft.MinecraftConnection.getHandle;
|
import static com.cryptomorin.xseries.reflection.minecraft.MinecraftConnection.getHandle;
|
||||||
import static tech.sbdevelopment.mapreflectionapi.utils.ReflectionUtil.*;
|
import static tech.sbdevelopment.mapreflectionapi.utils.ReflectionUtil.*;
|
||||||
import static com.cryptomorin.xseries.reflection.XReflection.*;
|
import static com.cryptomorin.xseries.reflection.XReflection.*;
|
||||||
|
@ -51,7 +55,7 @@ public class PacketListener implements Listener {
|
||||||
private static final Class<?> playerCommonConnection;
|
private static final Class<?> playerCommonConnection;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (supports(20) && supportsPatch(2)) {
|
if (supports(20, 2)) {
|
||||||
// The packet send method has been abstracted from ServerGamePacketListenerImpl to ServerCommonPacketListenerImpl in 1.20.2
|
// The packet send method has been abstracted from ServerGamePacketListenerImpl to ServerCommonPacketListenerImpl in 1.20.2
|
||||||
playerCommonConnection = getNMSClass("server.network", "ServerCommonPacketListenerImpl");
|
playerCommonConnection = getNMSClass("server.network", "ServerCommonPacketListenerImpl");
|
||||||
} else {
|
} else {
|
||||||
|
@ -78,11 +82,34 @@ public class PacketListener implements Listener {
|
||||||
if (packet.getClass().isAssignableFrom(packetPlayOutMapClass)) {
|
if (packet.getClass().isAssignableFrom(packetPlayOutMapClass)) {
|
||||||
Object packetPlayOutMap = packetPlayOutMapClass.cast(packet);
|
Object packetPlayOutMap = packetPlayOutMapClass.cast(packet);
|
||||||
|
|
||||||
int id = (int) getDeclaredField(packetPlayOutMap, "a");
|
int id;
|
||||||
|
boolean inv = false;
|
||||||
|
if (supports(20, 4)) { //1.20.4 uses MapId class and record classes (final fields...)
|
||||||
|
Object mapId = getDeclaredField(packetPlayOutMap, "b");
|
||||||
|
id = (int) getDeclaredField(mapId, "c");
|
||||||
|
|
||||||
if (id < 0) {
|
if (id < 0) {
|
||||||
int newId = -id;
|
Object newMapid = callConstructor(mapId.getClass(), -id);
|
||||||
setDeclaredField(packetPlayOutMap, "a", newId);
|
Object c = getDeclaredField(packetPlayOutMap, "c");
|
||||||
|
Object d = getDeclaredField(packetPlayOutMap, "d");
|
||||||
|
Object e = getDeclaredField(packetPlayOutMap, "e");
|
||||||
|
Object f = getDeclaredField(packetPlayOutMap, "f");
|
||||||
|
|
||||||
|
packetPlayOutMap = callConstructor(packetPlayOutMapClass, newMapid, c, d, e, f);
|
||||||
|
packet = packetPlayOutMap;
|
||||||
|
|
||||||
|
inv = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
id = (int) getDeclaredField(packetPlayOutMap, "a");
|
||||||
|
|
||||||
|
if (id < 0) {
|
||||||
|
setDeclaredField(packetPlayOutMap, "a", -id);
|
||||||
|
inv = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inv) {
|
||||||
boolean async = !MapReflectionAPI.getInstance().getServer().isPrimaryThread();
|
boolean async = !MapReflectionAPI.getInstance().getServer().isPrimaryThread();
|
||||||
MapCancelEvent event = new MapCancelEvent(player, id, async);
|
MapCancelEvent event = new MapCancelEvent(player, id, async);
|
||||||
if (MapReflectionAPI.getMapManager().isIdUsedBy(player, id)) event.setCancelled(true);
|
if (MapReflectionAPI.getMapManager().isIdUsedBy(player, id)) event.setCancelled(true);
|
||||||
|
@ -102,13 +129,13 @@ public class PacketListener implements Listener {
|
||||||
if (packet.getClass().isAssignableFrom(packetPlayInUseEntityClass)) {
|
if (packet.getClass().isAssignableFrom(packetPlayInUseEntityClass)) {
|
||||||
Object packetPlayInEntity = packetPlayInUseEntityClass.cast(packet);
|
Object packetPlayInEntity = packetPlayInUseEntityClass.cast(packet);
|
||||||
|
|
||||||
int entityId = (int) getDeclaredField(packetPlayInEntity, "a");
|
int entityId = (int) getDeclaredField(packetPlayInEntity, supports(20, 4) ? "b" : "a");
|
||||||
|
|
||||||
Enum<?> actionEnum;
|
Enum<?> actionEnum;
|
||||||
Enum<?> hand;
|
Enum<?> hand;
|
||||||
Object pos;
|
Object pos;
|
||||||
if (supports(17)) {
|
if (supports(17)) {
|
||||||
Object action = getDeclaredField(packetPlayInEntity, "b");
|
Object action = getDeclaredField(packetPlayInEntity, supports(20, 4) ? "c" : "b");
|
||||||
actionEnum = (Enum<?>) callDeclaredMethod(action, "a");
|
actionEnum = (Enum<?>) callDeclaredMethod(action, "a");
|
||||||
Class<?> d = getNMSClass("network.protocol.game", "PacketPlayInUseEntity$d");
|
Class<?> d = getNMSClass("network.protocol.game", "PacketPlayInUseEntity$d");
|
||||||
Class<?> e = getNMSClass("network.protocol.game", "PacketPlayInUseEntity$e");
|
Class<?> e = getNMSClass("network.protocol.game", "PacketPlayInUseEntity$e");
|
||||||
|
@ -141,7 +168,12 @@ public class PacketListener implements Listener {
|
||||||
} else if (packet.getClass().isAssignableFrom(packetPlayInSetCreativeSlotClass)) {
|
} else if (packet.getClass().isAssignableFrom(packetPlayInSetCreativeSlotClass)) {
|
||||||
Object packetPlayInSetCreativeSlot = packetPlayInSetCreativeSlotClass.cast(packet);
|
Object packetPlayInSetCreativeSlot = packetPlayInSetCreativeSlotClass.cast(packet);
|
||||||
|
|
||||||
int slot = (int) ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(20, 4) ? "b" : supports(19, 4) ? "a" : supports(13) ? "b" : "a"); //1.20.4 - 1.19.4 = a, 1.19.3 - 1.13 and 1.20.5 = b, 1.12 = a
|
int slot;
|
||||||
|
if (supports(20, 4)) { //1.20.4+ uses short
|
||||||
|
slot = (short) ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, "b");
|
||||||
|
} else { //1.20.3 and lower uses int
|
||||||
|
slot = (int) ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(19, 4) ? "a" : supports(13) ? "b" : "a"); //1.20.4 - 1.19.4 = a, 1.19.3 - 1.13 and 1.20.5 = b, 1.12 = a
|
||||||
|
}
|
||||||
Object nmsStack = ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(20, 4) ? "e" : supports(20, 2) ? "d" : supports(18) ? "c" : "getItemStack"); //1.20.5 = e, 1.20.2-1.20.4 = d, >= 1.18 = c, 1.17 = getItemStack
|
Object nmsStack = ReflectionUtil.callDeclaredMethod(packetPlayInSetCreativeSlot, supports(20, 4) ? "e" : supports(20, 2) ? "d" : supports(18) ? "c" : "getItemStack"); //1.20.5 = e, 1.20.2-1.20.4 = d, >= 1.18 = c, 1.17 = getItemStack
|
||||||
ItemStack craftStack = (ItemStack) ReflectionUtil.callMethod(craftStackClass, "asBukkitCopy", nmsStack);
|
ItemStack craftStack = (ItemStack) ReflectionUtil.callMethod(craftStackClass, "asBukkitCopy", nmsStack);
|
||||||
|
|
||||||
|
@ -167,9 +199,7 @@ public class PacketListener implements Listener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Channel getChannel(Player player) {
|
private Channel getChannel(Player player) {
|
||||||
Object playerHandle = getHandle(player);
|
Object networkManager = getDeclaredField(playerCommonConnection, getConnection(player), supports(21) ? "e" : supports(20, 2) ? "c" : supports(19, 4) ? "h" : supports(19) ? "b" : supports(17) ? "a" : "networkManager"); //1.20.2 = ServerCommonPacketListenerImpl#c, 1.20(.1) & 1.19.4 = h, >= 1.19.3 = b, 1.18 - 1.17 = a, 1.16 = networkManager
|
||||||
Object playerConnection = getDeclaredField(playerHandle, supports(20) ? "c" : supports(17) ? "b" : "playerConnection"); //1.20 = c, 1.17-1.19 = b, 1.16 = playerConnection
|
|
||||||
Object networkManager = getDeclaredField(playerCommonConnection, playerConnection, supports(20, 2) ? "c" : supports(19, 4) ? "h" : supports(19) ? "b" : supports(17) ? "a" : "networkManager"); //1.20.2 = ServerCommonPacketListenerImpl#c, 1.20(.1) & 1.19.4 = h, >= 1.19.3 = b, 1.18 - 1.17 = a, 1.16 = networkManager
|
|
||||||
return (Channel) getDeclaredField(networkManager, supports(20, 2) ? "n" : supports(18) ? "m" : supports(17) ? "k" : "channel"); //1.20.2 = n, 1.20(.1), 1.19 & 1.18 = m, 1.17 = k, 1.16 = channel
|
return (Channel) getDeclaredField(networkManager, supports(20, 2) ? "n" : supports(18) ? "m" : supports(17) ? "k" : "channel"); //1.20.2 = n, 1.20(.1), 1.19 & 1.18 = m, 1.17 = k, 1.16 = channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ public class ReflectionUtil {
|
||||||
private static final Map<String, Constructor<?>> constructorCache = new HashMap<>();
|
private static final Map<String, Constructor<?>> constructorCache = new HashMap<>();
|
||||||
private static final Map<String, Method> methodCache = new HashMap<>();
|
private static final Map<String, Method> methodCache = new HashMap<>();
|
||||||
private static final Map<String, Field> fieldCache = new HashMap<>();
|
private static final Map<String, Field> fieldCache = new HashMap<>();
|
||||||
|
private static final Class<?> craftWorld = getCraftClass("CraftWorld");
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class converted to {@link List}
|
* Helper class converted to {@link List}
|
||||||
|
@ -76,17 +77,8 @@ public class ReflectionUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Object getHandle(@NotNull World world) {
|
public static Object getHandle(@NotNull World world) {;
|
||||||
Class<?> worldServer = getNMSClass("server.level", "WorldServer");
|
return callDeclaredMethod(craftWorld, world, "getHandle");
|
||||||
Class<?> craftWorld = getCraftClass("CraftWorld");
|
|
||||||
try {
|
|
||||||
Method m = craftWorld.getMethod("getHandle", worldServer);
|
|
||||||
m.setAccessible(true);
|
|
||||||
return m.invoke(null, world);
|
|
||||||
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
|
|
||||||
ex.printStackTrace();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -243,6 +235,26 @@ public class ReflectionUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static Object callDeclaredMethod(Class<?> clazz, Object obj, String method, Object... params) {
|
||||||
|
try {
|
||||||
|
String cacheKey = "DeclaredMethod:" + clazz.getName() + ":" + method + ":" + Arrays.hashCode(params);
|
||||||
|
|
||||||
|
if (methodCache.containsKey(cacheKey)) {
|
||||||
|
Method cachedMethod = methodCache.get(cacheKey);
|
||||||
|
return cachedMethod.invoke(obj, params);
|
||||||
|
} else {
|
||||||
|
Method m = clazz.getDeclaredMethod(method, toParamTypes(params));
|
||||||
|
m.setAccessible(true);
|
||||||
|
methodCache.put(cacheKey, m);
|
||||||
|
return m.invoke(obj, params);
|
||||||
|
}
|
||||||
|
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean hasField(Object packet, String field) {
|
public static boolean hasField(Object packet, String field) {
|
||||||
try {
|
try {
|
||||||
String cacheKey = "HasField:" + packet.getClass().getName() + ":" + field;
|
String cacheKey = "HasField:" + packet.getClass().getName() + ":" + field;
|
||||||
|
|
Loading…
Add table
Reference in a new issue