Add new armorstand option for player disguise names, clean up config cos of the player name options
Added ability to set multiple names on a player disguise, also normal mob but that is untested and has no command accessibility Permission to do this is libsdisguises.multiname Renamed "Now disguised as a %s" to "Now disguised as %s" for messages
This commit is contained in:
parent
6170d8e77f
commit
888bbd9521
@ -95,9 +95,6 @@ public class DisguiseConfig {
|
||||
private static boolean explicitDisguisePermissions;
|
||||
@Getter
|
||||
@Setter
|
||||
private static boolean extendedDisguiseNames;
|
||||
@Getter
|
||||
@Setter
|
||||
private static boolean hideDisguisedPlayers;
|
||||
@Getter
|
||||
@Setter
|
||||
@ -228,9 +225,6 @@ public class DisguiseConfig {
|
||||
private static PermissionDefault commandVisibility = PermissionDefault.TRUE;
|
||||
@Getter
|
||||
@Setter
|
||||
private static boolean scoreboardDisguiseNames;
|
||||
@Getter
|
||||
@Setter
|
||||
private static int tablistRemoveDelay;
|
||||
@Getter
|
||||
private static boolean usingReleaseBuild = true;
|
||||
@ -246,6 +240,17 @@ public class DisguiseConfig {
|
||||
@Getter
|
||||
@Setter
|
||||
private static boolean hideTallSelfDisguises;
|
||||
@Getter
|
||||
@Setter
|
||||
private static PlayerNameType playerNameType = PlayerNameType.ARMORSTANDS;
|
||||
|
||||
public static boolean isArmorstandsName() {
|
||||
return getPlayerNameType() == PlayerNameType.ARMORSTANDS;
|
||||
}
|
||||
|
||||
public static boolean isExtendedNames() {
|
||||
return getPlayerNameType() == PlayerNameType.TEAMS_EXTENDED;
|
||||
}
|
||||
|
||||
public static void setAutoUpdate(boolean update) {
|
||||
if (isAutoUpdate() == update) {
|
||||
@ -447,6 +452,10 @@ public class DisguiseConfig {
|
||||
return new HashMap.SimpleEntry(entry.getKey(), DisguiseParser.parseDisguise(invoker, target, entry.getValue()));
|
||||
}
|
||||
|
||||
public static boolean isScoreboardNames() {
|
||||
return getPlayerNameType() != PlayerNameType.VANILLA;
|
||||
}
|
||||
|
||||
public static void removeCustomDisguise(String disguise) {
|
||||
for (DisguisePerm entry : customDisguises.keySet()) {
|
||||
String name = entry.toReadable();
|
||||
@ -596,8 +605,6 @@ public class DisguiseConfig {
|
||||
setEntityStatusPacketsEnabled(config.getBoolean("PacketsEnabled.EntityStatus"));
|
||||
setEquipmentPacketsEnabled(config.getBoolean("PacketsEnabled.Equipment"));
|
||||
setExplicitDisguisePermissions(config.getBoolean("Permissions.ExplicitDisguises"));
|
||||
// The default value shall be false if you don't update config
|
||||
setExtendedDisguiseNames(config.contains("ScoreboardNames") && config.getBoolean("ExtendedNames"));
|
||||
setHideArmorFromSelf(config.getBoolean("RemoveArmor"));
|
||||
setHideDisguisedPlayers(config.getBoolean("HideDisguisedPlayersFromTab"));
|
||||
setHideHeldItemFromSelf(config.getBoolean("RemoveHeldItem"));
|
||||
@ -634,7 +641,6 @@ public class DisguiseConfig {
|
||||
setWarnScoreboardConflict(config.getBoolean("Scoreboard.WarnConflict"));
|
||||
setWitherSkullPacketsEnabled(config.getBoolean("PacketsEnabled.WitherSkull"));
|
||||
setWolfDyeable(config.getBoolean("DyeableWolf"));
|
||||
setScoreboardDisguiseNames(config.getBoolean("ScoreboardNames"));
|
||||
setTablistRemoveDelay(config.getInt("TablistRemoveDelay"));
|
||||
setAutoUpdate(config.getBoolean("AutoUpdate"));
|
||||
setHideTallSelfDisguises(config.getBoolean("HideTallSelfDisguises"));
|
||||
@ -643,6 +649,14 @@ public class DisguiseConfig {
|
||||
DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!");
|
||||
}
|
||||
|
||||
try {
|
||||
setPlayerNameType(PlayerNameType.valueOf(config.getString("PlayerNames").toUpperCase()));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
DisguiseUtilities.getLogger()
|
||||
.warning("Cannot parse '" + config.getString("PlayerNames") + "' to a valid option for PlayerNames");
|
||||
}
|
||||
|
||||
try {
|
||||
setNotifyBar(NotifyBar.valueOf(config.getString("NotifyBar").toUpperCase()));
|
||||
|
||||
@ -1077,6 +1091,17 @@ public class DisguiseConfig {
|
||||
CREATE_SCOREBOARD
|
||||
}
|
||||
|
||||
public enum PlayerNameType {
|
||||
VANILLA,
|
||||
TEAMS,
|
||||
TEAMS_EXTENDED,
|
||||
ARMORSTANDS;
|
||||
|
||||
public boolean isTeams() {
|
||||
return this == TEAMS || this == TEAMS_EXTENDED;
|
||||
}
|
||||
}
|
||||
|
||||
public enum UpdatesBranch {
|
||||
SAME_BUILDS,
|
||||
SNAPSHOTS,
|
||||
|
@ -36,7 +36,7 @@ public class LDScoreboard implements LDCommand {
|
||||
|
||||
@Override
|
||||
public void onCommand(CommandSender sender, String[] args) {
|
||||
if (DisguiseConfig.isScoreboardDisguiseNames()) {
|
||||
if (DisguiseConfig.isScoreboardNames()) {
|
||||
int issuesFound = 0;
|
||||
int unexpected = 0;
|
||||
|
||||
|
@ -96,16 +96,59 @@ public abstract class Disguise {
|
||||
*/
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean customName = true;
|
||||
private boolean customDisguiseName = true;
|
||||
@Getter
|
||||
@Setter
|
||||
private boolean tallDisguisesVisible = !DisguiseConfig.isHideTallSelfDisguises();
|
||||
@Getter
|
||||
private String[] multiName = new String[0];
|
||||
private transient int[] armorstandIds = new int[0];
|
||||
|
||||
public Disguise(DisguiseType disguiseType) {
|
||||
this.disguiseType = disguiseType;
|
||||
this.disguiseName = disguiseType.toReadable();
|
||||
}
|
||||
|
||||
public void setMultiName(String... name) {
|
||||
String[] oldName = getMultiName();
|
||||
multiName = name;
|
||||
|
||||
if (!isDisguiseInUse()) {
|
||||
return;
|
||||
}
|
||||
|
||||
sendArmorStands(oldName);
|
||||
}
|
||||
|
||||
protected void sendArmorStands(String[] oldName) {
|
||||
ArrayList<PacketContainer> packets = DisguiseUtilities.getNamePackets(this, oldName);
|
||||
|
||||
try {
|
||||
for (Player player : DisguiseUtilities.getPerverts(this)) {
|
||||
for (PacketContainer packet : packets) {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getArmorstandIds() {
|
||||
if (getMultiName().length > armorstandIds.length) {
|
||||
int oldLen = armorstandIds.length;
|
||||
|
||||
armorstandIds = Arrays.copyOf(armorstandIds, getMultiName().length);
|
||||
|
||||
for (int i = oldLen; i < armorstandIds.length; i++) {
|
||||
armorstandIds[i] = ReflectionManager.getNewEntityId();
|
||||
}
|
||||
}
|
||||
|
||||
return armorstandIds;
|
||||
}
|
||||
|
||||
public void addCustomData(String key, Object data) {
|
||||
customData.put(key, data);
|
||||
}
|
||||
@ -123,7 +166,7 @@ public abstract class Disguise {
|
||||
|
||||
protected void clone(Disguise disguise) {
|
||||
disguise.setDisguiseName(getDisguiseName());
|
||||
disguise.setCustomName(isCustomName());
|
||||
disguise.setCustomDisguiseName(isCustomDisguiseName());
|
||||
disguise.setTallDisguisesVisible(isTallDisguisesVisible());
|
||||
|
||||
disguise.setReplaceSounds(isSoundsReplaced());
|
||||
@ -133,6 +176,7 @@ public abstract class Disguise {
|
||||
disguise.setHideHeldItemFromSelf(isHidingHeldItemFromSelf());
|
||||
disguise.setVelocitySent(isVelocitySent());
|
||||
disguise.setModifyBoundingBox(isModifyBoundingBox());
|
||||
disguise.multiName = Arrays.copyOf(multiName, multiName.length);
|
||||
|
||||
if (getWatcher() != null) {
|
||||
disguise.setWatcher(getWatcher().clone(disguise));
|
||||
@ -795,20 +839,13 @@ public abstract class Disguise {
|
||||
task = null;
|
||||
}
|
||||
|
||||
// If this disguise has a entity set
|
||||
// If this disguise hasn't a entity set
|
||||
if (getEntity() == null) {
|
||||
// Loop through the disguises because it could be used with a unknown entity id.
|
||||
HashMap<Integer, HashSet<TargetedDisguise>> future = DisguiseUtilities.getFutureDisguises();
|
||||
|
||||
Iterator<Integer> itel = DisguiseUtilities.getFutureDisguises().keySet().iterator();
|
||||
|
||||
while (itel.hasNext()) {
|
||||
int id = itel.next();
|
||||
|
||||
if (future.get(id).remove(this) && future.get(id).isEmpty()) {
|
||||
itel.remove();
|
||||
}
|
||||
}
|
||||
DisguiseUtilities.getFutureDisguises().keySet()
|
||||
.removeIf(id -> future.get(id).remove(this) && future.get(id).isEmpty());
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -842,7 +879,7 @@ public abstract class Disguise {
|
||||
// Remove the disguise from the current disguises.
|
||||
if (DisguiseUtilities.removeDisguise((TargetedDisguise) this)) {
|
||||
if (getEntity() instanceof Player) {
|
||||
DisguiseUtilities.removeSelfDisguise((Player) getEntity());
|
||||
DisguiseUtilities.removeSelfDisguise(this);
|
||||
}
|
||||
|
||||
// Better refresh the entity to undisguise it
|
||||
@ -893,6 +930,20 @@ public abstract class Disguise {
|
||||
}
|
||||
}
|
||||
|
||||
if (getMultiName().length > 0) {
|
||||
PacketContainer packet = new PacketContainer(Server.ENTITY_DESTROY);
|
||||
packet.getIntegerArrays().write(0, Arrays.copyOf(getArmorstandIds(), getMultiName().length));
|
||||
|
||||
try {
|
||||
for (Player player : DisguiseUtilities.getPerverts(this)) {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
||||
}
|
||||
}
|
||||
catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -970,7 +1021,7 @@ public abstract class Disguise {
|
||||
if (isSelfDisguiseVisible()) {
|
||||
DisguiseUtilities.setupFakeDisguise(this);
|
||||
} else {
|
||||
DisguiseUtilities.removeSelfDisguise((Player) getEntity());
|
||||
DisguiseUtilities.removeSelfDisguise(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1053,7 +1104,7 @@ public abstract class Disguise {
|
||||
DisguiseUtilities.addDisguise(entity.getUniqueId(), (TargetedDisguise) this);
|
||||
|
||||
if (isSelfDisguiseVisible() && getEntity() instanceof Player) {
|
||||
DisguiseUtilities.removeSelfDisguise((Player) getEntity());
|
||||
DisguiseUtilities.removeSelfDisguise(this);
|
||||
}
|
||||
|
||||
// Resend the disguised entity's packet
|
||||
|
@ -12,7 +12,6 @@ import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
|
||||
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
||||
import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup;
|
||||
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Entity;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -27,6 +26,10 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
private String playerName = "Herobrine";
|
||||
private String skinToUse;
|
||||
private boolean nameVisible = true;
|
||||
/**
|
||||
* Has someone set name visible explicitly?
|
||||
*/
|
||||
private boolean explicitNameVisible = false;
|
||||
private UUID uuid = UUID.randomUUID();
|
||||
@Getter
|
||||
@Setter
|
||||
@ -82,8 +85,7 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
|
||||
@Deprecated
|
||||
public DisguiseUtilities.DScoreTeam getScoreboardName() {
|
||||
if (getName().length() <= 32 ? !DisguiseConfig.isScoreboardDisguiseNames() :
|
||||
!DisguiseConfig.isExtendedDisguiseNames()) {
|
||||
if (!DisguiseConfig.isScoreboardNames()) {
|
||||
throw new IllegalStateException("Cannot use this method when it's been disabled in config!");
|
||||
}
|
||||
|
||||
@ -103,11 +105,11 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
}
|
||||
|
||||
public boolean hasScoreboardName() {
|
||||
if (isStaticName(getName())) {
|
||||
if (!DisguiseConfig.isArmorstandsName() && isStaticName(getName())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return scoreboardName != null || DisguiseConfig.isScoreboardDisguiseNames() || getName().length() > 16;
|
||||
return DisguiseConfig.isScoreboardNames();
|
||||
}
|
||||
|
||||
public String getProfileName() {
|
||||
@ -123,12 +125,23 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
}
|
||||
|
||||
public PlayerDisguise setNameVisible(boolean nameVisible) {
|
||||
if (isNameVisible() == nameVisible) {
|
||||
return setNameVisible(nameVisible, false);
|
||||
}
|
||||
|
||||
private PlayerDisguise setNameVisible(boolean nameVisible, boolean setInternally) {
|
||||
if (isNameVisible() == nameVisible || (setInternally && explicitNameVisible)) {
|
||||
return this;
|
||||
}
|
||||
|
||||
if (!setInternally) {
|
||||
explicitNameVisible = true;
|
||||
}
|
||||
|
||||
if (isDisguiseInUse()) {
|
||||
if (!DisguiseConfig.isScoreboardDisguiseNames()) {
|
||||
if (DisguiseConfig.isArmorstandsName()) {
|
||||
this.nameVisible = nameVisible;
|
||||
sendArmorStands(isNameVisible() ? getMultiName() : new String[0]);
|
||||
} else if (!DisguiseConfig.isScoreboardNames()) {
|
||||
if (stopDisguise()) {
|
||||
this.nameVisible = nameVisible;
|
||||
|
||||
@ -172,7 +185,8 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
}
|
||||
|
||||
disguise.setName(getName());
|
||||
disguise.setNameVisible(isNameVisible());
|
||||
disguise.nameVisible = isNameVisible();
|
||||
disguise.explicitNameVisible = explicitNameVisible;
|
||||
disguise.setDynamicName(isDynamicName());
|
||||
|
||||
clone(disguise);
|
||||
@ -214,16 +228,37 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
return;
|
||||
}
|
||||
|
||||
int cLimit = DisguiseConfig.isExtendedDisguiseNames() ? 16 * 3 :
|
||||
DisguiseConfig.isScoreboardDisguiseNames() ? 16 * 2 : 16;
|
||||
int cLimit;
|
||||
|
||||
switch (DisguiseConfig.getPlayerNameType()) {
|
||||
case TEAMS:
|
||||
cLimit = 16 * 2;
|
||||
break;
|
||||
case TEAMS_EXTENDED:
|
||||
cLimit = 16 * 3;
|
||||
break;
|
||||
case ARMORSTANDS:
|
||||
cLimit = 256;
|
||||
break;
|
||||
default:
|
||||
cLimit = 16;
|
||||
break;
|
||||
}
|
||||
|
||||
if (name.length() > cLimit) {
|
||||
name = name.substring(0, cLimit);
|
||||
}
|
||||
|
||||
if (isDisguiseInUse()) {
|
||||
if (DisguiseConfig.isArmorstandsName()) {
|
||||
playerName = name;
|
||||
|
||||
setNameVisible(!name.isEmpty(), true);
|
||||
setMultiName(DisguiseUtilities.splitNewLine(name));
|
||||
} else {
|
||||
boolean resendDisguise = false;
|
||||
|
||||
if (DisguiseConfig.isScoreboardDisguiseNames() && !isStaticName(name)) {
|
||||
if (DisguiseConfig.isScoreboardNames() && !isStaticName(name)) {
|
||||
DisguiseUtilities.DScoreTeam team = getScoreboardName();
|
||||
String[] split = DisguiseUtilities.getExtendedNameSplit(team.getPlayer(), name);
|
||||
|
||||
@ -231,16 +266,15 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
setScoreboardName(split);
|
||||
}
|
||||
|
||||
resendDisguise =
|
||||
!DisguiseConfig.isScoreboardDisguiseNames() || isStaticName(name) || isStaticName(getName()) ||
|
||||
resendDisguise = !DisguiseConfig.isScoreboardNames() || isStaticName(name) || isStaticName(getName()) ||
|
||||
resendDisguise;
|
||||
|
||||
if (resendDisguise) {
|
||||
if (stopDisguise()) {
|
||||
if (getName().isEmpty() && !name.isEmpty()) {
|
||||
setNameVisible(true);
|
||||
setNameVisible(true, true);
|
||||
} else if (!getName().isEmpty() && name.isEmpty()) {
|
||||
setNameVisible(false);
|
||||
setNameVisible(false, true);
|
||||
}
|
||||
|
||||
playerName = name;
|
||||
@ -258,15 +292,16 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
}
|
||||
} else {
|
||||
if (getName().isEmpty() && !name.isEmpty() && !isNameVisible()) {
|
||||
setNameVisible(true);
|
||||
setNameVisible(true, true);
|
||||
} else if (!getName().isEmpty() && name.isEmpty() && isNameVisible()) {
|
||||
setNameVisible(false);
|
||||
setNameVisible(false, true);
|
||||
} else {
|
||||
DisguiseUtilities.updateExtendedName(this);
|
||||
}
|
||||
|
||||
playerName = name;
|
||||
}
|
||||
}
|
||||
|
||||
if (isDisplayedInTab()) {
|
||||
PacketContainer addTab = DisguiseUtilities.getTabPacket(this, PlayerInfoAction.UPDATE_DISPLAY_NAME);
|
||||
@ -291,12 +326,11 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
setScoreboardName(split);
|
||||
}
|
||||
|
||||
if (name.isEmpty()) {
|
||||
setNameVisible(false);
|
||||
} else {
|
||||
setNameVisible(true);
|
||||
if (DisguiseConfig.isScoreboardNames()) {
|
||||
setMultiName(DisguiseUtilities.splitNewLine(name));
|
||||
}
|
||||
|
||||
setNameVisible(!name.isEmpty(), true);
|
||||
playerName = name;
|
||||
|
||||
if (gameProfile != null) {
|
||||
@ -310,19 +344,23 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
}
|
||||
|
||||
public PlayerDisguise setSkin(String newSkin) {
|
||||
if (newSkin != null && newSkin.length() > 70) {
|
||||
if (newSkin != null && newSkin.length() > 70 && newSkin.startsWith("{") && newSkin.endsWith("}")) {
|
||||
try {
|
||||
return setSkin(DisguiseUtilities.getGson().fromJson(newSkin, WrappedGameProfile.class));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
if (!"12345".equals("%%__USER__%%")) {
|
||||
throw new IllegalArgumentException(String.format(
|
||||
"The skin %s is too long to be a playername, but cannot be parsed to a GameProfile!",
|
||||
newSkin));
|
||||
"The skin %s is too long to normally be a playername, but cannot be parsed to a " +
|
||||
"GameProfile!", newSkin));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (newSkin != null && newSkin.length() > 16) {
|
||||
newSkin = null;
|
||||
}
|
||||
|
||||
String oldSkin = skinToUse;
|
||||
skinToUse = newSkin;
|
||||
|
||||
@ -376,8 +414,6 @@ public class PlayerDisguise extends TargetedDisguise {
|
||||
return this;
|
||||
}
|
||||
|
||||
Validate.notEmpty(gameProfile.getName(), "Name must be set");
|
||||
|
||||
currentLookup = null;
|
||||
|
||||
this.skinToUse = gameProfile.getName();
|
||||
|
@ -22,7 +22,7 @@ public class DroppedItemWatcher extends FlagWatcher {
|
||||
setData(MetaIndex.DROPPED_ITEM, item);
|
||||
sendData(MetaIndex.DROPPED_ITEM);
|
||||
|
||||
if (!getDisguise().isCustomName()) {
|
||||
if (!getDisguise().isCustomDisguiseName()) {
|
||||
getDisguise().setDisguiseName(TranslateType.DISGUISES.get(DisguiseType.DROPPED_ITEM.toReadable()) + " " +
|
||||
TranslateType.DISGUISE_OPTIONS_PARAMETERS
|
||||
.get(ReflectionManager.toReadable((item == null ? Material.AIR : item.getType()).name())));
|
||||
|
@ -87,7 +87,7 @@ public class FallingBlockWatcher extends FlagWatcher {
|
||||
|
||||
this.block = block;
|
||||
|
||||
if (!getDisguise().isCustomName()) {
|
||||
if (!getDisguise().isCustomDisguiseName()) {
|
||||
getDisguise().setDisguiseName(TranslateType.DISGUISE_OPTIONS_PARAMETERS.get("Block") + " " +
|
||||
TranslateType.DISGUISE_OPTIONS_PARAMETERS
|
||||
.get(ReflectionManager.toReadable(block.getType().name())));
|
||||
|
@ -22,6 +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.ZombieWatcher;
|
||||
import me.libraryaddict.disguise.utilities.json.*;
|
||||
import me.libraryaddict.disguise.utilities.mineskin.MineSkinAPI;
|
||||
@ -84,6 +85,7 @@ public class DisguiseUtilities {
|
||||
}
|
||||
|
||||
public void handleTeam(Scoreboard board, boolean nameVisible) {
|
||||
nameVisible = !DisguiseConfig.isArmorstandsName() && nameVisible;
|
||||
Team team = board.getTeam(getTeamName());
|
||||
|
||||
if (team == null) {
|
||||
@ -1037,7 +1039,7 @@ public class DisguiseUtilities {
|
||||
|
||||
if (disguise.isDisguiseInUse() && disguise.getEntity() instanceof Player &&
|
||||
disguise.getEntity().getName().equalsIgnoreCase(player)) {
|
||||
removeSelfDisguise((Player) disguise.getEntity());
|
||||
removeSelfDisguise(disguise);
|
||||
|
||||
if (disguise.isSelfDisguiseVisible()) {
|
||||
selfDisguised.add(disguise.getEntity().getUniqueId());
|
||||
@ -1167,7 +1169,7 @@ public class DisguiseUtilities {
|
||||
|
||||
try {
|
||||
if (selfDisguised.contains(disguise.getEntity().getUniqueId()) && disguise.isDisguiseInUse()) {
|
||||
removeSelfDisguise((Player) disguise.getEntity());
|
||||
removeSelfDisguise(disguise);
|
||||
|
||||
selfDisguised.add(disguise.getEntity().getUniqueId());
|
||||
|
||||
@ -1257,16 +1259,21 @@ public class DisguiseUtilities {
|
||||
file.delete();
|
||||
}
|
||||
|
||||
public static void removeSelfDisguise(Player player) {
|
||||
public static void removeSelfDisguise(Disguise disguise) {
|
||||
if (!Bukkit.isPrimaryThread())
|
||||
throw new IllegalStateException("Cannot modify disguises on an async thread");
|
||||
|
||||
Player player = (Player) disguise.getEntity();
|
||||
|
||||
if (!selfDisguised.contains(player.getUniqueId())) {
|
||||
return;
|
||||
}
|
||||
|
||||
int[] ids = Arrays.copyOf(disguise.getArmorstandIds(), 1 + disguise.getMultiName().length);
|
||||
ids[ids.length - 1] = DisguiseAPI.getSelfDisguiseId();
|
||||
|
||||
// Send a packet to destroy the fake entity
|
||||
PacketContainer packet = getDestroyPacket(DisguiseAPI.getSelfDisguiseId());
|
||||
PacketContainer packet = getDestroyPacket(ids);
|
||||
|
||||
try {
|
||||
ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet);
|
||||
@ -1439,7 +1446,7 @@ public class DisguiseUtilities {
|
||||
}
|
||||
|
||||
public static String[] getExtendedNameSplit(String playerName, String name) {
|
||||
if (name.length() <= 16 && !DisguiseConfig.isScoreboardDisguiseNames()) {
|
||||
if (name.length() <= 16 && !DisguiseConfig.isScoreboardNames()) {
|
||||
throw new IllegalStateException("This can only be used for names longer than 16 characters!");
|
||||
}
|
||||
|
||||
@ -1450,7 +1457,7 @@ public class DisguiseUtilities {
|
||||
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
|
||||
|
||||
// If name is short enough to be used outside of player name
|
||||
if (DisguiseConfig.isScoreboardDisguiseNames() && name.length() <= 32) {
|
||||
if (DisguiseConfig.isScoreboardNames() && name.length() <= 32) {
|
||||
String[] newName = new String[]{name, playerName, ""};
|
||||
|
||||
if (name.length() > 16) {
|
||||
@ -1749,6 +1756,39 @@ public class DisguiseUtilities {
|
||||
"\"";
|
||||
}
|
||||
|
||||
public static String quoteNewLine(String string) {
|
||||
return string.replaceAll("\\\\(?=\\\\+n)", "\\\\\\\\");
|
||||
}
|
||||
|
||||
public static String[] splitNewLine(String string) {
|
||||
Pattern regex = Pattern.compile("\\\\+n");
|
||||
Matcher result = regex.matcher(string);
|
||||
|
||||
ArrayList<String> lines = new ArrayList<>();
|
||||
StringBuilder builder = new StringBuilder();
|
||||
int last = 0;
|
||||
|
||||
while (result.find()) {
|
||||
builder.append(string, last, result.start());
|
||||
last = result.end();
|
||||
|
||||
if (result.group().matches("(\\\\\\\\)+n")) {
|
||||
builder.append(result.group().replace("\\\\", "\\"));
|
||||
} else {
|
||||
String group = result.group().replace("\\\\", "\\");
|
||||
|
||||
builder.append(group, 0, group.length() - 2);
|
||||
|
||||
lines.add(builder.toString());
|
||||
builder = new StringBuilder();
|
||||
}
|
||||
}
|
||||
|
||||
lines.add(builder.toString() + string.substring(last));
|
||||
|
||||
return lines.toArray(new String[0]);
|
||||
}
|
||||
|
||||
public static String[] split(String string) {
|
||||
// Regex where we first match any character that isn't a slash, if it is a slash then it must not have more
|
||||
// slashes until it hits the quote
|
||||
@ -2020,7 +2060,7 @@ public class DisguiseUtilities {
|
||||
}
|
||||
|
||||
// Remove the old disguise, else we have weird disguises around the place
|
||||
DisguiseUtilities.removeSelfDisguise(player);
|
||||
DisguiseUtilities.removeSelfDisguise(disguise);
|
||||
|
||||
// If the disguised player can't see himself. Return
|
||||
if (!disguise.isSelfDisguiseVisible() || !PacketsManager.isViewDisguisesListenerEnabled() ||
|
||||
@ -2237,6 +2277,100 @@ public class DisguiseUtilities {
|
||||
}
|
||||
}
|
||||
|
||||
public static ArrayList<PacketContainer> getNamePackets(Disguise disguise, String[] oldNames) {
|
||||
ArrayList<PacketContainer> packets = new ArrayList<>();
|
||||
String[] newNames =
|
||||
(disguise instanceof PlayerDisguise && !((PlayerDisguise) disguise).isNameVisible()) ? new String[0] :
|
||||
disguise.getMultiName();
|
||||
int[] standIds = disguise.getArmorstandIds();
|
||||
int[] destroyIds = new int[0];
|
||||
|
||||
if (oldNames.length > newNames.length) {
|
||||
// Destroy packet
|
||||
destroyIds = Arrays.copyOfRange(standIds, newNames.length, oldNames.length);
|
||||
}
|
||||
|
||||
for (int i = 0; i < newNames.length; i++) {
|
||||
if (i < oldNames.length) {
|
||||
if (newNames[i].equals(oldNames[i]) || newNames[i].isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
WrappedDataWatcher watcher = new WrappedDataWatcher();
|
||||
|
||||
Object name = NmsVersion.v1_13.isSupported() ? Optional.of(WrappedChatComponent.fromText(newNames[i])) :
|
||||
newNames[i];
|
||||
|
||||
WrappedDataWatcher.WrappedDataWatcherObject obj = ReflectionManager.createDataWatcherObject(
|
||||
NmsVersion.v1_13.isSupported() ? MetaIndex.ENTITY_CUSTOM_NAME :
|
||||
MetaIndex.ENTITY_CUSTOM_NAME_OLD, name);
|
||||
|
||||
watcher.setObject(obj, ReflectionManager.convertInvalidMeta(name));
|
||||
|
||||
PacketContainer metaPacket = ProtocolLibrary.getProtocolManager()
|
||||
.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, 0, watcher, true)
|
||||
.createPacket(standIds[i], watcher, true);
|
||||
|
||||
packets.add(metaPacket);
|
||||
} else if (newNames[i].isEmpty()) {
|
||||
destroyIds = Arrays.copyOf(destroyIds, destroyIds.length + 1);
|
||||
destroyIds[destroyIds.length - 1] = standIds[i];
|
||||
} else {
|
||||
PacketContainer packet = new PacketContainer(Server.SPAWN_ENTITY_LIVING);
|
||||
packet.getIntegers().write(0, standIds[i]);
|
||||
packet.getIntegers().write(1, DisguiseType.ARMOR_STAND.getTypeId());
|
||||
|
||||
packet.getUUIDs().write(0, UUID.randomUUID());
|
||||
|
||||
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(2, loc.getZ());
|
||||
packets.add(packet);
|
||||
|
||||
WrappedDataWatcher watcher = new WrappedDataWatcher();
|
||||
|
||||
for (MetaIndex index : MetaIndex.getMetaIndexes(LivingWatcher.class)) {
|
||||
Object val = index.getDefault();
|
||||
|
||||
if (index == MetaIndex.ENTITY_META) {
|
||||
val = (byte) 32;
|
||||
} else if (index == MetaIndex.ARMORSTAND_META) {
|
||||
val = (byte) 17;
|
||||
} else if (index == MetaIndex.ENTITY_CUSTOM_NAME) {
|
||||
val = Optional.of(WrappedChatComponent.fromText(newNames[i]));
|
||||
} else if (index == MetaIndex.ENTITY_CUSTOM_NAME_OLD) {
|
||||
val = newNames[i];
|
||||
} else if (index == MetaIndex.ENTITY_CUSTOM_NAME_VISIBLE) {
|
||||
val = true;
|
||||
}
|
||||
|
||||
WrappedDataWatcher.WrappedDataWatcherObject obj = ReflectionManager
|
||||
.createDataWatcherObject(index, val);
|
||||
|
||||
watcher.setObject(obj, ReflectionManager.convertInvalidMeta(val));
|
||||
}
|
||||
|
||||
if (NmsVersion.v1_15.isSupported()) {
|
||||
PacketContainer metaPacket = ProtocolLibrary.getProtocolManager()
|
||||
.createPacketConstructor(PacketType.Play.Server.ENTITY_METADATA, 0, watcher, true)
|
||||
.createPacket(standIds[i], watcher, true);
|
||||
|
||||
packets.add(metaPacket);
|
||||
} else {
|
||||
packet.getDataWatcherModifier().write(0, watcher);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (destroyIds.length > 0) {
|
||||
packets.add(getDestroyPacket(destroyIds));
|
||||
}
|
||||
|
||||
return packets;
|
||||
}
|
||||
|
||||
public static Disguise getDisguise(Player observer, int entityId) {
|
||||
// If the entity ID is the same as self disguises id, then it needs to be set to the observers id
|
||||
if (entityId == DisguiseAPI.getSelfDisguiseId()) {
|
||||
|
@ -583,13 +583,20 @@ public class DisguiseListener implements Listener {
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVehicleEnter(VehicleEnterEvent event) {
|
||||
if (event.getEntered() instanceof Player &&
|
||||
DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) {
|
||||
DisguiseUtilities.removeSelfDisguise((Player) event.getEntered());
|
||||
if (!(event.getEntered() instanceof Player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
Disguise disguise = DisguiseAPI.getDisguise((Player) event.getEntered(), event.getEntered());
|
||||
|
||||
if (disguise == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
DisguiseUtilities.removeSelfDisguise(disguise);
|
||||
|
||||
((Player) event.getEntered()).updateInventory();
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
|
||||
public void onVehicleLeave(VehicleExitEvent event) {
|
||||
|
@ -25,6 +25,7 @@ public class PacketsManager {
|
||||
private static PacketListener viewDisguisesListener;
|
||||
private static boolean viewDisguisesListenerEnabled;
|
||||
private static PacketsHandler packetsHandler;
|
||||
private static PacketListener destroyListener;
|
||||
|
||||
public static void addPacketListeners() {
|
||||
// Add a client listener to cancel them interacting with uninteractable disguised entitys.
|
||||
@ -160,8 +161,10 @@ public class PacketsManager {
|
||||
}
|
||||
|
||||
mainListener = new PacketListenerMain(LibsDisguises.getInstance(), packetsToListen);
|
||||
destroyListener = new PacketListenerDestroyEntity(LibsDisguises.getInstance());
|
||||
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(mainListener);
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(destroyListener);
|
||||
}
|
||||
}
|
||||
|
||||
@ -183,7 +186,7 @@ public class PacketsManager {
|
||||
if (enabled) {
|
||||
DisguiseUtilities.setupFakeDisguise(disguise);
|
||||
} else {
|
||||
DisguiseUtilities.removeSelfDisguise(player);
|
||||
DisguiseUtilities.removeSelfDisguise(disguise);
|
||||
}
|
||||
|
||||
if (inventoryModifierEnabled &&
|
||||
|
@ -18,6 +18,8 @@ import org.bukkit.entity.Player;
|
||||
import org.bukkit.metadata.FixedMetadataValue;
|
||||
import org.bukkit.util.Vector;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by libraryaddict on 3/01/2019.
|
||||
*/
|
||||
@ -38,6 +40,36 @@ public class PacketHandlerMovement implements IPacketHandler {
|
||||
@Override
|
||||
public void handle(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer,
|
||||
Entity entity) {
|
||||
handle2(disguise, sentPacket, packets, observer, entity);
|
||||
|
||||
int len = disguise.getMultiName().length;
|
||||
|
||||
if (len == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArrayList<PacketContainer> toAdd = new ArrayList<>();
|
||||
|
||||
for (PacketContainer packet : packets.getPackets()) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
for (int standId : disguise.getArmorstandIds()) {
|
||||
PacketContainer packet2 = packet.shallowClone();
|
||||
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));
|
||||
}
|
||||
|
||||
toAdd.add(packet2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
packets.getPackets().addAll(toAdd);
|
||||
}
|
||||
|
||||
public void handle2(Disguise disguise, PacketContainer sentPacket, LibsPackets packets, Player observer,
|
||||
Entity entity) {
|
||||
if (invalid && RandomUtils.nextDouble() < 0.1) {
|
||||
packets.clear();
|
||||
return;
|
||||
|
@ -151,7 +151,7 @@ public class PacketHandlerSpawn implements IPacketHandler {
|
||||
mods.write(5, pitch);
|
||||
} else if (disguise.getType().isPlayer()) {
|
||||
PlayerDisguise playerDisguise = (PlayerDisguise) disguise;
|
||||
boolean visibleOrNewCompat = playerDisguise.isNameVisible() || DisguiseConfig.isScoreboardDisguiseNames();
|
||||
boolean visibleOrNewCompat = playerDisguise.isNameVisible() || DisguiseConfig.isScoreboardNames();
|
||||
|
||||
WrappedGameProfile spawnProfile = visibleOrNewCompat ? playerDisguise.getGameProfile() : ReflectionManager
|
||||
.getGameProfileWithThisSkin(UUID.randomUUID(), visibleOrNewCompat ? playerDisguise.getName() : "",
|
||||
@ -387,6 +387,8 @@ public class PacketHandlerSpawn implements IPacketHandler {
|
||||
packets.addPacket(newPacket);
|
||||
}
|
||||
|
||||
DisguiseUtilities.getNamePackets(disguise, new String[0]).forEach(packets::addPacket);
|
||||
|
||||
// If armor must be sent because its currently not displayed and would've been sent normally
|
||||
|
||||
// This sends the armor packets so that the player isn't naked.
|
||||
|
@ -78,7 +78,8 @@ public class PacketListenerViewSelfDisguise extends PacketAdapter {
|
||||
}
|
||||
|
||||
for (PacketContainer newPacket : transformed.getPackets()) {
|
||||
if (newPacket.getType() != Server.PLAYER_INFO) {
|
||||
if (newPacket.getType() != Server.PLAYER_INFO &&
|
||||
newPacket.getIntegers().read(0) == observer.getEntityId()) {
|
||||
if (newPacket == packet) {
|
||||
newPacket = newPacket.shallowClone();
|
||||
}
|
||||
|
@ -698,6 +698,10 @@ public class DisguiseParser {
|
||||
|
||||
args[1] = args[1].replace("\\_", " ");
|
||||
|
||||
if (DisguiseConfig.isArmorstandsName() && !sender.hasPermission("libsdisguises.multiname")) {
|
||||
args[1] = DisguiseUtilities.quoteNewLine(args[1]);
|
||||
}
|
||||
|
||||
// Construct the player disguise
|
||||
disguise = new PlayerDisguise(ChatColor.translateAlternateColorCodes('&', args[1]));
|
||||
|
||||
@ -904,6 +908,10 @@ public class DisguiseParser {
|
||||
}
|
||||
}
|
||||
|
||||
if (DisguiseConfig.isArmorstandsName() && methodToUse.getName().equals("setName") && !sender.hasPermission("libsdisguises.multiname")) {
|
||||
valueToSet = DisguiseUtilities.quoteNewLine((String) valueToSet);
|
||||
}
|
||||
|
||||
if (FlagWatcher.class.isAssignableFrom(methodToUse.getDeclaringClass())) {
|
||||
methodToUse.invoke(disguise.getWatcher(), valueToSet);
|
||||
} else {
|
||||
|
@ -59,7 +59,7 @@ public enum LibsMsg {
|
||||
DISG_HELP4(ChatColor.DARK_GREEN + "/disguise <Dropped_Item/Falling_Block> <Id> <Durability>"),
|
||||
DISG_PLAYER_AS_DISG(ChatColor.RED + "Successfully disguised %s as a %s!"),
|
||||
DISG_PLAYER_AS_DISG_FAIL(ChatColor.RED + "Failed to disguise %s as a %s!"),
|
||||
DISGUISED(ChatColor.RED + "Now disguised as a %s"),
|
||||
DISGUISED(ChatColor.RED + "Now disguised as %s"),
|
||||
DISRADIUS(ChatColor.RED + "Successfully disguised %s entities!"),
|
||||
DISRADIUS_FAIL(ChatColor.RED + "Couldn't find any entities to disguise!"),
|
||||
DMODENT_HELP1(ChatColor.DARK_GREEN + "Choose the options for a disguise then right click a entity to modify it!"),
|
||||
@ -116,7 +116,7 @@ public enum LibsMsg {
|
||||
"disabled in the config"),
|
||||
DRADIUS_NEEDOPTIONS(ChatColor.RED + "You need to supply a disguise as well as the radius"),
|
||||
DRADIUS_NEEDOPTIONS_ENTITY(ChatColor.RED + "You need to supply a disguise as well as the radius and EntityType"),
|
||||
FAILED_DISGIUSE(ChatColor.RED + "Failed to disguise as a %s"),
|
||||
FAILED_DISGIUSE(ChatColor.RED + "Failed to disguise as %s"),
|
||||
GRABBED_SKIN(ChatColor.GOLD + "Grabbed skin and saved as %s!"),
|
||||
PLEASE_WAIT(ChatColor.GRAY + "Please wait..."),
|
||||
INVALID_CLONE(ChatColor.DARK_RED + "Unknown method '%s' - Valid methods are 'IgnoreEquipment' 'DoSneakSprint' " +
|
||||
|
@ -66,13 +66,14 @@ SaveDisguises:
|
||||
Players: false
|
||||
Entities: false
|
||||
|
||||
# Do names go beyond the 16 char limit for player disguises?
|
||||
ExtendedNames: false
|
||||
# Do names resolve into scoreboard teams so changing the player name is flawless?
|
||||
# This will only work properly for names 28 chars or less in length.
|
||||
# Notch [DragonSlayer lvl: 28]
|
||||
# It's recommended to leave this on unless you need it off
|
||||
ScoreboardNames: true
|
||||
# There are four options you can use
|
||||
# VANILLA - Names are limited to 16 chars but can't be changed without resending disguise
|
||||
# TEAMS - Names are limited to 32 chars but can be changed willy nilly
|
||||
# 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
|
||||
PlayerNames: TEAMS
|
||||
|
||||
# How many ticks before tab packet is sent to remove from tablist. This shouldn't need to be touched
|
||||
TablistRemoveDelay: 2
|
||||
|
||||
|
@ -121,6 +121,8 @@ permissions:
|
||||
libsdisguises.noactionbar:
|
||||
description: Hides the action bar even if enabled in config
|
||||
default: false
|
||||
libsdisguises.multiname:
|
||||
description: Allows the command user to set names on different heights
|
||||
libsdisguises.seecmd:
|
||||
description: See all commands in tab-completion
|
||||
default: true
|
||||
|
Loading…
Reference in New Issue
Block a user