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
* need to change unless it has a different package for the minecraft server parts
*
* @author sekwah41
* @author sekwah41 maxqia
*/
public class CraftBukkit {
private final String craftBukkitPackage;
private final String minecraftPackage;
private final AdvancedPortalsPlugin plugin;
private Method serializeMessage;
private Constructor<?> chatPacketConstructor;
private Method chatMessageMethod;
private Class<?> craftPlayer;
private Class<?> chatPacket;
private Class<?> chatBaseComponent;
private Class<?> packet;
private Method playerGetHandle;
private Field playerConnection;
private Method sendPacket;
// Classes so it doesnt keep fetching them.
public CraftBukkit(AdvancedPortalsPlugin plugin, String craftBukkitVer) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
this.craftBukkitPackage = "org.bukkit.craftbukkit." + craftBukkitVer + ".";
this.minecraftPackage = "net.minecraft.server." + craftBukkitVer + ".";
public CraftBukkit(AdvancedPortalsPlugin plugin, String bukkitImpl) throws ClassNotFoundException, NoSuchFieldException, NoSuchMethodException {
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) {
@ -72,22 +69,13 @@ public class CraftBukkit {
public void sendMessage(String rawMessage, Player player, byte msgType) {
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);
Field playerConnectionObj = handle.getClass().getDeclaredField("playerConnection");
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) {
Object handle = this.playerGetHandle.invoke(player);
Object playerConnection = this.playerConnection.get(handle); // get players connection
sendPacket.invoke(playerConnection, packet); // send packet
} catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
this.plugin.getLogger().warning("Error creating raw message, something must be wrong with reflection");
e.printStackTrace();
}