Cache all methods and support PoreRT!

This commit is contained in:
Max Qian 2016-11-21 00:50:26 -08:00
parent f45aeab806
commit 2952d59743

View File

@ -14,52 +14,49 @@ import java.lang.reflect.Method;
* I don't think there will be any others supported other than bukkit but if there are its not just the compat that will * I don't think there will be any others supported other than bukkit but if there are its not just the compat that will
* need to change unless it has a different package for the minecraft server parts * need to change unless it has a different package for the minecraft server parts
* *
* @author sekwah41 * @author sekwah41 maxqia
*/ */
public class CraftBukkit { public class CraftBukkit {
private final String craftBukkitPackage;
private final String minecraftPackage;
private final AdvancedPortalsPlugin plugin; private final AdvancedPortalsPlugin plugin;
private Method serializeMessage;
private Constructor<?> chatPacketConstructor;
private Method chatMessageMethod; private Method playerGetHandle;
private Field playerConnection;
private Class<?> craftPlayer; private Method sendPacket;
private Class<?> chatPacket;
private Class<?> chatBaseComponent;
private Class<?> packet;
// Classes so it doesnt keep fetching them. // Classes so it doesnt keep fetching them.
public CraftBukkit(AdvancedPortalsPlugin plugin, String craftBukkitVer) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException { public CraftBukkit(AdvancedPortalsPlugin plugin, String bukkitImpl) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
this.craftBukkitPackage = "org.bukkit.craftbukkit." + craftBukkitVer + ".";
this.minecraftPackage = "net.minecraft.server." + craftBukkitVer + ".";
this.plugin = plugin; this.plugin = plugin;
this.setupCompat(); try {
// CraftBukkit Ahoy!
String craftBukkitPackage = "org.bukkit.craftbukkit." + bukkitImpl + ".";
String minecraftPackage = "net.minecraft.server." + bukkitImpl + ".";
Class<?> chatBaseComponent = Class.forName(minecraftPackage + "IChatBaseComponent"); // string to packet methods
this.serializeMessage = this.findClass(chatBaseComponent, "ChatSerializer").getMethod("a", String.class);
this.chatPacketConstructor = Class.forName(minecraftPackage + "PacketPlayOutChat").getConstructor(chatBaseComponent, byte.class);
this.playerGetHandle = Class.forName(craftBukkitPackage + "entity.CraftPlayer").getMethod("getHandle");
this.playerConnection = Class.forName(minecraftPackage + "EntityPlayer").getField("playerConnection"); // get player connection
Class<?> packet = Class.forName(minecraftPackage + "Packet");
this.sendPacket = playerConnection.getType().getMethod("sendPacket", packet);
} catch (Exception e) {
// Fall back on your Porekit
Class<?> textBaseComponent = Class.forName("net.minecraft.util.text.ITextComponent"); // string to packet methods
this.serializeMessage = this.findClass(textBaseComponent, "Serializer").getMethod("func_150699_a", String.class); // md: jsonToComponent
this.chatPacketConstructor = Class.forName("net.minecraft.network.play.server.SPacketChat").getConstructor(textBaseComponent, byte.class);
this.playerGetHandle = Class.forName("blue.lapis.pore.impl.entity.PorePlayer").getMethod("getHandle");
this.playerConnection = Class.forName("net.minecraft.entity.player.EntityPlayerMP").getField("field_71135_a"); // get player connection fd: connection
Class<?> packet = Class.forName("net.minecraft.network.Packet");
this.sendPacket = playerConnection.getType().getMethod("func_147359_a", packet); //md: sendPacket
} }
private void setupCompat() throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
this.craftPlayer = Class.forName(craftBukkitPackage + "entity.CraftPlayer");
this.chatBaseComponent = Class.forName(minecraftPackage + "IChatBaseComponent");
this.chatMessageMethod = this.findClass(chatBaseComponent, "ChatSerializer").getMethod("a", String.class);
this.chatPacket = Class.forName(minecraftPackage + "PacketPlayOutChat");
this.packet = Class.forName(minecraftPackage + "Packet");
} }
public void sendRawMessage(String rawMessage, Player player) { public void sendRawMessage(String rawMessage, Player player) {
@ -72,22 +69,13 @@ public class CraftBukkit {
public void sendMessage(String rawMessage, Player player, byte msgType) { public void sendMessage(String rawMessage, Player player, byte msgType) {
try { try {
Object comp = this.chatMessageMethod.invoke(null,rawMessage); Object comp = this.serializeMessage.invoke(null,rawMessage); // convert string into bytes
Object packet = this.chatPacketConstructor.newInstance(comp, msgType); // convert bytes into packet
Object handle = this.craftPlayer.getMethod("getHandle").invoke(player); Object handle = this.playerGetHandle.invoke(player);
Object playerConnection = this.playerConnection.get(handle); // get players connection
Field playerConnectionObj = handle.getClass().getDeclaredField("playerConnection"); sendPacket.invoke(playerConnection, packet); // send packet
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
Constructor<?> packetConstructor = this.chatPacket.getConstructor(this.chatBaseComponent, byte.class);
Object packet = packetConstructor.newInstance(comp, msgType);
Object playerConnection = playerConnectionObj.get(handle);
playerConnection.getClass().getMethod("sendPacket", this.packet).invoke(playerConnection, packet);
} catch (IllegalAccessException | InvocationTargetException | NoSuchMethodException | NoSuchFieldException
| InstantiationException e) {
this.plugin.getLogger().warning("Error creating raw message, something must be wrong with reflection"); this.plugin.getLogger().warning("Error creating raw message, something must be wrong with reflection");
e.printStackTrace(); e.printStackTrace();
} }