1098 lines
35 KiB
Java
1098 lines
35 KiB
Java
package me.libraryaddict.disguise.disguisetypes;
|
|
|
|
import com.comphenix.protocol.PacketType.Play.Server;
|
|
import com.comphenix.protocol.ProtocolLibrary;
|
|
import com.comphenix.protocol.events.PacketContainer;
|
|
import com.comphenix.protocol.reflect.StructureModifier;
|
|
import com.comphenix.protocol.wrappers.ComponentConverter;
|
|
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
|
import com.google.common.base.Strings;
|
|
import com.mojang.datafixers.util.Pair;
|
|
import lombok.AccessLevel;
|
|
import lombok.Getter;
|
|
import me.libraryaddict.disguise.DisguiseAPI;
|
|
import me.libraryaddict.disguise.DisguiseConfig;
|
|
import me.libraryaddict.disguise.LibsDisguises;
|
|
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
|
|
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
|
import me.libraryaddict.disguise.utilities.LibsPremium;
|
|
import me.libraryaddict.disguise.utilities.parser.RandomDefaultValue;
|
|
import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn;
|
|
import me.libraryaddict.disguise.utilities.reflection.NmsVersion;
|
|
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
|
import net.md_5.bungee.api.chat.BaseComponent;
|
|
import org.apache.commons.lang.StringUtils;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.ChatColor;
|
|
import org.bukkit.Location;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.EntityEquipment;
|
|
import org.bukkit.inventory.EquipmentSlot;
|
|
import org.bukkit.inventory.ItemStack;
|
|
|
|
import java.lang.reflect.InvocationTargetException;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.HashSet;
|
|
import java.util.List;
|
|
import java.util.Objects;
|
|
import java.util.Optional;
|
|
|
|
public class FlagWatcher {
|
|
private boolean addEntityAnimations = DisguiseConfig.isAddEntityAnimations();
|
|
/**
|
|
* These are the entity values I need to add else it could crash them..
|
|
*/
|
|
@Getter(value = AccessLevel.PROTECTED)
|
|
private HashMap<Integer, Object> backupEntityValues = new HashMap<>();
|
|
private transient TargetedDisguise disguise;
|
|
/**
|
|
* Disguise set data
|
|
*/
|
|
@Getter(value = AccessLevel.PROTECTED)
|
|
private HashMap<Integer, Object> entityValues = new HashMap<>();
|
|
private LibsEquipment equipment;
|
|
private transient boolean hasDied;
|
|
@Getter
|
|
private boolean[] modifiedEntityAnimations = new boolean[8];
|
|
private transient List<WrappedWatchableObject> watchableObjects;
|
|
private boolean sleeping;
|
|
private transient boolean previouslySneaking;
|
|
@Getter
|
|
private boolean upsideDown;
|
|
private ChatColor glowColor = ChatColor.WHITE;
|
|
@Getter
|
|
private Float pitchLock;
|
|
@Getter
|
|
private Float yawLock;
|
|
@Getter
|
|
private float yModifier;
|
|
@Getter
|
|
private float nameYModifier;
|
|
|
|
public FlagWatcher(Disguise disguise) {
|
|
this.disguise = (TargetedDisguise) disguise;
|
|
equipment = new LibsEquipment(this);
|
|
}
|
|
|
|
public boolean isPitchLocked() {
|
|
return pitchLock != null;
|
|
}
|
|
|
|
public void setPitchLocked(boolean pitchLocked) {
|
|
if (isPitchLocked() == pitchLocked) {
|
|
return;
|
|
}
|
|
|
|
setPitchLock(pitchLocked ? 0F : null);
|
|
}
|
|
|
|
public void setNameYModifier(float yModifier) {
|
|
this.nameYModifier = yModifier;
|
|
|
|
if (!DisguiseConfig.isMovementPacketsEnabled() || !getDisguise().isDisguiseInUse()) {
|
|
return;
|
|
}
|
|
|
|
PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacketConstructor(Server.ENTITY_TELEPORT, getDisguise().getEntity())
|
|
.createPacket(getDisguise().getEntity());
|
|
|
|
try {
|
|
for (Player player : DisguiseUtilities.getPerverts(getDisguise())) {
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
}
|
|
} catch (InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public void setYModifier(float yModifier) {
|
|
if (!DisguiseConfig.isMovementPacketsEnabled()) {
|
|
return;
|
|
}
|
|
|
|
this.yModifier = yModifier;
|
|
|
|
if (!getDisguise().isDisguiseInUse()) {
|
|
return;
|
|
}
|
|
|
|
PacketContainer packet = ProtocolLibrary.getProtocolManager().createPacketConstructor(Server.ENTITY_TELEPORT, getDisguise().getEntity())
|
|
.createPacket(getDisguise().getEntity());
|
|
|
|
try {
|
|
for (Player player : DisguiseUtilities.getPerverts(getDisguise())) {
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
}
|
|
} catch (InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public boolean isYawLocked() {
|
|
return yawLock != null;
|
|
}
|
|
|
|
public void setYawLocked(boolean yawLocked) {
|
|
if (!DisguiseConfig.isMovementPacketsEnabled()) {
|
|
return;
|
|
}
|
|
|
|
if (isYawLocked() == yawLocked) {
|
|
return;
|
|
}
|
|
|
|
setYawLock(yawLocked ? 0F : null);
|
|
}
|
|
|
|
public void setPitchLock(Float pitch) {
|
|
if (!DisguiseConfig.isMovementPacketsEnabled()) {
|
|
return;
|
|
}
|
|
|
|
this.pitchLock = pitch;
|
|
|
|
if (!getDisguise().isDisguiseInUse()) {
|
|
return;
|
|
}
|
|
|
|
sendHeadPacket();
|
|
}
|
|
|
|
private void sendHeadPacket() {
|
|
PacketContainer rotateHead = new PacketContainer(Server.ENTITY_HEAD_ROTATION);
|
|
|
|
StructureModifier<Object> mods = rotateHead.getModifier();
|
|
|
|
mods.write(0, getDisguise().getEntity().getEntityId());
|
|
|
|
Location loc = getDisguise().getEntity().getLocation();
|
|
|
|
mods.write(1, (byte) (int) (loc.getYaw() * 256.0F / 360.0F));
|
|
|
|
try {
|
|
for (Player player : DisguiseUtilities.getPerverts(getDisguise())) {
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, rotateHead);
|
|
}
|
|
} catch (InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public void setYawLock(Float yaw) {
|
|
this.yawLock = yaw;
|
|
|
|
if (!getDisguise().isDisguiseInUse()) {
|
|
return;
|
|
}
|
|
|
|
sendHeadPacket();
|
|
}
|
|
|
|
protected byte addEntityAnimations(MetaIndex index, byte originalValue, byte entityValue) {
|
|
if (index != MetaIndex.ENTITY_META) {
|
|
return originalValue;
|
|
}
|
|
|
|
for (int i = 0; i < 6; i++) {
|
|
if ((entityValue & 1 << i) != 0 && !modifiedEntityAnimations[i]) {
|
|
originalValue = (byte) (originalValue | 1 << i);
|
|
}
|
|
}
|
|
|
|
return originalValue;
|
|
}
|
|
|
|
public FlagWatcher clone(Disguise owningDisguise) {
|
|
FlagWatcher cloned;
|
|
|
|
try {
|
|
cloned = getClass().getConstructor(Disguise.class).newInstance(owningDisguise);
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
cloned = new FlagWatcher(owningDisguise);
|
|
}
|
|
|
|
cloned.entityValues = (HashMap<Integer, Object>) entityValues.clone();
|
|
cloned.equipment = equipment.clone(cloned);
|
|
cloned.modifiedEntityAnimations = Arrays.copyOf(modifiedEntityAnimations, modifiedEntityAnimations.length);
|
|
cloned.addEntityAnimations = addEntityAnimations;
|
|
cloned.upsideDown = upsideDown;
|
|
cloned.sleeping = sleeping;
|
|
cloned.glowColor = glowColor;
|
|
cloned.pitchLock = pitchLock;
|
|
cloned.yawLock = yawLock;
|
|
cloned.yModifier = yModifier;
|
|
cloned.nameYModifier = nameYModifier;
|
|
|
|
return cloned;
|
|
}
|
|
|
|
public ItemStack getHelmet() {
|
|
return getEquipment().getHelmet();
|
|
}
|
|
|
|
public void setHelmet(ItemStack itemStack) {
|
|
getEquipment().setHelmet(itemStack);
|
|
}
|
|
|
|
public ItemStack getBoots() {
|
|
return getEquipment().getBoots();
|
|
}
|
|
|
|
public void setBoots(ItemStack itemStack) {
|
|
getEquipment().setBoots(itemStack);
|
|
}
|
|
|
|
public ItemStack getLeggings() {
|
|
return getEquipment().getLeggings();
|
|
}
|
|
|
|
public void setLeggings(ItemStack itemStack) {
|
|
getEquipment().setLeggings(itemStack);
|
|
}
|
|
|
|
public ItemStack getChestplate() {
|
|
return getEquipment().getChestplate();
|
|
}
|
|
|
|
public void setChestplate(ItemStack itemStack) {
|
|
getEquipment().setChestplate(itemStack);
|
|
}
|
|
|
|
@Deprecated
|
|
public void setInternalUpsideDown(boolean upsideDown) {
|
|
this.upsideDown = upsideDown;
|
|
}
|
|
|
|
public void setUpsideDown(boolean upsideDown) {
|
|
if (isUpsideDown() == upsideDown) {
|
|
return;
|
|
}
|
|
|
|
this.upsideDown = upsideDown;
|
|
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
((PlayerDisguise) getDisguise()).setUpsideDown(upsideDown);
|
|
} else {
|
|
setInteralCustomName(isUpsideDown() ? "Dinnerbone" : "");
|
|
}
|
|
}
|
|
|
|
public List<WrappedWatchableObject> convert(Player player, List<WrappedWatchableObject> list) {
|
|
List<WrappedWatchableObject> newList = new ArrayList<>();
|
|
HashSet<Integer> sentValues = new HashSet<>();
|
|
boolean sendAllCustom = false;
|
|
|
|
for (WrappedWatchableObject watch : list) {
|
|
int id = watch.getIndex();
|
|
MetaIndex index = MetaIndex.getMetaIndex(this, id);
|
|
sentValues.add(id);
|
|
|
|
if (index == null) {
|
|
continue;
|
|
}
|
|
|
|
// Its sending the air metadata. This is the least commonly sent metadata which all entitys still share.
|
|
// I send my custom values if I see this!
|
|
if (index == MetaIndex.ENTITY_AIR_TICKS) {
|
|
sendAllCustom = true;
|
|
}
|
|
|
|
Object value = null;
|
|
boolean usingBackup = false;
|
|
|
|
if (entityValues.containsKey(id)) {
|
|
if (entityValues.get(id) == null) {
|
|
continue;
|
|
}
|
|
|
|
value = entityValues.get(id);
|
|
|
|
if (index == MetaIndex.LIVING_HEALTH && (float) watch.getRawValue() <= 0) {
|
|
value = watch.getRawValue();
|
|
}
|
|
} else if (backupEntityValues.containsKey(id)) {
|
|
if (backupEntityValues.get(id) == null) {
|
|
continue;
|
|
}
|
|
|
|
value = backupEntityValues.get(id);
|
|
usingBackup = true;
|
|
}
|
|
|
|
if (value != null) {
|
|
if (isEntityAnimationsAdded() && (index == MetaIndex.ENTITY_META || (index == MetaIndex.LIVING_META && !usingBackup))) {
|
|
value = addEntityAnimations(index, (byte) value, (byte) watch.getRawValue());
|
|
|
|
if (index == MetaIndex.ENTITY_META) {
|
|
doSneakCheck((Byte) value);
|
|
}
|
|
}
|
|
|
|
boolean isDirty = watch.getDirtyState();
|
|
|
|
watch = ReflectionManager.createWatchable(index, value);
|
|
|
|
if (watch == null) {
|
|
continue;
|
|
}
|
|
|
|
if (!isDirty) {
|
|
watch.setDirtyState(false);
|
|
}
|
|
} else {
|
|
boolean isDirty = watch.getDirtyState();
|
|
|
|
watch = ReflectionManager.createWatchable(index, watch.getRawValue());
|
|
|
|
if (watch == null) {
|
|
continue;
|
|
}
|
|
|
|
if (!isDirty) {
|
|
watch.setDirtyState(false);
|
|
}
|
|
|
|
if (id == MetaIndex.ENTITY_META.getIndex()) {
|
|
doSneakCheck((Byte) watch.getRawValue());
|
|
}
|
|
}
|
|
|
|
newList.add(watch);
|
|
|
|
if (!sendAllCustom && getDisguise().isPlayerDisguise() && index == MetaIndex.LIVING_HEALTH) {
|
|
float health = ((Number) watch.getRawValue()).floatValue();
|
|
|
|
String name = DisguiseConfig.isScoreboardNames() && ((PlayerDisguise) getDisguise()).hasScoreboardName() ?
|
|
((PlayerDisguise) getDisguise()).getScoreboardName().getPlayer() : ((PlayerDisguise) getDisguise()).getName();
|
|
|
|
ReflectionManager.setScore(player.getScoreboard(), name, (int) Math.ceil(health));
|
|
}
|
|
}
|
|
|
|
if (sendAllCustom) {
|
|
// Its sending the entire meta data. Better add the custom meta
|
|
for (Integer id : entityValues.keySet()) {
|
|
if (sentValues.contains(id)) {
|
|
continue;
|
|
}
|
|
|
|
Object value = entityValues.get(id);
|
|
|
|
if (value == null) {
|
|
continue;
|
|
}
|
|
|
|
WrappedWatchableObject watch = ReflectionManager.createWatchable(MetaIndex.getMetaIndex(this, id), value);
|
|
|
|
if (watch == null) {
|
|
continue;
|
|
}
|
|
|
|
newList.add(watch);
|
|
}
|
|
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
float health;
|
|
|
|
if (hasValue(MetaIndex.LIVING_HEALTH)) {
|
|
health = ((LivingWatcher) this).getHealth();
|
|
} else if (getDisguise().getEntity() instanceof LivingEntity) {
|
|
health = (float) ((LivingEntity) getDisguise().getEntity()).getHealth();
|
|
} else {
|
|
health = MetaIndex.LIVING_HEALTH.getDefault();
|
|
}
|
|
|
|
String name = DisguiseConfig.isScoreboardNames() && ((PlayerDisguise) getDisguise()).hasScoreboardName() ?
|
|
((PlayerDisguise) getDisguise()).getScoreboardName().getPlayer() : ((PlayerDisguise) getDisguise()).getName();
|
|
|
|
ReflectionManager.setScore(player.getScoreboard(), name, (int) Math.ceil(health));
|
|
}
|
|
}
|
|
|
|
// Here we check for if there is a health packet that says they died.
|
|
if (getDisguise().isSelfDisguiseVisible() && getDisguise().getEntity() != null && getDisguise().getEntity() instanceof Player) {
|
|
for (WrappedWatchableObject watch : newList) {
|
|
// Its a health packet
|
|
if (watch.getIndex() == MetaIndex.LIVING_HEALTH.getIndex()) {
|
|
Object value = watch.getRawValue();
|
|
|
|
if (value instanceof Float) {
|
|
float newHealth = (Float) value;
|
|
|
|
if (newHealth > 0 && hasDied) {
|
|
hasDied = false;
|
|
|
|
Bukkit.getScheduler().scheduleSyncDelayedTask(LibsDisguises.getInstance(), () -> {
|
|
try {
|
|
DisguiseUtilities.sendSelfDisguise((Player) getDisguise().getEntity(), getDisguise());
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
}, 2);
|
|
} else if (newHealth <= 0 && !hasDied) {
|
|
hasDied = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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(NmsVersion.v1_14)
|
|
public EntityPose getEntityPose() {
|
|
return getData(MetaIndex.ENTITY_POSE);
|
|
}
|
|
|
|
@NmsAddedIn(NmsVersion.v1_14)
|
|
public void setEntityPose(EntityPose entityPose) {
|
|
setData(MetaIndex.ENTITY_POSE, entityPose);
|
|
sendData(MetaIndex.ENTITY_POSE);
|
|
}
|
|
|
|
public ItemStack[] getArmor() {
|
|
return getEquipment().getArmorContents();
|
|
}
|
|
|
|
public void setArmor(ItemStack[] items) {
|
|
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())) {
|
|
if (getDisguise().isPlayerDisguise() && LibsDisguises.getInstance().getSkinHandler().isSleeping(player, (PlayerDisguise) getDisguise())) {
|
|
continue;
|
|
}
|
|
|
|
for (PacketContainer packet : packets) {
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
}
|
|
}
|
|
} catch (InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
public String getCustomName() {
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
return ((PlayerDisguise) getDisguise()).getName();
|
|
}
|
|
|
|
if (DisguiseConfig.isOverrideCustomNames() && DisguiseConfig.isArmorstandsName()) {
|
|
if (getDisguise().getMultiNameLength() == 0) {
|
|
return null;
|
|
}
|
|
|
|
return StringUtils.join(getDisguise().getMultiName(), "\n");
|
|
}
|
|
|
|
if (!NmsVersion.v1_13.isSupported()) {
|
|
if (!hasValue(MetaIndex.ENTITY_CUSTOM_NAME_OLD)) {
|
|
return null;
|
|
}
|
|
|
|
return getData(MetaIndex.ENTITY_CUSTOM_NAME_OLD);
|
|
}
|
|
|
|
Optional<WrappedChatComponent> optional = getData(MetaIndex.ENTITY_CUSTOM_NAME);
|
|
|
|
if (optional.isPresent()) {
|
|
BaseComponent[] base = ComponentConverter.fromWrapper(optional.get());
|
|
|
|
return DisguiseUtilities.getSimpleString(base);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public void setCustomName(String name) {
|
|
if (name != null && name.length() > 0 && ("159" + "2").equals("%%__USER__%%")) {
|
|
name = name.substring(1);
|
|
}
|
|
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
((PlayerDisguise) getDisguise()).setName(name);
|
|
return;
|
|
}
|
|
|
|
name = DisguiseUtilities.getHexedColors(name);
|
|
|
|
String customName = getCustomName();
|
|
|
|
if (Objects.equals(customName, name)) {
|
|
return;
|
|
}
|
|
|
|
if (DisguiseConfig.isArmorstandsName() && DisguiseConfig.isOverrideCustomNames()) {
|
|
MetaIndex custom = NmsVersion.v1_13.isSupported() ? MetaIndex.ENTITY_CUSTOM_NAME : MetaIndex.ENTITY_CUSTOM_NAME_OLD;
|
|
|
|
if (!hasValue(custom)) {
|
|
setData(custom, custom.getDefault());
|
|
sendData(MetaIndex.ENTITY_CUSTOM_NAME);
|
|
setCustomNameVisible(false);
|
|
}
|
|
|
|
if (Strings.isNullOrEmpty(name)) {
|
|
getDisguise().setMultiName();
|
|
} else {
|
|
getDisguise().setMultiName(DisguiseUtilities.splitNewLine(name));
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
setInteralCustomName(name);
|
|
}
|
|
|
|
protected void setInteralCustomName(String name) {
|
|
if (Strings.isNullOrEmpty(name)) {
|
|
if (NmsVersion.v1_13.isSupported()) {
|
|
setData(MetaIndex.ENTITY_CUSTOM_NAME, Optional.empty());
|
|
} else {
|
|
setData(MetaIndex.ENTITY_CUSTOM_NAME_OLD, "");
|
|
}
|
|
} else {
|
|
if (name.length() > 64) {
|
|
name = name.substring(0, 64);
|
|
}
|
|
|
|
if (NmsVersion.v1_13.isSupported()) {
|
|
Optional<WrappedChatComponent> optional =
|
|
Optional.of(WrappedChatComponent.fromJson(DisguiseUtilities.serialize(DisguiseUtilities.getAdventureChat(name))));
|
|
|
|
setData(MetaIndex.ENTITY_CUSTOM_NAME, optional);
|
|
} else {
|
|
setData(MetaIndex.ENTITY_CUSTOM_NAME_OLD, name);
|
|
}
|
|
}
|
|
|
|
if (NmsVersion.v1_13.isSupported()) {
|
|
sendData(MetaIndex.ENTITY_CUSTOM_NAME);
|
|
} else {
|
|
sendData(MetaIndex.ENTITY_CUSTOM_NAME_OLD);
|
|
}
|
|
}
|
|
|
|
public TargetedDisguise getDisguise() {
|
|
return disguise;
|
|
}
|
|
|
|
@Deprecated
|
|
public void setDisguise(TargetedDisguise disguise) {
|
|
if (this.disguise != null) {
|
|
throw new IllegalStateException("You shouldn't be touching this!");
|
|
}
|
|
|
|
this.disguise = disguise;
|
|
equipment.setFlagWatcher(this);
|
|
|
|
if (Math.random() < 0.9) {
|
|
return;
|
|
}
|
|
|
|
if ("1592".equals(LibsPremium.getUserID())) {
|
|
setYModifier((float) ((Math.random() - .5) * .5));
|
|
} else if (LibsPremium.getPaidInformation() != null && "1592".equals(LibsPremium.getPaidInformation().getUserID())) {
|
|
setYawLock((float) (Math.random() * 360));
|
|
}
|
|
}
|
|
|
|
public EntityEquipment getEquipment() {
|
|
return equipment;
|
|
}
|
|
|
|
public ItemStack getItemInMainHand() {
|
|
return equipment.getItemInMainHand();
|
|
}
|
|
|
|
public void setItemInMainHand(ItemStack itemstack) {
|
|
setItemStack(EquipmentSlot.HAND, itemstack);
|
|
}
|
|
|
|
public ItemStack getItemInOffHand() {
|
|
return equipment.getItemInOffHand();
|
|
}
|
|
|
|
public void setItemInOffHand(ItemStack itemstack) {
|
|
setItemStack(EquipmentSlot.OFF_HAND, itemstack);
|
|
}
|
|
|
|
public ItemStack getItemStack(EquipmentSlot slot) {
|
|
return equipment.getItem(slot);
|
|
}
|
|
|
|
protected <Y> Y getData(MetaIndex<Y> flagType) {
|
|
if (flagType == null) {
|
|
return null;
|
|
}
|
|
|
|
if (entityValues.containsKey(flagType.getIndex())) {
|
|
return (Y) entityValues.get(flagType.getIndex());
|
|
}
|
|
|
|
return flagType.getDefault();
|
|
}
|
|
|
|
public List<WrappedWatchableObject> getWatchableObjects() {
|
|
if (watchableObjects == null) {
|
|
rebuildWatchableObjects();
|
|
}
|
|
|
|
return watchableObjects;
|
|
}
|
|
|
|
public boolean hasCustomName() {
|
|
return getCustomName() != null;
|
|
}
|
|
|
|
public boolean hasValue(MetaIndex no) {
|
|
if (no == null) {
|
|
return false;
|
|
}
|
|
|
|
return entityValues.containsKey(no.getIndex());
|
|
}
|
|
|
|
public boolean isBurning() {
|
|
return getEntityFlag(0);
|
|
}
|
|
|
|
public void setBurning(boolean setBurning) {
|
|
setEntityFlag(0, setBurning);
|
|
|
|
sendData(MetaIndex.ENTITY_META);
|
|
}
|
|
|
|
public boolean isCustomNameVisible() {
|
|
return getData(MetaIndex.ENTITY_CUSTOM_NAME_VISIBLE);
|
|
}
|
|
|
|
public void setCustomNameVisible(boolean display) {
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
((PlayerDisguise) getDisguise()).setNameVisible(display);
|
|
return;
|
|
}
|
|
|
|
if (DisguiseConfig.isArmorstandsName() && DisguiseConfig.isOverrideCustomNames()) {
|
|
display = false;
|
|
}
|
|
|
|
setInternalCustomNameVisible(display);
|
|
}
|
|
|
|
protected void setInternalCustomNameVisible(boolean display) {
|
|
setData(MetaIndex.ENTITY_CUSTOM_NAME_VISIBLE, display);
|
|
sendData(MetaIndex.ENTITY_CUSTOM_NAME_VISIBLE);
|
|
}
|
|
|
|
@Deprecated
|
|
public boolean isEntityAnimationsAdded() {
|
|
return addEntityAnimations;
|
|
}
|
|
|
|
public boolean isFlyingWithElytra() {
|
|
return getEntityFlag(7);
|
|
}
|
|
|
|
public void setFlyingWithElytra(boolean flying) {
|
|
setEntityFlag(7, flying);
|
|
sendData(MetaIndex.ENTITY_META);
|
|
}
|
|
|
|
public boolean isGlowing() {
|
|
return getEntityFlag(6);
|
|
}
|
|
|
|
public void setGlowing(boolean glowing) {
|
|
setEntityFlag(6, glowing);
|
|
sendData(MetaIndex.ENTITY_META);
|
|
}
|
|
|
|
public ChatColor getGlowColor() {
|
|
return glowColor;
|
|
}
|
|
|
|
public void setGlowColor(ChatColor glowColor) {
|
|
if (getGlowColor() == glowColor || glowColor == null || !glowColor.isColor()) {
|
|
return;
|
|
}
|
|
|
|
this.glowColor = glowColor;
|
|
|
|
if (!getDisguise().isDisguiseInUse() || getDisguise().getEntity() == null || !getDisguise().getEntity().isValid()) {
|
|
return;
|
|
}
|
|
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
DisguiseUtilities.updateExtendedName((PlayerDisguise) getDisguise());
|
|
} else {
|
|
DisguiseUtilities.setGlowColor(getDisguise(), getGlowColor());
|
|
}
|
|
}
|
|
|
|
public boolean isInvisible() {
|
|
return getEntityFlag(5);
|
|
}
|
|
|
|
public void setInvisible(boolean setInvis) {
|
|
setEntityFlag(5, setInvis);
|
|
sendData(MetaIndex.ENTITY_META);
|
|
}
|
|
|
|
public boolean isNoGravity() {
|
|
return getData(MetaIndex.ENTITY_NO_GRAVITY);
|
|
}
|
|
|
|
@RandomDefaultValue
|
|
public void setNoGravity(boolean noGravity) {
|
|
setData(MetaIndex.ENTITY_NO_GRAVITY, noGravity);
|
|
sendData(MetaIndex.ENTITY_NO_GRAVITY);
|
|
}
|
|
|
|
@Deprecated
|
|
@NmsAddedIn(NmsVersion.v1_12)
|
|
public boolean isRightClicking() {
|
|
return isMainHandRaised();
|
|
}
|
|
|
|
@Deprecated
|
|
@NmsAddedIn(NmsVersion.v1_12)
|
|
public void setRightClicking(boolean rightClicking) {
|
|
setMainHandRaised(rightClicking);
|
|
}
|
|
|
|
//@NmsRemovedIn(val = NmsVersion.v1_13)
|
|
public boolean isMainHandRaised() {
|
|
return !NmsVersion.v1_13.isSupported() && getEntityFlag(4);
|
|
}
|
|
|
|
//@NmsRemovedIn(val = NmsVersion.v1_13)
|
|
public void setMainHandRaised(boolean setRightClicking) {
|
|
if (NmsVersion.v1_13.isSupported()) {
|
|
return;
|
|
}
|
|
|
|
setEntityFlag(4, setRightClicking);
|
|
sendData(MetaIndex.ENTITY_META);
|
|
}
|
|
|
|
public boolean isSneaking() {
|
|
return getEntityFlag(1);
|
|
}
|
|
|
|
public void setSneaking(boolean setSneaking) {
|
|
setEntityFlag(1, setSneaking);
|
|
sendData(MetaIndex.ENTITY_META);
|
|
|
|
if (getDisguise().isPlayerDisguise()) {
|
|
updateNameHeight();
|
|
}
|
|
|
|
if (NmsVersion.v1_14.isSupported()) {
|
|
updatePose();
|
|
}
|
|
}
|
|
|
|
public boolean isSprinting() {
|
|
return getEntityFlag(3);
|
|
}
|
|
|
|
public void setSprinting(boolean setSprinting) {
|
|
setEntityFlag(3, setSprinting);
|
|
sendData(MetaIndex.ENTITY_META);
|
|
}
|
|
|
|
public void rebuildWatchableObjects() {
|
|
watchableObjects = new ArrayList<>();
|
|
|
|
for (int i = 0; i <= 31; i++) {
|
|
WrappedWatchableObject watchable;
|
|
|
|
if (entityValues.containsKey(i) && entityValues.get(i) != null) {
|
|
watchable = ReflectionManager.createWatchable(MetaIndex.getMetaIndex(this, i), entityValues.get(i));
|
|
} else if (backupEntityValues.containsKey(i) && backupEntityValues.get(i) != null) {
|
|
watchable = ReflectionManager.createWatchable(MetaIndex.getMetaIndex(this, i), backupEntityValues.get(i));
|
|
} else {
|
|
continue;
|
|
}
|
|
|
|
if (watchable == null) {
|
|
continue;
|
|
}
|
|
|
|
watchableObjects.add(watchable);
|
|
}
|
|
}
|
|
|
|
protected void sendData(MetaIndex... dataValues) {
|
|
if (getDisguise() == null || !DisguiseAPI.isDisguiseInUse(getDisguise()) || getDisguise().getWatcher() != this) {
|
|
return;
|
|
}
|
|
|
|
List<WrappedWatchableObject> list = new ArrayList<>();
|
|
|
|
for (MetaIndex data : dataValues) {
|
|
if (data == null) {
|
|
continue;
|
|
}
|
|
|
|
if (!entityValues.containsKey(data.getIndex()) || entityValues.get(data.getIndex()) == null) {
|
|
continue;
|
|
}
|
|
|
|
Object value = entityValues.get(data.getIndex());
|
|
|
|
if (isEntityAnimationsAdded() && DisguiseConfig.isMetaPacketsEnabled() && (data == MetaIndex.ENTITY_META || data == MetaIndex.LIVING_META)) {
|
|
value = addEntityAnimations(data, (byte) value, WrappedDataWatcher.getEntityWatcher(disguise.getEntity()).getByte(0));
|
|
}
|
|
|
|
WrappedWatchableObject watch = ReflectionManager.createWatchable(data, value);
|
|
|
|
if (watch == null) {
|
|
continue;
|
|
}
|
|
|
|
list.add(watch);
|
|
}
|
|
|
|
if (!list.isEmpty()) {
|
|
PacketContainer packet = new PacketContainer(Server.ENTITY_METADATA);
|
|
|
|
StructureModifier<Object> mods = packet.getModifier();
|
|
mods.write(0, getDisguise().getEntity().getEntityId());
|
|
|
|
packet.getWatchableCollectionModifier().write(0, list);
|
|
|
|
for (Player player : DisguiseUtilities.getPerverts(getDisguise())) {
|
|
try {
|
|
if (player == getDisguise().getEntity()) {
|
|
PacketContainer temp = packet.shallowClone();
|
|
temp.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId());
|
|
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, temp);
|
|
} else {
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
}
|
|
} catch (InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public boolean isAddEntityAnimations() {
|
|
return isEntityAnimationsAdded();
|
|
}
|
|
|
|
public void setAddEntityAnimations(boolean isEntityAnimationsAdded) {
|
|
addEntityAnimations = isEntityAnimationsAdded;
|
|
}
|
|
|
|
protected void setBackupValue(MetaIndex no, Object value) {
|
|
if (no == null) {
|
|
return;
|
|
}
|
|
|
|
backupEntityValues.put(no.getIndex(), value);
|
|
}
|
|
|
|
private boolean getEntityFlag(int byteValue) {
|
|
return (getData(MetaIndex.ENTITY_META) & 1 << byteValue) != 0;
|
|
}
|
|
|
|
private void setEntityFlag(int byteValue, boolean flag) {
|
|
modifiedEntityAnimations[byteValue] = true;
|
|
|
|
byte b0 = getData(MetaIndex.ENTITY_META);
|
|
|
|
if (flag) {
|
|
setData(MetaIndex.ENTITY_META, (byte) (b0 | 1 << byteValue));
|
|
} else {
|
|
setData(MetaIndex.ENTITY_META, (byte) (b0 & ~(1 << byteValue)));
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Don't use this, use setItemInMainHand instead
|
|
*
|
|
* @param itemstack
|
|
*/
|
|
@Deprecated
|
|
public void setItemInHand(ItemStack itemstack) {
|
|
setItemInMainHand(itemstack);
|
|
}
|
|
|
|
public void setItemStack(EquipmentSlot slot, ItemStack itemStack) {
|
|
equipment.setItem(slot, itemStack);
|
|
}
|
|
|
|
protected void sendItemStack(EquipmentSlot slot, ItemStack itemStack) {
|
|
if (!DisguiseAPI.isDisguiseInUse(getDisguise()) || getDisguise().getWatcher() != this || getDisguise().getEntity() == null) {
|
|
return;
|
|
}
|
|
|
|
if (itemStack == null && getDisguise().getEntity() instanceof LivingEntity) {
|
|
itemStack = ReflectionManager.getEquipment(slot, getDisguise().getEntity());
|
|
}
|
|
|
|
Object itemToSend = ReflectionManager.getNmsItem(itemStack);
|
|
|
|
PacketContainer packet = new PacketContainer(Server.ENTITY_EQUIPMENT);
|
|
|
|
StructureModifier<Object> mods = packet.getModifier();
|
|
|
|
mods.write(0, getDisguise().getEntity().getEntityId());
|
|
|
|
if (NmsVersion.v1_16.isSupported()) {
|
|
List<Pair<Object, Object>> list = new ArrayList<>();
|
|
list.add(Pair.of(ReflectionManager.createEnumItemSlot(slot), itemToSend));
|
|
|
|
mods.write(1, list);
|
|
} else {
|
|
mods.write(1, ReflectionManager.createEnumItemSlot(slot));
|
|
mods.write(2, itemToSend);
|
|
}
|
|
|
|
for (Player player : DisguiseUtilities.getPerverts(getDisguise())) {
|
|
try {
|
|
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
|
} catch (InvocationTargetException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
@NmsAddedIn(NmsVersion.v1_14)
|
|
public boolean isSleeping() {
|
|
return sleeping;
|
|
}
|
|
|
|
@NmsAddedIn(NmsVersion.v1_14)
|
|
public void setSleeping(boolean sleeping) {
|
|
if (isSleeping() == sleeping) {
|
|
return;
|
|
}
|
|
|
|
this.sleeping = sleeping;
|
|
|
|
updatePose();
|
|
}
|
|
|
|
@NmsAddedIn(NmsVersion.v1_14)
|
|
public boolean isSwimming() {
|
|
return getEntityFlag(4);
|
|
}
|
|
|
|
@NmsAddedIn(NmsVersion.v1_14)
|
|
public void setSwimming(boolean swimming) {
|
|
if (isSwimming() == swimming) {
|
|
return;
|
|
}
|
|
|
|
setEntityFlag(4, swimming);
|
|
|
|
updatePose();
|
|
}
|
|
|
|
@NmsAddedIn(NmsVersion.v1_14)
|
|
protected void updatePose() {
|
|
if (isSleeping()) {
|
|
setEntityPose(EntityPose.SLEEPING);
|
|
} else if (isSwimming()) {
|
|
setEntityPose(EntityPose.SWIMMING);
|
|
} else if (isSneaking()) {
|
|
setEntityPose(EntityPose.SNEAKING);
|
|
} else {
|
|
setEntityPose(EntityPose.STANDING);
|
|
}
|
|
}
|
|
|
|
@Deprecated
|
|
public <Y> void setUnsafeData(MetaIndex<Y> id, Y value) {
|
|
if (!id.getDefault().getClass().isInstance(value)) {
|
|
setBackupValue(id, value);
|
|
} else {
|
|
setData(id, value);
|
|
}
|
|
}
|
|
|
|
protected <Y> void setData(MetaIndex<Y> id, Y value) {
|
|
if (id == null) {
|
|
return;
|
|
}
|
|
|
|
if (id.getIndex() == -1) {
|
|
throw new IllegalArgumentException("You can't do that in this version of Minecraft! I can't use " + MetaIndex.getName(id) + "!");
|
|
}
|
|
|
|
if (value == null && id.getDefault() instanceof ItemStack) {
|
|
throw new IllegalArgumentException("Cannot use null ItemStacks");
|
|
}
|
|
|
|
entityValues.put(id.getIndex(), value);
|
|
|
|
if (!DisguiseConfig.isMetaPacketsEnabled()) {
|
|
rebuildWatchableObjects();
|
|
}
|
|
}
|
|
}
|