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 #422

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

View File

@ -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!");

View File

@ -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);
}

View File

@ -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;

View File

@ -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()) {

View File

@ -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;
}
}

View File

@ -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());

View File

@ -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();

View File

@ -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())) {

View File

@ -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;
}

View File

@ -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