Introduces a cross-version way to send packets via NMSManager

This commit is contained in:
Christian Koop 2021-12-02 20:29:18 +01:00
parent 41d6df6205
commit 6c8c8a3a29
No known key found for this signature in database
GPG Key ID: 89A8181384E010A3
23 changed files with 273 additions and 11 deletions

View File

@ -15,6 +15,8 @@ import java.util.logging.Logger;
/**
* Particle effects for servers 1.8 and below
*
* TODO: Needs a recode, this class should not have any advanced logic like NMS magic
*/
public class LegacyParticleEffects {
public enum Type {
@ -124,7 +126,7 @@ public class LegacyParticleEffects {
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField("playerConnection");
mc_playerConnectionClazz = Class.forName("net.minecraft.server." + version + ".PlayerConnection");
mc_PacketInterface = Class.forName("net.minecraft.server." + version + ".Packet");
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod(ServerVersion.isServerVersion(ServerVersion.V1_18) ? "a" : "sendPacket", mc_PacketInterface); // FIXME: Doesn't work cross version, use NMSManager#getPlayer() instead
if (version.startsWith("v1_8")) {
// Aren't worrying about anything after 1.8 in this class here
mc_EnumParticle = Class.forName("net.minecraft.server." + version + ".EnumParticle");
@ -244,6 +246,12 @@ public class LegacyParticleEffects {
}
}
// FIXME: Remove this method on next major release
/**
* @deprecated Doesn't work cross version, use NMSManager#getPlayer() instead
*/
@Deprecated
private static void sendPacket(Object packet, Player to) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Object cbPlayer = cb_craftPlayer_getHandle.invoke(to);
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);

View File

@ -5,6 +5,7 @@ import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.utils.TextUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
@ -234,9 +235,7 @@ public class ChatMessage {
packet = mc_PacketPlayOutChat_new.newInstance(mc_IChatBaseComponent_ChatSerializer_a.invoke(null, gson.toJson(textList)));
}
Object cbPlayer = cb_craftPlayer_getHandle.invoke(sender);
Object mcConnection = mc_entityPlayer_playerConnection.get(cbPlayer);
mc_playerConnection_sendPacket.invoke(mcConnection, packet);
NmsManager.getPlayer().sendPacket((Player) sender, packet);
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
Bukkit.getLogger().log(Level.WARNING, "Problem preparing raw chat packets (disabling further packets)", ex);
enabled = false;
@ -251,7 +250,7 @@ public class ChatMessage {
private static boolean enabled = ServerVersion.isServerVersionAtLeast(ServerVersion.V1_8);
private static Class<?> mc_ChatMessageType;
private static Method mc_IChatBaseComponent_ChatSerializer_a, cb_craftPlayer_getHandle, mc_playerConnection_sendPacket;
private static Method mc_IChatBaseComponent_ChatSerializer_a, cb_craftPlayer_getHandle;
private static Constructor mc_PacketPlayOutChat_new;
private static Field mc_entityPlayer_playerConnection, mc_chatMessageType_Chat;
@ -263,16 +262,13 @@ public class ChatMessage {
if (enabled) {
try {
final String version = ServerVersion.getServerVersionString();
Class<?> cb_craftPlayerClazz, mc_entityPlayerClazz, mc_playerConnectionClazz, mc_PacketInterface,
Class<?> cb_craftPlayerClazz, mc_entityPlayerClazz,
mc_IChatBaseComponent, mc_IChatBaseComponent_ChatSerializer, mc_PacketPlayOutChat;
cb_craftPlayerClazz = ClassMapping.CRAFT_PLAYER.getClazz();
cb_craftPlayer_getHandle = cb_craftPlayerClazz.getDeclaredMethod("getHandle");
mc_entityPlayerClazz = ClassMapping.ENTITY_PLAYER.getClazz();
mc_entityPlayer_playerConnection = mc_entityPlayerClazz.getDeclaredField(ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17) ? "b" : "playerConnection");
mc_playerConnectionClazz = ClassMapping.PLAYER_CONNECTION.getClazz();
mc_PacketInterface = ClassMapping.PACKET.getClazz();
mc_playerConnection_sendPacket = mc_playerConnectionClazz.getDeclaredMethod("sendPacket", mc_PacketInterface);
mc_IChatBaseComponent = ClassMapping.I_CHAT_BASE_COMPONENT.getClazz();
mc_IChatBaseComponent_ChatSerializer = ClassMapping.I_CHAT_BASE_COMPONENT.getClazz("ChatSerializer");
mc_IChatBaseComponent_ChatSerializer_a = mc_IChatBaseComponent_ChatSerializer.getMethod("a", String.class);

View File

@ -1,6 +1,7 @@
package com.songoda.core.nms;
import com.songoda.core.nms.anvil.AnvilCore;
import com.songoda.core.nms.entity.NMSPlayer;
import com.songoda.core.nms.nbt.NBTCore;
import com.songoda.core.nms.world.WorldCore;
import org.bukkit.Bukkit;
@ -11,6 +12,7 @@ import java.util.logging.Logger;
public class NmsManager {
private static final String serverPackagePath = Bukkit.getServer().getClass().getPackage().getName();
private static final String serverPackageVersion = serverPackagePath.substring(serverPackagePath.lastIndexOf('.') + 1);
private static final NMSPlayer player;
private static final AnvilCore anvil;
private static final NBTCore nbt;
private static final WorldCore world;
@ -18,86 +20,103 @@ public class NmsManager {
static {
switch (serverPackageVersion) {
case "v1_8_R1":
player = new com.songoda.core.nms.v1_8_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_8_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_8_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_8_R1.world.WorldCoreImpl();
break;
case "v1_8_R2":
player = new com.songoda.core.nms.v1_8_R2.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_8_R2.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_8_R2.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_8_R2.world.WorldCoreImpl();
break;
case "v1_8_R3":
player = new com.songoda.core.nms.v1_8_R3.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_8_R3.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_8_R3.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_8_R3.world.WorldCoreImpl();
break;
case "v1_9_R1":
player = new com.songoda.core.nms.v1_9_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_9_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_9_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_9_R1.world.WorldCoreImpl();
break;
case "v1_9_R2":
player = new com.songoda.core.nms.v1_9_R2.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_9_R2.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_9_R2.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_9_R2.world.WorldCoreImpl();
break;
case "v1_10_R1":
player = new com.songoda.core.nms.v1_10_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_10_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_10_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_10_R1.world.WorldCoreImpl();
break;
case "v1_11_R1":
player = new com.songoda.core.nms.v1_11_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_11_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_11_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_11_R1.world.WorldCoreImpl();
break;
case "v1_12_R1":
player = new com.songoda.core.nms.v1_12_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_12_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_12_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_12_R1.world.WorldCoreImpl();
break;
case "v1_13_R1":
player = new com.songoda.core.nms.v1_13_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_13_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_13_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_13_R1.world.WorldCoreImpl();
break;
case "v1_13_R2":
player = new com.songoda.core.nms.v1_13_R2.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_13_R2.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_13_R2.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_13_R2.world.WorldCoreImpl();
break;
case "v1_14_R1":
player = new com.songoda.core.nms.v1_14_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_14_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_14_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_14_R1.world.WorldCoreImpl();
break;
case "v1_15_R1":
player = new com.songoda.core.nms.v1_15_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_15_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_15_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_15_R1.world.WorldCoreImpl();
break;
case "v1_16_R1":
player = new com.songoda.core.nms.v1_16_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_16_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_16_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_16_R1.world.WorldCoreImpl();
break;
case "v1_16_R2":
player = new com.songoda.core.nms.v1_16_R2.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_16_R2.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_16_R2.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_16_R2.world.WorldCoreImpl();
break;
case "v1_16_R3":
player = new com.songoda.core.nms.v1_16_R3.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_16_R3.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_16_R3.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_16_R3.world.WorldCoreImpl();
break;
case "v1_17_R1":
player = new com.songoda.core.nms.v1_17_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_17_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_17_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_17_R1.world.WorldCoreImpl();
break;
case "v1_18_R1":
player = new com.songoda.core.nms.v1_18_R1.entity.NMSPlayerImpl();
anvil = new com.songoda.core.nms.v1_18_R1.anvil.AnvilCore();
nbt = new com.songoda.core.nms.v1_18_R1.nbt.NBTCoreImpl();
world = new com.songoda.core.nms.v1_18_R1.world.WorldCoreImpl();
@ -105,6 +124,7 @@ public class NmsManager {
default:
Logger.getLogger(NmsManager.class.getName()).log(Level.SEVERE, "Failed to load NMS for this server version: version {0} not found", serverPackageVersion);
player = null;
anvil = null;
nbt = null;
world = null;
@ -112,6 +132,10 @@ public class NmsManager {
}
}
public static NMSPlayer getPlayer() {
return player;
}
public static AnvilCore getAnvil() {
return anvil;
}

View File

@ -66,6 +66,11 @@ public class NMSUtils {
}
}
// FIXME: Remove this method on next major release
/**
* @deprecated Doesn't work cross version, use NMSManager#getPlayer() instead
*/
@Deprecated
public static void sendPacket(Player player, Object packet) {
try {
Object handle = player.getClass().getMethod("getHandle").invoke(player);

View File

@ -2,6 +2,7 @@ package com.songoda.core.world;
import com.songoda.core.compatibility.ClassMapping;
import com.songoda.core.compatibility.ServerVersion;
import com.songoda.core.nms.NmsManager;
import com.songoda.core.utils.NMSUtils;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -82,12 +83,12 @@ public class SWorldBorder {
if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_17)) {
Object packet = clientboundInitializeBorderPacketConstructor.newInstance(worldBorder);
NMSUtils.sendPacket(player, packet);
NmsManager.getPlayer().sendPacket(player, packet);
} else {
@SuppressWarnings({"unchecked", "rawtypes"})
Object packet = packetPlayOutWorldBorderConstructor.newInstance(worldBorder,
Enum.valueOf((Class<Enum>) packetPlayOutWorldBorderEnumClass, "INITIALIZE"));
NMSUtils.sendPacket(player, packet);
NmsManager.getPlayer().sendPacket(player, packet);
}
} catch (InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException ex) {
ex.printStackTrace();

View File

@ -0,0 +1,7 @@
package com.songoda.core.nms.entity;
import org.bukkit.entity.Player;
public interface NMSPlayer {
void sendPacket(Player p, Object packet);
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_10_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_10_R1.Packet;
import org.bukkit.craftbukkit.v1_10_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_11_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_11_R1.Packet;
import org.bukkit.craftbukkit.v1_11_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_12_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_12_R1.Packet;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_13_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_13_R1.Packet;
import org.bukkit.craftbukkit.v1_13_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_13_R2.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_13_R2.Packet;
import org.bukkit.craftbukkit.v1_13_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_14_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_14_R1.Packet;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_15_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_15_R1.Packet;
import org.bukkit.craftbukkit.v1_15_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_16_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_16_R1.Packet;
import org.bukkit.craftbukkit.v1_16_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_16_R2.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_16_R2.Packet;
import org.bukkit.craftbukkit.v1_16_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_16_R3.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_16_R3.Packet;
import org.bukkit.craftbukkit.v1_16_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_17_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.network.protocol.Packet;
import org.bukkit.craftbukkit.v1_17_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().b.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_18_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.network.protocol.Packet;
import org.bukkit.craftbukkit.v1_18_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().b.a((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_8_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_8_R1.Packet;
import org.bukkit.craftbukkit.v1_8_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_8_R2.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_8_R2.Packet;
import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_8_R3.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_8_R3.Packet;
import org.bukkit.craftbukkit.v1_8_R3.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_9_R1.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_9_R1.Packet;
import org.bukkit.craftbukkit.v1_9_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}

View File

@ -0,0 +1,13 @@
package com.songoda.core.nms.v1_9_R2.entity;
import com.songoda.core.nms.entity.NMSPlayer;
import net.minecraft.server.v1_9_R2.Packet;
import org.bukkit.craftbukkit.v1_9_R2.entity.CraftPlayer;
import org.bukkit.entity.Player;
public class NMSPlayerImpl implements NMSPlayer {
@Override
public void sendPacket(Player p, Object packet) {
((CraftPlayer) p).getHandle().playerConnection.sendPacket((Packet<?>) packet);
}
}