I've been trying to use reflection with Net Minecraft Server classes since they are version dependent. I've made a class that emulates the PacketPlayOutWorldParticles, but I wanted to do more. Since I needed to make a Chest look open and so, first I made sure that the packet would work. Then I made this:
public class ChestReflection {
// Reference
// PacketPlayOutBlockAction packet = new PacketPlayOutBlockAction(new
// BlockPosition(x, y, z), BlockChest, 1, 1);
private Class<?> getNMSClass(String nmsClassString) throws ClassNotFoundException {
String version = Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + ".";
String name = "net.minecraft.server." + version + nmsClassString;
Class<?> nmsClass = Class.forName(name);
return nmsClass;
}
private Object getConnection(Player player) throws SecurityException, NoSuchMethodException, NoSuchFieldException,
IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Method getHandle = player.getClass().getMethod("getHandle");
Object nmsPlayer = getHandle.invoke(player);
Field conField = nmsPlayer.getClass().getField("playerConnection");
Object con = conField.get(nmsPlayer);
return con;
}
private Object getBlockPosition(Location loc)
throws ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException,
InvocationTargetException, NoSuchMethodException, SecurityException {
Class<?> nmsBlockPosition = getNMSClass("BlockPosition");
Object nmsBlockPositionInstance = nmsBlockPosition
.getConstructor(new Class[] { Double.TYPE, Double.TYPE, Double.TYPE })
.newInstance(new Object[] { loc.getX(), loc.getY(), loc.getZ() });
return nmsBlockPositionInstance;
}
public void setChest(Player player, int open, Location loc) {
try {
Class<?> nmsBlockPositionClass = getNMSClass("BlockPosition");
Object nmsBlockPos = getBlockPosition(loc);
Class<?> nmsPacketBlockAction = getNMSClass("PacketPlayOutBlockAction");
Class<?> nmsBlock = getNMSClass("Block");
Object nmsChest = getNMSClass("Blocks").getField("Chest");
Class<?> nmsPacket = getNMSClass("Packet");
Object nmsPackInstance = nmsPacketBlockAction
.getConstructor(new Class[] { nmsBlockPositionClass, nmsBlock, Integer.TYPE, Integer.TYPE })
.newInstance(new Object[] { nmsBlockPos, nmsChest, Integer.valueOf(1), Integer.valueOf(open) });
Method sendPacket = getConnection(player).getClass().getMethod("sendPacket", nmsPacket);
sendPacket.invoke(new Object[] { nmsPackInstance });
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException | SecurityException | NoSuchFieldException e) {
e.printStackTrace();
}
-this is the reference-
new PacketPlayOutBlockAction(new BlockPosition(loc.getX(), loc.getY(), loc.getZ()), Blocks.CHEST, 1, 0);
}
public void setChestOpenForEveryone(int open, Location loc) {
for (Player player : Bukkit.getOnlinePlayers()) {
setChest(player, open, loc);
}
}
}
And it gives me an error, at line 54 wich is .newInstance(new Object[] { nmsBlockPos, nmsChest, Integer.valueOf(1), Integer.valueOf(open) });
Error: java.lang.IllegalArgumentException: java.lang.ClassCastException@61f9358b
And I don't actually know what is causing it. Also I have included the packet without reflection for reference.
Sorry if this is formatted badly, but I could not get all the code in the 'code' cointainer.
Aucun commentaire:
Enregistrer un commentaire