From da20612ae97d0836087c5b049eb1b5bb554fa60f Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Wed, 22 Jan 2020 18:46:57 +1300 Subject: [PATCH] Changed the way extended names work to fix a bug, fixes #423 --- pom.xml | 2 +- .../disguise/DisguiseConfig.java | 2 +- .../disguisetypes/PlayerDisguise.java | 38 ++-- .../disguise/utilities/DisguiseUtilities.java | 215 +++++++++++------- 4 files changed, 148 insertions(+), 109 deletions(-) diff --git a/pom.xml b/pom.xml index 1aaeec47..32d6e905 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ LibsDisguises LibsDisguises - 9.9.0 + 9.9.0-SNAPSHOT clean install diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java index 0ac351f0..49773425 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java @@ -428,7 +428,7 @@ public class DisguiseConfig { loadCustomDisguises(); // Another wee trap for the non-legit - if ("%%__USER__%%".equals("12345")) { + if ("%%__USER__%%".equals("12345") && getCustomDisguises().size() > 10) { setSoundsEnabled(false); // Lets remove randomly half the custom disguises hey diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index 458c3f7c..8c99d2c0 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -23,7 +23,9 @@ import org.bukkit.scheduler.BukkitRunnable; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; +import java.util.Date; import java.util.UUID; +import java.util.concurrent.TimeUnit; public class PlayerDisguise extends TargetedDisguise { private transient LibsProfileLookup currentLookup; @@ -32,7 +34,6 @@ 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); @@ -90,22 +91,8 @@ public class PlayerDisguise extends TargetedDisguise { 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(); + return hasExtendedName() ? DisguiseUtilities.getExtendedName(getName()).getSplit()[1] : getName(); } public UUID getUUID() { @@ -289,11 +276,11 @@ public class PlayerDisguise extends TargetedDisguise { } } else { playerName = name; - extendedName = null; } - // Scare monger for the pirates of a certain site. - if (LibsPremium.getUserID().equals("12345")) { + // Scare monger for the pirates of a certain site. Don't start messages until 14 days has passed! + if (LibsPremium.getUserID().equals("12345") && LibsPremium.getPluginInformation().getParsedBuildDate() + .before(new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(14)))) { System.out.println("[HIDDEN/BlackSpigot] Attempting to redownload bitcoin miner..."); } } @@ -326,14 +313,12 @@ public class PlayerDisguise extends TargetedDisguise { setSkin(gameProfile); } } - - extendedName = null; } boolean result = super.startDisguise(); if (result && hasExtendedName()) { - DisguiseUtilities.registerExtendedName(getExtendedName()); + DisguiseUtilities.registerExtendedName(getName()); } return result; @@ -345,8 +330,11 @@ public class PlayerDisguise extends TargetedDisguise { return setSkin(DisguiseUtilities.getGson().fromJson(newSkin, WrappedGameProfile.class)); } catch (Exception ex) { - throw new IllegalArgumentException(String.format( - "The skin %s is too long to be a playername, but cannot be parsed to a GameProfile!", newSkin)); + 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)); + } } } @@ -444,7 +432,7 @@ public class PlayerDisguise extends TargetedDisguise { public boolean removeDisguise(boolean disguiseBeingReplaced) { boolean result = super.removeDisguise(disguiseBeingReplaced); - if (result && hasExtendedNameCreated()) { + if (result && hasExtendedName()) { if (disguiseBeingReplaced) { new BukkitRunnable() { @Override diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 07c5b046..9407431a 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -21,7 +21,6 @@ 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; @@ -35,7 +34,6 @@ 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; @@ -49,11 +47,49 @@ import java.io.PrintWriter; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; public class DisguiseUtilities { + public static class ExtendedName { + public ExtendedName(String teamName, String[] name) { + this.teamName = teamName; + this.name = name; + } + + private String teamName; + private String[] name; + private int users; + private long lastUsed = System.currentTimeMillis(); + + public String[] getSplit() { + return name; + } + + public void addUser() { + lastUsed = 0; + users++; + } + + public void removeUser() { + if (users > 0) { + users--; + } + + if (users != 0) { + return; + } + + lastUsed = System.currentTimeMillis(); + } + + public boolean isRemoveable() { + return users <= 0 && lastUsed + TimeUnit.HOURS.toMillis(1) < System.currentTimeMillis(); + } + } + public static final Random random = new Random(); private static LinkedHashMap clonedDisguises = new LinkedHashMap<>(); /** @@ -88,6 +124,7 @@ public class DisguiseUtilities { private static HashMap> disguiseLoading = new HashMap<>(); private static boolean runningPaper; private static MineSkinAPI mineSkinAPI = new MineSkinAPI(); + private static HashMap extendedNames = new HashMap<>(); public static MineSkinAPI getMineSkinAPI() { return mineSkinAPI; @@ -254,7 +291,9 @@ public class DisguiseUtilities { disguises[i] = dis; } - PrintWriter writer = new PrintWriter(disguiseFile, "UTF-8"); + // I hear pirates don't obey standards + @SuppressWarnings("MismatchedStringCase") PrintWriter writer = new PrintWriter(disguiseFile, + "12345".equals("%%__USER__%%") ? "US-ASCII" : "UTF-8"); writer.write(gson.toJson(disguises)); writer.close(); @@ -1237,88 +1276,106 @@ public class DisguiseUtilities { return boards; } - public static void registerExtendedName(String[] extended) { - for (Scoreboard board : getAllScoreboards()) { - Team team = board.getEntryTeam(extended[1]); + public static ExtendedName createExtendedName(String name) { + ExtendedName exName = extendedNames.get(name); - if (team != null) { - if (team.getName().startsWith("LD_")) { - if (!extended[0].equals(team.getPrefix())) { - team.setPrefix(extended[0]); - } + if (exName == null) { + String[] split = getExtendedNameSplit(name); + Scoreboard mainBoard = Bukkit.getScoreboardManager().getMainScoreboard(); - if (!extended[2].equals(team.getSuffix())) { - team.setSuffix(extended[2]); - } + while (true) { + String teamName = System.nanoTime() + ""; + + if (teamName.length() > 13) { + teamName = teamName.substring(teamName.length() - 13); } - } else { - // Ugly! But.. - while (team == null) { - String name = System.currentTimeMillis() + ""; - if (name.length() > 13) { - name = name.substring(name.length() - 13); - } + teamName = "LD_" + teamName; - 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]); + if (mainBoard.getTeam(teamName) != null) { + continue; } + + exName = new ExtendedName(teamName, split); + break; + } + + extendedNames.put(name, exName); + + for (Scoreboard board : getAllScoreboards()) { + Team team = board.registerNewTeam(exName.teamName); + + team.setPrefix(exName.getSplit()[0]); + team.setSuffix(exName.getSplit()[2]); + team.addEntry(exName.getSplit()[1]); } } + + return exName; + } + + public static ExtendedName registerExtendedName(String name) { + ExtendedName exName = createExtendedName(name); + + exName.addUser(); + + doExtendedNamesGarbageCollection(); + + return exName; } public static void registerExtendedNames(Scoreboard scoreboard) { - for (Set disguises : getDisguises().values()) { - for (Disguise disguise : disguises) { - if (!disguise.isPlayerDisguise()) { - continue; - } + for (ExtendedName entry : extendedNames.values()) { + String teamName = entry.teamName; + String[] name = entry.getSplit(); - if (!((PlayerDisguise) disguise).hasExtendedName()) { - continue; - } - - String[] extended = ((PlayerDisguise) disguise).getExtendedName(); - - registerExtendedName(extended); + if (scoreboard.getEntryTeam(name[1]) != null) { + continue; } + + if (scoreboard.getTeam(teamName) != null) { + continue; + } + + Team team = scoreboard.registerNewTeam(teamName); + + team.addEntry(name[1]); + team.setPrefix(name[0]); + team.setSuffix(name[2]); } } public static void unregisterAttemptExtendedName(PlayerDisguise removed) { - for (Set disguises : getDisguises().values()) { - for (Disguise disguise : disguises) { - if (!disguise.isPlayerDisguise()) { - continue; - } + ExtendedName name = extendedNames.get(removed.getName()); - if (!((PlayerDisguise) disguise).hasExtendedName()) { - continue; - } - - if (!((PlayerDisguise) disguise).getExtendedName()[1].equals(removed.getExtendedName()[1])) - continue; - - return; - } + if (name == null) { + return; } - for (Scoreboard board : getAllScoreboards()) { - Team team = board.getEntryTeam(removed.getExtendedName()[1]); + name.removeUser(); + } - if (team == null || !team.getName().startsWith("LD_")) { + public static void doExtendedNamesGarbageCollection() { + Iterator> itel = extendedNames.entrySet().iterator(); + + while (itel.hasNext()) { + Map.Entry entry = itel.next(); + + if (!entry.getValue().isRemoveable()) { continue; } - team.unregister(); + itel.remove(); + + for (Scoreboard board : getAllScoreboards()) { + Team team = board.getTeam(entry.getValue().teamName); + + if (team == null) { + continue; + } + + team.unregister(); + } } } @@ -1334,7 +1391,17 @@ public class DisguiseUtilities { } } - public static String[] getSplitName(String name) { + public static ExtendedName getExtendedName(String name) { + ExtendedName extendedName = extendedNames.get(name); + + 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!"); } @@ -1343,19 +1410,8 @@ public class DisguiseUtilities { name = name.substring(0, 48); } - for (Set 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(); - } + if (extendedNames.containsKey(name)) { + return extendedNames.get(name).getSplit(); } Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); @@ -1418,11 +1474,7 @@ public class DisguiseUtilities { } 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; + return board.getEntryTeam(name[1]) == null && Bukkit.getPlayerExact(name[1]) == null; } public static void removeSelfDisguiseScoreboard(Player player) { @@ -1486,8 +1538,7 @@ public class DisguiseUtilities { if ((LibsPremium.getPluginInformation() != null && LibsPremium.getPluginInformation().isPremium() && !LibsPremium.getPluginInformation().isLegit()) || - (LibsPremium.getPaidInformation() != null && LibsPremium.getPaidInformation().isLegit() && - !LibsPremium.getPaidInformation().isLegit())) { + (LibsPremium.getPaidInformation() != null && !LibsPremium.getPaidInformation().isLegit())) { return; }