package eu.univento.core.api; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.List; public class Hologram { private List lines; private Location loc; private static final double ABS = 0.23D; private static String path = Bukkit.getServer().getClass().getPackage().getName(); private static String version = path.substring(path.lastIndexOf(".") + 1, path.length()); private static Class armorStand; private static Class worldClass; private static Class nmsEntity; private static Class craftWorld; private static Class packetClass; private static Class entityLivingClass; private static Constructor armorStandConstructor; private static Class nmsPacket; static { try { armorStand = Class.forName("net.minecraft.server." + version + ".EntityArmorStand"); worldClass = Class.forName("net.minecraft.server." + version + ".World"); nmsEntity = Class.forName("net.minecraft.server." + version + ".Entity"); craftWorld = Class.forName("org.bukkit.craftbukkit." + version + ".CraftWorld"); packetClass = Class.forName("net.minecraft.server." + version + ".PacketPlayOutSpawnEntityLiving"); entityLivingClass = Class.forName("net.minecraft.server." + version + ".EntityLiving"); armorStandConstructor = armorStand .getConstructor(new Class[] { worldClass }); nmsPacket = Class.forName("net.minecraft.server." + version + ".Packet"); } catch (java.lang.NoSuchMethodException ex) { System.err.println("Error - Classes not initialized!"); ex.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public Hologram(Location loc, List lines) { this.lines = lines; this.loc = loc; } public boolean display(Player p) { Location displayLoc = this.loc.clone().add(0.0D, 0.23D * this.lines.size() - 1.97D, 0.0D); for (int i = 0; i < this.lines.size(); i++) { Object packet = null; try { packet = getPacket(this.loc.getWorld(), displayLoc.getX(), displayLoc.getY(), displayLoc.getZ(), this.lines.get(i)); } catch (NoSuchMethodException e) { e.printStackTrace(); } if (packet == null) return false; sendPacket(p, packet); displayLoc.add(0.0D, -0.23D, 0.0D); } return true; } private Object getPacket(World w, double x, double y, double z, String text) throws NoSuchMethodException { try { Object craftWorldObj = craftWorld.cast(w); Method getHandleMethod = craftWorldObj.getClass().getMethod( "getHandle", new Class[0]); Object entityObject = armorStandConstructor .newInstance(new Object[] { getHandleMethod .invoke(craftWorldObj, new Object[0]) }); Method setCustomName = entityObject.getClass().getMethod( "setCustomName", new Class[] { String.class }); setCustomName.invoke(entityObject, new Object[] { text }); Method setCustomNameVisible = nmsEntity.getMethod( "setCustomNameVisible", new Class[] { Boolean.TYPE }); setCustomNameVisible.invoke(entityObject, new Object[] { Boolean.valueOf(true) }); Method setGravity = entityObject.getClass().getMethod("setGravity", new Class[] { Boolean.TYPE }); setGravity.invoke(entityObject, new Object[] { Boolean.valueOf(false) }); Method setLocation = entityObject.getClass().getMethod( "setLocation", new Class[] { Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE }); setLocation.invoke(entityObject, new Object[] { Double.valueOf(x), Double.valueOf(y), Double.valueOf(z), Float.valueOf(0.0F), Float.valueOf(0.0F) }); Method setInvisible = entityObject.getClass().getMethod( "setInvisible", new Class[] { Boolean.TYPE }); setInvisible.invoke(entityObject, new Object[] { Boolean.valueOf(true) }); Constructor cw = packetClass .getConstructor(new Class[] { entityLivingClass }); Object packetObject = cw.newInstance(new Object[] { entityObject }); return packetObject; } catch (java.lang.SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return null; } private void sendPacket(Player p, Object packet) { try { Method getHandle = p.getClass().getMethod("getHandle", new Class[0]); Object entityPlayer = getHandle.invoke(p, new Object[0]); Object pConnection = entityPlayer.getClass() .getField("playerConnection").get(entityPlayer); Method sendMethod = pConnection.getClass().getMethod("sendPacket", new Class[] { nmsPacket }); sendMethod.invoke(pConnection, new Object[] { packet }); } catch (Exception e) { e.printStackTrace(); } } public static double getAbs() { return ABS; } }