Armorstand names now adapt to basic entity sizes, and player sneaking. Doesn't handle poses.
This commit is contained in:
		| @@ -116,6 +116,8 @@ public abstract class Disguise { | ||||
|         return DisguiseUtilities.reverse(multiName); | ||||
|     } | ||||
|  | ||||
|     public abstract double getHeight(); | ||||
|  | ||||
|     public void setMultiName(String... name) { | ||||
|         if (name.length == 1 && name[0].isEmpty()) { | ||||
|             name = new String[0]; | ||||
|   | ||||
| @@ -47,10 +47,12 @@ public class FlagWatcher { | ||||
|     private HashMap<Integer, Object> entityValues = new HashMap<>(); | ||||
|     private LibsEquipment equipment; | ||||
|     private boolean hasDied; | ||||
|     @Getter | ||||
|     private boolean[] modifiedEntityAnimations = new boolean[8]; | ||||
|     private transient List<WrappedWatchableObject> watchableObjects; | ||||
|     private boolean sleeping; | ||||
|     private boolean swimming; | ||||
|     private transient boolean previouslySneaking; | ||||
|  | ||||
|     public FlagWatcher(Disguise disguise) { | ||||
|         this.disguise = (TargetedDisguise) disguise; | ||||
| @@ -150,8 +152,10 @@ public class FlagWatcher { | ||||
|             } | ||||
|  | ||||
|             if (value != null) { | ||||
|                 if (isEntityAnimationsAdded() && id == 0) { | ||||
|                 if (isEntityAnimationsAdded() && id == MetaIndex.ENTITY_META.getIndex()) { | ||||
|                     value = addEntityAnimations((byte) value, (byte) watch.getValue()); | ||||
|  | ||||
|                     doSneakCheck((Byte) value); | ||||
|                 } | ||||
|  | ||||
|                 boolean isDirty = watch.getDirtyState(); | ||||
| @@ -175,6 +179,10 @@ public class FlagWatcher { | ||||
|                 if (!isDirty) { | ||||
|                     watch.setDirtyState(false); | ||||
|                 } | ||||
|  | ||||
|                 if (id == MetaIndex.ENTITY_META.getIndex()) { | ||||
|                     doSneakCheck((Byte) watch.getValue()); | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             newList.add(watch); | ||||
| @@ -207,7 +215,7 @@ public class FlagWatcher { | ||||
|                 getDisguise().getEntity() instanceof Player) { | ||||
|             for (WrappedWatchableObject watch : newList) { | ||||
|                 // Its a health packet | ||||
|                 if (watch.getIndex() == 6) { | ||||
|                 if (watch.getIndex() == MetaIndex.LIVING_HEALTH.getIndex()) { | ||||
|                     Object value = watch.getValue(); | ||||
|  | ||||
|                     if (value instanceof Float) { | ||||
| @@ -236,6 +244,21 @@ public class FlagWatcher { | ||||
|         return newList; | ||||
|     } | ||||
|  | ||||
|     private void doSneakCheck(byte value) { | ||||
|         if (getModifiedEntityAnimations()[1] || !getDisguise().isPlayerDisguise()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         boolean sneak = (value & 1 << 1) != 0; | ||||
|  | ||||
|         if (sneak == previouslySneaking) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         previouslySneaking = sneak; | ||||
|         updateNameHeight(); | ||||
|     } | ||||
|  | ||||
|     @NmsAddedIn(val = NmsVersion.v1_14) | ||||
|     public EntityPose getEntityPose() { | ||||
|         return getData(MetaIndex.ENTITY_POSE); | ||||
| @@ -255,6 +278,55 @@ public class FlagWatcher { | ||||
|         getEquipment().setArmorContents(items); | ||||
|     } | ||||
|  | ||||
|     protected void updateNameHeight() { | ||||
|         if (!getDisguise().isDisguiseInUse()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!DisguiseConfig.isArmorstandsName()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (!getDisguise().isPlayerDisguise() && !DisguiseConfig.isOverrideCustomNames()) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         if (getDisguise().getEntity() == null) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         // Not using this as it's "Smooth" and looks a bit weirder | ||||
|         /*int[] ids = getDisguise().getArmorstandIds(); | ||||
|  | ||||
|         ArrayList<PacketContainer> packets = new ArrayList<>(); | ||||
|         Location loc = getDisguise().getEntity().getLocation(); | ||||
|  | ||||
|         for (int i = 0; i < getDisguise().getMultiNameLength(); i++) { | ||||
|             PacketContainer packet = new PacketContainer(Server.ENTITY_TELEPORT); | ||||
|             packet.getIntegers().write(0, ids[i]); | ||||
|  | ||||
|             StructureModifier<Double> doubles = packet.getDoubles(); | ||||
|             doubles.write(0, loc.getX()); | ||||
|             doubles.write(1, loc.getY() + getDisguise().getHeight() + (0.28 * i)); | ||||
|             doubles.write(2, loc.getZ()); | ||||
|  | ||||
|             packets.add(packet); | ||||
|         }*/ | ||||
|  | ||||
|         ArrayList<PacketContainer> packets = DisguiseUtilities.getNamePackets(getDisguise(), new String[0]); | ||||
|  | ||||
|         try { | ||||
|             for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { | ||||
|                 for (PacketContainer packet : packets) { | ||||
|                     ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         catch (InvocationTargetException e) { | ||||
|             e.printStackTrace(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public String getCustomName() { | ||||
|         if (!getDisguise().isPlayerDisguise() && DisguiseConfig.isOverrideCustomNames() && | ||||
|                 DisguiseConfig.isArmorstandsName()) { | ||||
| @@ -266,6 +338,10 @@ public class FlagWatcher { | ||||
|         } | ||||
|  | ||||
|         if (!NmsVersion.v1_13.isSupported()) { | ||||
|             if (!hasValue(MetaIndex.ENTITY_CUSTOM_NAME_OLD)) { | ||||
|                 return null; | ||||
|             } | ||||
|  | ||||
|             return getData(MetaIndex.ENTITY_CUSTOM_NAME_OLD); | ||||
|         } | ||||
|  | ||||
| @@ -470,6 +546,10 @@ public class FlagWatcher { | ||||
|         setEntityFlag(1, setSneaking); | ||||
|         sendData(MetaIndex.ENTITY_META); | ||||
|  | ||||
|         if (getDisguise().isPlayerDisguise()) { | ||||
|             updateNameHeight(); | ||||
|         } | ||||
|  | ||||
|         if (NmsVersion.v1_14.isSupported()) { | ||||
|             updatePose(); | ||||
|         } | ||||
|   | ||||
| @@ -4,6 +4,7 @@ import me.libraryaddict.disguise.disguisetypes.watchers.DroppedItemWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.FallingBlockWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.PaintingWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.SplashPotionWatcher; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseValues; | ||||
| import org.bukkit.Art; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.entity.Entity; | ||||
| @@ -63,6 +64,17 @@ public class MiscDisguise extends TargetedDisguise { | ||||
|         apply(id, new ItemStack(Material.STONE)); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public double getHeight() { | ||||
|         DisguiseValues values = DisguiseValues.getDisguiseValues(getType()); | ||||
|  | ||||
|         if (values == null || values.getAdultBox() == null) { | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         return values.getAdultBox().getY(); | ||||
|     } | ||||
|  | ||||
|     private void apply(int id, ItemStack itemStack) { | ||||
|         createDisguise(); | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,7 @@ | ||||
| package me.libraryaddict.disguise.disguisetypes; | ||||
|  | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.*; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseValues; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.Player; | ||||
|  | ||||
| @@ -30,6 +29,30 @@ public class MobDisguise extends TargetedDisguise { | ||||
|         createDisguise(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public double getHeight() { | ||||
|         DisguiseValues values = DisguiseValues.getDisguiseValues(getType()); | ||||
|  | ||||
|         if (values == null || values.getAdultBox() == null) { | ||||
|             return 0; | ||||
|         } | ||||
|  | ||||
|         if (!isAdult() && values.getBabyBox() != null) { | ||||
|             return values.getBabyBox().getY(); | ||||
|         } | ||||
|  | ||||
|         if (getWatcher() != null) { | ||||
|             if (getType() == DisguiseType.ARMOR_STAND) { | ||||
|                 return (((ArmorStandWatcher) getWatcher()).isSmall() ? values.getBabyBox() : values.getAdultBox()) | ||||
|                         .getY(); | ||||
|             } else if (getType() == DisguiseType.SLIME || getType() == DisguiseType.MAGMA_CUBE) { | ||||
|                 return 0.51 * (0.255 * ((SlimeWatcher) getWatcher()).getSize()); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         return values.getAdultBox().getY(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public MobDisguise addPlayer(Player player) { | ||||
|         return (MobDisguise) super.addPlayer(player); | ||||
|   | ||||
| @@ -38,6 +38,11 @@ public class ModdedDisguise extends TargetedDisguise { | ||||
|         createDisguise(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public double getHeight() { | ||||
|         return 0; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean isCustomDisguise() { | ||||
|         return true; | ||||
|   | ||||
| @@ -83,6 +83,19 @@ public class PlayerDisguise extends TargetedDisguise { | ||||
|         createDisguise(); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public double getHeight() { | ||||
|         if (getWatcher() == null) { | ||||
|             return 1.8; | ||||
|         } | ||||
|  | ||||
|         if (getEntity() == null || getWatcher().getModifiedEntityAnimations()[1]) { | ||||
|             return getWatcher().isSneaking() ? 1.5 : 1.8; | ||||
|         } | ||||
|  | ||||
|         return getEntity() instanceof Player && ((Player) getEntity()).isSneaking() ? 1.5 : 1.8; | ||||
|     } | ||||
|  | ||||
|     @Deprecated | ||||
|     public DisguiseUtilities.DScoreTeam getScoreboardName() { | ||||
|         if (!DisguiseConfig.isScoreboardNames()) { | ||||
|   | ||||
| @@ -25,7 +25,13 @@ public class SlimeWatcher extends InsentientWatcher { | ||||
|             size = 50; | ||||
|         } | ||||
|  | ||||
|         if (hasValue(MetaIndex.SLIME_SIZE) && getData(MetaIndex.SLIME_SIZE) == size) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         setData(MetaIndex.SLIME_SIZE, size); | ||||
|         sendData(MetaIndex.SLIME_SIZE); | ||||
|  | ||||
|         updateNameHeight(); | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -22,7 +22,7 @@ import me.libraryaddict.disguise.LibsDisguises; | ||||
| import me.libraryaddict.disguise.disguisetypes.*; | ||||
| import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.ArmorStandWatcher; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; | ||||
| import me.libraryaddict.disguise.utilities.json.*; | ||||
| import me.libraryaddict.disguise.utilities.mineskin.MineSkinAPI; | ||||
| @@ -2323,6 +2323,8 @@ public class DisguiseUtilities { | ||||
|             destroyIds = Arrays.copyOfRange(standIds, newNames.length, internalOldNames.length); | ||||
|         } | ||||
|  | ||||
|         double height = disguise.getHeight(); | ||||
|  | ||||
|         for (int i = 0; i < newNames.length; i++) { | ||||
|             if (i < internalOldNames.length) { | ||||
|                 if (newNames[i].equals(internalOldNames[i]) || newNames[i].isEmpty()) { | ||||
| @@ -2358,19 +2360,19 @@ public class DisguiseUtilities { | ||||
|                 Location loc = disguise.getEntity().getLocation(); | ||||
|  | ||||
|                 packet.getDoubles().write(0, loc.getX()); | ||||
|                 packet.getDoubles().write(1, loc.getY() + -0.175 + (0.28 * i)); | ||||
|                 packet.getDoubles().write(1, loc.getY() + height + (0.28 * i)); | ||||
|                 packet.getDoubles().write(2, loc.getZ()); | ||||
|                 packets.add(packet); | ||||
|  | ||||
|                 WrappedDataWatcher watcher = new WrappedDataWatcher(); | ||||
|  | ||||
|                 for (MetaIndex index : MetaIndex.getMetaIndexes(LivingWatcher.class)) { | ||||
|                 for (MetaIndex index : MetaIndex.getMetaIndexes(ArmorStandWatcher.class)) { | ||||
|                     Object val = index.getDefault(); | ||||
|  | ||||
|                     if (index == MetaIndex.ENTITY_META) { | ||||
|                         val = (byte) 32; | ||||
|                     } else if (index == MetaIndex.ARMORSTAND_META) { | ||||
|                         val = (byte) 17; | ||||
|                         val = (byte) 19; | ||||
|                     } else if (index == MetaIndex.ENTITY_CUSTOM_NAME) { | ||||
|                         val = Optional.of(WrappedChatComponent.fromText(newNames[i])); | ||||
|                     } else if (index == MetaIndex.ENTITY_CUSTOM_NAME_OLD) { | ||||
| @@ -2387,7 +2389,7 @@ public class DisguiseUtilities { | ||||
|  | ||||
|                 if (NmsVersion.v1_15.isSupported()) { | ||||
|                     PacketContainer metaPacket = ProtocolLibrary.getProtocolManager() | ||||
|                             .createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, 0, watcher, true) | ||||
|                             .createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, standIds[i], watcher, true) | ||||
|                             .createPacket(standIds[i], watcher, true); | ||||
|  | ||||
|                     packets.add(metaPacket); | ||||
|   | ||||
| @@ -15,19 +15,12 @@ public class DisguiseValues { | ||||
|         return values.get(type); | ||||
|     } | ||||
|  | ||||
|     public static Class getNmsEntityClass(DisguiseType type) { | ||||
|         return getDisguiseValues(type).getNmsEntityClass(); | ||||
|     } | ||||
|  | ||||
|     private FakeBoundingBox adultBox; | ||||
|     private FakeBoundingBox babyBox; | ||||
|     private float[] entitySize; | ||||
|     private double maxHealth; | ||||
|     private Class nmsEntityClass; | ||||
|     private final double maxHealth; | ||||
|  | ||||
|     public DisguiseValues(DisguiseType type, Class classType, double maxHealth) { | ||||
|     public DisguiseValues(DisguiseType type, double maxHealth) { | ||||
|         values.put(type, this); | ||||
|         nmsEntityClass = classType; | ||||
|         this.maxHealth = maxHealth; | ||||
|     } | ||||
|  | ||||
| @@ -50,8 +43,4 @@ public class DisguiseValues { | ||||
|     public double getMaxHealth() { | ||||
|         return maxHealth; | ||||
|     } | ||||
|  | ||||
|     public Class getNmsEntityClass() { | ||||
|         return nmsEntityClass; | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -49,6 +49,7 @@ public class PacketHandlerMovement implements IPacketHandler { | ||||
|         } | ||||
|  | ||||
|         ArrayList<PacketContainer> toAdd = new ArrayList<>(); | ||||
|         double height = disguise.getHeight(); | ||||
|  | ||||
|         for (PacketContainer packet : packets.getPackets()) { | ||||
|             for (int i = 0; i < len; i++) { | ||||
| @@ -57,7 +58,7 @@ public class PacketHandlerMovement implements IPacketHandler { | ||||
|                 packet2.getIntegers().write(0, standId); | ||||
|  | ||||
|                 if (packet2.getType() == PacketType.Play.Server.ENTITY_TELEPORT) { | ||||
|                     packet2.getDoubles().write(1, packet2.getDoubles().read(1) + -0.175 + (0.28 * i)); | ||||
|                     packet2.getDoubles().write(1, packet2.getDoubles().read(1) + height + (0.28 * i)); | ||||
|                 } | ||||
|  | ||||
|                 toAdd.add(packet2); | ||||
|   | ||||
| @@ -48,8 +48,10 @@ public class DisguiseParser { | ||||
|                     disguise = new MiscDisguise(type); | ||||
|                 } else if (type.isMob()) { | ||||
|                     disguise = new MobDisguise(type); | ||||
|                 } else { | ||||
|                 } else if (type.isPlayer()) { | ||||
|                     disguise = new PlayerDisguise("Foobar"); | ||||
|                 } else { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 FlagWatcher watcher = type.getWatcherClass().getConstructor(Disguise.class).newInstance(disguise); | ||||
| @@ -217,15 +219,14 @@ public class DisguiseParser { | ||||
|     } | ||||
|  | ||||
|     private static void addWatcherDefault(Method setMethod, Method getMethod, Object object) { | ||||
|  | ||||
|         if (defaultWatcherValues.containsKey(setMethod)) { | ||||
|             Object dObj = defaultWatcherValues.get(setMethod).getValue(); | ||||
|  | ||||
|             if (!Objects.deepEquals(dObj, object)) { | ||||
|                 throw new IllegalStateException(String.format( | ||||
|                         "%s has conflicting values! This means it expected the same value again but received a " + | ||||
|                                 "different value on a different disguise! %s is not the same as %s!", setMethod.getName(), object, | ||||
|                         dObj)); | ||||
|                                 "different value on a different disguise! %s is not the same as %s!", | ||||
|                         setMethod.getName(), object, dObj)); | ||||
|             } | ||||
|  | ||||
|             return; | ||||
|   | ||||
| @@ -1722,7 +1722,7 @@ public class ReflectionManager { | ||||
|  | ||||
|         try { | ||||
|             if (disguiseType == DisguiseType.UNKNOWN || disguiseType.isCustom()) { | ||||
|                 DisguiseValues disguiseValues = new DisguiseValues(disguiseType, null, 0); | ||||
|                 DisguiseValues disguiseValues = new DisguiseValues(disguiseType, 0); | ||||
|  | ||||
|                 disguiseValues.setAdultBox(new FakeBoundingBox(0, 0, 0)); | ||||
|  | ||||
| @@ -1763,7 +1763,7 @@ public class ReflectionManager { | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             DisguiseValues disguiseValues = new DisguiseValues(disguiseType, nmsEntity.getClass(), | ||||
|             DisguiseValues disguiseValues = new DisguiseValues(disguiseType, | ||||
|                     bukkitEntity instanceof Damageable ? ((Damageable) bukkitEntity).getMaxHealth() : 0); | ||||
|  | ||||
|             WrappedDataWatcher watcher = WrappedDataWatcher.getEntityWatcher(bukkitEntity); | ||||
| @@ -1841,9 +1841,11 @@ public class ReflectionManager { | ||||
|                 ((Zombie) bukkitEntity).setBaby(true); | ||||
|  | ||||
|                 disguiseValues.setBabyBox(ReflectionManager.getBoundingBox(bukkitEntity)); | ||||
|             } | ||||
|             } else if (bukkitEntity instanceof ArmorStand) { | ||||
|                 ((ArmorStand) bukkitEntity).setSmall(true); | ||||
|  | ||||
|             //disguiseValues.setEntitySize(ReflectionManager.getSize(bukkitEntity)); | ||||
|                 disguiseValues.setBabyBox(ReflectionManager.getBoundingBox(bukkitEntity)); | ||||
|             } | ||||
|         } | ||||
|         catch (SecurityException | IllegalArgumentException | IllegalAccessException | FieldAccessException ex) { | ||||
|             DisguiseUtilities.getLogger() | ||||
|   | ||||
| @@ -72,8 +72,10 @@ SaveDisguises: | ||||
| # EXTENDED - Names are limited to 48 chars but can't be changed without resending disguise | ||||
| # ARMORSTANDS - Names are limited to 256 chars, uses a mix of armorstands and teams to do this. Slightly hacky. | ||||
| # Downside of armorstand names is that there's a chance of it becoming desynced from the player disguise | ||||
| # And names will always display even if the entity is invisible using potion effects | ||||
| PlayerNames: TEAMS | ||||
| # If doing armorstands, should CustomNames be overridden to use armorstands too? | ||||
| # If doing ARMORSTANDS in the above option, should CustomNames be overridden to use armorstands too? | ||||
| # This allows multiline names | ||||
| OverrideCustomNames: true | ||||
|  | ||||
| # How many ticks before tab packet is sent to remove from tablist. This shouldn't need to be touched | ||||
|   | ||||
		Reference in New Issue
	
	Block a user