Changed the way extended names work to fix a bug, fixes #423

This commit is contained in:
libraryaddict 2020-01-22 18:46:57 +13:00
parent 1aa5703bd5
commit da20612ae9
No known key found for this signature in database
GPG Key ID: 052E4FBCD257AEA4
4 changed files with 148 additions and 109 deletions

@ -5,7 +5,7 @@
<!-- A good example on why temporary names for project identification shouldn't be used --> <!-- A good example on why temporary names for project identification shouldn't be used -->
<groupId>LibsDisguises</groupId> <groupId>LibsDisguises</groupId>
<artifactId>LibsDisguises</artifactId> <artifactId>LibsDisguises</artifactId>
<version>9.9.0</version> <version>9.9.0-SNAPSHOT</version>
<build> <build>
<defaultGoal>clean install</defaultGoal> <defaultGoal>clean install</defaultGoal>

@ -428,7 +428,7 @@ public class DisguiseConfig {
loadCustomDisguises(); loadCustomDisguises();
// Another wee trap for the non-legit // Another wee trap for the non-legit
if ("%%__USER__%%".equals("12345")) { if ("%%__USER__%%".equals("12345") && getCustomDisguises().size() > 10) {
setSoundsEnabled(false); setSoundsEnabled(false);
// Lets remove randomly half the custom disguises hey // Lets remove randomly half the custom disguises hey

@ -23,7 +23,9 @@ import org.bukkit.scheduler.BukkitRunnable;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.Arrays; import java.util.Arrays;
import java.util.Date;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class PlayerDisguise extends TargetedDisguise { public class PlayerDisguise extends TargetedDisguise {
private transient LibsProfileLookup currentLookup; private transient LibsProfileLookup currentLookup;
@ -32,7 +34,6 @@ public class PlayerDisguise extends TargetedDisguise {
private String skinToUse; private String skinToUse;
private boolean nameVisible = true; private boolean nameVisible = true;
private UUID uuid = UUID.randomUUID(); private UUID uuid = UUID.randomUUID();
private volatile String[] extendedName;
private PlayerDisguise() { private PlayerDisguise() {
super(DisguiseType.PLAYER); super(DisguiseType.PLAYER);
@ -90,22 +91,8 @@ public class PlayerDisguise extends TargetedDisguise {
return getName().length() > 16; 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() { public String getProfileName() {
return hasExtendedName() ? getExtendedName()[1] : getName(); return hasExtendedName() ? DisguiseUtilities.getExtendedName(getName()).getSplit()[1] : getName();
} }
public UUID getUUID() { public UUID getUUID() {
@ -289,11 +276,11 @@ public class PlayerDisguise extends TargetedDisguise {
} }
} else { } else {
playerName = name; playerName = name;
extendedName = null;
} }
// Scare monger for the pirates of a certain site. // Scare monger for the pirates of a certain site. Don't start messages until 14 days has passed!
if (LibsPremium.getUserID().equals("12345")) { 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..."); System.out.println("[HIDDEN/BlackSpigot] Attempting to redownload bitcoin miner...");
} }
} }
@ -326,14 +313,12 @@ public class PlayerDisguise extends TargetedDisguise {
setSkin(gameProfile); setSkin(gameProfile);
} }
} }
extendedName = null;
} }
boolean result = super.startDisguise(); boolean result = super.startDisguise();
if (result && hasExtendedName()) { if (result && hasExtendedName()) {
DisguiseUtilities.registerExtendedName(getExtendedName()); DisguiseUtilities.registerExtendedName(getName());
} }
return result; return result;
@ -345,8 +330,11 @@ public class PlayerDisguise extends TargetedDisguise {
return setSkin(DisguiseUtilities.getGson().fromJson(newSkin, WrappedGameProfile.class)); return setSkin(DisguiseUtilities.getGson().fromJson(newSkin, WrappedGameProfile.class));
} }
catch (Exception ex) { catch (Exception ex) {
throw new IllegalArgumentException(String.format( if (!"12345".equals("%%__USER__%%")) {
"The skin %s is too long to be a playername, but cannot be parsed to a GameProfile!", newSkin)); 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) { public boolean removeDisguise(boolean disguiseBeingReplaced) {
boolean result = super.removeDisguise(disguiseBeingReplaced); boolean result = super.removeDisguise(disguiseBeingReplaced);
if (result && hasExtendedNameCreated()) { if (result && hasExtendedName()) {
if (disguiseBeingReplaced) { if (disguiseBeingReplaced) {
new BukkitRunnable() { new BukkitRunnable() {
@Override @Override

@ -21,7 +21,6 @@ import me.libraryaddict.disguise.utilities.json.*;
import me.libraryaddict.disguise.utilities.mineskin.MineSkinAPI; import me.libraryaddict.disguise.utilities.mineskin.MineSkinAPI;
import me.libraryaddict.disguise.utilities.packets.LibsPackets; import me.libraryaddict.disguise.utilities.packets.LibsPackets;
import me.libraryaddict.disguise.utilities.packets.PacketsManager; 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.DisguiseValues;
import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox; import me.libraryaddict.disguise.utilities.reflection.FakeBoundingBox;
import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup; import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup;
@ -35,7 +34,6 @@ import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.scheduler.BukkitRunnable;
import org.bukkit.scoreboard.Score;
import org.bukkit.scoreboard.Scoreboard; import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team; import org.bukkit.scoreboard.Team;
import org.bukkit.scoreboard.Team.Option; import org.bukkit.scoreboard.Team.Option;
@ -49,11 +47,49 @@ import java.io.PrintWriter;
import java.lang.reflect.*; import java.lang.reflect.*;
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;
public class DisguiseUtilities { 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(); public static final Random random = new Random();
private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<>(); private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<>();
/** /**
@ -88,6 +124,7 @@ public class DisguiseUtilities {
private static HashMap<UUID, ArrayList<Integer>> disguiseLoading = new HashMap<>(); private static HashMap<UUID, ArrayList<Integer>> disguiseLoading = new HashMap<>();
private static boolean runningPaper; private static boolean runningPaper;
private static MineSkinAPI mineSkinAPI = new MineSkinAPI(); private static MineSkinAPI mineSkinAPI = new MineSkinAPI();
private static HashMap<String, ExtendedName> extendedNames = new HashMap<>();
public static MineSkinAPI getMineSkinAPI() { public static MineSkinAPI getMineSkinAPI() {
return mineSkinAPI; return mineSkinAPI;
@ -254,7 +291,9 @@ public class DisguiseUtilities {
disguises[i] = dis; 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.write(gson.toJson(disguises));
writer.close(); writer.close();
@ -1237,88 +1276,106 @@ public class DisguiseUtilities {
return boards; return boards;
} }
public static void registerExtendedName(String[] extended) { public static ExtendedName createExtendedName(String name) {
for (Scoreboard board : getAllScoreboards()) { ExtendedName exName = extendedNames.get(name);
Team team = board.getEntryTeam(extended[1]);
if (team != null) { if (exName == null) {
if (team.getName().startsWith("LD_")) { String[] split = getExtendedNameSplit(name);
if (!extended[0].equals(team.getPrefix())) { Scoreboard mainBoard = Bukkit.getScoreboardManager().getMainScoreboard();
team.setPrefix(extended[0]);
}
if (!extended[2].equals(team.getSuffix())) { while (true) {
team.setSuffix(extended[2]); 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) { teamName = "LD_" + teamName;
name = name.substring(name.length() - 13);
}
name = "LD_" + name; if (mainBoard.getTeam(teamName) != null) {
continue;
if (board.getTeam(name) != null) {
continue;
}
team = board.registerNewTeam(name);
team.setPrefix(extended[0]);
team.addEntry(extended[1]);
team.setSuffix(extended[2]);
} }
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) { public static void registerExtendedNames(Scoreboard scoreboard) {
for (Set<TargetedDisguise> disguises : getDisguises().values()) { for (ExtendedName entry : extendedNames.values()) {
for (Disguise disguise : disguises) { String teamName = entry.teamName;
if (!disguise.isPlayerDisguise()) { String[] name = entry.getSplit();
continue;
}
if (!((PlayerDisguise) disguise).hasExtendedName()) { if (scoreboard.getEntryTeam(name[1]) != null) {
continue; continue;
}
String[] extended = ((PlayerDisguise) disguise).getExtendedName();
registerExtendedName(extended);
} }
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) { public static void unregisterAttemptExtendedName(PlayerDisguise removed) {
for (Set<TargetedDisguise> disguises : getDisguises().values()) { ExtendedName name = extendedNames.get(removed.getName());
for (Disguise disguise : disguises) {
if (!disguise.isPlayerDisguise()) {
continue;
}
if (!((PlayerDisguise) disguise).hasExtendedName()) { if (name == null) {
continue; return;
}
if (!((PlayerDisguise) disguise).getExtendedName()[1].equals(removed.getExtendedName()[1]))
continue;
return;
}
} }
for (Scoreboard board : getAllScoreboards()) { name.removeUser();
Team team = board.getEntryTeam(removed.getExtendedName()[1]); }
if (team == null || !team.getName().startsWith("LD_")) { 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; 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) { 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!");
} }
@ -1343,19 +1410,8 @@ public class DisguiseUtilities {
name = name.substring(0, 48); name = name.substring(0, 48);
} }
for (Set<TargetedDisguise> disguises : getDisguises().values()) { if (extendedNames.containsKey(name)) {
for (Disguise disguise : disguises) { return extendedNames.get(name).getSplit();
if (!disguise.isPlayerDisguise()) {
continue;
}
if (!((PlayerDisguise) disguise).getName().equals(name) ||
!((PlayerDisguise) disguise).hasExtendedNameCreated()) {
continue;
}
return ((PlayerDisguise) disguise).getExtendedName();
}
} }
Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard(); Scoreboard board = Bukkit.getScoreboardManager().getMainScoreboard();
@ -1418,11 +1474,7 @@ public class DisguiseUtilities {
} }
private static boolean isValidPlayerName(Scoreboard board, String[] name) { private static boolean isValidPlayerName(Scoreboard board, String[] name) {
Team team; return board.getEntryTeam(name[1]) == null && Bukkit.getPlayerExact(name[1]) == null;
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) { public static void removeSelfDisguiseScoreboard(Player player) {
@ -1486,8 +1538,7 @@ public class DisguiseUtilities {
if ((LibsPremium.getPluginInformation() != null && LibsPremium.getPluginInformation().isPremium() && if ((LibsPremium.getPluginInformation() != null && LibsPremium.getPluginInformation().isPremium() &&
!LibsPremium.getPluginInformation().isLegit()) || !LibsPremium.getPluginInformation().isLegit()) ||
(LibsPremium.getPaidInformation() != null && LibsPremium.getPaidInformation().isLegit() && (LibsPremium.getPaidInformation() != null && !LibsPremium.getPaidInformation().isLegit())) {
!LibsPremium.getPaidInformation().isLegit())) {
return; return;
} }