Skip to content

Instantly share code, notes, and snippets.

@chaseking
Last active July 16, 2019 22:52
Show Gist options
  • Save chaseking/7671942 to your computer and use it in GitHub Desktop.
Save chaseking/7671942 to your computer and use it in GitHub Desktop.
Utilizing the boss health bar v2! Now uses reflection! Big thanks to CaptainBern for letting me use his wonderful NMS/reflection classes.
/**
* Created by chasechocolate, with classes created by CaptainBern.
*/
public class BarAPI {
public static class FakeDragon {
private class LazyPacket { //THANKS CAPTAINBERN :D
protected Object crafted_packet = null;
/**
* This is a little class that makes it possible for me
* to easily craft/send packets. It has been created with the
* aim to make it as easy as possible.
*/
public LazyPacket(String name){
try{
crafted_packet = BarAPI.BarReflectionUtils.getNMSClass(name);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Sets a public field value of a class/packet.
*/
public void setPublicValue(String field, Object value){
try{
Field f = crafted_packet.getClass().getField(field);
f.setAccessible(true);
f.set(crafted_packet, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Sets a private field value of a class/packet.
*/
public void setPrivateValue(String field, Object value){
try{
Field f = crafted_packet.getClass().getDeclaredField(field);
f.setAccessible(true);
f.set(crafted_packet, value);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Returns the packet-object.
*/
public Object getPacketObject(){
return this.crafted_packet;
}
/**
* Method used to send the packet to specified player.
*/
public void send(Player player){
try {
Object entityPlayer = player.getClass().getMethod("getHandle").invoke(player);
Object playerConnection = entityPlayer.getClass().getField("playerConnection").get(entityPlayer);
BarAPI.BarReflectionUtils.getMethod("sendPacket", playerConnection.getClass(), 1).invoke(playerConnection, crafted_packet);
} catch (Exception e) {
cAPI.getInstance().getLogger().warning("Failed to send packet to player: " + player.getName() + "!");
}
}
}
private class LazyDataWatcher { //THANKS CAPTAINBERN :D
private Object datawatcher;
public LazyDataWatcher(){
try {
datawatcher = BarAPI.BarReflectionUtils.getNMSClass("DataWatcher");
} catch (Exception e){
}
}
public void write(int i, Object object){
try{
Method method = datawatcher.getClass().getMethod("a", int.class, Object.class);
method.invoke(datawatcher, i, object);
} catch(Exception e){
e.printStackTrace();
}
}
public Object getDataWatcherObject(){
return datawatcher;
}
}
public static final int ENTITY_ID = 696969;
public static final float MAX_HEALTH = 200.0F;
private Player player;
private String name = "null";
private float health = FakeDragon.MAX_HEALTH;
private boolean invisible = false;
private boolean exists = false;
private LazyDataWatcher dataWatcher;
public FakeDragon(Player player){
this.player = player;
}
public Player getPlayer(){
return player;
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
spawn();
update();
}
public float getHealth(){
return health;
}
public void setHealth(float health){
this.health = health;
spawn();
update();
}
public boolean isInvisible(){
return invisible;
}
public void setInvisible(boolean invisible){
this.invisible = invisible;
spawn();
update();
}
public boolean doesExist(){
return exists;
}
public void spawn(){
if(!(exists)){
updateWatcher();
LazyPacket mobSpawnPacket = new LazyPacket("Packet24MobSpawn");
Location loc = player.getLocation().clone().subtract(0, 200, 0);
Vector velocity = new Vector(0, 0, 0);
mobSpawnPacket.setPublicValue("a", FakeDragon.ENTITY_ID);
mobSpawnPacket.setPublicValue("b", (byte) EntityType.ENDER_DRAGON.getTypeId());
mobSpawnPacket.setPublicValue("c", (int) Math.floor(loc.getBlockX() * 32.0D));
mobSpawnPacket.setPublicValue("d", (int) Math.floor(loc.getBlockY() * 32.0D));
mobSpawnPacket.setPublicValue("e", (int) Math.floor(loc.getBlockZ() * 32.0D));
mobSpawnPacket.setPublicValue("f", (byte) ((int) ((loc.getPitch() * 256.0F) / 360.0F)));
mobSpawnPacket.setPublicValue("g", (byte) 0);
mobSpawnPacket.setPublicValue("h", (byte) ((int) ((loc.getYaw() * 256.0F) / 360.0F)));
mobSpawnPacket.setPublicValue("i", (byte) velocity.getX());
mobSpawnPacket.setPublicValue("j", (byte) velocity.getY());
mobSpawnPacket.setPublicValue("k", (byte) velocity.getZ());
mobSpawnPacket.setPrivateValue("t", dataWatcher.getDataWatcherObject());
mobSpawnPacket.send(player);
exists = true;
}
}
public void destroy(){
if(exists){
LazyPacket destroyEntityPacket = new LazyPacket("Packet29DestroyEntity");
destroyEntityPacket.setPublicValue("a", new int[]{ FakeDragon.ENTITY_ID });
destroyEntityPacket.send(player);
exists = false;
}
}
public void update(){
updateWatcher();
if(exists){
//Metadata packet
LazyPacket metadataPacket = new LazyPacket("Packet40EntityMetadata");
metadataPacket.setPublicValue("a", FakeDragon.ENTITY_ID);
Method watcherC = BarAPI.BarReflectionUtils.getMethod("c", dataWatcher.getDataWatcherObject().getClass());
try{
metadataPacket.setPrivateValue("b", watcherC.invoke(dataWatcher.getDataWatcherObject()));
} catch(IllegalAccessException e){
e.printStackTrace();
} catch(InvocationTargetException e){
e.printStackTrace();
}
metadataPacket.send(player);
//Teleport packet
LazyPacket teleportPacket = new LazyPacket("Packet34EntityTeleport");
Location loc = player.getLocation().clone().subtract(0, 200, 0);
teleportPacket.setPublicValue("a", FakeDragon.ENTITY_ID);
teleportPacket.setPublicValue("b", (int) Math.floor(loc.getBlockX() * 32.0D));
teleportPacket.setPublicValue("c", (int) Math.floor(loc.getBlockY() * 32.0D));
teleportPacket.setPublicValue("d", (int) Math.floor(loc.getBlockZ() * 32.0D));
teleportPacket.setPublicValue("e", (byte) ((int) ((loc.getYaw() * 256.0F) / 360.0F)));
teleportPacket.setPublicValue("f", (byte) ((int) ((loc.getPitch() * 256.0F) / 360.0F)));
teleportPacket.send(player);
}
}
public void updateWatcher(){
dataWatcher = new LazyDataWatcher();
dataWatcher.write(0, (invisible ? (Byte) (byte) 0x20 : (Byte) (byte) 0));
dataWatcher.write(6, (Float) (float) health);
dataWatcher.write(7, (Integer) (int) 0);
dataWatcher.write(8, (Byte) (byte) 0);
dataWatcher.write(10, (String) name);
dataWatcher.write(11, (Byte) (byte) 1);
}
}
public static class BarReflectionUtils {
public static Object getNMSClass(String name, Object... args) throws Exception {
Class<?> c = Class.forName(BarReflectionUtils.getNMSPackageName() + "." + name);
int params = 0;
if (args != null) {
params = args.length;
}
for (Constructor<?> co : c.getConstructors()) {
if (co.getParameterTypes().length == params) {
return co.newInstance(args);
}
}
return null;
}
public static Class<?> getNMSClassExact(String name, Object... args){
Class<?> c;
try{
c = Class.forName(BarReflectionUtils.getNMSPackageName() + "." + name);
}catch(Exception e){
return null;
}
return c;
}
public static Object getOBCClass(String name, Object... args) throws Exception {
Class<?> c = Class.forName(BarReflectionUtils.getOBCPackageName() + "." + name);
int params = 0;
if (args != null) {
params = args.length;
}
for (Constructor<?> co : c.getConstructors()) {
if (co.getParameterTypes().length == params) {
return co.newInstance(args);
}
}
return null;
}
public static Class<?> getOBCClassExact(String name, Object... args){
Class<?> c;
try{
c= Class.forName(BarReflectionUtils.getOBCPackageName() + "." + name);
}catch(Exception e){
return null;
}
return c;
}
public static Method getMethod(String name, Class<?> c, int params){
for (Method m : c.getMethods()){
if (m.getName().equals(name) && m.getParameterTypes().length == params){
return m;
}
}
return null;
}
public static Method getMethod(String name, Class<?> c){
for (Method m : c.getMethods()) {
if (m.getName().equals(name)) {
return m;
}
}
return null;
}
public static Field getField(String name, Class<?> c){
for (Field f : c.getFields()) {
if (f.getName().equals(name)) {
return f;
}
}
return null;
}
public static void setValue(Object instance, String fieldName, Object value) throws Exception{
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(instance, value);
}
public static String getNMSPackageName(){
return "net.minecraft.server." + Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
}
public static String getOBCPackageName(){
return "org.bukkit.craftbukkit" + Bukkit.getServer().getClass().getPackage().getName().replace(".", ",").split(",")[3];
}
public static Object bukkitPlayerToEntityPlayer(Player player){
Object entityPlayer = null;
try{
entityPlayer = BarReflectionUtils.getMethod("getHandle", player.getClass(), 0).invoke(player);
} catch(Exception e){
return null;
}
return entityPlayer;
}
}
private static HashMap<String, FakeDragon> playerDragons = new HashMap<String, FakeDragon>();
public static String getMessage(Player player){
FakeDragon dragon = getDragon(player);
return dragon.getName();
}
public static void setMessage(Player player, String msg, boolean override){
if(hasBar(player)){
if(!(override)){
return;
}
}
FakeDragon dragon = getDragon(player);
if(msg.length() > 64){
msg = msg.substring(0, 63);
}
dragon.setName(msg);
}
public static float getHealth(Player player){
FakeDragon dragon = getDragon(player);
return dragon.getHealth();
}
public static void setHealth(Player player, float health, boolean override){
if(hasBar(player)){
if(!(override)){
return;
}
}
FakeDragon dragon = getDragon(player);
dragon.setHealth(health);
}
public static void setPercent(Player player, float percent, boolean override){
if(hasBar(player)){
if(!(override)){
return;
}
}
FakeDragon dragon = getDragon(player);
float health = (percent / 100.0F) * com.chasechocolate.capi.bar.FakeDragon.MAX_HEALTH;
dragon.setHealth(health);
}
public static void displayBar(final Player player, String msg, float percent, int seconds, boolean override){
setMessage(player, msg, override);
setPercent(player, percent, override);
new BukkitRunnable(){
@Override
public void run(){
removeBar(player);
}
}.runTaskLater(cAPI.getInstance(), (seconds * 20));
}
public static void displayLoadingBar(final Player player, String msg, final String endMsg, int seconds, final boolean loadUp, final boolean override){
setMessage(player, msg, override);
setPercent(player, (loadUp ? 0.0F : 100.0F), override);
final float changePerSecond = com.chasechocolate.capi.bar.FakeDragon.MAX_HEALTH / seconds;
final float changePerTick = changePerSecond / 20;
new BukkitRunnable(){
@Override
public void run(){
FakeDragon dragon = getDragon(player);
if((loadUp ? dragon.getHealth() < com.chasechocolate.capi.bar.FakeDragon.MAX_HEALTH : dragon.getHealth() > 0)){
if(loadUp){
setHealth(player, getHealth(player) + changePerTick, override);
} else {
setHealth(player, getHealth(player) - changePerTick, override);
}
} else {
setMessage(player, endMsg, override);
setPercent(player, 100, override);
this.cancel();
new BukkitRunnable(){
@Override
public void run(){
removeBar(player);
}
}.runTaskLater(cAPI.getInstance(), 40L);
}
}
}.runTaskTimer(cAPI.getInstance(), 0L, 1L);
}
public static void removeBar(Player player){
if(hasBar(player)){
FakeDragon dragon = getDragon(player);
dragon.destroy();
playerDragons.remove(player.getName());
}
}
public static boolean hasBar(Player player){
return playerDragons.containsKey(player.getName());
}
public static FakeDragon getDragon(Player player){
if(hasBar(player)){
return playerDragons.get(player.getName());
} else {
FakeDragon dragon = new FakeDragon(player);
dragon.setInvisible(true);
playerDragons.put(player.getName(), dragon);
return dragon;
}
}
}
@OneAvocet
Copy link

Where do i get com.chasechocolate.capi?

@armbruer
Copy link

Replace this with your package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment