Added ability to set the max health of a disguise using attributes
This commit is contained in:
		@@ -17,6 +17,7 @@ public class DisguiseConfig {
 | 
			
		||||
    private static boolean keepDisguiseEntityDespawn;
 | 
			
		||||
    private static boolean keepDisguisePlayerDeath;
 | 
			
		||||
    private static boolean keepDisguisePlayerLogout;
 | 
			
		||||
    private static boolean maxHealthIsDisguisedEntity;
 | 
			
		||||
    private static boolean miscDisguisesForLivingEnabled;
 | 
			
		||||
    private static boolean modifyBoundingBox;
 | 
			
		||||
    private static boolean movementEnabled;
 | 
			
		||||
@@ -87,6 +88,10 @@ public class DisguiseConfig {
 | 
			
		||||
        return keepDisguisePlayerLogout;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isMaxHealthDeterminedByDisguisedEntity() {
 | 
			
		||||
        return maxHealthIsDisguisedEntity;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static boolean isMetadataPacketsEnabled() {
 | 
			
		||||
        return sendsEntityMetadata;
 | 
			
		||||
    }
 | 
			
		||||
@@ -240,6 +245,10 @@ public class DisguiseConfig {
 | 
			
		||||
        keepDisguisePlayerLogout = keepDisguise;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setMaxHealthDeterminedByDisguisedEntity(boolean isDetermined) {
 | 
			
		||||
        maxHealthIsDisguisedEntity = isDetermined;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static void setMetadataPacketsEnabled(boolean enabled) {
 | 
			
		||||
        sendsEntityMetadata = enabled;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -27,6 +27,7 @@ import org.bukkit.configuration.ConfigurationSection;
 | 
			
		||||
import org.bukkit.configuration.file.FileConfiguration;
 | 
			
		||||
import org.bukkit.configuration.file.YamlConfiguration;
 | 
			
		||||
import org.bukkit.entity.Ageable;
 | 
			
		||||
import org.bukkit.entity.Damageable;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.LivingEntity;
 | 
			
		||||
import org.bukkit.entity.Zombie;
 | 
			
		||||
@@ -107,6 +108,7 @@ public class LibsDisguises extends JavaPlugin {
 | 
			
		||||
        DisguiseConfig.setEntityStatusPacketsEnabled(getConfig().getBoolean("PacketsEnabled.EntityStatus"));
 | 
			
		||||
        DisguiseConfig.setCollectPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Collect"));
 | 
			
		||||
        DisguiseConfig.setMetadataPacketsEnabled(getConfig().getBoolean("PacketsEnabled.Metadata"));
 | 
			
		||||
        DisguiseConfig.setMaxHealthDeterminedByDisguisedEntity(getConfig().getBoolean("MaxHealthDeterminedByEntity"));
 | 
			
		||||
        try {
 | 
			
		||||
            // Here I use reflection to set the plugin for Disguise..
 | 
			
		||||
            // Kind of stupid but I don't want open API calls for a commonly used object.
 | 
			
		||||
@@ -234,7 +236,8 @@ public class LibsDisguises extends JavaPlugin {
 | 
			
		||||
                        break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                DisguiseValues disguiseValues = new DisguiseValues(disguiseType, nmsEntity.getClass(), entitySize);
 | 
			
		||||
                DisguiseValues disguiseValues = new DisguiseValues(disguiseType, nmsEntity.getClass(), entitySize,
 | 
			
		||||
                        bukkitEntity instanceof Damageable ? ((Damageable) bukkitEntity).getMaxHealth() : 0);
 | 
			
		||||
                for (WrappedWatchableObject watch : WrappedDataWatcher.getEntityWatcher(bukkitEntity).getWatchableObjects()) {
 | 
			
		||||
                    disguiseValues.setMetaValue(watch.getIndex(), watch.getValue());
 | 
			
		||||
                    // Uncomment when I need to find the new datawatcher values for a class..
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,8 @@ public class LivingWatcher extends FlagWatcher {
 | 
			
		||||
            ex.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    private double maxHealth;
 | 
			
		||||
    private boolean maxHealthSet;
 | 
			
		||||
    private HashSet<Integer> potionEffects = new HashSet<Integer>();
 | 
			
		||||
 | 
			
		||||
    public LivingWatcher(Disguise disguise) {
 | 
			
		||||
@@ -48,6 +50,8 @@ public class LivingWatcher extends FlagWatcher {
 | 
			
		||||
    public LivingWatcher clone(Disguise disguise) {
 | 
			
		||||
        LivingWatcher clone = (LivingWatcher) super.clone(disguise);
 | 
			
		||||
        clone.potionEffects = (HashSet<Integer>) potionEffects.clone();
 | 
			
		||||
        clone.maxHealth = maxHealth;
 | 
			
		||||
        clone.maxHealthSet = maxHealthSet;
 | 
			
		||||
        return clone;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -59,6 +63,10 @@ public class LivingWatcher extends FlagWatcher {
 | 
			
		||||
        return (Float) getValue(6, 0F);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public double getMaxHealth() {
 | 
			
		||||
        return maxHealth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean getPotionParticlesRemoved() {
 | 
			
		||||
        return (Byte) getValue(8, (byte) 0) == 1;
 | 
			
		||||
    }
 | 
			
		||||
@@ -105,6 +113,10 @@ public class LivingWatcher extends FlagWatcher {
 | 
			
		||||
        return (Byte) getValue(11, (byte) 0) == 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isMaxHealthSet() {
 | 
			
		||||
        return maxHealthSet;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void removePotionEffect(PotionEffectType type) {
 | 
			
		||||
        if (potionEffects.contains(type.getId())) {
 | 
			
		||||
            potionEffects.remove(type.getId());
 | 
			
		||||
@@ -139,4 +151,10 @@ public class LivingWatcher extends FlagWatcher {
 | 
			
		||||
        sendData(6);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setMaxHealth(double newHealth) {
 | 
			
		||||
        this.maxHealth = newHealth;
 | 
			
		||||
        maxHealthSet = true;
 | 
			
		||||
        // TODO Send packet
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -47,13 +47,15 @@ public class DisguiseValues {
 | 
			
		||||
    private FakeBoundingBox babyBox;
 | 
			
		||||
    private float[] entitySize;
 | 
			
		||||
    private int enumEntitySize;
 | 
			
		||||
    private double maxHealth;
 | 
			
		||||
    private HashMap<Integer, Object> metaValues = new HashMap<Integer, Object>();
 | 
			
		||||
    private Class nmsEntityClass;
 | 
			
		||||
 | 
			
		||||
    public DisguiseValues(DisguiseType type, Class classType, int entitySize) {
 | 
			
		||||
    public DisguiseValues(DisguiseType type, Class classType, int entitySize, double maxHealth) {
 | 
			
		||||
        values.put(type, this);
 | 
			
		||||
        enumEntitySize = entitySize;
 | 
			
		||||
        nmsEntityClass = classType;
 | 
			
		||||
        this.maxHealth = maxHealth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public FakeBoundingBox getAdultBox() {
 | 
			
		||||
@@ -112,6 +114,10 @@ public class DisguiseValues {
 | 
			
		||||
        return (int) Math.floor(paramDouble * 32.0D);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public double getMaxHealth() {
 | 
			
		||||
        return maxHealth;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public HashMap<Integer, Object> getMetaValues() {
 | 
			
		||||
        return metaValues;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,7 @@ import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType;
 | 
			
		||||
import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion;
 | 
			
		||||
@@ -43,6 +44,8 @@ import com.comphenix.protocol.events.PacketContainer;
 | 
			
		||||
import com.comphenix.protocol.events.PacketEvent;
 | 
			
		||||
import com.comphenix.protocol.events.PacketListener;
 | 
			
		||||
import com.comphenix.protocol.reflect.StructureModifier;
 | 
			
		||||
import com.comphenix.protocol.wrappers.WrappedAttribute;
 | 
			
		||||
import com.comphenix.protocol.wrappers.WrappedAttribute.Builder;
 | 
			
		||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
 | 
			
		||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
 | 
			
		||||
 | 
			
		||||
@@ -1173,10 +1176,39 @@ public class PacketsManager {
 | 
			
		||||
            if (disguise != null) {
 | 
			
		||||
                packets = new PacketContainer[] { sentPacket };
 | 
			
		||||
 | 
			
		||||
                // If packet is PacketType.Play.Server.UPDATE_ATTRIBUTES
 | 
			
		||||
                // This packet sends attributes
 | 
			
		||||
                if (sentPacket.getType() == PacketType.Play.Server.UPDATE_ATTRIBUTES) {
 | 
			
		||||
                    packets = new PacketContainer[0];
 | 
			
		||||
                    if (disguise.isMiscDisguise()) {
 | 
			
		||||
                        packets = new PacketContainer[0];
 | 
			
		||||
                    } else {
 | 
			
		||||
                        List<WrappedAttribute> attributes = new ArrayList<WrappedAttribute>();
 | 
			
		||||
                        for (WrappedAttribute attribute : sentPacket.getAttributeCollectionModifier().read(0)) {
 | 
			
		||||
                            if (attribute.getAttributeKey().equals("generic.maxHealth")) {
 | 
			
		||||
                                packets[0] = new PacketContainer(PacketType.Play.Server.UPDATE_ATTRIBUTES);
 | 
			
		||||
                                Builder builder;
 | 
			
		||||
                                if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
 | 
			
		||||
                                    builder = WrappedAttribute.newBuilder();
 | 
			
		||||
                                    builder.attributeKey("generic.maxHealth");
 | 
			
		||||
                                    builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
 | 
			
		||||
                                } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity()) {
 | 
			
		||||
                                    builder = WrappedAttribute.newBuilder(attribute);
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    builder = WrappedAttribute.newBuilder();
 | 
			
		||||
                                    builder.attributeKey("generic.maxHealth");
 | 
			
		||||
                                    builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
 | 
			
		||||
                                }
 | 
			
		||||
                                builder.packet(packets[0]);
 | 
			
		||||
                                attributes.add(builder.build());
 | 
			
		||||
                                break;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                        if (!attributes.isEmpty()) {
 | 
			
		||||
                            packets[0].getIntegers().write(0, entity.getEntityId());
 | 
			
		||||
                            packets[0].getAttributeCollectionModifier().write(0, attributes);
 | 
			
		||||
                        } else {
 | 
			
		||||
                            packets = new PacketContainer[0];
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                else if (sentPacket.getType() == PacketType.Play.Server.ATTACH_ENTITY) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user