From 3ced8ae9e45145aa10d117b6737f00c7356d5ba9 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Fri, 3 Jul 2020 17:08:58 +1200 Subject: [PATCH] Added savePreferences and config option for it, added command to view notify bar, cleaned up code, action bar and custom names now support hex colors, uses a better hex color system conversion --- .../libraryaddict/disguise/DisguiseAPI.java | 42 +- .../disguise/DisguiseConfig.java | 4 + .../libraryaddict/disguise/LibsDisguises.java | 1 + .../utils/DisguiseViewBarCommand.java | 34 ++ .../disguise/disguisetypes/Disguise.java | 16 +- .../disguise/disguisetypes/FlagWatcher.java | 7 +- .../disguise/utilities/DisguiseUtilities.java | 377 ++++++++++++++---- .../utilities/translations/LibsMsg.java | 2 + .../disguise/utilities/updates/LDGithub.java | 6 +- src/main/resources/config.yml | 4 + src/main/resources/plugin.yml | 29 +- 11 files changed, 392 insertions(+), 130 deletions(-) create mode 100644 src/main/java/me/libraryaddict/disguise/commands/utils/DisguiseViewBarCommand.java diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java b/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java index 64f4ad8e..cfeda7dd 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java @@ -442,8 +442,22 @@ public class DisguiseAPI { return hasSelfDisguisePreference(entity) != DisguiseConfig.isViewDisguises(); } + /** + * Returns true if the entitiy has /disguiseviewself toggled on. + * + * @param entity + * @return + */ + public static boolean isViewBarToggled(Player entity) { + return hasViewBarPreference(entity) == (DisguiseConfig.getNotifyBar() != DisguiseConfig.NotifyBar.NONE); + } + public static boolean hasSelfDisguisePreference(Entity entity) { - return Disguise.getViewSelf().contains(entity.getUniqueId()); + return DisguiseUtilities.getViewSelf().contains(entity.getUniqueId()); + } + + public static boolean hasViewBarPreference(Entity entity) { + return DisguiseUtilities.getViewSelf().contains(entity.getUniqueId()); } /** @@ -478,10 +492,32 @@ public class DisguiseAPI { if (!canSeeSelfDisguises == DisguiseConfig.isViewDisguises()) { if (!hasSelfDisguisePreference(entity)) { - Disguise.getViewSelf().add(entity.getUniqueId()); + DisguiseUtilities.getViewSelf().add(entity.getUniqueId()); + DisguiseUtilities.addSaveAttempt(); } } else { - Disguise.getViewSelf().remove(entity.getUniqueId()); + DisguiseUtilities.getViewSelf().remove(entity.getUniqueId()); + DisguiseUtilities.addSaveAttempt(); + } + } + + public static void setViewBarToggled(Player player, boolean canSeeNotifyBar) { + if (isDisguised(player)) { + Disguise[] disguises = getDisguises(player); + + for (Disguise disguise : disguises) { + disguise.setNotifyBar(canSeeNotifyBar ? DisguiseConfig.getNotifyBar() : DisguiseConfig.NotifyBar.NONE); + } + } + + if (canSeeNotifyBar == (DisguiseConfig.getNotifyBar() != DisguiseConfig.NotifyBar.NONE)) { + if (!hasSelfDisguisePreference(player)) { + DisguiseUtilities.getViewBar().add(player.getUniqueId()); + DisguiseUtilities.addSaveAttempt(); + } + } else { + DisguiseUtilities.getViewBar().remove(player.getUniqueId()); + DisguiseUtilities.addSaveAttempt(); } } diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java index 4a08c8cf..c9fade9c 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java @@ -250,6 +250,9 @@ public class DisguiseConfig { @Getter @Setter private static boolean loginPayloadPackets; + @Getter + @Setter + private static boolean saveUserPreferences; public static boolean isArmorstandsName() { return getPlayerNameType() == PlayerNameType.ARMORSTANDS; @@ -668,6 +671,7 @@ public class DisguiseConfig { setTallSelfDisguises(config.getBoolean("TallSelfDisguises")); setOverrideCustomNames(config.getBoolean("OverrideCustomNames")); setRandomDisguises(config.getBoolean("RandomDisguiseOptions")); + setSaveUserPreferences(config.getBoolean("SaveUserPreferences")); if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) { DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!"); diff --git a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java index a8c9ac42..b5dddb49 100644 --- a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java @@ -178,6 +178,7 @@ public class LibsDisguises extends JavaPlugin { registerCommand("disguisehelp", new DisguiseHelpCommand()); registerCommand("disguiseclone", new DisguiseCloneCommand()); registerCommand("disguiseviewself", new DisguiseViewSelfCommand()); + registerCommand("disguiseviewbar", new DisguiseViewBarCommand()); registerCommand("disguisemodify", new DisguiseModifyCommand()); registerCommand("disguisemodifyentity", new DisguiseModifyEntityCommand()); registerCommand("disguisemodifyplayer", new DisguiseModifyPlayerCommand()); diff --git a/src/main/java/me/libraryaddict/disguise/commands/utils/DisguiseViewBarCommand.java b/src/main/java/me/libraryaddict/disguise/commands/utils/DisguiseViewBarCommand.java new file mode 100644 index 00000000..9f15088b --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/commands/utils/DisguiseViewBarCommand.java @@ -0,0 +1,34 @@ +package me.libraryaddict.disguise.commands.utils; + +import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.translations.LibsMsg; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +/** + * Created by libraryaddict on 2/07/2020. + */ +public class DisguiseViewBarCommand implements CommandExecutor { + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (sender.getName().equals("CONSOLE")) { + DisguiseUtilities.sendMessage(sender, LibsMsg.NO_CONSOLE); + return true; + } + + Player player = (Player) sender; + + if (DisguiseAPI.isViewBarToggled(player)) { + DisguiseAPI.setViewBarToggled(player, false); + DisguiseUtilities.sendMessage(sender, LibsMsg.VIEW_BAR_OFF); + } else { + DisguiseAPI.setViewBarToggled(player, true); + DisguiseUtilities.sendMessage(sender, LibsMsg.VIEW_BAR_ON); + } + + return true; + } +} diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java index 10a8fd73..6e17cfab 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/Disguise.java @@ -28,7 +28,6 @@ import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.translations.LibsMsg; import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.ComponentBuilder; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.NamespacedKey; @@ -45,17 +44,6 @@ import java.util.*; import java.util.concurrent.TimeUnit; public abstract class Disguise { - private static List viewSelf = new ArrayList<>(); - - /** - * Returns the list of people who have /disguiseViewSelf toggled on - * - * @return - */ - public static List getViewSelf() { - return viewSelf; - } - private transient boolean disguiseInUse; private DisguiseType disguiseType; private transient BukkitRunnable runnable; @@ -358,8 +346,8 @@ public abstract class Disguise { if (getNotifyBar() == DisguiseConfig.NotifyBar.ACTION_BAR && getEntity() instanceof Player && !getEntity().hasPermission("libsdisguises.noactionbar") && DisguiseAPI.getDisguise(getEntity()) == Disguise.this) { - ((Player) getEntity()).spigot().sendMessage(ChatMessageType.ACTION_BAR, - new ComponentBuilder(LibsMsg.ACTION_BAR_MESSAGE.get(getDisguiseName())).create()); + ((Player) getEntity()).spigot() + .sendMessage(ChatMessageType.ACTION_BAR, LibsMsg.ACTION_BAR_MESSAGE.getChat(getDisguiseName())); } if (isDynamicName()) { diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java index 7b44ced0..800bab9b 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/FlagWatcher.java @@ -21,7 +21,7 @@ import me.libraryaddict.disguise.utilities.reflection.NmsAddedIn; import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.entity.LivingEntity; @@ -373,7 +373,7 @@ public class FlagWatcher { if (optional.isPresent()) { BaseComponent[] base = ComponentConverter.fromWrapper(optional.get()); - return TextComponent.toLegacyText(base); + return DisguiseUtilities.getSimpleChat(base); } return null; @@ -416,7 +416,8 @@ public class FlagWatcher { } if (NmsVersion.v1_13.isSupported()) { - setData(MetaIndex.ENTITY_CUSTOM_NAME, Optional.of(WrappedChatComponent.fromText(name))); + setData(MetaIndex.ENTITY_CUSTOM_NAME, Optional.of(WrappedChatComponent + .fromJson(ComponentSerializer.toString(DisguiseUtilities.getColoredChat(name))))); } else { setData(MetaIndex.ENTITY_CUSTOM_NAME_OLD, name); } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 66f8971b..05c9f709 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -36,7 +36,9 @@ import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.watchers.CompileMethods; import net.md_5.bungee.api.chat.BaseComponent; -import net.md_5.bungee.api.chat.ComponentBuilder; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.chat.ComponentSerializer; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.math.RandomUtils; import org.apache.logging.log4j.util.Strings; @@ -58,7 +60,10 @@ import org.bukkit.util.Vector; import java.io.*; import java.lang.reflect.*; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.StandardOpenOption; import java.util.*; +import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -111,29 +116,29 @@ public class DisguiseUtilities { @Getter public static final Random random = new Random(); - private static LinkedHashMap clonedDisguises = new LinkedHashMap<>(); + private static final LinkedHashMap clonedDisguises = new LinkedHashMap<>(); private static final List isNoInteract = new ArrayList<>(); /** * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use */ @Getter - private static Map> disguises = new HashMap<>(); + private static final Map> disguises = new HashMap<>(); /** * Disguises which are stored ready for a entity to be seen by a player Preferably, disguises in this should only * stay in for * a max of a second. */ @Getter - private static HashMap> futureDisguises = new HashMap<>(); - private static HashSet savedDisguiseList = new HashSet<>(); - private static HashSet cachedNames = new HashSet<>(); + private static final HashMap> futureDisguises = new HashMap<>(); + private static final HashSet savedDisguiseList = new HashSet<>(); + private static final HashSet cachedNames = new HashSet<>(); private static final HashMap> runnables = new HashMap<>(); @Getter - private static HashSet selfDisguised = new HashSet<>(); - private static HashMap preDisguiseTeam = new HashMap<>(); - private static HashMap disguiseTeam = new HashMap<>(); - private static File profileCache = new File("plugins/LibsDisguises/GameProfiles"), savedDisguises = new File( - "plugins/LibsDisguises/SavedDisguises"); + private static final HashSet selfDisguised = new HashSet<>(); + private static final HashMap preDisguiseTeam = new HashMap<>(); + private static final HashMap disguiseTeam = new HashMap<>(); + private static final File profileCache = new File("plugins/LibsDisguises/GameProfiles"); + private static final File savedDisguises = new File("plugins/LibsDisguises/SavedDisguises"); @Getter private static Gson gson; @Getter @@ -145,16 +150,104 @@ public class DisguiseUtilities { */ private static long velocityTime; private static int velocityID; - private static HashMap> disguiseLoading = new HashMap<>(); + private static final HashMap> disguiseLoading = new HashMap<>(); @Getter private static boolean runningPaper; @Getter - private static MineSkinAPI mineSkinAPI = new MineSkinAPI(); + private static final MineSkinAPI mineSkinAPI = new MineSkinAPI(); @Getter private static boolean invalidFile; @Getter - private static char[] alphabet = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray(); - private static Pattern hexColor; + private static final char[] alphabet = "0123456789abcdefghijklmnopqrstuvwxyz".toCharArray(); + private static final Pattern urlMatcher = Pattern.compile("^(?:(https?)://)?([-\\w_.]{2,}\\.[a-z]{2,4})(/\\S*)?$"); + private final static List viewSelf = new ArrayList<>(); + private final static List viewBar = new ArrayList<>(); + private static long lastSavedPreferences; + + /** + * Only allow saves every 2 minutes + */ + public static void addSaveAttempt() { + if (lastSavedPreferences + TimeUnit.SECONDS.toMillis(120) > System.currentTimeMillis()) { + return; + } + + lastSavedPreferences = System.currentTimeMillis(); + + new BukkitRunnable() { + @Override + public void run() { + saveViewPreferances(); + } + }.runTaskLater(LibsDisguises.getInstance(), 20 * TimeUnit.SECONDS.toMillis(120)); + } + + /** + * Returns the list of people who have /disguiseViewSelf toggled + * + * @return + */ + public static List getViewSelf() { + return viewSelf; + } + + public static void saveViewPreferances() { + if (!DisguiseConfig.isSaveUserPreferences()) { + return; + } + + File viewPreferences = new File(LibsDisguises.getInstance().getDataFolder(), "preferences.json"); + + HashMap> map = new HashMap<>(); + map.put("selfdisguise", getViewSelf()); + map.put("notifybar", getViewBar()); + + String json = getGson().toJson(map); + + try { + Files.write(viewPreferences.toPath(), json.getBytes(), StandardOpenOption.CREATE); + } + catch (IOException e) { + e.printStackTrace(); + } + } + + public static void loadViewPreferences() { + File viewPreferences = new File(LibsDisguises.getInstance().getDataFolder(), "preferences.json"); + + if (!viewPreferences.exists()) { + return; + } + + HashMap> map; + + try { + String disguiseText = new String(Files.readAllBytes(viewPreferences.toPath())); + map = getGson().fromJson(disguiseText, HashMap.class); + + if (map.containsKey("selfdisguise")) { + getViewSelf().clear(); + map.get("selfdisguise").forEach(uuid -> getViewSelf().add(UUID.fromString(uuid))); + } + + if (map.containsKey("notifybar")) { + getViewBar().clear(); + map.get("notifybar").forEach(uuid -> getViewBar().add(UUID.fromString(uuid))); + } + } + catch (IOException e) { + e.printStackTrace(); + } + } + + /** + * Returns the list of people who have /disguiseviewbar toggled + * + * @return + */ + public static List getViewBar() { + return viewBar; + } public static void setPlayerVelocity(Player player) { if (player == null) { @@ -231,6 +324,8 @@ public class DisguiseUtilities { } public static void saveDisguises() { + saveViewPreferances(); + if (!LibsPremium.isPremium()) return; @@ -308,8 +403,6 @@ public class DisguiseUtilities { if (disguise == null || disguise.length == 0) { if (savedDisguiseList.contains(owningEntity)) { disguiseFile.delete(); - } else { - return; } } else { Disguise[] disguises = new Disguise[disguise.length]; @@ -356,7 +449,7 @@ public class DisguiseUtilities { } try { - String cached = null; + String cached; try (FileInputStream input = new FileInputStream( disguiseFile); InputStreamReader inputReader = new InputStreamReader(input, @@ -829,21 +922,17 @@ public class DisguiseUtilities { public static WrappedGameProfile getProfileFromMojang(final PlayerDisguise disguise) { final String nameToFetch = disguise.getSkin() != null ? disguise.getSkin() : disguise.getName(); - return getProfileFromMojang(nameToFetch, new LibsProfileLookup() { + return getProfileFromMojang(nameToFetch, gameProfile -> { + if (gameProfile == null || gameProfile.getProperties().isEmpty()) { + return; + } - @Override - public void onLookup(WrappedGameProfile gameProfile) { - if (gameProfile == null || gameProfile.getProperties().isEmpty()) { - return; - } + if (DisguiseAPI.isDisguiseInUse(disguise) && (!gameProfile.getName() + .equals(disguise.getSkin() != null ? disguise.getSkin() : disguise.getName()) || + !gameProfile.getProperties().isEmpty())) { + disguise.setGameProfile(gameProfile); - if (DisguiseAPI.isDisguiseInUse(disguise) && (!gameProfile.getName() - .equals(disguise.getSkin() != null ? disguise.getSkin() : disguise.getName()) || - !gameProfile.getProperties().isEmpty())) { - disguise.setGameProfile(gameProfile); - - DisguiseUtilities.refreshTrackers(disguise); - } + DisguiseUtilities.refreshTrackers(disguise); } }, LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); } @@ -902,41 +991,35 @@ public class DisguiseUtilities { runnables.get(playerName).add(runnable); } - Bukkit.getScheduler().runTaskAsynchronously(LibsDisguises.getInstance(), new Runnable() { - @Override - public void run() { - try { - final WrappedGameProfile gameProfile = lookupGameProfile(origName); + Bukkit.getScheduler().runTaskAsynchronously(LibsDisguises.getInstance(), () -> { + try { + final WrappedGameProfile gameProfile = lookupGameProfile(origName); - Bukkit.getScheduler().runTask(LibsDisguises.getInstance(), new Runnable() { - @Override - public void run() { - if (DisguiseConfig.isSaveGameProfiles()) { - addGameProfile(playerName, gameProfile); - } + Bukkit.getScheduler().runTask(LibsDisguises.getInstance(), () -> { + if (DisguiseConfig.isSaveGameProfiles()) { + addGameProfile(playerName, gameProfile); + } - synchronized (runnables) { - if (runnables.containsKey(playerName)) { - for (Object obj : runnables.remove(playerName)) { - if (obj instanceof Runnable) { - ((Runnable) obj).run(); - } else if (obj instanceof LibsProfileLookup) { - ((LibsProfileLookup) obj).onLookup(gameProfile); - } - } + synchronized (runnables) { + if (runnables.containsKey(playerName)) { + for (Object obj : runnables.remove(playerName)) { + if (obj instanceof Runnable) { + ((Runnable) obj).run(); + } else if (obj instanceof LibsProfileLookup) { + ((LibsProfileLookup) obj).onLookup(gameProfile); } } } - }); - } - catch (Exception e) { - synchronized (runnables) { - runnables.remove(playerName); } - - getLogger().severe("Error when fetching " + playerName + "'s uuid from mojang: " + - e.getMessage()); + }); + } + catch (Exception e) { + synchronized (runnables) { + runnables.remove(playerName); } + + getLogger().severe("Error when fetching " + playerName + "'s uuid from mojang: " + + e.getMessage()); } }); } else if (runnable != null && contactMojang) { @@ -978,11 +1061,7 @@ public class DisguiseUtilities { // Don't really need this here, but it's insurance! runningPaper = Class.forName("com.destroystokyo.paper.VersionHistoryManager$VersionData") != null; } - catch (Exception ex) { - } - - if (NmsVersion.v1_16.isSupported()) { - hexColor = Pattern.compile("<#[0-9a-fA-F]{6}>"); + catch (Exception ignored) { } GsonBuilder gsonBuilder = new GsonBuilder(); @@ -1049,7 +1128,7 @@ public class DisguiseUtilities { bar.removeAll(); Bukkit.removeBossBar(bar.getKey()); } - catch (IllegalArgumentException ex) { + catch (IllegalArgumentException ignored) { } } } @@ -1071,6 +1150,8 @@ public class DisguiseUtilities { catch (NoSuchMethodException e) { e.printStackTrace(); } + + loadViewPreferences(); } public static boolean isDisguiseInUse(Disguise disguise) { @@ -2077,7 +2158,7 @@ public class DisguiseUtilities { public static int[] getNumericVersion(String version) { int[] v = new int[0]; - for (String split : version.split("\\.|-")) { + for (String split : version.split("[.\\-]")) { if (!split.matches("[0-9]+")) { return v; } @@ -2089,31 +2170,151 @@ public class DisguiseUtilities { return v; } - public static BaseComponent[] getColoredChat(String string) { - if (hexColor == null) { - return new ComponentBuilder().appendLegacy(string).create(); - } + public static String getSimpleChat(BaseComponent[] components) { + StringBuilder builder = new StringBuilder(); - Matcher match = hexColor.matcher(string); + for (BaseComponent component : components) { + net.md_5.bungee.api.ChatColor color = component.getColor(); + String string = color.toString(); - ComponentBuilder builder = new ComponentBuilder(); - int lastMatch = 0; - - while (match.find()) { - if (match.start() > lastMatch) { - builder.appendLegacy(string.substring(lastMatch, match.start())); + if (string.length() > 2) { + builder.append("<#") + .append(string.substring(2).replace(net.md_5.bungee.api.ChatColor.COLOR_CHAR + "", "")) + .append(">"); + } else { + builder.append(string); } - lastMatch = match.end(); + if (component.isBold()) { + builder.append(net.md_5.bungee.api.ChatColor.BOLD); + } - builder.color(net.md_5.bungee.api.ChatColor.of(match.group().substring(1, 8))); + if (component.isItalic()) { + builder.append(net.md_5.bungee.api.ChatColor.ITALIC); + } + + if (component.isUnderlined()) { + builder.append(net.md_5.bungee.api.ChatColor.UNDERLINE); + } + + if (component.isStrikethrough()) { + builder.append(net.md_5.bungee.api.ChatColor.STRIKETHROUGH); + } + + if (component.isObfuscated()) { + builder.append(net.md_5.bungee.api.ChatColor.MAGIC); + } + + if (!(component instanceof TextComponent)) { + continue; + } + + builder.append(((TextComponent) component).getText()); } - if (lastMatch < string.length()) { - builder.appendLegacy(string.substring(lastMatch)); + return builder.toString(); + } + + /** + * Modification of TextComponent.fromLegacyText + */ + public static BaseComponent[] getColoredChat(String message) { + ArrayList components = new ArrayList(); + StringBuilder builder = new StringBuilder(); + TextComponent component = new TextComponent(); + Matcher matcher = urlMatcher.matcher(message); + + for (int i = 0; i < message.length(); ++i) { + char c = message.charAt(i); + TextComponent old; + + if (c == ChatColor.COLOR_CHAR || (c == '<' && i + 9 < message.length() && NmsVersion.v1_16.isSupported() && + Pattern.matches("<#[0-9a-fA-F]{6}>", message.substring(i, i + 9)))) { + // If normal color char + if (c == ChatColor.COLOR_CHAR) { + ++i; + + if (i >= message.length()) { + break; + } + } + + net.md_5.bungee.api.ChatColor format; + + if (c != ChatColor.COLOR_CHAR) { + format = net.md_5.bungee.api.ChatColor.of(message.substring(i + 1, i + 8)); + + i += 8; + } else { + c = message.charAt(i); + + if (c >= 'A' && c <= 'Z') { + c = (char) (c + 32); + } + + format = net.md_5.bungee.api.ChatColor.getByChar(c); + } + + if (format != null) { + if (builder.length() > 0) { + old = component; + component = new TextComponent(component); + old.setText(builder.toString()); + builder = new StringBuilder(); + components.add(old); + } + + if (format == net.md_5.bungee.api.ChatColor.BOLD) { + component.setBold(true); + } else if (format == net.md_5.bungee.api.ChatColor.ITALIC) { + component.setItalic(true); + } else if (format == net.md_5.bungee.api.ChatColor.UNDERLINE) { + component.setUnderlined(true); + } else if (format == net.md_5.bungee.api.ChatColor.STRIKETHROUGH) { + component.setStrikethrough(true); + } else if (format == net.md_5.bungee.api.ChatColor.MAGIC) { + component.setObfuscated(true); + } else if (format == net.md_5.bungee.api.ChatColor.RESET) { + component = new TextComponent(); + component.setColor(net.md_5.bungee.api.ChatColor.WHITE); + } else { + component = new TextComponent(); + component.setColor(format); + } + } + } else { + int pos = message.indexOf(32, i); + if (pos == -1) { + pos = message.length(); + } + + if (matcher.region(i, pos).find()) { + if (builder.length() > 0) { + old = component; + component = new TextComponent(component); + old.setText(builder.toString()); + builder = new StringBuilder(); + components.add(old); + } + + old = component; + component = new TextComponent(component); + String urlString = message.substring(i, pos); + component.setText(urlString); + component.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, + urlString.startsWith("http") ? urlString : "http://" + urlString)); + components.add(component); + i += pos - i - 1; + component = old; + } else { + builder.append(c); + } + } } - return builder.create(); + component.setText(builder.toString()); + components.add(component); + return components.toArray(new BaseComponent[components.size()]); } public static boolean isOlderThan(String requiredVersion, String theirVersion) { @@ -2367,12 +2568,11 @@ public class DisguiseUtilities { return (byte) -value; } - switch (disguiseType) { - case PHANTOM: - return (byte) -value; - default: - return value; + if (disguiseType == DisguiseType.PHANTOM) { + return (byte) -value; } + + return value; } public static byte getYaw(DisguiseType disguiseType, EntityType entityType, byte value) { @@ -2441,7 +2641,8 @@ public class DisguiseUtilities { Object name; if (NmsVersion.v1_13.isSupported()) { - name = Optional.of(WrappedChatComponent.fromText(newNames[i])); + name = Optional.of(WrappedChatComponent + .fromJson(ComponentSerializer.toString(DisguiseUtilities.getColoredChat(newNames[i])))); } else { name = newNames[i]; } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java b/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java index ec5215c2..a2be9ee9 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java @@ -208,6 +208,8 @@ public enum LibsMsg { " to download the update!"), VIEW_SELF_ON(ChatColor.GREEN + "Toggled viewing own disguise on!"), VIEW_SELF_OFF(ChatColor.GREEN + "Toggled viewing own disguise off!"), + VIEW_BAR_ON(ChatColor.GREEN + "Toggled disguised notify bar on!"), + VIEW_BAR_OFF(ChatColor.GREEN + "Toggled disguised notify bar off!"), CLICK_TO_COPY(ChatColor.GREEN + "Click to Copy:"), SKIN_DATA(ChatColor.GREEN + "Skin Data: " + ChatColor.YELLOW + "%s"), CLICK_TO_COPY_DATA(ChatColor.YELLOW + "Data"), diff --git a/src/main/java/me/libraryaddict/disguise/utilities/updates/LDGithub.java b/src/main/java/me/libraryaddict/disguise/utilities/updates/LDGithub.java index 93509f6d..fb20e222 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/updates/LDGithub.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/updates/LDGithub.java @@ -96,10 +96,12 @@ public class LDGithub { for (String s : users) { if (LibsPremium.getPaidInformation() != null && - LibsPremium.getPaidInformation().getUserID().equals(s)) { + (s.equals(LibsPremium.getPaidInformation().getDownloadID()) || + s.equals(LibsPremium.getPaidInformation().getUserID()))) { LibsDisguises.getInstance().unregisterCommands(true); } else { - if (LibsPremium.getUserID() == null || !LibsPremium.getUserID().equals(s)) { + if (LibsPremium.getUserID() == null || + (!s.equals(LibsPremium.getUserID()) && !s.equals(LibsPremium.getDownloadID()))) { continue; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 7859366b..881ea1f1 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -156,6 +156,10 @@ BossBarColor: GREEN # https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/boss/BarStyle.html BossBarStyle: SOLID +# By the default the plugin saves the users of the /viewdisguisebar and /viewselfdisguises to a file +# So that it persists after restart +SaveUserPreferences: true + # Shall I send the velocity packets? I REALLY recommend you don't disable. # This is the only thing allowing the mobs to fly without glitching out. SendVelocity: true diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 7f586641..01ca5d56 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -56,6 +56,11 @@ commands: aliases: [dviewself, dvs, disguisevs, disvs, vsd, viewselfdisguise, viewselfd, selfdisguise, selfdisg, selfd] permission: libsdisguises.seecmd.viewself description: Toggle seeing your own disguise on or off. + disguiseviewbar: + aliases: [dviewbar, dvb, disguisevb, disvb, vsd, viewdisguisebar, viewbardisguise, bardisguise, bardisg, bard, + notifybar, viewnotifybar, disguisenotifybar, disgnotifybar, dnotifybar] + permission: libsdisguises.seecmd.viewself + description: Toggle seeing your own disguise on or off. disguisemodify: aliases: [dmodify, dmod, disgmodify] permission: libsdisguises.seecmd.disguisemodify @@ -144,6 +149,7 @@ permissions: libsdisguises.seecmd.undisguiseradius: true libsdisguises.seecmd.disguiseclone: true libsdisguises.seecmd.disguiseviewself: true + libsdisguises.seecmd.disguiseviewbar: true libsdisguises.seecmd.disguisemodify: true libsdisguises.seecmd.disguisemodifyplayer: true libsdisguises.seecmd.disguisemodifyradius: true @@ -154,58 +160,41 @@ permissions: libsdisguises.seecmd.grabhead: true libsdisguises.seecmd.disguiseviewself: description: See the /disguiseviewself command in tab-completion - default: true + libsdisguises.seecmd.disguiseviewbar: + description: See the /disguiseviewbar command in tab-completion libsdisguises.seecmd.disguise: description: See the /disguise command in tab-completion - default: true libsdisguises.seecmd.disguiseentity: description: See the /disguiseentity command in tab-completion - default: true libsdisguises.seecmd.disguisehelp: description: See the /disguisehelp command in tab-completion - default: true libsdisguises.seecmd.disguiseplayer: description: See the /disguiseplayer command in tab-completion - default: true libsdisguises.seecmd.disguiseradius: description: See the /disguiseradius command in tab-completion - default: true libsdisguises.seecmd.undisguise: description: See the /undisguise command in tab-completion - default: true libsdisguises.seecmd.undisguiseentity: description: See the /undisguiseentity command in tab-completion - default: true libsdisguises.seecmd.undisguiseplayer: description: See the /undisguiseplayer command in tab-completion - default: true libsdisguises.seecmd.undisguiseradius: description: See the /undisguiseradius command in tab-completion - default: true libsdisguises.seecmd.disguiseclone: description: See the /disguiseclone command in tab-completion - default: true libsdisguises.seecmd.disguisemodify: description: See the /disguisemodify command in tab-completion - default: true libsdisguises.seecmd.disguisemodifyplayer: description: See the /disguisemodifyplayer command in tab-completion - default: true libsdisguises.seecmd.disguisemodifyradius: description: See the /disguisemodifyradius command in tab-completion - default: true libsdisguises.seecmd.disguisemodifyentity: description: See the /disguisemodifyentity command in tab-completion - default: true libsdisguises.seecmd.copydisguise: description: See the /copydisguise command in tab-completion - default: true libsdisguises.seecmd.grabskin: description: See the /grabskin command in tab-completion - default: true libsdisguises.seecmd.savedisguise: description: See the /savedisguise command in tab-completion - default: true libsdisguises.seecmd.grabhead: - description: See the /grabhead command in tab-completion - default: true \ No newline at end of file + description: See the /grabhead command in tab-completion \ No newline at end of file