Improve extended names, normal player disguises now use teams instead of actual player names to better support names changing at will

Added setName to PlayerDisguise disguise options in command
This commit is contained in:
libraryaddict 2020-03-30 20:22:33 +13:00
parent ab5cb8a1f1
commit 901c6ef06f
No known key found for this signature in database
GPG Key ID: 052E4FBCD257AEA4
8 changed files with 292 additions and 197 deletions

View File

@ -221,6 +221,9 @@ public class DisguiseConfig {
@Setter @Setter
private static BarColor bossBarColor = BarColor.GREEN; private static BarColor bossBarColor = BarColor.GREEN;
private static PermissionDefault commandVisibility = PermissionDefault.TRUE; private static PermissionDefault commandVisibility = PermissionDefault.TRUE;
@Getter
@Setter
private static boolean scoreboardDisguiseNames;
public static PermissionDefault getCommandVisibility() { public static PermissionDefault getCommandVisibility() {
return commandVisibility; return commandVisibility;
@ -432,6 +435,7 @@ public class DisguiseConfig {
setWarnScoreboardConflict(config.getBoolean("Scoreboard.WarnConflict")); setWarnScoreboardConflict(config.getBoolean("Scoreboard.WarnConflict"));
setWitherSkullPacketsEnabled(config.getBoolean("PacketsEnabled.WitherSkull")); setWitherSkullPacketsEnabled(config.getBoolean("PacketsEnabled.WitherSkull"));
setWolfDyeable(config.getBoolean("DyeableWolf")); setWolfDyeable(config.getBoolean("DyeableWolf"));
setScoreboardDisguiseNames(config.getBoolean("ScoreboardNames"));
if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) { if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) {
DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!"); DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!");

View File

@ -443,7 +443,7 @@ public class DisguiseListener implements Listener {
DisguiseUtilities.registerNoName(event.getPlayer().getScoreboard()); DisguiseUtilities.registerNoName(event.getPlayer().getScoreboard());
if (event.getPlayer().getScoreboard() != Bukkit.getScoreboardManager().getMainScoreboard()) { if (event.getPlayer().getScoreboard() != Bukkit.getScoreboardManager().getMainScoreboard()) {
DisguiseUtilities.registerExtendedNames(event.getPlayer().getScoreboard()); DisguiseUtilities.registerAllExtendedNames(event.getPlayer().getScoreboard());
} }
} }
}.runTaskLater(LibsDisguises.getInstance(), 20); }.runTaskLater(LibsDisguises.getInstance(), 20);

View File

@ -29,13 +29,14 @@ import java.util.UUID;
public class PlayerDisguise extends TargetedDisguise { public class PlayerDisguise extends TargetedDisguise {
private transient LibsProfileLookup currentLookup; private transient LibsProfileLookup currentLookup;
private WrappedGameProfile gameProfile; private WrappedGameProfile gameProfile;
private String playerName; private String playerName = "Herobrine";
private String skinToUse; private String skinToUse;
private boolean nameVisible = true; private boolean nameVisible = true;
private UUID uuid = UUID.randomUUID(); private UUID uuid = UUID.randomUUID();
@Getter @Getter
@Setter @Setter
private boolean dynamicName; private boolean dynamicName;
private DisguiseUtilities.DisguiseTeam scoreboardName;
private PlayerDisguise() { private PlayerDisguise() {
super(DisguiseType.PLAYER); super(DisguiseType.PLAYER);
@ -84,12 +85,25 @@ public class PlayerDisguise extends TargetedDisguise {
createDisguise(); createDisguise();
} }
public boolean hasExtendedName() { public DisguiseUtilities.DisguiseTeam getScoreboardName() {
return getName().length() > 16; if (getName().length() <= 16 ? !DisguiseConfig.isScoreboardDisguiseNames() :
!DisguiseConfig.isExtendedDisguiseNames()) {
throw new IllegalStateException("Cannot use this method when it's been disabled in config!");
}
if (scoreboardName == null) {
scoreboardName = DisguiseUtilities.createExtendedName(getName());
}
return scoreboardName;
}
public boolean hasScoreboardName() {
return scoreboardName != null || DisguiseConfig.isScoreboardDisguiseNames() || getName().length() > 16;
} }
public String getProfileName() { public String getProfileName() {
return hasExtendedName() ? DisguiseUtilities.getExtendedName(getName()).getSplit()[1] : getName(); return hasScoreboardName() ? getScoreboardName().getPlayer() : getName();
} }
public UUID getUUID() { public UUID getUUID() {
@ -106,6 +120,7 @@ public class PlayerDisguise extends TargetedDisguise {
} }
if (isDisguiseInUse()) { if (isDisguiseInUse()) {
if (!DisguiseConfig.isScoreboardDisguiseNames()) {
if (stopDisguise()) { if (stopDisguise()) {
this.nameVisible = nameVisible; this.nameVisible = nameVisible;
@ -115,6 +130,10 @@ public class PlayerDisguise extends TargetedDisguise {
} else { } else {
throw new IllegalStateException("Unable to restart disguise"); throw new IllegalStateException("Unable to restart disguise");
} }
} else {
this.nameVisible = nameVisible;
DisguiseUtilities.updateExtendedName(this);
}
} else { } else {
this.nameVisible = nameVisible; this.nameVisible = nameVisible;
} }
@ -194,11 +213,22 @@ public class PlayerDisguise extends TargetedDisguise {
name = name.substring(0, 16); name = name.substring(0, 16);
} }
if (isDisguiseInUse() && isNameVisible()) { if (isDisguiseInUse()) {
boolean resendDisguise = !DisguiseConfig.isScoreboardDisguiseNames();
if (hasScoreboardName()) {
DisguiseUtilities.DisguiseTeam team = getScoreboardName();
String[] split = DisguiseUtilities.getExtendedNameSplit(team.getPlayer(), name);
resendDisguise = !split[1].equals(team.getPlayer());
team.setSplit(split);
}
if (resendDisguise) {
if (stopDisguise()) { if (stopDisguise()) {
if (getName().isEmpty() && !name.isEmpty()) { if (getName().isEmpty() && !name.isEmpty()) {
setNameVisible(true); setNameVisible(true);
} else if (name.isEmpty()) { } else if (!getName().isEmpty() && name.isEmpty()) {
setNameVisible(false); setNameVisible(false);
} }
@ -216,9 +246,27 @@ public class PlayerDisguise extends TargetedDisguise {
throw new IllegalStateException("Unable to restart disguise"); throw new IllegalStateException("Unable to restart disguise");
} }
} else { } else {
if (getName() != null&&!getName().isEmpty() && name.isEmpty()) { if (getName().isEmpty() && !name.isEmpty() && !isNameVisible()) {
setNameVisible(true);
} else if (!getName().isEmpty() && name.isEmpty() && isNameVisible()) {
setNameVisible(false); setNameVisible(false);
} else if (!name.isEmpty()) { } else {
DisguiseUtilities.updateExtendedName(this);
}
playerName = name;
}
} else {
if (scoreboardName != null) {
DisguiseUtilities.DisguiseTeam team = getScoreboardName();
String[] split = DisguiseUtilities.getExtendedNameSplit(team.getPlayer(), name);
team.setSplit(split);
}
if (name.isEmpty()) {
setNameVisible(false);
} else {
setNameVisible(true); setNameVisible(true);
} }
@ -388,7 +436,10 @@ public class PlayerDisguise extends TargetedDisguise {
@Override @Override
public boolean startDisguise() { public boolean startDisguise() {
if (!isDisguiseInUse()) { if (isDisguiseInUse()) {
return false;
}
if (skinToUse != null && gameProfile == null) { if (skinToUse != null && gameProfile == null) {
currentLookup = new LibsProfileLookup() { currentLookup = new LibsProfileLookup() {
@Override @Override
@ -429,12 +480,11 @@ public class PlayerDisguise extends TargetedDisguise {
setName(name); setName(name);
} }
}
boolean result = super.startDisguise(); boolean result = super.startDisguise();
if (result && hasExtendedName()) { if (result && hasScoreboardName()) {
DisguiseUtilities.registerExtendedName(getName()); DisguiseUtilities.registerExtendedName(this);
} }
return result; return result;
@ -464,16 +514,16 @@ public class PlayerDisguise extends TargetedDisguise {
public boolean removeDisguise(boolean disguiseBeingReplaced) { public boolean removeDisguise(boolean disguiseBeingReplaced) {
boolean result = super.removeDisguise(disguiseBeingReplaced); boolean result = super.removeDisguise(disguiseBeingReplaced);
if (result && hasExtendedName()) { if (result && hasScoreboardName()) {
if (disguiseBeingReplaced) { if (disguiseBeingReplaced) {
new BukkitRunnable() { new BukkitRunnable() {
@Override @Override
public void run() { public void run() {
DisguiseUtilities.unregisterAttemptExtendedName(PlayerDisguise.this); DisguiseUtilities.unregisterExtendedName(PlayerDisguise.this);
} }
}.runTaskLater(LibsDisguises.getInstance(), 5); }.runTaskLater(LibsDisguises.getInstance(), 5);
} else { } else {
DisguiseUtilities.unregisterAttemptExtendedName(this); DisguiseUtilities.unregisterExtendedName(this);
} }
} }

View File

@ -13,6 +13,7 @@ import com.google.gson.GsonBuilder;
import com.google.gson.JsonSyntaxException; import com.google.gson.JsonSyntaxException;
import com.mojang.authlib.properties.PropertyMap; import com.mojang.authlib.properties.PropertyMap;
import lombok.Getter; import lombok.Getter;
import lombok.Setter;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.DisguiseConfig.DisguisePushing; import me.libraryaddict.disguise.DisguiseConfig.DisguisePushing;
@ -49,47 +50,52 @@ import java.lang.reflect.*;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger; import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class DisguiseUtilities { public class DisguiseUtilities {
public static class ExtendedName { @Setter
public ExtendedName(String teamName, String[] name) { public static class DisguiseTeam {
this.teamName = teamName; public DisguiseTeam(String[] name) {
this.name = name; this.split = name;
} }
@Getter
private String teamName; private String teamName;
private String[] name; private String[] split;
private int users; private PlayerDisguise disguise;
private long lastUsed = System.currentTimeMillis();
public String[] getSplit() { public String getPlayer() {
return name; return split[1];
} }
public void addUser() { public String getPrefix() {
lastUsed = 0; return split[0];
users++;
} }
public void removeUser() { public String getSuffix() {
if (users > 0) { return split[2];
users--;
} }
if (users != 0) { public void handleTeam(Scoreboard board, boolean nameVisible) {
return; Team team = board.getTeam(getTeamName());
if (team == null) {
team = board.registerNewTeam(getTeamName());
team.addEntry(getPlayer());
if (!nameVisible) {
team.setOption(Option.NAME_TAG_VISIBILITY, OptionStatus.NEVER);
}
} else if (team.getOption(Option.NAME_TAG_VISIBILITY) !=
(nameVisible ? OptionStatus.ALWAYS : OptionStatus.NEVER)) {
team.setOption(Option.NAME_TAG_VISIBILITY, nameVisible ? OptionStatus.ALWAYS : OptionStatus.NEVER);
} }
lastUsed = System.currentTimeMillis(); team.setPrefix(getPrefix());
} team.setSuffix(getSuffix());
public boolean isRemoveable() {
return users <= 0 && lastUsed + TimeUnit.HOURS.toMillis(1) < System.currentTimeMillis();
} }
} }
@ -132,9 +138,10 @@ public class DisguiseUtilities {
private static boolean runningPaper; private static boolean runningPaper;
@Getter @Getter
private static MineSkinAPI mineSkinAPI = new MineSkinAPI(); private static MineSkinAPI mineSkinAPI = new MineSkinAPI();
private static HashMap<String, ExtendedName> extendedNames = new HashMap<>();
@Getter @Getter
private static boolean invalidFile; private static boolean invalidFile;
@Getter
private static char[] alphabet = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray();
public static void setPlayerVelocity(Player player) { public static void setPlayerVelocity(Player player) {
if (player == null) { if (player == null) {
@ -235,8 +242,6 @@ public class DisguiseUtilities {
disguise = disguise.clone(); disguise = disguise.clone();
} }
char[] alphabet = "abcdefghijklmnopqrstuvwxyz".toCharArray();
String reference = null; String reference = null;
int referenceLength = Math.max(2, (int) Math.ceil((0.1D + DisguiseConfig.getMaxClonedDisguises()) / 26D)); int referenceLength = Math.max(2, (int) Math.ceil((0.1D + DisguiseConfig.getMaxClonedDisguises()) / 26D));
int attempts = 0; int attempts = 0;
@ -928,14 +933,14 @@ public class DisguiseUtilities {
// Clear the old scoreboard teams for extended names! // Clear the old scoreboard teams for extended names!
for (Scoreboard board : getAllScoreboards()) { for (Scoreboard board : getAllScoreboards()) {
for (Team team : board.getTeams()) { for (Team team : board.getTeams()) {
if (!team.getName().matches("LD_[0-9]{10,}")) { if (!team.getName().startsWith("LD_")) {
continue; continue;
} }
team.unregister(); team.unregister();
} }
registerExtendedNames(board); registerAllExtendedNames(board);
registerNoName(board); registerNoName(board);
} }
} }
@ -1264,15 +1269,17 @@ public class DisguiseUtilities {
return boards; return boards;
} }
public static ExtendedName createExtendedName(String name) { public static DisguiseTeam createExtendedName(String name) {
ExtendedName exName = extendedNames.get(name); String[] split = getExtendedNameSplit(null, name);
if (exName == null) { return new DisguiseTeam(split);
String[] split = getExtendedNameSplit(name); }
public static String getUniqueTeam() {
Scoreboard mainBoard = Bukkit.getScoreboardManager().getMainScoreboard(); Scoreboard mainBoard = Bukkit.getScoreboardManager().getMainScoreboard();
while (true) { for (int i = 0; i < 1000; i++) {
String teamName = System.nanoTime() + ""; String teamName = encode(System.nanoTime() / 100 % 100000) + "";
if (teamName.length() > 13) { if (teamName.length() > 13) {
teamName = teamName.substring(teamName.length() - 13); teamName = teamName.substring(teamName.length() - 13);
@ -1284,87 +1291,62 @@ public class DisguiseUtilities {
continue; continue;
} }
exName = new ExtendedName(teamName, split); return teamName;
break;
} }
extendedNames.put(name, exName); throw new IllegalStateException("Lib's Disguises unable to find a unique team name!");
}
public static void updateExtendedName(PlayerDisguise disguise) {
DisguiseTeam exName = disguise.getScoreboardName();
for (Scoreboard board : getAllScoreboards()) { for (Scoreboard board : getAllScoreboards()) {
Team team = board.registerNewTeam(exName.teamName); exName.handleTeam(board, disguise.isNameVisible());
team.setPrefix(exName.getSplit()[0]);
team.setSuffix(exName.getSplit()[2]);
team.addEntry(exName.getSplit()[1]);
} }
} }
return exName; public static void registerExtendedName(PlayerDisguise disguise) {
DisguiseTeam exName = disguise.getScoreboardName();
if (exName.getTeamName() == null) {
exName.setTeamName(getUniqueTeam());
} }
public static ExtendedName registerExtendedName(String name) { for (Scoreboard board : getAllScoreboards()) {
ExtendedName exName = createExtendedName(name); exName.handleTeam(board, disguise.isNameVisible());
}
exName.addUser();
doExtendedNamesGarbageCollection();
return exName;
} }
public static void registerExtendedNames(Scoreboard scoreboard) { public static void registerAllExtendedNames(Scoreboard scoreboard) {
for (ExtendedName entry : extendedNames.values()) { for (Set<TargetedDisguise> disguises : getDisguises().values()) {
String teamName = entry.teamName; for (Disguise disguise : disguises) {
String[] name = entry.getSplit(); if (!disguise.isPlayerDisguise() || !disguise.isDisguiseInUse()) {
if (scoreboard.getEntryTeam(name[1]) != null) {
continue; continue;
} }
if (scoreboard.getTeam(teamName) != null) { DisguiseTeam name = ((PlayerDisguise) disguise).getScoreboardName();
continue;
name.handleTeam(scoreboard, ((PlayerDisguise) disguise).isNameVisible());
} }
Team team = scoreboard.registerNewTeam(teamName);
team.addEntry(name[1]);
team.setPrefix(name[0]);
team.setSuffix(name[2]);
} }
} }
public static void unregisterAttemptExtendedName(PlayerDisguise removed) { public static void unregisterExtendedName(PlayerDisguise removed) {
ExtendedName name = extendedNames.get(removed.getName()); if (removed.getScoreboardName().getTeamName() == null) {
if (name == null) {
return; return;
} }
name.removeUser();
}
public static void doExtendedNamesGarbageCollection() {
Iterator<Map.Entry<String, ExtendedName>> itel = extendedNames.entrySet().iterator();
while (itel.hasNext()) {
Map.Entry<String, ExtendedName> entry = itel.next();
if (!entry.getValue().isRemoveable()) {
continue;
}
itel.remove();
for (Scoreboard board : getAllScoreboards()) { for (Scoreboard board : getAllScoreboards()) {
Team team = board.getTeam(entry.getValue().teamName); Team t = board.getTeam(removed.getScoreboardName().getTeamName());
if (team == null) { if (t == null) {
continue; continue;
} }
team.unregister(); t.unregister();
}
} }
removed.getScoreboardName().setTeamName(null);
} }
public static void registerNoName(Scoreboard scoreboard) { public static void registerNoName(Scoreboard scoreboard) {
@ -1379,18 +1361,8 @@ public class DisguiseUtilities {
} }
} }
public static ExtendedName getExtendedName(String name) { public static String[] getExtendedNameSplit(String playerName, String name) {
ExtendedName extendedName = extendedNames.get(name); if (name.length() <= 16 && !DisguiseConfig.isScoreboardDisguiseNames()) {
if (extendedName != null) {
return extendedName;
}
return createExtendedName(name);
}
private static String[] getExtendedNameSplit(String name) {
if (name.length() <= 16) {
throw new IllegalStateException("This can only be used for names longer than 16 characters!"); throw new IllegalStateException("This can only be used for names longer than 16 characters!");
} }
@ -1398,11 +1370,52 @@ public class DisguiseUtilities {
name = name.substring(0, 48); name = name.substring(0, 48);
} }
if (extendedNames.containsKey(name)) { Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
return extendedNames.get(name).getSplit();
// If name is short enough to be used outside of player name
if (DisguiseConfig.isScoreboardDisguiseNames() && name.length() <= 32) {
String[] newName = new String[]{name, playerName, ""};
if (name.length() > 16) {
if (name.charAt(16) == ChatColor.COLOR_CHAR) {
newName[0] = name.substring(0, 15);
} else {
newName[0] = name.substring(0, 16);
} }
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); String suffix = ChatColor.getLastColors(newName[0]) + name.substring(newName[0].length());
if (suffix.length() > 16) {
suffix = suffix.substring(0, 16);
}
// Don't allow second name to hit 17 chars
newName[2] = suffix;
}
String namePrefix = colorize("LD");
if (playerName == null || !playerName.startsWith(namePrefix)) {
String nameSuffix = "" + ChatColor.RESET;
long time = System.nanoTime() / 100 % 10000;
for (int i = 0; i < 1000; i++) {
String testName = namePrefix + colorize(encode(time + i)) + nameSuffix;
if (testName.length() > 16) {
break;
}
if (!isValidPlayerName(board, testName)) {
continue;
}
newName[1] = testName;
break;
}
}
return newName;
}
for (int prefixLen = 16; prefixLen >= 0; prefixLen--) { for (int prefixLen = 16; prefixLen >= 0; prefixLen--) {
String prefix = name.substring(0, prefixLen); String prefix = name.substring(0, prefixLen);
@ -1430,7 +1443,7 @@ public class DisguiseUtilities {
String[] extended = new String[]{prefix, nName, suffix}; String[] extended = new String[]{prefix, nName, suffix};
if (!isValidPlayerName(board, extended)) { if ((playerName == null || !playerName.equals(extended[1])) && !isValidPlayerName(board, extended[1])) {
continue; continue;
} }
@ -1461,8 +1474,29 @@ public class DisguiseUtilities {
return new String[]{prefix, nName, suffix}; return new String[]{prefix, nName, suffix};
} }
private static boolean isValidPlayerName(Scoreboard board, String[] name) { private static String colorize(String s) {
return board.getEntryTeam(name[1]) == null && Bukkit.getPlayerExact(name[1]) == null; StringBuilder builder = new StringBuilder(s.length() * 2);
for (char c : s.toCharArray()) {
builder.append(ChatColor.COLOR_CHAR).append(c);
}
return builder.toString();
}
private static String encode(long toConvert) {
StringBuilder builder = new StringBuilder();
while (toConvert != 0) {
builder.append(alphabet[(int) (toConvert % alphabet.length)]);
toConvert /= alphabet.length;
}
return builder.reverse().toString();
}
private static boolean isValidPlayerName(Scoreboard board, String name) {
return board.getEntryTeam(name) == null && Bukkit.getPlayerExact(name) == null;
} }
public static void removeSelfDisguiseScoreboard(Player player) { public static void removeSelfDisguiseScoreboard(Player player) {
@ -1633,7 +1667,9 @@ public class DisguiseUtilities {
return string; return string;
} }
return "\"" + string.replaceAll("\\\\(?=\\\\*\"( |$))", "\\\\\\\\").replaceAll("((?<= )\")|(\"(?= ))", "\\\\\"") + "\""; return "\"" +
string.replaceAll("\\\\(?=\\\\*\"( |$))", "\\\\\\\\").replaceAll("((?<= )\")|(\"(?= ))", "\\\\\"") +
"\"";
} }
public static String[] split(String string) { public static String[] split(String string) {

View File

@ -155,10 +155,10 @@ public class PacketHandlerSpawn implements IPacketHandler {
mods.write(5, pitch); mods.write(5, pitch);
} else if (disguise.getType().isPlayer()) { } else if (disguise.getType().isPlayer()) {
PlayerDisguise playerDisguise = (PlayerDisguise) disguise; PlayerDisguise playerDisguise = (PlayerDisguise) disguise;
boolean visibleOrNewCompat = playerDisguise.isNameVisible() || DisguiseConfig.isScoreboardDisguiseNames();
WrappedGameProfile spawnProfile = playerDisguise.isNameVisible() ? playerDisguise.getGameProfile() : WrappedGameProfile spawnProfile = visibleOrNewCompat ? playerDisguise.getGameProfile() : ReflectionManager
ReflectionManager.getGameProfileWithThisSkin(UUID.randomUUID(), .getGameProfileWithThisSkin(UUID.randomUUID(), visibleOrNewCompat ? playerDisguise.getProfileName() : "",
playerDisguise.isNameVisible() ? playerDisguise.getProfileName() : "",
playerDisguise.getGameProfile()); playerDisguise.getGameProfile());
int entityId = disguisedEntity.getEntityId(); int entityId = disguisedEntity.getEntityId();

View File

@ -146,6 +146,7 @@ public class ParamInfoManager {
try { try {
methods.add(PlayerDisguise.class.getMethod("setNameVisible", boolean.class)); methods.add(PlayerDisguise.class.getMethod("setNameVisible", boolean.class));
methods.add(PlayerDisguise.class.getMethod("setDynamicName", boolean.class)); methods.add(PlayerDisguise.class.getMethod("setDynamicName", boolean.class));
methods.add(PlayerDisguise.class.getMethod("setName", String.class));
} }
catch (NoSuchMethodException e) { catch (NoSuchMethodException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -18,7 +18,6 @@ import org.apache.commons.lang.StringUtils;
import org.bukkit.*; import org.bukkit.*;
import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.craftbukkit.v1_15_R1.inventory.CraftItemStack;
import org.bukkit.entity.*; import org.bukkit.entity.*;
import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;

View File

@ -64,6 +64,11 @@ SaveDisguises:
# Do names go beyond the 16 char limit for player disguises? # Do names go beyond the 16 char limit for player disguises?
ExtendedNames: true ExtendedNames: true
# 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
# Does the player keep their disguise after they die? # Does the player keep their disguise after they die?
KeepDisguises: KeepDisguises: