2019-08-04 06:38:21 +02:00
|
|
|
package com.zeshanaslam.actionhealth.utils;
|
2017-03-10 18:04:15 +01:00
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
import com.zeshanaslam.actionhealth.Main;
|
2019-08-04 20:59:35 +02:00
|
|
|
import com.zeshanaslam.actionhealth.support.McMMOSupport;
|
2019-08-04 06:38:21 +02:00
|
|
|
import com.zeshanaslam.actionhealth.support.PreAction;
|
2019-08-04 20:59:35 +02:00
|
|
|
import org.apache.commons.lang.WordUtils;
|
2017-03-10 18:04:15 +01:00
|
|
|
import org.bukkit.ChatColor;
|
2017-03-20 06:15:09 +01:00
|
|
|
import org.bukkit.Location;
|
|
|
|
import org.bukkit.entity.LivingEntity;
|
2017-03-10 18:04:15 +01:00
|
|
|
import org.bukkit.entity.Player;
|
2019-08-04 20:59:35 +02:00
|
|
|
import org.bukkit.metadata.MetadataValue;
|
2017-06-22 22:32:24 +02:00
|
|
|
import org.bukkit.potion.PotionEffectType;
|
2017-03-20 06:15:09 +01:00
|
|
|
import org.bukkit.scheduler.BukkitRunnable;
|
2017-03-10 18:04:15 +01:00
|
|
|
|
|
|
|
import java.lang.reflect.Field;
|
2019-08-04 20:59:35 +02:00
|
|
|
import java.lang.reflect.InvocationTargetException;
|
2017-03-10 18:04:15 +01:00
|
|
|
import java.lang.reflect.Method;
|
2019-08-04 20:59:35 +02:00
|
|
|
import java.util.List;
|
2017-03-10 18:04:15 +01:00
|
|
|
|
|
|
|
public class HealthUtil {
|
|
|
|
|
|
|
|
private Main plugin;
|
|
|
|
|
|
|
|
public HealthUtil(Main plugin) {
|
|
|
|
this.plugin = plugin;
|
|
|
|
}
|
|
|
|
|
2017-05-10 00:01:42 +02:00
|
|
|
public void sendHealth(Player receiver, LivingEntity entity, double health) {
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.canSee) {
|
2017-06-22 22:32:24 +02:00
|
|
|
|
|
|
|
if (entity instanceof Player) {
|
|
|
|
Player player = (Player) entity;
|
|
|
|
|
|
|
|
if (!receiver.canSee(player)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.spectatorMode) {
|
2017-06-22 22:32:24 +02:00
|
|
|
|
|
|
|
if (entity instanceof Player) {
|
|
|
|
Player player = (Player) entity;
|
|
|
|
|
2018-06-21 01:54:08 +02:00
|
|
|
// Using string version for older versions. Checking for gamemode is null because of fake player npcs.
|
|
|
|
if (player.getGameMode() != null && player.getGameMode().name().equals("SPECTATOR")) {
|
2017-06-22 22:32:24 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.invisiblePotion) {
|
2017-06-22 22:32:24 +02:00
|
|
|
if (entity.hasPotionEffect(PotionEffectType.INVISIBILITY)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.delay) {
|
2017-03-20 20:54:21 +01:00
|
|
|
|
|
|
|
new BukkitRunnable() {
|
|
|
|
public void run() {
|
2017-05-10 00:01:42 +02:00
|
|
|
String output = getOutput(entity.getHealth(), receiver, entity);
|
2017-03-24 01:10:10 +01:00
|
|
|
|
|
|
|
if (output != null)
|
2017-05-10 00:01:42 +02:00
|
|
|
sendActionBar(receiver, output);
|
2017-03-20 20:54:21 +01:00
|
|
|
}
|
2019-08-04 06:38:21 +02:00
|
|
|
}.runTaskLater(plugin, plugin.configStore.delayTick);
|
2017-03-20 20:54:21 +01:00
|
|
|
} else {
|
2017-05-10 00:01:42 +02:00
|
|
|
String output = getOutput(health, receiver, entity);
|
2017-03-24 01:10:10 +01:00
|
|
|
|
|
|
|
if (output != null)
|
2017-05-10 00:01:42 +02:00
|
|
|
sendActionBar(receiver, output);
|
2017-03-20 20:54:21 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-10 00:01:42 +02:00
|
|
|
private String getOutput(double health, Player receiver, LivingEntity entity) {
|
2017-03-23 18:28:26 +01:00
|
|
|
double maxHealth = entity.getMaxHealth();
|
2017-03-20 20:54:21 +01:00
|
|
|
|
2017-03-23 18:28:26 +01:00
|
|
|
if (health < 0.0 || entity.isDead()) health = 0.0;
|
2017-03-20 06:15:09 +01:00
|
|
|
|
2019-08-04 20:59:35 +02:00
|
|
|
String name = getName(entity);
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.blacklist.contains(name)) return null;
|
|
|
|
if (plugin.configStore.stripName) name = ChatColor.stripColor(name);
|
2017-03-20 06:15:09 +01:00
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
String output = plugin.configStore.healthMessage;
|
2017-03-20 06:15:09 +01:00
|
|
|
|
2017-05-10 00:01:42 +02:00
|
|
|
if (entity instanceof Player) {
|
|
|
|
String displayName;
|
|
|
|
Player player = (Player) entity;
|
|
|
|
|
|
|
|
if (player.getDisplayName() == null) {
|
|
|
|
displayName = name;
|
|
|
|
} else {
|
|
|
|
displayName = player.getDisplayName();
|
|
|
|
}
|
|
|
|
|
|
|
|
output = output.replace("{displayname}", displayName);
|
2018-07-13 01:46:42 +02:00
|
|
|
|
|
|
|
// Placeholder apis
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.hasMVdWPlaceholderAPI) {
|
2018-07-13 01:46:42 +02:00
|
|
|
output = be.maximvdw.placeholderapi.PlaceholderAPI.replacePlaceholders(player, output);
|
|
|
|
}
|
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.hasPlaceholderAPI) {
|
2018-07-13 01:46:42 +02:00
|
|
|
output = me.clip.placeholderapi.PlaceholderAPI.setPlaceholders(player, output);
|
2018-08-03 04:19:13 +02:00
|
|
|
output = me.clip.placeholderapi.PlaceholderAPI.setRelationalPlaceholders(receiver, player, output);
|
2018-07-13 01:46:42 +02:00
|
|
|
}
|
2017-05-16 21:10:18 +02:00
|
|
|
} else {
|
2019-08-04 06:38:21 +02:00
|
|
|
if (!plugin.configStore.healthMessageOther.isEmpty()) {
|
|
|
|
output = plugin.configStore.healthMessageOther;
|
2018-07-25 00:22:26 +02:00
|
|
|
}
|
|
|
|
|
2017-05-16 21:10:18 +02:00
|
|
|
output = output.replace("{displayname}", name);
|
2017-05-10 00:01:42 +02:00
|
|
|
}
|
|
|
|
|
2018-07-25 00:22:26 +02:00
|
|
|
output = output.replace("{name}", name);
|
|
|
|
output = output.replace("{health}", String.valueOf((int) health));
|
|
|
|
output = output.replace("{maxhealth}", String.valueOf((int) maxHealth));
|
|
|
|
|
2017-03-20 06:15:09 +01:00
|
|
|
if (output.contains("{usestyle}")) {
|
2017-07-25 19:24:12 +02:00
|
|
|
StringBuilder style = new StringBuilder();
|
2019-08-04 06:38:21 +02:00
|
|
|
int left = plugin.configStore.limitHealth;
|
|
|
|
double heart = maxHealth / plugin.configStore.limitHealth;
|
2017-03-23 18:28:26 +01:00
|
|
|
double halfHeart = heart / 2;
|
|
|
|
double tempHealth = health;
|
2017-03-20 06:15:09 +01:00
|
|
|
|
|
|
|
if (maxHealth != health && health >= 0 && !entity.isDead()) {
|
2019-08-04 06:38:21 +02:00
|
|
|
for (int i = 0; i < plugin.configStore.limitHealth; i++) {
|
2017-03-20 06:15:09 +01:00
|
|
|
if (tempHealth - heart > 0) {
|
|
|
|
tempHealth = tempHealth - heart;
|
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
style.append(plugin.configStore.filledHeartIcon);
|
2017-03-20 06:15:09 +01:00
|
|
|
left--;
|
2017-03-23 18:28:26 +01:00
|
|
|
} else {
|
|
|
|
break;
|
2017-03-20 06:15:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-23 05:15:16 +01:00
|
|
|
if (tempHealth > halfHeart) {
|
2019-08-04 06:38:21 +02:00
|
|
|
style.append(plugin.configStore.filledHeartIcon);
|
2017-03-20 06:15:09 +01:00
|
|
|
left--;
|
2017-03-23 18:32:45 +01:00
|
|
|
} else if (tempHealth > 0 && tempHealth <= halfHeart) {
|
2019-08-04 06:38:21 +02:00
|
|
|
style.append(plugin.configStore.halfHeartIcon);
|
2017-03-23 18:32:45 +01:00
|
|
|
left--;
|
2017-03-20 06:15:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-24 01:10:10 +01:00
|
|
|
if (maxHealth != health) {
|
|
|
|
for (int i = 0; i < left; i++) {
|
2019-08-04 06:38:21 +02:00
|
|
|
style.append(plugin.configStore.emptyHeartIcon);
|
2017-03-24 01:10:10 +01:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for (int i = 0; i < left; i++) {
|
2019-08-04 06:38:21 +02:00
|
|
|
style.append(plugin.configStore.filledHeartIcon);
|
2017-03-24 01:10:10 +01:00
|
|
|
}
|
2017-03-20 06:15:09 +01:00
|
|
|
}
|
|
|
|
|
2017-07-25 19:24:12 +02:00
|
|
|
output = output.replace("{usestyle}", style.toString());
|
2017-03-10 18:04:15 +01:00
|
|
|
}
|
|
|
|
|
2017-03-20 20:54:21 +01:00
|
|
|
return output;
|
2017-03-20 06:15:09 +01:00
|
|
|
}
|
|
|
|
|
2019-08-04 20:59:35 +02:00
|
|
|
public String getName(LivingEntity entity) {
|
|
|
|
String name;
|
|
|
|
|
|
|
|
// Supporting mcmmo health bar to get to display correct name.
|
|
|
|
List<MetadataValue> metadataValues = entity.getMetadata("mcMMO_oldName");
|
|
|
|
List<MetadataValue> metadataValuesOld = entity.getMetadata("mcMMO: Custom Name");
|
|
|
|
|
|
|
|
String mcMMOName = null;
|
|
|
|
if (plugin.mcMMOEnabled && entity.getCustomName() != null && (!metadataValues.isEmpty() || !metadataValuesOld.isEmpty())) {
|
|
|
|
mcMMOName = new McMMOSupport().getName(metadataValues.isEmpty() ? metadataValuesOld.get(0) : metadataValues.get(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (mcMMOName == null) {
|
|
|
|
if (entity.getCustomName() == null) {
|
|
|
|
name = getNameReflection(entity);
|
|
|
|
} else {
|
|
|
|
name = entity.getCustomName();
|
|
|
|
}
|
|
|
|
} else if (mcMMOName.equals("")) {
|
|
|
|
name = getNameReflection(entity);
|
|
|
|
} else {
|
|
|
|
name = mcMMOName;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (plugin.configStore.translate.containsKey(name))
|
|
|
|
name = plugin.configStore.translate.get(name);
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String getNameReflection(LivingEntity entity) {
|
|
|
|
String name;
|
|
|
|
Method getName = null;
|
|
|
|
try {
|
|
|
|
if (entity.getCustomName() == null)
|
|
|
|
getName = entity.getClass().getMethod("getName", (Class<?>[]) null);
|
|
|
|
} catch (NoSuchMethodException | SecurityException ignored) {
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getName != null) {
|
|
|
|
try {
|
|
|
|
name = (String) getName.invoke(entity, (Object[]) null);
|
|
|
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
|
|
name = capitalizeFully(entity.getType().name().replace("_", ""));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
name = capitalizeFully(entity.getType().name().replace("_", ""));
|
|
|
|
}
|
|
|
|
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String capitalizeFully(String words) {
|
|
|
|
words = words.toLowerCase();
|
|
|
|
return WordUtils.capitalizeFully(words);
|
|
|
|
}
|
|
|
|
|
2017-03-24 01:10:10 +01:00
|
|
|
public void sendActionBar(Player player, String message) {
|
2017-03-10 18:04:15 +01:00
|
|
|
message = ChatColor.translateAlternateColorCodes('&', message);
|
|
|
|
|
|
|
|
try {
|
2019-08-04 06:38:21 +02:00
|
|
|
if (plugin.configStore.mcVersion.equals("v1_12_R1") || plugin.configStore.mcVersion.startsWith("v1_13") || plugin.configStore.mcVersion.startsWith("v1_14_")) {
|
2017-05-16 21:10:18 +02:00
|
|
|
new PreAction(player, message);
|
2019-08-04 06:38:21 +02:00
|
|
|
} else if (!(plugin.configStore.mcVersion.equalsIgnoreCase("v1_8_R1") || (plugin.configStore.mcVersion.contains("v1_7_")))) {
|
|
|
|
Class<?> c1 = Class.forName("org.bukkit.craftbukkit." + plugin.configStore.mcVersion + ".entity.CraftPlayer");
|
2017-05-16 21:10:18 +02:00
|
|
|
Object p = c1.cast(player);
|
|
|
|
Object ppoc;
|
2019-08-04 06:38:21 +02:00
|
|
|
Class<?> c4 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".PacketPlayOutChat");
|
|
|
|
Class<?> c5 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".Packet");
|
2017-05-16 21:10:18 +02:00
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
Class<?> c2 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".ChatComponentText");
|
|
|
|
Class<?> c3 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".IChatBaseComponent");
|
2017-05-16 21:10:18 +02:00
|
|
|
Object o = c2.getConstructor(new Class<?>[]{String.class}).newInstance(message);
|
|
|
|
ppoc = c4.getConstructor(new Class<?>[]{c3, byte.class}).newInstance(o, (byte) 2);
|
|
|
|
|
|
|
|
Method getHandle = c1.getDeclaredMethod("getHandle");
|
|
|
|
Object handle = getHandle.invoke(p);
|
|
|
|
|
|
|
|
Field fieldConnection = handle.getClass().getDeclaredField("playerConnection");
|
|
|
|
Object playerConnection = fieldConnection.get(handle);
|
|
|
|
|
|
|
|
Method sendPacket = playerConnection.getClass().getDeclaredMethod("sendPacket", c5);
|
|
|
|
sendPacket.invoke(playerConnection, ppoc);
|
|
|
|
} else {
|
2019-08-04 06:38:21 +02:00
|
|
|
Class<?> c1 = Class.forName("org.bukkit.craftbukkit." + plugin.configStore.mcVersion + ".entity.CraftPlayer");
|
2017-05-16 21:10:18 +02:00
|
|
|
Object p = c1.cast(player);
|
|
|
|
Object ppoc;
|
2019-08-04 06:38:21 +02:00
|
|
|
Class<?> c4 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".PacketPlayOutChat");
|
|
|
|
Class<?> c5 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".Packet");
|
2017-03-10 18:04:15 +01:00
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
Class<?> c2 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".ChatSerializer");
|
|
|
|
Class<?> c3 = Class.forName("net.minecraft.server." + plugin.configStore.mcVersion + ".IChatBaseComponent");
|
2017-03-10 18:04:15 +01:00
|
|
|
Method m3 = c2.getDeclaredMethod("a", String.class);
|
|
|
|
Object cbc = c3.cast(m3.invoke(c2, "{\"text\": \"" + message + "\"}"));
|
|
|
|
ppoc = c4.getConstructor(new Class<?>[]{c3, byte.class}).newInstance(cbc, (byte) 2);
|
|
|
|
|
2017-05-16 21:10:18 +02:00
|
|
|
Method getHandle = c1.getDeclaredMethod("getHandle");
|
|
|
|
Object handle = getHandle.invoke(p);
|
2017-03-23 18:28:26 +01:00
|
|
|
|
2017-05-16 21:10:18 +02:00
|
|
|
Field fieldConnection = handle.getClass().getDeclaredField("playerConnection");
|
|
|
|
Object playerConnection = fieldConnection.get(handle);
|
2017-03-23 18:28:26 +01:00
|
|
|
|
2017-05-16 21:10:18 +02:00
|
|
|
Method sendPacket = playerConnection.getClass().getDeclaredMethod("sendPacket", c5);
|
|
|
|
sendPacket.invoke(playerConnection, ppoc);
|
|
|
|
}
|
2017-03-23 18:28:26 +01:00
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
2017-03-10 18:04:15 +01:00
|
|
|
}
|
|
|
|
}
|
2017-03-20 06:15:09 +01:00
|
|
|
|
|
|
|
public boolean isDisabled(Location location) {
|
|
|
|
if (plugin.worldGuardPlugin == null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2019-08-04 06:38:21 +02:00
|
|
|
for (String regionName : plugin.worldGuardAPI.getRegionNames(location)) {
|
|
|
|
if (plugin.configStore.regions.contains(regionName)) {
|
2018-08-31 00:48:21 +02:00
|
|
|
return true;
|
2017-03-20 06:15:09 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2017-03-10 18:04:15 +01:00
|
|
|
}
|