Added extended names + config option, fixed nms version incorrect reporting, small code cleanup, fixed player disguises with spaces not being quoted, fixed disguises saving as unknown charset format. Adds

This commit is contained in:
libraryaddict 2020-01-20 13:35:55 +13:00
parent ef981b3787
commit 9a555dafb8
No known key found for this signature in database
GPG Key ID: 052E4FBCD257AEA4
10 changed files with 317 additions and 55 deletions

@ -93,6 +93,15 @@ public class DisguiseConfig {
private static int playerDisguisesTablistExpires;
private static boolean dynamicExpiry;
private static boolean playerHideArmor;
private static boolean extendedDisguisesNames;
public static boolean isExtendedDisguiseNames() {
return extendedDisguisesNames;
}
public static void setExtendedDisguiseNames(boolean extendedDisguiseNames) {
extendedDisguisesNames = extendedDisguiseNames;
}
public static boolean isPlayerHideArmor() {
return playerHideArmor;
@ -388,6 +397,7 @@ public class DisguiseConfig {
setPlayerDisguisesTablistExpires(config.getInt("PlayerDisguisesTablistExpires"));
setDynamicExpiry(config.getBoolean("DynamicExpiry"));
setPlayerHideArmor(config.getBoolean("PlayerHideArmor"));
setExtendedDisguiseNames(config.getBoolean("ExtendedNames"));
if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) {
DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!");

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

@ -1,36 +1,24 @@
package me.libraryaddict.disguise;
import com.comphenix.protocol.reflect.FieldAccessException;
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import me.libraryaddict.disguise.commands.*;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MetaIndex;
import me.libraryaddict.disguise.disguisetypes.watchers.*;
import me.libraryaddict.disguise.utilities.DisguiseSound;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
import me.libraryaddict.disguise.utilities.LibsPremium;
import me.libraryaddict.disguise.utilities.metrics.MetricsInitalizer;
import me.libraryaddict.disguise.utilities.packets.PacketsManager;
import me.libraryaddict.disguise.utilities.parser.DisguiseParser;
import me.libraryaddict.disguise.utilities.reflection.DisguiseValues;
import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.PluginCommand;
import org.bukkit.command.TabCompleter;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.*;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
public class LibsDisguises extends JavaPlugin {
private static LibsDisguises instance;

@ -531,7 +531,7 @@ public abstract class Disguise {
deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
deleteTab.getPlayerInfoDataLists().write(0, Collections.singletonList(
new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getName()))));
WrappedChatComponent.fromText(disguise.getProfileName()))));
try {
for (Player player : Bukkit.getOnlinePlayers()) {
@ -820,7 +820,7 @@ public abstract class Disguise {
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Collections.singletonList(
new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getName()))));
WrappedChatComponent.fromText(disguise.getProfileName()))));
try {
for (Player player : Bukkit.getOnlinePlayers()) {

@ -8,6 +8,7 @@ import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
import com.comphenix.protocol.wrappers.PlayerInfoData;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
@ -18,6 +19,7 @@ import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
@ -30,6 +32,7 @@ public class PlayerDisguise extends TargetedDisguise {
private String skinToUse;
private boolean nameVisible = true;
private UUID uuid = UUID.randomUUID();
private volatile String[] extendedName;
private PlayerDisguise() {
super(DisguiseType.PLAYER);
@ -83,6 +86,28 @@ public class PlayerDisguise extends TargetedDisguise {
createDisguise();
}
public boolean hasExtendedName() {
return getName().length() > 16;
}
public boolean hasExtendedNameCreated() {
return extendedName != null;
}
public String[] getExtendedName() {
if (!hasExtendedName() || hasExtendedNameCreated()) {
return extendedName;
}
extendedName = DisguiseUtilities.getSplitName(getName());
return extendedName;
}
public String getProfileName() {
return hasExtendedName() ? getExtendedName()[1] : getName();
}
public UUID getUUID() {
return uuid;
}
@ -158,10 +183,10 @@ public class PlayerDisguise extends TargetedDisguise {
public WrappedGameProfile getGameProfile() {
if (gameProfile == null) {
if (getSkin() != null) {
gameProfile = ReflectionManager.getGameProfile(uuid, getName());
gameProfile = ReflectionManager.getGameProfile(uuid, getProfileName());
} else {
gameProfile = ReflectionManager
.getGameProfileWithThisSkin(uuid, getName(), DisguiseUtilities.getProfileFromMojang(this));
gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getProfileName(),
DisguiseUtilities.getProfileFromMojang(this));
}
}
@ -244,14 +269,14 @@ public class PlayerDisguise extends TargetedDisguise {
}
public void setName(String name) {
if (name.length() > 16) {
name = name.substring(0, 16);
}
if (name.equals(playerName)) {
return;
}
if (!DisguiseConfig.isExtendedDisguiseNames() && name.length() > 16) {
name = name.substring(0, 16);
}
if (isDisguiseInUse()) {
if (stopDisguise()) {
playerName = name;
@ -264,6 +289,7 @@ public class PlayerDisguise extends TargetedDisguise {
}
} else {
playerName = name;
extendedName = null;
}
// Scare monger for the pirates of a certain site.
@ -279,28 +305,38 @@ public class PlayerDisguise extends TargetedDisguise {
@Override
public boolean startDisguise() {
if (!isDisguiseInUse() && skinToUse != null && gameProfile == null) {
currentLookup = new LibsProfileLookup() {
@Override
public void onLookup(WrappedGameProfile gameProfile) {
if (currentLookup != this || gameProfile == null || gameProfile.getProperties().isEmpty())
return;
if (!isDisguiseInUse()) {
if (skinToUse != null && gameProfile == null) {
currentLookup = new LibsProfileLookup() {
@Override
public void onLookup(WrappedGameProfile gameProfile) {
if (currentLookup != this || gameProfile == null || gameProfile.getProperties().isEmpty())
return;
setSkin(gameProfile);
currentLookup = null;
}
};
WrappedGameProfile gameProfile = DisguiseUtilities.getProfileFromMojang(this.skinToUse, currentLookup,
LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true));
if (gameProfile != null) {
setSkin(gameProfile);
currentLookup = null;
}
};
WrappedGameProfile gameProfile = DisguiseUtilities.getProfileFromMojang(this.skinToUse, currentLookup,
LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true));
if (gameProfile != null) {
setSkin(gameProfile);
}
extendedName = null;
}
return super.startDisguise();
boolean result = super.startDisguise();
if (result && hasExtendedName()) {
DisguiseUtilities.registerExtendedName(getExtendedName());
}
return result;
}
public PlayerDisguise setSkin(String newSkin) {
@ -346,7 +382,7 @@ public class PlayerDisguise extends TargetedDisguise {
currentLookup = null;
this.skinToUse = gameProfile.getName();
this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getName(), gameProfile);
this.gameProfile = ReflectionManager.getGameProfileWithThisSkin(uuid, getProfileName(), gameProfile);
if (DisguiseUtilities.isDisguiseInUse(this)) {
if (isDisplayedInTab()) {
@ -354,7 +390,7 @@ public class PlayerDisguise extends TargetedDisguise {
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Arrays.asList(
new PlayerInfoData(getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(getName()))));
WrappedChatComponent.fromText(getProfileName()))));
PacketContainer deleteTab = addTab.shallowClone();
deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
@ -403,4 +439,24 @@ public class PlayerDisguise extends TargetedDisguise {
public PlayerDisguise silentlyRemovePlayer(String playername) {
return (PlayerDisguise) super.silentlyRemovePlayer(playername);
}
@Override
public boolean removeDisguise(boolean disguiseBeingReplaced) {
boolean result = super.removeDisguise(disguiseBeingReplaced);
if (result && hasExtendedNameCreated()) {
if (disguiseBeingReplaced) {
new BukkitRunnable() {
@Override
public void run() {
DisguiseUtilities.unregisterAttemptExtendedName(PlayerDisguise.this);
}
}.runTaskLater(LibsDisguises.getInstance(), 5);
} else {
DisguiseUtilities.unregisterAttemptExtendedName(this);
}
}
return result;
}
}

@ -21,22 +21,21 @@ import me.libraryaddict.disguise.utilities.json.*;
import me.libraryaddict.disguise.utilities.mineskin.MineSkinAPI;
import me.libraryaddict.disguise.utilities.packets.LibsPackets;
import me.libraryaddict.disguise.utilities.packets.PacketsManager;
import me.libraryaddict.disguise.utilities.parser.DisguiseParseException;
import me.libraryaddict.disguise.utilities.reflection.DisguiseValues;
import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox;
import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup;
import me.libraryaddict.disguise.utilities.reflection.ReflectionManager;
import me.libraryaddict.disguise.utilities.translations.LibsMsg;
import org.apache.logging.log4j.util.Strings;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.*;
import org.bukkit.craftbukkit.libs.org.apache.commons.io.FileUtils;
import org.bukkit.entity.*;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import org.bukkit.scoreboard.Team.Option;
@ -255,7 +254,7 @@ public class DisguiseUtilities {
disguises[i] = dis;
}
PrintWriter writer = new PrintWriter(disguiseFile);
PrintWriter writer = new PrintWriter(disguiseFile, "UTF-8");
writer.write(gson.toJson(disguises));
writer.close();
@ -905,10 +904,18 @@ public class DisguiseUtilities {
}
}
registerNoName(Bukkit.getScoreboardManager().getMainScoreboard());
// Clear the old scoreboard teams for extended names!
for (Scoreboard board : getAllScoreboards()) {
for (Team team : board.getTeams()) {
if (!team.getName().matches("LD_[0-9]{10,}")) {
continue;
}
for (Player player : Bukkit.getOnlinePlayers()) {
registerNoName(player.getScoreboard());
team.unregister();
}
registerExtendedNames(board);
registerNoName(board);
}
}
@ -1214,6 +1221,107 @@ public class DisguiseUtilities {
player.updateInventory();
}
public static List<Scoreboard> getAllScoreboards() {
List<Scoreboard> boards = new ArrayList<>();
boards.add(Bukkit.getScoreboardManager().getMainScoreboard());
for (Player player : Bukkit.getOnlinePlayers()) {
if (boards.contains(player.getScoreboard())) {
continue;
}
boards.add(player.getScoreboard());
}
return boards;
}
public static void registerExtendedName(String[] extended) {
for (Scoreboard board : getAllScoreboards()) {
Team team = board.getEntryTeam(extended[1]);
if (team != null) {
if (team.getName().startsWith("LD_")) {
if (!extended[0].equals(team.getPrefix())) {
team.setPrefix(extended[0]);
}
if (!extended[2].equals(team.getSuffix())) {
team.setSuffix(extended[2]);
}
}
} else {
// Ugly! But..
while (team == null) {
String name = System.currentTimeMillis() + "";
if (name.length() > 13) {
name = name.substring(name.length() - 13);
}
name = "LD_" + name;
if (board.getTeam(name) != null) {
continue;
}
team = board.registerNewTeam(name);
team.setPrefix(extended[0]);
team.addEntry(extended[1]);
team.setSuffix(extended[2]);
}
}
}
}
public static void registerExtendedNames(Scoreboard scoreboard) {
for (Set<TargetedDisguise> disguises : getDisguises().values()) {
for (Disguise disguise : disguises) {
if (!disguise.isPlayerDisguise()) {
continue;
}
if (!((PlayerDisguise) disguise).hasExtendedName()) {
continue;
}
String[] extended = ((PlayerDisguise) disguise).getExtendedName();
registerExtendedName(extended);
}
}
}
public static void unregisterAttemptExtendedName(PlayerDisguise removed) {
for (Set<TargetedDisguise> disguises : getDisguises().values()) {
for (Disguise disguise : disguises) {
if (!disguise.isPlayerDisguise()) {
continue;
}
if (!((PlayerDisguise) disguise).hasExtendedName()) {
continue;
}
if (!((PlayerDisguise) disguise).getExtendedName()[1].equals(removed.getExtendedName()[1]))
continue;
return;
}
}
for (Scoreboard board : getAllScoreboards()) {
Team team = board.getEntryTeam(removed.getExtendedName()[1]);
if (team == null || !team.getName().startsWith("LD_")) {
continue;
}
team.unregister();
}
}
public static void registerNoName(Scoreboard scoreboard) {
Team mainTeam = scoreboard.getTeam("LD_NoName");
@ -1226,6 +1334,97 @@ public class DisguiseUtilities {
}
}
public static String[] getSplitName(String name) {
if (name.length() <= 16) {
throw new IllegalStateException("This can only be used for names longer than 16 characters!");
}
if (name.length() > 48) {
name = name.substring(0, 48);
}
for (Set<TargetedDisguise> disguises : getDisguises().values()) {
for (Disguise disguise : disguises) {
if (!disguise.isPlayerDisguise()) {
continue;
}
if (!((PlayerDisguise) disguise).getName().equals(name) ||
!((PlayerDisguise) disguise).hasExtendedNameCreated()) {
continue;
}
return ((PlayerDisguise) disguise).getExtendedName();
}
}
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
for (int prefixLen = 16; prefixLen >= 0; prefixLen--) {
String prefix = name.substring(0, prefixLen);
if (prefix.endsWith("" + ChatColor.COLOR_CHAR)) {
continue;
}
String colors = ChatColor.getLastColors(prefix);
// We found our prefix. Now we check about seperating it between name and suffix
for (int nameLen = Math.min(name.length() - (prefixLen + colors.length()), 16 - colors.length());
nameLen > 0; nameLen--) {
String nName = colors + name.substring(prefixLen, nameLen + prefixLen);
if (nName.endsWith("" + ChatColor.COLOR_CHAR)) {
continue;
}
String suffix = name.substring(nameLen + prefixLen);
if (suffix.length() > 16) {
suffix = suffix.substring(0, 16);
}
String[] extended = new String[]{prefix, nName, suffix};
if (!isValidPlayerName(board, extended)) {
continue;
}
return extended;
}
}
// Failed to find a unique name.. Ah well.
String prefix = name.substring(0, 16);
if (prefix.endsWith(ChatColor.COLOR_CHAR + "")) {
prefix = prefix.substring(0, 15);
}
String nName = name.substring(prefix.length(), prefix.length() + Math.min(16, prefix.length()));
if (nName.endsWith(ChatColor.COLOR_CHAR + "") && nName.length() > 1) {
nName = nName.substring(0, nName.length() - 1);
}
String suffix = name.substring(prefix.length() + nName.length());
if (suffix.length() > 16) {
suffix = suffix.substring(0, 16);
}
return new String[]{prefix, nName, suffix};
}
private static boolean isValidPlayerName(Scoreboard board, String[] name) {
Team team;
return ((team = board.getEntryTeam(name[1])) == null ||
(team.getName().startsWith("LD_") && team.getPrefix().equals(name[0]) &&
team.getSuffix().equals(name[2]))) && Bukkit.getPlayerExact(name[1]) == null;
}
public static void removeSelfDisguiseScoreboard(Player player) {
String originalTeam = preDisguiseTeam.remove(player.getUniqueId());
String teamDisguise = disguiseTeam.remove(player.getUniqueId());

@ -155,9 +155,9 @@ public class PacketHandlerSpawn implements IPacketHandler {
} else if (disguise.getType().isPlayer()) {
PlayerDisguise playerDisguise = (PlayerDisguise) disguise;
String name = playerDisguise.getName();
WrappedGameProfile spawnProfile = playerDisguise.isNameVisible() ? playerDisguise.getGameProfile() :
ReflectionManager.getGameProfileWithThisSkin(UUID.randomUUID(), "",
ReflectionManager.getGameProfileWithThisSkin(UUID.randomUUID(),
playerDisguise.isNameVisible() ? playerDisguise.getProfileName() : "",
playerDisguise.getGameProfile());
int entityId = disguisedEntity.getEntityId();

@ -136,7 +136,7 @@ public class DisguiseParser {
stringBuilder.append(disguise.getType().name());
if (disguise.isPlayerDisguise()) {
stringBuilder.append(" ").append(((PlayerDisguise) disguise).getName());
stringBuilder.append(" ").append(DisguiseUtilities.quote(((PlayerDisguise) disguise).getName()));
}
for (Method m : ParamInfoManager.getDisguiseWatcherMethods(disguise.getType().getWatcherClass())) {

@ -49,8 +49,6 @@ public class ReflectionManager {
private static Field trackedEntitiesField;
public static void init() {
bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3];
try {
Object entity = createEntityInstance(DisguiseType.COW, "Cow");
@ -286,6 +284,10 @@ public class ReflectionManager {
}
public static String getBukkitVersion() {
if (bukkitVersion == null) {
bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3];
}
return bukkitVersion;
}

@ -42,6 +42,9 @@ SaveDisguises:
Players: false
Entities: false
# Do names go beyond the 16 char limit for player disguises?
ExtendedNames: true
# Does the player keep their disguise after they die?
KeepDisguises:
PlayerDeath: false