package eu.univento.core.api.utils; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import org.bukkit.Location; import org.bukkit.entity.Player; public class FakeWither { private static Constructor packetPlayOutSpawnEntityLiving; private static Constructor entityEntityWither; private static Method setLocation; private static Method setCustomName; private static Method setHealth; private static Method setInvisible; private static Method getWorldHandle; private static Method getPlayerHandle; private static Field playerConnection; private static Method sendPacket; private static Method getDatawatcher; private static Method a; private static Field d; private static Map playerWithers = new HashMap(); private static Map playerWithers2 = new HashMap(); private static Map playerTextWither = new HashMap(); static { try { packetPlayOutSpawnEntityLiving = getMCClass("PacketPlayOutSpawnEntityLiving").getConstructor(new Class[] { getMCClass("EntityLiving") }); entityEntityWither = getMCClass("EntityWither").getConstructor(new Class[] { getMCClass("World") }); setLocation = getMCClass("EntityWither").getMethod("setLocation", new Class[] { Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE }); setCustomName = getMCClass("EntityWither").getMethod("setCustomName", new Class[] { String.class }); setHealth = getMCClass("EntityWither").getMethod("setHealth", new Class[] { Float.TYPE }); setInvisible = getMCClass("EntityWither").getMethod("setInvisible", new Class[] { Boolean.TYPE }); getWorldHandle = getCraftClass("CraftWorld").getMethod("getHandle", new Class[0]); getPlayerHandle = getCraftClass("entity.CraftPlayer").getMethod("getHandle", new Class[0]); playerConnection = getMCClass("EntityPlayer").getDeclaredField("playerConnection"); sendPacket = getMCClass("PlayerConnection").getMethod("sendPacket", new Class[] { getMCClass("Packet") }); getDatawatcher = getMCClass("EntityWither").getMethod("getDataWatcher", new Class[0]); a = getMCClass("DataWatcher").getMethod("a", new Class[] { Integer.TYPE, Object.class }); d = getMCClass("DataWatcher").getDeclaredField("d"); d.setAccessible(true); } catch (Exception e) { e.printStackTrace(); } } public static Object getWither(Player p) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { if (playerWithers.containsKey(p.getName())) { return playerWithers.get(p.getName()); } Object nms_world = getWorldHandle.invoke(p.getWorld(), new Object[0]); playerWithers.put(p.getName(), entityEntityWither.newInstance(new Object[] { nms_world })); return getWither(p); } public static Object getWither2(Player p) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException { if (playerWithers2.containsKey(p.getName())) { return playerWithers2.get(p.getName()); } Object nms_world = getWorldHandle.invoke(p.getWorld(), new Object[0]); playerWithers2.put(p.getName(), entityEntityWither.newInstance(new Object[] { nms_world })); return getWither2(p); } public static void setBossBartext(Player p, String text) { playerTextWither.put(p.getName(), text); int xr = ThreadLocalRandom.current().nextInt(-3, 3); int xr2 = ThreadLocalRandom.current().nextInt(-3, 3); try { Object nms_wither = getWither(p); setLocation.invoke(nms_wither, new Object[] { Double.valueOf(getPlayerLoc(p).getX() + xr), Double.valueOf(getPlayerLoc(p).getY()), Double.valueOf(getPlayerLoc(p).getZ() + xr2), Float.valueOf(0.0F), Float.valueOf(0.0F) }); setCustomName.invoke(nms_wither, new Object[] { text }); setHealth.invoke(nms_wither, new Object[] { Integer.valueOf(300) }); setInvisible.invoke(nms_wither, new Object[] { Boolean.valueOf(true) }); changeWatcher(nms_wither, text); Object nms_packet = packetPlayOutSpawnEntityLiving.newInstance(new Object[] { nms_wither }); Object nms_player = getPlayerHandle.invoke(p, new Object[0]); Object nms_connection = playerConnection.get(nms_player); sendPacket.invoke(nms_connection, new Object[] { nms_packet }); } catch (Exception e) { e.printStackTrace(); } try { Object nms_wither = getWither2(p); setLocation.invoke(nms_wither, new Object[] { Double.valueOf(getPlayerLoc(p).getX() + xr2), Double.valueOf(p.getLocation().getY() - 10.0D), Double.valueOf(getPlayerLoc(p).getZ() + xr), Float.valueOf(0.0F), Float.valueOf(0.0F) }); setCustomName.invoke(nms_wither, new Object[] { text }); setHealth.invoke(nms_wither, new Object[] { Integer.valueOf(300) }); setInvisible.invoke(nms_wither, new Object[] { Boolean.valueOf(true) }); changeWatcher(nms_wither, text); Object nms_packet = packetPlayOutSpawnEntityLiving.newInstance(new Object[] { nms_wither }); Object nms_player = getPlayerHandle.invoke(p, new Object[0]); Object nms_connection = playerConnection.get(nms_player); sendPacket.invoke(nms_connection, new Object[] { nms_packet }); } catch (Exception e) { e.printStackTrace(); } } public static void setBossBar(Player p, String text, float vie) { playerTextWither.put(p.getName(), text); int xr = ThreadLocalRandom.current().nextInt(0, 2); int xr2 = ThreadLocalRandom.current().nextInt(0, 2); try { Object nms_wither = getWither(p); setLocation.invoke(nms_wither, new Object[] { Double.valueOf(getPlayerLoc(p).getX() + xr), Double.valueOf(getPlayerLoc(p).getY()), Double.valueOf(getPlayerLoc(p).getZ() + xr2), Float.valueOf(0.0F), Float.valueOf(0.0F) }); setCustomName.invoke(nms_wither, new Object[] { text }); setHealth.invoke(nms_wither, new Object[] { Float.valueOf(vie) }); setInvisible.invoke(nms_wither, new Object[] { Boolean.valueOf(true) }); changeWatcher(nms_wither, text); Object nms_packet = packetPlayOutSpawnEntityLiving.newInstance(new Object[] { nms_wither }); Object nms_player = getPlayerHandle.invoke(p, new Object[0]); Object nms_connection = playerConnection.get(nms_player); sendPacket.invoke(nms_connection, new Object[] { nms_packet }); } catch (Exception e) { e.printStackTrace(); } try { Object nms_wither = getWither2(p); setLocation.invoke(nms_wither, new Object[] { Double.valueOf(getPlayerLoc(p).getX() + xr2), Double.valueOf(p.getLocation().getY() - 10.0D), Double.valueOf(getPlayerLoc(p).getZ() + xr), Float.valueOf(0.0F), Float.valueOf(0.0F) }); setCustomName.invoke(nms_wither, new Object[] { text }); setHealth.invoke(nms_wither, new Object[] { Float.valueOf(vie) }); setInvisible.invoke(nms_wither, new Object[] { Boolean.valueOf(true) }); changeWatcher(nms_wither, text); Object nms_packet = packetPlayOutSpawnEntityLiving.newInstance(new Object[] { nms_wither }); Object nms_player = getPlayerHandle.invoke(p, new Object[0]); Object nms_connection = playerConnection.get(nms_player); sendPacket.invoke(nms_connection, new Object[] { nms_packet }); } catch (Exception e) { e.printStackTrace(); } } public static void removeBossBar(Player p) { playerTextWither.remove(p.getName()); try { Object nms_wither = getWither(p); setLocation.invoke(nms_wither, new Object[] { Double.valueOf(p.getLocation().getX()), Integer.valueOf(-5000), Double.valueOf(p.getLocation().getZ()), Float.valueOf(0.0F), Float.valueOf(0.0F) }); setCustomName.invoke(nms_wither, new Object[] { " " }); setHealth.invoke(nms_wither, new Object[] { Integer.valueOf(0) }); setInvisible.invoke(nms_wither, new Object[] { Boolean.valueOf(true) }); changeWatcher(nms_wither, " "); Object nms_packet = packetPlayOutSpawnEntityLiving.newInstance(new Object[] { nms_wither }); Object nms_player = getPlayerHandle.invoke(p, new Object[0]); Object nms_connection = playerConnection.get(nms_player); sendPacket.invoke(nms_connection, new Object[] { nms_packet }); } catch (Exception e) { e.printStackTrace(); } } public void removehorligneW(Player p) { playerWithers.remove(p.getName()); playerTextWither.remove(p.getName()); } private static void changeWatcher(Object nms_entity, String text) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { Object nms_watcher = getDatawatcher.invoke(nms_entity, new Object[0]); Map map = (Map)d.get(nms_watcher); map.remove(Integer.valueOf(10)); a.invoke(nms_watcher, new Object[] { Integer.valueOf(10), text }); } private static Class getMCClass(String name) throws ClassNotFoundException { String version = org.bukkit.Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + "."; String className = "net.minecraft.server." + version + name; return Class.forName(className); } private static Class getCraftClass(String name) throws ClassNotFoundException { String version = org.bukkit.Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3] + "."; String className = "org.bukkit.craftbukkit." + version + name; return Class.forName(className); } public static String getCardinalDirection(Player player) { double rotation = (player.getLocation().getYaw() - 180.0F) % 360.0F; if (rotation < 0.0D) { rotation += 360.0D; } if ((0.0D <= rotation) && (rotation < 22.5D)) return "N"; if ((22.5D <= rotation) && (rotation < 67.5D)) return "NE"; if ((67.5D <= rotation) && (rotation < 112.5D)) return "E"; if ((112.5D <= rotation) && (rotation < 157.5D)) return "SE"; if ((157.5D <= rotation) && (rotation < 202.5D)) return "S"; if ((202.5D <= rotation) && (rotation < 247.5D)) return "SW"; if ((247.5D <= rotation) && (rotation < 292.5D)) return "W"; if ((292.5D <= rotation) && (rotation < 337.5D)) return "NW"; if ((337.5D <= rotation) && (rotation <= 360.0D)) { return "N"; } return "N"; } public static Location getPlayerLoc(Player p) { Location loc = p.getLocation(); String str; switch ((str = getCardinalDirection(p)).hashCode()) { case 69: if (!str.equals("E")) break; break; case 78: case 83: if ((!str.equals("N")) || (goto 284) || (!str.equals("S"))) break; break; case 87: case 2487: if ((!str.equals("W")) || (goto 284) || (!str.equals("NE"))) break; break; case 2505: case 2642: if ((!str.equals("NW")) || (goto 284) || (!str.equals("SE"))) break; break; case 2660: if (!str.equals("SW")) { loc.add(0.0D, 0.0D, -50.0D); loc.add(50.0D, 0.0D, 0.0D); loc.add(0.0D, 0.0D, 50.0D); loc.add(-50.0D, 0.0D, 0.0D); loc.add(50.0D, 0.0D, -50.0D); loc.add(50.0D, 0.0D, 50.0D); loc.add(-50.0D, 0.0D, -50.0D); } else { loc.add(-50.0D, 0.0D, 50.0D); } } return loc; } }