From bd0ca9ec8c99cea1f40a8d74db9fd017bd08f143 Mon Sep 17 00:00:00 2001 From: libraryaddict Date: Sun, 31 Jan 2021 21:28:07 +1300 Subject: [PATCH] Large config rewrite, updating creates incompatibility with older versions of LD. Probably need to clean up configs a bit more. --- pom.xml | 1 + .../libraryaddict/disguise/DisguiseAPI.java | 18 +- .../disguise/DisguiseConfig.java | 135 ++----- .../libraryaddict/disguise/LibsDisguises.java | 61 +-- .../disguise/DisguiseRadiusCommand.java | 13 +- .../commands/libsdisguises/LDConfig.java | 3 +- .../commands/libsdisguises/LDUploadLogs.java | 67 ++-- .../modify/DisguiseModifyRadiusCommand.java | 47 ++- .../undisguise/UndisguiseRadiusCommand.java | 18 +- .../disguisetypes/PlayerDisguise.java | 4 +- .../disguise/utilities/DisguiseUtilities.java | 20 +- .../utilities/config/ConfigLoader.java | 191 ++++++++++ .../config/DisguiseCommandConfig.java | 10 +- .../utilities/listeners/DisguiseListener.java | 8 +- .../disguise/utilities/metrics/Metrics.java | 1 + .../utilities/metrics/MetricsInitalizer.java | 6 +- .../utilities/reflection/ClassGetter.java | 60 +-- .../utilities/sounds/SoundManager.java | 23 +- .../utilities/translations/LibsMsg.java | 2 +- src/main/resources/config.yml | 352 ------------------ src/main/resources/configs/combat.yml | 29 ++ src/main/resources/configs/commands.yml | 54 +++ .../resources/{ => configs}/disguises.yml | 140 +++---- src/main/resources/configs/features.yml | 42 +++ src/main/resources/configs/libsdisguises.yml | 30 ++ src/main/resources/configs/nametags.yml | 49 +++ src/main/resources/configs/players.yml | 45 +++ src/main/resources/configs/protocol.yml | 74 ++++ src/main/resources/configs/sanity.yml | 41 ++ src/main/resources/{ => configs}/sounds.yml | 0 30 files changed, 841 insertions(+), 703 deletions(-) create mode 100644 src/main/java/me/libraryaddict/disguise/utilities/config/ConfigLoader.java delete mode 100644 src/main/resources/config.yml create mode 100644 src/main/resources/configs/combat.yml create mode 100644 src/main/resources/configs/commands.yml rename src/main/resources/{ => configs}/disguises.yml (98%) create mode 100644 src/main/resources/configs/features.yml create mode 100644 src/main/resources/configs/libsdisguises.yml create mode 100644 src/main/resources/configs/nametags.yml create mode 100644 src/main/resources/configs/players.yml create mode 100644 src/main/resources/configs/protocol.yml create mode 100644 src/main/resources/configs/sanity.yml rename src/main/resources/{ => configs}/sounds.yml (100%) diff --git a/pom.xml b/pom.xml index 8b1bcb79..ca28632c 100644 --- a/pom.xml +++ b/pom.xml @@ -17,6 +17,7 @@ true * + configs/* diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java b/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java index 48cfaa37..c8852328 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseAPI.java @@ -43,9 +43,10 @@ public class DisguiseAPI { DisguiseConfig.removeCustomDisguise(disguiseName); DisguiseConfig.addCustomDisguise(disguiseName, disguiseInfo); - File disguisesFile = new File("plugins/LibsDisguises/disguises.yml"); + File disguisesFile = new File(LibsDisguises.getInstance().getDataFolder(), "configs/disguises.yml"); if (!disguisesFile.exists()) { + disguisesFile.getParentFile().mkdirs(); disguisesFile.createNewFile(); } @@ -143,9 +144,8 @@ public class DisguiseAPI { } } for (Method method : entity.getClass().getMethods()) { - if ((doSneak || !method.getName().equals("setSneaking")) && - (doSprint || !method.getName().equals("setSprinting")) && method.getParameterTypes().length == 0 && - method.getReturnType() != void.class) { + if ((doSneak || !method.getName().equals("setSneaking")) && (doSprint || !method.getName().equals("setSprinting")) && + method.getParameterTypes().length == 0 && method.getReturnType() != void.class) { Class methodReturn = method.getReturnType(); if (methodReturn == float.class || methodReturn == Float.class || methodReturn == Double.class) { @@ -160,12 +160,11 @@ public class DisguiseAPI { watcherMethod.getParameterTypes().length == 1) { int firstCapitalWatcher = firstCapital(watcherMethod.getName()); - if (firstCapitalWatcher > 0 && method.getName().substring(firstCapitalMethod) - .equalsIgnoreCase(watcherMethod.getName().substring(firstCapitalWatcher))) { + if (firstCapitalWatcher > 0 && + method.getName().substring(firstCapitalMethod).equalsIgnoreCase(watcherMethod.getName().substring(firstCapitalWatcher))) { Class methodParam = watcherMethod.getParameterTypes()[0]; - if (methodParam == float.class || methodParam == Float.class || - methodParam == Double.class) { + if (methodParam == float.class || methodParam == Float.class || methodParam == Double.class) { methodParam = double.class; } else if (methodParam == AnimalColor.class) { methodParam = DyeColor.class; @@ -190,8 +189,7 @@ public class DisguiseAPI { value = AnimalColor.valueOf(((DyeColor) value).name()); } } - if (value instanceof Boolean && !(Boolean) value && - watcherMethod.getDeclaringClass() == FlagWatcher.class) { + if (value instanceof Boolean && !(Boolean) value && watcherMethod.getDeclaringClass() == FlagWatcher.class) { continue; } } diff --git a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java index 626c3b8f..afa954b2 100644 --- a/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java +++ b/src/main/java/me/libraryaddict/disguise/DisguiseConfig.java @@ -4,9 +4,9 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.Setter; import me.libraryaddict.disguise.disguisetypes.Disguise; -import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; import me.libraryaddict.disguise.utilities.DisguiseUtilities; import me.libraryaddict.disguise.utilities.LibsPremium; +import me.libraryaddict.disguise.utilities.config.ConfigLoader; import me.libraryaddict.disguise.utilities.modded.ModdedEntity; import me.libraryaddict.disguise.utilities.modded.ModdedManager; import me.libraryaddict.disguise.utilities.packets.PacketsManager; @@ -17,20 +17,15 @@ import me.libraryaddict.disguise.utilities.reflection.NmsVersion; import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; import me.libraryaddict.disguise.utilities.translations.LibsMsg; import me.libraryaddict.disguise.utilities.translations.TranslateType; -import org.apache.commons.lang.StringEscapeUtils; -import org.apache.commons.lang.StringUtils; import org.bukkit.Bukkit; import org.bukkit.ChatColor; -import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.boss.BarColor; import org.bukkit.boss.BarStyle; import org.bukkit.command.CommandSender; import org.bukkit.configuration.ConfigurationSection; -import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Entity; -import org.bukkit.inventory.ItemStack; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import org.bukkit.scheduler.BukkitTask; @@ -63,12 +58,6 @@ public class DisguiseConfig { @Getter @Setter private static boolean collectPacketsEnabled; - /** - * No setter provided as this cannot be changed after startup - */ - @Setter(value = AccessLevel.PRIVATE) - @Getter - private static boolean disableCommands; @Getter @Setter private static boolean disableFriendlyInvisibles; @@ -277,6 +266,12 @@ public class DisguiseConfig { @Getter @Setter private static String lastPluginUpdateVersion; + @Getter + @Setter + private static boolean contactMojangServers; + @Getter + @Setter(AccessLevel.PROTECTED) + private static int disguiseRadiusMax; public static boolean isArmorstandsName() { return getPlayerNameType() == PlayerNameType.ARMORSTANDS; @@ -322,22 +317,6 @@ public class DisguiseConfig { return; } - if (!LibsDisguises.getInstance().getConfig().getDefaults().getBoolean("AutoUpdate")) { - updaterTask = Bukkit.getScheduler().runTaskTimer(LibsDisguises.getInstance(), new Runnable() { - @Override - public void run() { - for (Set disguises : DisguiseUtilities.getDisguises().values()) { - for (Disguise disguise : disguises) { - disguise.getWatcher().setSprinting(true); - disguise.getWatcher().setHelmet(new ItemStack(Material.LEATHER_HELMET)); - } - } - } - }, TimeUnit.HOURS.toSeconds(1) * 20, (20 * TimeUnit.MINUTES.toSeconds(10))); - - return; - } - if (updaterTask == null != startTask) { return; } @@ -560,75 +539,9 @@ public class DisguiseConfig { TranslateType.refreshTranslations(); } - public static void saveDefaultConfig() { - DisguiseUtilities.getLogger().info("Config is out of date! Now updating it!"); - String[] string = ReflectionManager.getResourceAsString(LibsDisguises.getInstance().getFile(), "config.yml").split("\n"); - FileConfiguration savedConfig = LibsDisguises.getInstance().getConfig(); - - StringBuilder section = new StringBuilder(); - - for (int i = 0; i < string.length; i++) { - String s = string[i]; - - if (s.trim().startsWith("#") || !s.contains(":")) { - continue; - } - - String rawKey = s.split(":")[0]; - - if (section.length() > 0) { - int matches = StringUtils.countMatches(rawKey, " "); - - int allowed = 0; - - for (int a = 0; a < matches; a++) { - allowed = section.indexOf(".", allowed) + 1; - } - - section = new StringBuilder(section.substring(0, allowed)); - } - - String key = (rawKey.startsWith(" ") ? section.toString() : "") + rawKey.trim(); - - if (savedConfig.isConfigurationSection(key)) { - section.append(key).append("."); - } else if (savedConfig.isSet(key)) { - String rawVal = s.split(":")[1].trim(); - Object val = savedConfig.get(key); - - if (savedConfig.isString(key) && !rawVal.equals("true") && !rawVal.equals("false")) { - val = "'" + StringEscapeUtils.escapeJava(val.toString().replace(ChatColor.COLOR_CHAR + "", "&")) + "'"; - } - - string[i] = rawKey + ": " + val; - } - } - - File config = new File(LibsDisguises.getInstance().getDataFolder(), "config.yml"); - - try { - if (config.exists()) { - config.renameTo(new File(config.getParentFile(), "config-old.yml")); - - DisguiseUtilities.getLogger().info("Old config has been copied to config-old.yml"); - } - - config.createNewFile(); - - try (PrintWriter out = new PrintWriter(config)) { - out.write(StringUtils.join(string, "\n")); - } - } catch (IOException e) { - e.printStackTrace(); - } - } - public static void loadConfig() { - // Always save the default config - LibsDisguises.getInstance().saveDefaultConfig(); - // Redundant for the first load, however other plugins may call loadConfig() at a later stage where we - // definitely want to reload it. - LibsDisguises.getInstance().reloadConfig(); + ConfigLoader configLoader = new ConfigLoader(); + configLoader.saveMissingConfigs(); loadModdedDisguiseTypes(); @@ -650,10 +563,9 @@ public class DisguiseConfig { } } - ConfigurationSection config = LibsDisguises.getInstance().getConfig(); + ConfigurationSection config = configLoader.load(); PacketsManager.setViewDisguisesListener(true); - disableCommands = config.getBoolean("DisableCommands"); setAddEntityAnimations(config.getBoolean("AddEntityAnimations")); setAnimationPacketsEnabled(config.getBoolean("PacketsEnabled.Animation")); @@ -719,6 +631,8 @@ public class DisguiseConfig { setSaveUserPreferences(config.getBoolean("SaveUserPreferences")); setPlayerDisguisesSkinExpiresMove(config.getInt("PlayerDisguisesTablistExpiresMove")); setViewSelfDisguisesDefault(config.getBoolean("ViewSelfDisguisesDefault")); + setContactMojangServers(config.getBoolean("ContactMojangServers")); + setDisguiseRadiusMax(config.getInt("DisguiseRadiusMax")); if (!LibsPremium.isPremium() && (isSavePlayerDisguises() || isSaveEntityDisguises())) { DisguiseUtilities.getLogger().warning("You must purchase the plugin to use saved disguises!"); @@ -826,19 +740,11 @@ public class DisguiseConfig { } } - int missingConfigs = 0; - - for (String key : config.getDefaultSection().getKeys(true)) { - if (config.contains(key, true)) { - continue; - } - - missingConfigs++; - } + int missingConfigs = doOutput(config, false, true).size(); if (missingConfigs > 0) { if (config.getBoolean("UpdateConfig", true)) { - saveDefaultConfig(); + configLoader.saveDefaultConfigs(); DisguiseUtilities.getLogger().info("Config has been auto-updated!"); } else if (!verbose) { DisguiseUtilities.getLogger().warning("Your config is missing " + missingConfigs + " options! Please consider regenerating your config!"); @@ -850,7 +756,7 @@ public class DisguiseConfig { } public static void loadModdedDisguiseTypes() { - File disguisesFile = new File("plugins/LibsDisguises/disguises.yml"); + File disguisesFile = new File(LibsDisguises.getInstance().getDataFolder(), "configs/disguises.yml"); if (!disguisesFile.exists()) { return; @@ -929,9 +835,18 @@ public class DisguiseConfig { new ModdedManager(channels); } + public static ArrayList doOutput(boolean informChangedUnknown, boolean informMissing) { + return doOutput(new ConfigLoader().load(), informChangedUnknown, informMissing); + } + public static ArrayList doOutput(ConfigurationSection config, boolean informChangedUnknown, boolean informMissing) { HashMap configs = new HashMap<>(); ConfigurationSection defaultSection = config.getDefaultSection(); + + if (defaultSection == null) { + defaultSection = new ConfigLoader().loadDefaults(); + } + ArrayList returns = new ArrayList<>(); for (String key : defaultSection.getKeys(true)) { @@ -975,7 +890,7 @@ public class DisguiseConfig { static void loadCustomDisguises() { customDisguises.clear(); - File disguisesFile = new File("plugins/LibsDisguises/disguises.yml"); + File disguisesFile = new File(LibsDisguises.getInstance().getDataFolder(), "configs/disguises.yml"); if (!disguisesFile.exists()) { return; diff --git a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java index c9b74fa7..fce5b5d6 100644 --- a/src/main/java/me/libraryaddict/disguise/LibsDisguises.java +++ b/src/main/java/me/libraryaddict/disguise/LibsDisguises.java @@ -82,7 +82,7 @@ public class LibsDisguises extends JavaPlugin { Bukkit.getPluginManager().enablePlugin(plugin); } else { - getLogger().severe("Please restar the server to complete the ProtocolLib update!"); + getLogger().severe("Please restart the server to complete the ProtocolLib update!"); } } catch (Exception e) { e.printStackTrace(); @@ -119,8 +119,18 @@ public class LibsDisguises extends JavaPlugin { "plugin will continue to load, but it will look like a mugging victim"); } - if (!new File(getDataFolder(), "disguises.yml").exists()) { - saveResource("disguises.yml", false); + File disguiseFile = new File(getDataFolder(), "configs/disguises.yml"); + + if (!disguiseFile.exists()) { + disguiseFile.getParentFile().mkdirs(); + + File oldFile = new File(getDataFolder(), "disguises.yml"); + + if (oldFile.exists()) { + oldFile.renameTo(disguiseFile); + } else { + saveResource("configs/disguises.yml", false); + } } YamlConfiguration pluginYml = ReflectionManager.getPluginYAML(getFile()); @@ -209,31 +219,26 @@ public class LibsDisguises extends JavaPlugin { } registerCommand("libsdisguises", new LibsDisguisesCommand()); - - if (!DisguiseConfig.isDisableCommands()) { - registerCommand("disguise", new DisguiseCommand()); - registerCommand("undisguise", new UndisguiseCommand()); - registerCommand("disguiseplayer", new DisguisePlayerCommand()); - registerCommand("undisguiseplayer", new UndisguisePlayerCommand()); - registerCommand("undisguiseentity", new UndisguiseEntityCommand()); - registerCommand("disguiseentity", new DisguiseEntityCommand()); - registerCommand("disguiseradius", new DisguiseRadiusCommand(getConfig().getInt("DisguiseRadiusMax"))); - registerCommand("undisguiseradius", new UndisguiseRadiusCommand(getConfig().getInt("UndisguiseRadiusMax"))); - 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()); - registerCommand("disguisemodifyradius", new DisguiseModifyRadiusCommand(getConfig().getInt("DisguiseRadiusMax"))); - registerCommand("copydisguise", new CopyDisguiseCommand()); - registerCommand("grabskin", new GrabSkinCommand()); - registerCommand("savedisguise", new SaveDisguiseCommand()); - registerCommand("grabhead", new GrabHeadCommand()); - } else { - getLogger().info("Commands has been disabled, as per config"); - } + registerCommand("disguise", new DisguiseCommand()); + registerCommand("undisguise", new UndisguiseCommand()); + registerCommand("disguiseplayer", new DisguisePlayerCommand()); + registerCommand("undisguiseplayer", new UndisguisePlayerCommand()); + registerCommand("undisguiseentity", new UndisguiseEntityCommand()); + registerCommand("disguiseentity", new DisguiseEntityCommand()); + registerCommand("disguiseradius", new DisguiseRadiusCommand()); + registerCommand("undisguiseradius", new UndisguiseRadiusCommand()); + 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()); + registerCommand("disguisemodifyradius", new DisguiseModifyRadiusCommand()); + registerCommand("copydisguise", new CopyDisguiseCommand()); + registerCommand("grabskin", new GrabSkinCommand()); + registerCommand("savedisguise", new SaveDisguiseCommand()); + registerCommand("grabhead", new GrabHeadCommand()); unregisterCommands(false); diff --git a/src/main/java/me/libraryaddict/disguise/commands/disguise/DisguiseRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/disguise/DisguiseRadiusCommand.java index 54e99a16..bea36859 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/disguise/DisguiseRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/disguise/DisguiseRadiusCommand.java @@ -29,12 +29,9 @@ import java.util.List; import java.util.Locale; public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCompleter { - private int maxRadius = 30; private ArrayList> validClasses = new ArrayList<>(); - public DisguiseRadiusCommand(int maxRadius) { - this.maxRadius = maxRadius; - + public DisguiseRadiusCommand() { for (EntityType type : EntityType.values()) { Class c = type.getEntityClass(); @@ -131,9 +128,9 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom int radius = Integer.parseInt(args[starting]); - if (radius > maxRadius) { - LibsMsg.LIMITED_RADIUS.send(sender, maxRadius); - radius = maxRadius; + if (radius > DisguiseConfig.getDisguiseRadiusMax()) { + LibsMsg.LIMITED_RADIUS.send(sender, DisguiseConfig.getDisguiseRadiusMax()); + radius = DisguiseConfig.getDisguiseRadiusMax(); } String[] newArgs = new String[args.length - (starting + 1)]; @@ -291,7 +288,7 @@ public class DisguiseRadiusCommand extends DisguiseBaseCommand implements TabCom return; } - LibsMsg.DRADIUS_HELP1.send(sender, maxRadius); + LibsMsg.DRADIUS_HELP1.send(sender, DisguiseConfig.getDisguiseRadiusMax()); LibsMsg.CAN_USE_DISGS.send(sender, StringUtils.join(allowedDisguises, LibsMsg.CAN_USE_DISGS_SEPERATOR.get())); if (allowedDisguises.contains("player")) { diff --git a/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDConfig.java b/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDConfig.java index b2d8e805..bdd34adc 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDConfig.java +++ b/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDConfig.java @@ -1,7 +1,6 @@ package me.libraryaddict.disguise.commands.libsdisguises; import me.libraryaddict.disguise.DisguiseConfig; -import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; @@ -31,7 +30,7 @@ public class LDConfig implements LDCommand { @Override public void onCommand(CommandSender sender, String[] args) { - ArrayList returns = DisguiseConfig.doOutput(LibsDisguises.getInstance().getConfig(), true, true); + ArrayList returns = DisguiseConfig.doOutput(true, true); if (returns.isEmpty()) { LibsMsg.USING_DEFAULT_CONFIG.send(sender); diff --git a/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDUploadLogs.java b/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDUploadLogs.java index 1f7565c6..ec8ff2c1 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDUploadLogs.java +++ b/src/main/java/me/libraryaddict/disguise/commands/libsdisguises/LDUploadLogs.java @@ -3,6 +3,7 @@ package me.libraryaddict.disguise.commands.libsdisguises; import lombok.Data; import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.utilities.config.ConfigLoader; import me.libraryaddict.disguise.utilities.translations.LibsMsg; import net.md_5.bungee.api.chat.ClickEvent; import net.md_5.bungee.api.chat.ComponentBuilder; @@ -22,6 +23,7 @@ import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; /** * Created by libraryaddict on 18/06/2020. @@ -120,35 +122,42 @@ public class LDUploadLogs implements LDCommand { @Override public void onCommand(CommandSender sender, String[] args) { if (lastUsed + TimeUnit.MINUTES.toMillis(3) > System.currentTimeMillis()) { - sender.sendMessage(ChatColor.RED + - "You last used this command under 3 minutes ago! Restart the server or wait for this timer to " + - "disappear!"); + sender.sendMessage(ChatColor.RED + "You last used this command under 3 minutes ago! Restart the server or wait for this timer to " + "disappear!"); return; } File latest = new File("logs/latest.log"); - File disguises = new File(LibsDisguises.getInstance().getDataFolder(), "disguises.yml"); - File config = new File(LibsDisguises.getInstance().getDataFolder(), "config.yml"); + File disguises = new File(LibsDisguises.getInstance().getDataFolder(), "configs/disguises.yml"); + + List configs = + new ConfigLoader().getConfigs().stream().map(f -> new File(LibsDisguises.getInstance().getDataFolder(), f)).collect(Collectors.toList()); + + StringBuilder configText = new StringBuilder(); + + for (File config : configs) { + if (configText.length() != 0) { + configText.append("\n\n================\n\n"); + } + + try { + configText.append(new String(Files.readAllBytes(config.toPath()))); + } catch (IOException e) { + e.printStackTrace(); + } + } if (isTooBig(latest)) { - sender.sendMessage(ChatColor.RED + - "Your latest.log file is too big! It should be less than 512kb! Please restart and run this " + - "command again!"); + sender.sendMessage( + ChatColor.RED + "Your latest.log file is too big! It should be less than 512kb! Please restart and run this " + "command again!"); return; } if (isTooBig(disguises)) { - sender.sendMessage(ChatColor.RED + - "Your disguises.yml is too big! You'll need to trim that file down before using this command! It " + + sender.sendMessage(ChatColor.RED + "Your disguises.yml is too big! You'll need to trim that file down before using this command! It " + "should be less than 512kb!"); return; } - if (isTooBig(config)) { - sender.sendMessage(ChatColor.RED + "Your config.yml is too big! It should be less than 512kb!"); - return; - } - try { String latestText = new String(Files.readAllBytes(latest.toPath())); @@ -166,8 +175,7 @@ public class LDUploadLogs implements LDCommand { lastFind = nextLine + 2; - if (!str.contains("Starting minecraft server version") && !str.contains("Loading properties") && - !str.contains("This server is running")) { + if (!str.contains("Starting minecraft server version") && !str.contains("Loading properties") && !str.contains("This server is running")) { continue; } @@ -176,8 +184,7 @@ public class LDUploadLogs implements LDCommand { } if (!valid) { - sender.sendMessage( - ChatColor.RED + "Your latest.log is too old! Please restart the server and try again!"); + sender.sendMessage(ChatColor.RED + "Your latest.log is too old! Please restart the server and try again!"); return; } @@ -188,12 +195,10 @@ public class LDUploadLogs implements LDCommand { public void run() { try { String disguiseText = new String(Files.readAllBytes(disguises.toPath())); - StringBuilder configText = new StringBuilder(new String(Files.readAllBytes(config.toPath()))); - configText.append("\n================\n"); + configText.append("\n\n================\n"); - ArrayList modified = - DisguiseConfig.doOutput(LibsDisguises.getInstance().getConfig(), true, true); + ArrayList modified = DisguiseConfig.doOutput(true, true); for (String s : modified) { configText.append("\n").append(s); @@ -203,8 +208,10 @@ public class LDUploadLogs implements LDCommand { configText.append("\nUsing default config!"); } + String ctext = configText.toString().replaceAll("\n? *#[^\n]*", ""); + URL latestPaste = new GuestPaste("latest.log", latestText).paste(); - URL configPaste = new GuestPaste("LibsDisguises config.yml", configText.toString()).paste(); + URL configPaste = new GuestPaste("LibsDisguises config.yml", ctext).paste(); URL disguisesPaste = new GuestPaste("LibsDisguises disguises.yml", disguiseText).paste(); lastUsed = System.currentTimeMillis(); @@ -216,12 +223,10 @@ public class LDUploadLogs implements LDCommand { // Console can't click :( if (sender instanceof Player) { - sender.sendMessage(ChatColor.GOLD + - "Click on the below message to have it appear in your chat input"); + sender.sendMessage(ChatColor.GOLD + "Click on the below message to have it appear in your chat input"); } - String text = "My log file: " + latestPaste + ", my config file: " + configPaste + - " and my disguises file: " + disguisesPaste; + String text = "My log file: " + latestPaste + ", my config file: " + configPaste + " and my disguises file: " + disguisesPaste; ComponentBuilder builder = new ComponentBuilder(""); builder.append(text); @@ -243,7 +248,11 @@ public class LDUploadLogs implements LDCommand { } private boolean isTooBig(File file) { - return file.exists() && file.length() >= 512 * 1024; + return file.exists() && isTooBig(file.length()); + } + + private boolean isTooBig(long length) { + return length >= 512 * 1024; } @Override diff --git a/src/main/java/me/libraryaddict/disguise/commands/modify/DisguiseModifyRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/modify/DisguiseModifyRadiusCommand.java index 853c7c1b..22bad4df 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/modify/DisguiseModifyRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/modify/DisguiseModifyRadiusCommand.java @@ -1,6 +1,7 @@ package me.libraryaddict.disguise.commands.modify; import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.commands.DisguiseBaseCommand; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; @@ -26,12 +27,6 @@ import java.lang.reflect.Method; import java.util.*; public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements TabCompleter { - private int maxRadius = 30; - - public DisguiseModifyRadiusCommand(int maxRadius) { - this.maxRadius = maxRadius; - } - private Collection getNearbyEntities(CommandSender sender, int radius) { Location center; @@ -77,8 +72,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements Collections.sort(classes); - LibsMsg.DMODRADIUS_USABLE.send(sender, - ChatColor.GREEN + StringUtils.join(classes, ChatColor.DARK_GREEN + ", " + ChatColor.GREEN)); + LibsMsg.DMODRADIUS_USABLE.send(sender, ChatColor.GREEN + StringUtils.join(classes, ChatColor.DARK_GREEN + ", " + ChatColor.GREEN)); return true; } @@ -124,9 +118,9 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements int radius = Integer.parseInt(args[starting]); - if (radius > maxRadius) { - LibsMsg.LIMITED_RADIUS.send(sender, maxRadius); - radius = maxRadius; + if (radius > DisguiseConfig.getDisguiseRadiusMax()) { + LibsMsg.LIMITED_RADIUS.send(sender, DisguiseConfig.getDisguiseRadiusMax()); + radius = DisguiseConfig.getDisguiseRadiusMax(); } String[] newArgs = new String[args.length - (starting + 1)]; @@ -154,10 +148,11 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements Disguise disguise; - if (sender instanceof Player) + if (sender instanceof Player) { disguise = DisguiseAPI.getDisguise((Player) sender, entity); - else + } else { disguise = DisguiseAPI.getDisguise(entity); + } if (disguise == null) { continue; @@ -174,18 +169,15 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements tempArgs = DisguiseParser.parsePlaceholders(tempArgs, sender, entity); try { - DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(), tempArgs, - "DisguiseModifyRadius"); + DisguiseParser.callMethods(sender, disguise, permissions, disguisePerm, new ArrayList<>(), tempArgs, "DisguiseModifyRadius"); modifiedDisguises++; - } - catch (DisguiseParseException ex) { + } catch (DisguiseParseException ex) { if (ex.getMessage() != null) { DisguiseUtilities.sendMessage(sender, ex.getMessage()); } return true; - } - catch (Exception ex) { + } catch (Exception ex) { ex.printStackTrace(); return true; } @@ -238,8 +230,9 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements } // Not a valid radius - if (starting == 1 || args.length == 1 || !isInteger(args[1])) + if (starting == 1 || args.length == 1 || !isInteger(args[1])) { return filterTabs(tabs, origArgs); + } } if (args.length <= starting || !isInteger(args[starting])) { @@ -248,9 +241,9 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements int radius = Integer.parseInt(args[starting]); - if (radius > maxRadius) { - LibsMsg.LIMITED_RADIUS.send(sender, maxRadius); - radius = maxRadius; + if (radius > DisguiseConfig.getDisguiseRadiusMax()) { + LibsMsg.LIMITED_RADIUS.send(sender, DisguiseConfig.getDisguiseRadiusMax()); + radius = DisguiseConfig.getDisguiseRadiusMax(); } starting++; @@ -260,15 +253,17 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements for (Entity entity : getNearbyEntities(sender, radius)) { Disguise disguise = DisguiseAPI.getDisguise(entity); - if (disguise == null) + if (disguise == null) { continue; + } DisguiseType disguiseType = disguise.getType(); for (Method method : ParamInfoManager.getDisguiseWatcherMethods(disguiseType.getWatcherClass())) { for (String arg : args) { - if (!method.getName().equalsIgnoreCase(arg) || usedOptions.contains(arg)) + if (!method.getName().equalsIgnoreCase(arg) || usedOptions.contains(arg)) { continue; + } usedOptions.add(arg); } @@ -291,7 +286,7 @@ public class DisguiseModifyRadiusCommand extends DisguiseBaseCommand implements protected void sendCommandUsage(CommandSender sender, DisguisePermissions permissions) { ArrayList allowedDisguises = getAllowedDisguises(permissions); - LibsMsg.DMODRADIUS_HELP1.send(sender, maxRadius); + LibsMsg.DMODRADIUS_HELP1.send(sender, DisguiseConfig.getDisguiseRadiusMax()); LibsMsg.DMODIFY_HELP3.send(sender, StringUtils.join(allowedDisguises, LibsMsg.CAN_USE_DISGS_SEPERATOR.get())); LibsMsg.DMODRADIUS_HELP2.send(sender); diff --git a/src/main/java/me/libraryaddict/disguise/commands/undisguise/UndisguiseRadiusCommand.java b/src/main/java/me/libraryaddict/disguise/commands/undisguise/UndisguiseRadiusCommand.java index 5e752bca..ffe3fe15 100644 --- a/src/main/java/me/libraryaddict/disguise/commands/undisguise/UndisguiseRadiusCommand.java +++ b/src/main/java/me/libraryaddict/disguise/commands/undisguise/UndisguiseRadiusCommand.java @@ -1,6 +1,7 @@ package me.libraryaddict.disguise.commands.undisguise; import me.libraryaddict.disguise.DisguiseAPI; +import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.utilities.LibsPremium; import me.libraryaddict.disguise.utilities.translations.LibsMsg; import org.bukkit.ChatColor; @@ -13,12 +14,6 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Player; public class UndisguiseRadiusCommand implements CommandExecutor { - private int maxRadius = 30; - - public UndisguiseRadiusCommand(int maxRadius) { - this.maxRadius = maxRadius; - } - private boolean isNumeric(String string) { try { Integer.parseInt(string); @@ -43,16 +38,19 @@ public class UndisguiseRadiusCommand implements CommandExecutor { } if (sender.hasPermission("libsdisguises.undisguiseradius")) { - int radius = maxRadius; + int radius = DisguiseConfig.getDisguiseRadiusMax(); + if (args.length > 0) { if (!isNumeric(args[0])) { LibsMsg.NOT_NUMBER.send(sender, args[0]); return true; } + radius = Integer.parseInt(args[0]); - if (radius > maxRadius) { - LibsMsg.LIMITED_RADIUS.send(sender, maxRadius); - radius = maxRadius; + + if (radius > DisguiseConfig.getDisguiseRadiusMax()) { + LibsMsg.LIMITED_RADIUS.send(sender, DisguiseConfig.getDisguiseRadiusMax()); + radius = DisguiseConfig.getDisguiseRadiusMax(); } } diff --git a/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java b/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java index 20218edc..796c905e 100644 --- a/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java +++ b/src/main/java/me/libraryaddict/disguise/disguisetypes/PlayerDisguise.java @@ -469,7 +469,7 @@ public class PlayerDisguise extends TargetedDisguise { }; WrappedGameProfile gameProfile = DisguiseUtilities - .getProfileFromMojang(this.skinToUse, currentLookup, LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); + .getProfileFromMojang(this.skinToUse, currentLookup, DisguiseConfig.isContactMojangServers()); if (gameProfile != null) { setSkin(gameProfile); @@ -635,7 +635,7 @@ public class PlayerDisguise extends TargetedDisguise { }; WrappedGameProfile gameProfile = DisguiseUtilities - .getProfileFromMojang(this.skinToUse, currentLookup, LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); + .getProfileFromMojang(this.skinToUse, currentLookup, DisguiseConfig.isContactMojangServers()); if (gameProfile != null) { setSkin(gameProfile); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 6a08a929..25d3fcd8 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -161,7 +161,7 @@ public class DisguiseUtilities { 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 profileCache = new File("plugins/LibsDisguises/SavedSkins"); private static final File savedDisguises = new File("plugins/LibsDisguises/SavedDisguises"); @Getter private static Gson gson; @@ -1124,7 +1124,7 @@ public class DisguiseUtilities { DisguiseUtilities.refreshTrackers(disguise); } - }, LibsDisguises.getInstance().getConfig().getBoolean("ContactMojangServers", true)); + }, DisguiseConfig.isContactMojangServers()); } /** @@ -1271,7 +1271,13 @@ public class DisguiseUtilities { gson = gsonBuilder.create(); if (!profileCache.exists()) { - profileCache.mkdirs(); + File old = new File(profileCache.getParentFile(), "GameProfiles"); + + if (old.exists() && old.isDirectory()) { + old.renameTo(profileCache); + } else { + profileCache.mkdirs(); + } } if (!savedDisguises.exists()) { @@ -1331,13 +1337,7 @@ public class DisguiseUtilities { Method m = CompileMethods.class.getMethod("main", String[].class); if ((!m.isAnnotationPresent(CompileMethods.CompileMethodsIntfer.class) || - m.getAnnotation(CompileMethods.CompileMethodsIntfer.class).user().matches("[0-9]+")) && - !DisguiseConfig.doOutput(LibsDisguises.getInstance().getConfig(), true, false).isEmpty()) { - /*File f = new File(LibsDisguises.getInstance().getDataFolder(), "config.yml"); - File f2 = new File(f.getParentFile(), "config-older.yml"); - f2.delete(); - f.renameTo(f2); - LibsDisguises.getInstance().saveDefaultConfig();*/ + m.getAnnotation(CompileMethods.CompileMethodsIntfer.class).user().matches("[0-9]+")) && !DisguiseConfig.doOutput(true, false).isEmpty()) { DisguiseConfig.setViewDisguises(false); } } catch (NoSuchMethodException e) { diff --git a/src/main/java/me/libraryaddict/disguise/utilities/config/ConfigLoader.java b/src/main/java/me/libraryaddict/disguise/utilities/config/ConfigLoader.java new file mode 100644 index 00000000..9bac4d04 --- /dev/null +++ b/src/main/java/me/libraryaddict/disguise/utilities/config/ConfigLoader.java @@ -0,0 +1,191 @@ +package me.libraryaddict.disguise.utilities.config; + +import lombok.Getter; +import me.libraryaddict.disguise.LibsDisguises; +import me.libraryaddict.disguise.utilities.DisguiseUtilities; +import me.libraryaddict.disguise.utilities.reflection.ClassGetter; +import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; +import org.apache.commons.lang.StringEscapeUtils; +import org.apache.commons.lang.StringUtils; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.List; + +/** + * Created by libraryaddict on 31/01/2021. + */ +public class ConfigLoader { + @Getter + private final List configs = new ArrayList<>(); + + public ConfigLoader() { + for (String s : ClassGetter.getEntriesForPackage(ConfigLoader.class, "configs")) { + if (!s.endsWith(".yml")) { + continue; + } + + if (s.endsWith("/disguises.yml") || s.endsWith("/sounds.yml")) { + continue; + } + + configs.add(s); + } + } + + public void saveMissingConfigs() { + File oldFile = new File(LibsDisguises.getInstance().getDataFolder(), "config.yml"); + boolean migrated = oldFile.exists(); + + for (String config : configs) { + File f = new File(LibsDisguises.getInstance().getDataFolder(), config); + + if (f.exists()) { + migrated = false; + continue; + } + + saveDefaultConfig(config); + } + + if (migrated) { + DisguiseUtilities.getLogger().info("Migrated old config system to new config system"); + oldFile.delete(); + } + } + + public YamlConfiguration loadDefaults() { + YamlConfiguration globalConfig = new YamlConfiguration(); + + for (String config : configs) { + try { + YamlConfiguration c = new YamlConfiguration(); + c.loadFromString(ReflectionManager.getResourceAsString(LibsDisguises.getInstance().getFile(), config)); + + for (String k : c.getKeys(true)) { + if (c.isConfigurationSection(k)) { + continue; + } + + globalConfig.set(k, c.get(k)); + } + } catch (Exception ex) { + ex.printStackTrace(); + } + } + + return globalConfig; + } + + public YamlConfiguration load() { + YamlConfiguration globalConfig = new YamlConfiguration(); + + for (String config : configs) { + YamlConfiguration c = YamlConfiguration.loadConfiguration(new File(LibsDisguises.getInstance().getDataFolder(), config)); + + for (String k : c.getKeys(true)) { + if (c.isConfigurationSection(k)) { + continue; + } + + globalConfig.set(k, c.get(k)); + } + } + + return globalConfig; + } + + public void saveDefaultConfigs() { + for (String config : configs) { + saveDefaultConfig(config); + } + + File f = new File(LibsDisguises.getInstance().getDataFolder(), "config.yml"); + + f.delete(); + } + + public void saveDefaultConfig(String name) { + DisguiseUtilities.getLogger().info("Config " + name + " is out of date (Or missing)! Now refreshing it!"); + String ourConfig = ReflectionManager.getResourceAsString(LibsDisguises.getInstance().getFile(), name); + YamlConfiguration savedConfig = null; + + File loadFrom = new File(LibsDisguises.getInstance().getDataFolder(), name); + File configFile = loadFrom; + + if (!loadFrom.exists()) { + loadFrom = new File(LibsDisguises.getInstance().getDataFolder(), "config.yml"); + } + + if (loadFrom.exists()) { + savedConfig = YamlConfiguration.loadConfiguration(loadFrom); + } else { + try { + savedConfig = new YamlConfiguration(); + savedConfig.loadFromString(ourConfig); + } catch (Exception e) { + e.printStackTrace(); + } + } + + String[] string = ourConfig.split("\n"); + + StringBuilder section = new StringBuilder(); + + for (int i = 0; i < string.length; i++) { + String s = string[i]; + + if (s.trim().startsWith("#") || !s.contains(":")) { + continue; + } + + String rawKey = s.split(":")[0]; + + if (section.length() > 0) { + int matches = StringUtils.countMatches(rawKey, " "); + + int allowed = 0; + + for (int a = 0; a < matches; a++) { + allowed = section.indexOf(".", allowed) + 1; + } + + section = new StringBuilder(section.substring(0, allowed)); + } + + String key = (rawKey.startsWith(" ") ? section.toString() : "") + rawKey.trim(); + + if (savedConfig.isConfigurationSection(key)) { + section.append(key).append("."); + } else if (savedConfig.isSet(key)) { + String rawVal = s.split(":")[1].trim(); + Object val = savedConfig.get(key); + + if (savedConfig.isString(key) && !rawVal.equals("true") && !rawVal.equals("false")) { + val = "'" + StringEscapeUtils.escapeJava(val.toString().replace(ChatColor.COLOR_CHAR + "", "&")) + "'"; + } + + string[i] = rawKey + ": " + val; + } + } + + try { + if (!configFile.getParentFile().exists()) { + configFile.mkdirs(); + } + + configFile.delete(); + configFile.createNewFile(); + + try (PrintWriter out = new PrintWriter(configFile)) { + out.write(StringUtils.join(string, "\n")); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/me/libraryaddict/disguise/utilities/config/DisguiseCommandConfig.java b/src/main/java/me/libraryaddict/disguise/utilities/config/DisguiseCommandConfig.java index ff2a062b..7bc88091 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/config/DisguiseCommandConfig.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/config/DisguiseCommandConfig.java @@ -27,7 +27,7 @@ public class DisguiseCommandConfig { private boolean enabled; } - private File commandConfig = new File(LibsDisguises.getInstance().getDataFolder(), "commands.yml"); + private File commandConfig = new File(LibsDisguises.getInstance().getDataFolder(), "configs/plugin-commands.yml"); private HashMap commands = new HashMap<>(); private boolean modifyCommands = false; @@ -87,13 +87,19 @@ public class DisguiseCommandConfig { section.set("aliases", command.getAliases()); } + String configString = config.saveToString(); + + configString = configString.replaceAll("\n([a-zA-Z])", "\n\n$1"); + String s = "# The following can be changed to modify how the disguise commands are registered\n# This will only work on server startup\nModifyCommands: " + - modifyCommands + "\n\n" + config.saveToString(); + modifyCommands + "\n\n" + configString; commandConfig.delete(); try { + commandConfig.getParentFile().mkdirs(); + commandConfig.createNewFile(); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/me/libraryaddict/disguise/utilities/listeners/DisguiseListener.java b/src/main/java/me/libraryaddict/disguise/utilities/listeners/DisguiseListener.java index 7abbe8dd..0915091f 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/listeners/DisguiseListener.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/listeners/DisguiseListener.java @@ -95,18 +95,14 @@ public class DisguiseListener implements Listener { // If build number is null, or not a number. Then we can't check snapshots regardless return !plugin.isNumberedBuild(); - - // Check snapshots } private void runUpdateScheduler() { - boolean autoUpdate = plugin.getConfig().getBoolean("AutoUpdateDev"); - - if (!plugin.getConfig().getBoolean("NotifyUpdate")) { + if (!DisguiseConfig.isNotifyUpdate()) { return; } - if (autoUpdate && !isCheckReleases()) { + if (DisguiseConfig.isAutoUpdate() && !isCheckReleases()) { DisguiseUtilities.getLogger().info("Plugin will attempt to auto update when new builds are ready! Check config to disable."); } } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java b/src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java index f17e7d5a..d403919e 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/metrics/Metrics.java @@ -95,6 +95,7 @@ public class Metrics { "Check out https://bStats.org/ to learn more :)").copyDefaults(true); try { config.save(configFile); + DisguiseUtilities.getLogger().info("Saved bStats config"); } catch (IOException ignored) { } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java b/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java index efbe00bb..f9db36ed 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/metrics/MetricsInitalizer.java @@ -221,12 +221,12 @@ public class MetricsInitalizer { } }); - metrics.addCustomChart(new Metrics.SimplePie("commands") { + /*metrics.addCustomChart(new Metrics.SimplePie("commands") { @Override public String getValue() { return DisguiseConfig.isDisableCommands() ? "Enabled" : "Disabled"; } - }); + });*/ metrics.addCustomChart(new Metrics.SimplePie("spigot") { @Override @@ -241,7 +241,7 @@ public class MetricsInitalizer { } }); - final boolean updates = plugin.getConfig().getBoolean("NotifyUpdate"); + final boolean updates = DisguiseConfig.isNotifyUpdate(); metrics.addCustomChart(new Metrics.SimplePie("updates") { @Override diff --git a/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java b/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java index 20a25e00..010d0893 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/reflection/ClassGetter.java @@ -22,8 +22,31 @@ public class ClassGetter { return getClassesForPackage(Entity.class, pkgname); } + public static ArrayList getEntriesForPackage(String pkgname) { + return getEntriesForPackage(Entity.class, pkgname); + } + public static ArrayList> getClassesForPackage(Class runFrom, String pkgname) { - ArrayList> classes = new ArrayList<>(); + ArrayList list = getEntriesForPackage(runFrom, pkgname); + ArrayList> classList = new ArrayList<>(); + + for (String s : list) { + if (!s.endsWith(".class")) { + continue; + } + + Class c = loadClass(s.replace(".class", "").replace('/', '.')); + + if (c != null) { + classList.add(c); + } + } + + return classList; + } + + public static ArrayList getEntriesForPackage(Class runFrom, String pkgname) { + ArrayList classes = new ArrayList<>(); // String relPath = pkgname.replace('.', '/'); // Get a File object for the package @@ -36,16 +59,11 @@ public class ClassGetter { processJarfile(resource, pkgname, classes); } else { for (File f : new File(resource.getPath() + "/" + pkgname.replace(".", "/")).listFiles()) { - if (!f.getName().endsWith(".class") || f.getName().contains("$")) { + if (f.getName().contains("$")) { continue; } - try { - classes.add(Class.forName(pkgname + "." + f.getName().replace(".class", ""))); - } - catch (ClassNotFoundException e) { - e.printStackTrace(); - } + classes.add(pkgname + "/" + f.getName()); } } } @@ -56,16 +74,12 @@ public class ClassGetter { private static Class loadClass(String className) { try { return Class.forName(className); - } - catch (ClassNotFoundException e) { - throw new RuntimeException("Unexpected ClassNotFoundException loading class '" + className + "'"); - } - catch (NoClassDefFoundError e) { + } catch (ClassNotFoundException | NoClassDefFoundError e) { return null; } } - private static void processJarfile(URL resource, String pkgname, ArrayList> classes) { + private static void processJarfile(URL resource, String pkgname, ArrayList classes) { try { String relPath = pkgname.replace('.', '/'); String resPath = URLDecoder.decode(resource.getPath(), "UTF-8"); @@ -79,22 +93,18 @@ public class ClassGetter { JarEntry entry = entries.nextElement(); String entryName = entry.getName(); String className = null; - if (entryName.endsWith(".class") && entryName.startsWith(relPath) && - entryName.length() > (relPath.length() + "/".length())) { - className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); - } - if (className != null) { - Class c = loadClass(className); - if (c != null) { - classes.add(c); - } + if (entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) { + className = entryName.replace('\\', '/'); + } + + if (className != null) { + classes.add(className); } } jarFile.close(); - } - catch (Exception ex) { + } catch (Exception ex) { ex.printStackTrace(); } } diff --git a/src/main/java/me/libraryaddict/disguise/utilities/sounds/SoundManager.java b/src/main/java/me/libraryaddict/disguise/utilities/sounds/SoundManager.java index 07c81375..563e4405 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/sounds/SoundManager.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/sounds/SoundManager.java @@ -29,10 +29,18 @@ public class SoundManager { } private void loadCustomSounds() { - File f = new File(LibsDisguises.getInstance().getDataFolder(), "sounds.yml"); + File f = new File(LibsDisguises.getInstance().getDataFolder(), "configs/sounds.yml"); if (!f.exists()) { - LibsDisguises.getInstance().saveResource("sounds.yml", false); + f.getParentFile().mkdirs(); + + File old = new File(LibsDisguises.getInstance().getDataFolder(), "sounds.yml"); + + if (old.exists()) { + old.renameTo(f); + } else { + LibsDisguises.getInstance().saveResource("configs/sounds.yml", false); + } } YamlConfiguration config = YamlConfiguration.loadConfiguration(f); @@ -55,8 +63,7 @@ public class SoundManager { continue; } - List list = section.getStringList( - type.name().charAt(0) + type.name().substring(1).toLowerCase(Locale.ENGLISH)); + List list = section.getStringList(type.name().charAt(0) + type.name().substring(1).toLowerCase(Locale.ENGLISH)); if (list == null || list.isEmpty()) { continue; @@ -67,17 +74,15 @@ public class SoundManager { SoundGroup subGroup = SoundGroup.getGroup(sound); if (subGroup == null) { - DisguiseUtilities.getLogger().warning("Invalid sound '" + sound + - "'! Must be a minecraft:sound.name or SoundGroup name!"); + DisguiseUtilities.getLogger().warning("Invalid sound '" + sound + "'! Must be a minecraft:sound.name or SoundGroup name!"); continue; } Object[] sounds = subGroup.getDisguiseSounds().get(type); if (sounds == null) { - DisguiseUtilities.getLogger().warning( - "Sound group '" + sound + "' does not contain a category for " + type + - "! Can't use as default in " + key); + DisguiseUtilities.getLogger() + .warning("Sound group '" + sound + "' does not contain a category for " + type + "! Can't use as default in " + key); continue; } 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 11072c26..69e95dad 100644 --- a/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java +++ b/src/main/java/me/libraryaddict/disguise/utilities/translations/LibsMsg.java @@ -359,7 +359,7 @@ public enum LibsMsg { LD_COMMAND_DEBUG(ChatColor.BLUE + "/libsdisguises debug - " + ChatColor.AQUA + "Used to help debug scoreboard issues on a player disguise"), LD_COMMAND_UPLOAD_LOGS(ChatColor.BLUE + "/libsdisguises uploadlogs - " + ChatColor.AQUA + - "Uploads latest.log, disguises.yml and config.yml and gives you the link to share. Used when seeking " + + "Uploads latest.log, disguises.yml and configs and gives you the link to share. Used when seeking " + "assistance."), SELF_DISGUISE_HIDDEN(ChatColor.GREEN + "Self disguise hidden as it's too tall.."); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml deleted file mode 100644 index fd3f749a..00000000 --- a/src/main/resources/config.yml +++ /dev/null @@ -1,352 +0,0 @@ -Permissions: - # By default "libsdisguises.disguise.cow" will allow all options for cow disguise unless another permission has - # defined otherwise. - # If given "libsdisguises.disguise.animals.setburning" then "libsdisguises.disguise.cow" they will still be able to - # use other options like "setbaby". This was provided for backwards compatibility. - # By turning this from 'false' to 'true' the plugin will no longer give them the options unless the player was - # explicitly granted it. Even if by wildcard. The above example means they can only use "setburning" - - # To summarize, "libsdisguises.disguise.cow" will no longer let them do any options on the cow disguise unless it - # was added to their permissions - - # You can read more about permissions here: https://www.spigotmc.org/wiki/lib-s-disguises-setting-up-permissions/ - # The permission used to check OPs who may not have permissions defined, is "libsdisguises.*.*.*" which you can - # negate with your permissions plugin - ExplicitDisguises: false - - # What should the default permissions be for seeing commands? - # This is a config option because I can't verify if they should be able to see commands normally due to my - # permissions system. My system is complex, but its a ton of control. - # This isn't an issue normally, but I recently received complaints from someone who doesn't believe in permissions... - # Some of you may also wish to hide these commands! - # The permissions for commands are a simple 'libsdisguises.seecmd.command' where 'command' can be - # 'disguise', 'undisguise' etc. A simple 'libsdisguises.seecmd' permission may also work for children - # If you change this while the server is running, players may need to rejoin for it to take effect - # Remember that command blocks need 'TRUE' or 'OP' to use the commands. - # TRUE = Everyone can see this, the default. Can be negated with permissions - # FALSE = No one can see this without permissions to allow it - # OP = Only operators can see this - # NOT_OP = Only non operators can see this - SeeCommands: TRUE - -# Some disguises have randomized options on disguise, such as a fox type or a villager breed. -# This may be problematic for some server owners, so you can disable it below -RandomDisguiseOptions: true - -# You can also get this information through /libsdisguises config -# Should the plugin output missing config options instead of just counting them -VerboseConfig: false -# Should the plugin output changed config options? Will also list unknown extra options -ChangedConfig: false -# Should the config automatically update itself each time there's a config entry missing? -# The old config will have any custom comments or invalid config entries wiped. -UpdateConfig: true - -# Disables commands with the exception of /libsdisguises. Useful if you don't want the plugin to be used by anything -# but a plugin -# Useful if you didn't purchase the plugin. -DisableCommands: false - -# This means that the plugin doesn't need to constantly call Mojang just to find a skin for an offline player -# However some people may prefer to disable this. -# Even if you disable this, if there was disguises in the cache already then it will use them -SaveGameProfiles: true - -# This option is useless if you don't enable SaveGameProfiles! -# If a player has been disguised before and their skin saved into the cache -# When they join the server will automatically update the cache in case they changed their skin -UpdateGameProfiles: true - -# THIS IS A PREMIUM ONLY FEATURE. TO USE IT, PURCHASE THE PLUGIN. -# Saves disguises so that they persist after server shutdown, chunks unload, player logouts and so on. -# As such, this completely replaces the KeepDisguises aspect which has been removed except for the player death. -# Players - Are player disguises saved -# Entities - Are entities disguises saved (This is everything that's not a player) -# If you are using the dev builds, place your premium version of Lib's Disguises.jar inside the LibsDisguises folder -# This will enable premium only features for the dev builds. -# The saved disguises are saved in a json file format inside the plugin folder, there will be no other formats -SaveDisguises: - Players: false - Entities: false - -# There are four options you can use -# VANILLA - Names are limited to 16 chars but can't be changed without resending disguise -# TEAMS - Names are limited to 32 chars but can be changed willy nilly -# EXTENDED - Names are limited to 48 chars but can't be changed without resending disguise -# ARMORSTANDS - Names are limited to 256 chars, uses a mix of armorstands and teams to do this. Slightly hacky. -# Downside of armorstand names is that there's a chance of it becoming desynced from the player disguise -# And names will always display even if the entity is invisible using potion effects -# With ArmorStands & the Premium version, you can also use multiple lines in the nametag, use \n as a seperator. -# Read the next option for more information. -PlayerNames: TEAMS - -# If doing ARMORSTANDS in the above option, should CustomNames be overridden to use armorstands too? -# This allows multiline names if you have purchased the plugin -# Use \n for a new line, though if you're doing it in a config you may need to use \\n as " and ' are treated differently. -OverrideCustomNames: true - -# How many ticks before tab packet is sent to remove from tablist. This shouldn't need to be touched -TablistRemoveDelay: 3 - -# Does the player keep their disguise after they die? -KeepDisguises: - PlayerDeath: false - -# Should the plugin use translations? Note that a player must see the message before it will appear in translations.yml -Translations: false - -# How should the plugin handle self disguises scoreboards? It disables pushing in whichever team they're assigned. -# If you want them to be able to push again when they undisguise, set this to CREATE_SCOREBOARD -# I have to disable pushing or you will be pushed around by your own self disguise -# MODIFY_SCOREBOARD - Modifies the player's current team if possible, otherwise assigns them to a new scoreboard team. -# IGNORE_SCOREBOARD - Doesn't touch scoreboards at all, effectively means that if you didn't disable pushing in their scoreboard team; They will still be pushed around -# CREATE_SCOREBOARD - Creates a new team which copies the attributes of their previous scoreboard team which they are then assigned to. This means they keep nametag color and other options. -SelfDisguisesScoreboard: MODIFY_SCOREBOARD - -# More options in case you want to disable a specific setting of the scoreboard -Scoreboard: - # Should it modify the scoreboard to turn collisions off? - Collisions: true - # Should it modify the scoreboard teams to disable seeing friendly invisibles? - DisableFriendlyInvisibles: true - # Should the scoreboard warn you if it detects a potential conflict? - # If self disguises are disabled, or the scoreboard is using IGNORE_SCOREBOARD then this does nothing. - WarnConflict: true - # When disguising as a player, should the prefix/suffix of the player disguise name copy the team info? - # Only takes effect if using PlayerNames TEAMS or ARMORSTANDS - CopyPlayerTeamInfo: true - -# Shall I notify those with the correct permission when there's a LibsDisguises update? -# Disabling this will also disable notifications when the plugin updated -NotifyUpdate: true -# Should the plugin automatically update? -AutoUpdate: true - -# Where should the plugin check for updates? -# SAME_BUILDS - Will check snapshots if you're not using a release build -# RELEASES - Only check for actual releases -# SNAPSHOTS - Only check for new snapshots -UpdatesBranch: SAME_BUILDS - -# Whats the max size allowed for command disguiseradius -DisguiseRadiusMax: 50 - -# Whats the max size allowed for command undisguiseradius -UndisguiseRadiusMax: 50 - -# Shall the players view their disguises? -# Best used when viewing yourself in 3rd person -ViewSelfDisguises: true -# Are self disguises enabled by default -# Default is true -ViewSelfDisguisesDefault: true - -# Some disguises are rather big and tall and block your vision -# By default those disguises are enabled despite misgivings, such as zombies, players, etc. -# The baby versions however, should be short enough that it's a non-issue -TallSelfDisguises: true - -# Shall I disguise the sounds? -# This turns your damage sound into a MOOOO -DisguiseSounds: true - -# Shall the disguised hear their disguise sounds or their damage sounds. -# I disable this as it can be a little confusing when not used with self disguises -HearSelfDisguise: true - -# When disguised, should a message be displayed to the player? If so, where? -# The message can be customized in translations -# BOSS_BAR is not supported in 1.12! -# NONE, BOSS_BAR, ACTION_BAR -NotifyBar: ACTION_BAR -# If using boss bar, these two options come into play -# https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/boss/BarColor.html -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 - -# For self disguises, they need to have the armor and the held item removed -# Else they see floating armor, floating held items. -# This turns the items invisible in the disguised players inventory. It does not actually remove them! -# Be warned that in creative this can actually delete the item from the inventory due to a weird bug -RemoveArmor: true -RemoveHeldItem: false - -# If you set a disguise to burning, it will no longer be able to be shown as sneaking or invisible. -# Set this to true if you want the disguise to get the animations of the disguised entity. Such as invisible, on fire, sprinting, sneaking, blocking -# This is only valid if you set a animation on the disguise itself. Because the entity's animations are applied otherwise. -AddEntityAnimations: true - -# When a sheep or wolf is right clicked with dye. The client automatically assumes it was successful and displays the sheep's wool or the wolfs collar as dyed. -# This is a option that either prevents that happening, or it changes their color officially in the plugin so that everyone sees it changed. -# Its currently set to false which means that the color is not changed and will refresh itself to the player. -# Please note that this will not remove the dye from their hands. This also does not check if the disguised entity is actually a sheep/wolf and wants a say in its color. -DyeableSheep: false -DyeableWolf: false -DyeableCat: false -# Can a player interact with a llama with carpet to set or change their carpet color? -CarpetableLlama: false -# Can a player interact with a non-saddled horse of any type, to give it a saddle? -# This does not change what you can ride or control! -SaddleableHorse: false - -# This is only called into action when the disguise is constructed using the commands. -# And when the disguise supports that. This will not be used at all for plugins constructing the disguises for instance. -# Such as prophunt. Its also false because its kind of a retarded feature. -# This is pretty simple. It shows the players displayname (Name as it appears in chat) above their head. -# This also overrides any custom name they have set in their disguise options. -# This does not take effect on player disguises -# Permission to disable is libsdisguises.disablename -ShowNamesAboveDisguises: false - -# This supports the above option. -# If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not. -NameAboveHeadAlwaysVisible: true - -# What should the name be shown as? -# Two placeholders can be used. -# %simple% = The very basic name, 'libraryaddict' -# %complex% = Name will be grabbed from scoreboard or display name if scoreboard fails. -NameAboveDisguise: '%complex%' - -# This modifies the bounding box, This is stuff like can a arrow hit them. -# If you turn this to true, arrows will act like they hit the disguise in the right place! -# Clients will not see any difference in the hitboxes they are attacking, this is a server-sided calculation! -# So someone disguised as a enderdragon will easily get shot down by arrows! -# This WILL conflict with NoCheatPlus. Other plugins may also get problems. -# This shouldn't really be enabled for players as it also interferes with their movement because the server thinks -# the player is larger than they really are. -# That makes the player unable to approach this building because the server thinks they are trying to glitch inside -# blocks. -# This feature is highly experimental and is guaranteed to cause problems for players who are disguised -ModifyBoundingBox: false - -# This prevents disguised players from being targeted by monsters. -# This doesn't prevent their targeting you if already targeting when disguised -# They will just ignore you unless provoked. -MonstersIgnoreDisguises: false - -# This works only for players, disguised monsters and the like will not be undisguised -# Should the player's disguises be removed if they attacks something? -# Blown Disguise message can be changed in translations -# Message can be hidden with an empty translation -BlowDisguisesWhenAttacking: false - -# Should the player's disguises be removed if they're attacked by something? -BlowDisguisesWhenAttacked: false - -# Should PvP be disabled when disguised? -DisablePvP: false -# Should PvE be disabled when disguised? (Eg, fighting zombie) -DisablePvE: false - -# How long after disguise wears off, should pvp be allowed again? Requires above to be true -# Default value 5 seconds -PvPTimer: 5 - -# This works with 'DisablePvP' that if attacked by another entity, they have 'PvPTimer' amount of time -# to attack back. Timer is reset with every successful attack -RetaliationCombat: false - -#Stop shulker disguises from moving, they're weird. This option only effects PLAYERS that are disguised, other entities disguised as shulkers will NOT be effected! -StopShulkerDisguisesFromMoving: true - -# A option to choose how many seconds a DisguiseEntity command is valid for people to right click a entity to disguise it before expiring -DisguiseEntityExpire: 10 - -# Another option to choose the same thing for DisguiseClone command -DisguiseCloneExpire: 10 -# Max disguises to store at a time with the DisguiseClone command -DisguiseCloneSize: 3 - -# This controls if a entity's max health is determined by the entity, or by the disguise. -# Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health. -# Else it will be 1/20 of the boss bar when they are full health. -# Setting this in LivingWatcher overrides both values. -MaxHealthDeterminedByEntity: true - -# This here is a option to turn off misc disguises. -# This means you can not have a living entity disguise as a non-living entity. -# This disables the Attributes packet, Non-living entities can still disguise as other non-living -# This means that the above option will not work as it uses the attribute packet. -MiscDisguisesForLiving: true - -# Turn this to true to have players undisguised when switching worlds -UndisguiseOnWorldChange: false - -# Contact Mojang's servers? Disabling this option will disable player skin disguises! -ContactMojangServers: true - -# Hide players in tab when disguised? This means a disguised player cannot be seen when you press tab! This can be toggled on/off per disguise -HideDisguisedPlayersFromTab: false - -# Always show player disguises in tab? The names will continue to appear in tab until the disguise is removed. -ShowPlayerDisguisesInTab: false - -# On player disguise, a fake player is added to tablist so the skin can load properly. -# This option is ignored if 'ShowPlayerDisguisesInTab' is enabled. -# 3 ticks should easily be enough. -PlayerDisguisesTablistExpires: 3 - -# To prevent skins from defaulting to alex/steve, there is a timer that only expires after X ticks or when the player moves -# You shouldn't actually touch this, but eh. Your server. -# Default is 5 seconds -PlayerDisguisesTablistExpiresMove: 100 - -# Don't like players able to set themselves invisible when using the disguise commands? Toggle this to true and no one can use setInvisible! Plugins can still use this however. -DisableInvisibility: false - -# Disguises have a 'setExpires' option which removes the disguise after a set amount of time -# By default, this is set to false which means it expires 9 minutes afterwards, even if they logged off. -# If true, it means they will experience the full 9 minutes, even if they log on for just a minute per day -# Expired message can be hidden with an empty translation message -DynamicExpiry: false - -# Some players have issues with conflicting plugins where disguised entities will show the wrong armor -# This should be left alone unless you're trying to solve this issue. Such as MM and stone blocks. -# When true, the plugin will hide player disguises armor to prevent a minor visual bug for half a second -PlayerHideArmor: true - -# This will help performance, especially with CPU -# Due to safety reasons, self disguises can never have their packets disabled. -PacketsEnabled: - # This disables the animation packet. If a disguised entity sends a animation packet and they are using a non-living disguise. People will crash. - # Disabling this also means that if a player disguised as a non-player leaves a bug. People will crash - Animation: true - # This disguises the collect packet. If a living entity disguised as a non-living entity picks up a item. People will crash. This fixes it - # This also fixes people crashing if a item disguised as a sleeping player is picked up - Only true if Bed is enabled as well - Collect: true - # This disables a fix for when a disguised entity wearing armor dies, if the disguise can wear armor. It drops unpickupable items to anyone watching. - EntityStatus: true - # Entity equipment is the packets that are sent to ensure that a disguise has or doesn't have armor, and their held item. - # Disabling this means that any disguises which can wear armor or hold items will show the armor/held item that the disguised is wearing. - Equipment: true - # This doesn't actually disable the packet. It would introduce problems. Instead it does the next best thing and caches the data. - # This means that entity metadata will not change, and will only be sent in the spawn packet. - # This is good if performance is extremely in need. - # This is bad to disable unless you are ONLY going to use the disguises for decorations. - # To be honest. This is basically "Disable entity animations". That option is called 'AddEntityAnimations' in the config but unlike that, this is always in effect. - # Animations set by use of the api or through the disguise command are still in effect. - Metadata: true - # Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up. - # If you are using the Item_Frame disguise, when a packet is sent (Roughly every 2min) the disguise will bug up until they move. - Movement: true - # Disable this if you don't mind crashing everytime you see someone riding something disguised as a non-living entity - Riding: true - # When disguised as a wither skull, it sends a look packet every tick so that the wither skull is facing the right way. - WitherSkull: true - # This is only used when using a modded disguises thingy, check disguises.yml for more info - # This is used as a hack to bypass bungeecord issues - LoginPayload: true - -# Added to support a Chinese Minecraft Server which uses their own skin server unless the UUID is not version 4. -# Changing this from 4 to say, 3. Means their server will fetch skins from Mojang instead. -UUIDVersion: 4 diff --git a/src/main/resources/configs/combat.yml b/src/main/resources/configs/combat.yml new file mode 100644 index 00000000..3544f1aa --- /dev/null +++ b/src/main/resources/configs/combat.yml @@ -0,0 +1,29 @@ +# This config file is for settings that effects combat! + +# This prevents disguised players from being targeted by monsters. +# This doesn't prevent their targeting you if already targeting when disguised +# They will just ignore you unless provoked. +MonstersIgnoreDisguises: false + +# Should PvP be disabled when disguised? +DisablePvP: false +# Should PvE be disabled when disguised? (Eg, fighting zombie) +DisablePvE: false + +# This works only for players, disguised monsters and the like will not be undisguised +# Should the player's disguises be removed if they attacks something? +# Blown Disguise message can be changed in translations +# Message can be hidden with an empty translation +BlowDisguisesWhenAttacking: false + +# Should the player's disguises be removed if they're attacked by something? +BlowDisguisesWhenAttacked: false + +# This works with 'DisablePvP' that if attacked by another entity, they have 'PvPTimer' amount of time +# to attack back. Timer is reset with every successful attack +RetaliationCombat: false + +# If pvp or pve is disabled, this takes effect. +# If RetaliationCombat is false, or it's true but they haven't fought back in PvPTimer seconds, then they can't fight back. +# This also controls it so they can't fight back PvPTimer seconds after applying a disguise +PvPTimer: 5 \ No newline at end of file diff --git a/src/main/resources/configs/commands.yml b/src/main/resources/configs/commands.yml new file mode 100644 index 00000000..f970f3e5 --- /dev/null +++ b/src/main/resources/configs/commands.yml @@ -0,0 +1,54 @@ +# This config file is for settings that effect commands only! + +# Don't like players able to set themselves invisible when using the disguise commands? Toggle this to true and no one can use setInvisible! Plugins can still use this however. +DisableInvisibility: false + +# By the default the plugin saves the users of the /viewdisguisebar and /viewselfdisguises to a file +# So that it persists after restart +SaveUserPreferences: true + +Permissions: + # By default "libsdisguises.disguise.cow" will allow all options for cow disguise unless another permission has + # defined otherwise. + # If given "libsdisguises.disguise.animals.setburning" then "libsdisguises.disguise.cow" they will still be able to + # use other options like "setbaby". This was provided for backwards compatibility. + # By turning this from 'false' to 'true' the plugin will no longer give them the options unless the player was + # explicitly granted it. Even if by wildcard. The above example means they can only use "setburning" + + # To summarize, "libsdisguises.disguise.cow" will no longer let them do any options on the cow disguise unless it + # was added to their permissions + + # You can read more about permissions here: https://www.spigotmc.org/wiki/lib-s-disguises-setting-up-permissions/ + # The permission used to check OPs who may not have permissions defined, is "libsdisguises.*.*.*" which you can + # negate with your permissions plugin + ExplicitDisguises: false + + # What should the default permissions be for seeing commands? + # This is a config option because I can't verify if they should be able to see commands normally due to my + # permissions system. My system is complex, but its a ton of control. + # This isn't an issue normally, but I recently received complaints from someone who doesn't believe in permissions... + # Some of you may also wish to hide these commands! + # The permissions for commands are a simple 'libsdisguises.seecmd.command' where 'command' can be + # 'disguise', 'undisguise' etc. A simple 'libsdisguises.seecmd' permission may also work for children + # If you change this while the server is running, players may need to rejoin for it to take effect + # Remember that command blocks need 'TRUE' or 'OP' to use the commands. + # TRUE = Everyone can see this, the default. Can be negated with permissions + # FALSE = No one can see this without permissions to allow it + # OP = Only operators can see this + # NOT_OP = Only non operators can see this + SeeCommands: TRUE + +# Whats the max size allowed for command disguiseradius +DisguiseRadiusMax: 50 + +# Whats the max size allowed for command undisguiseradius +UndisguiseRadiusMax: 50 + +# A option to choose how many seconds a DisguiseEntity command is valid for people to right click a entity to disguise it before expiring +DisguiseEntityExpire: 10 + +# Another option to choose the same thing for DisguiseClone command +DisguiseCloneExpire: 10 + +# Max disguises to store at a time with the DisguiseClone command +DisguiseCloneSize: 3 \ No newline at end of file diff --git a/src/main/resources/disguises.yml b/src/main/resources/configs/disguises.yml similarity index 98% rename from src/main/resources/disguises.yml rename to src/main/resources/configs/disguises.yml index 43c7b862..f7b3f481 100644 --- a/src/main/resources/disguises.yml +++ b/src/main/resources/configs/disguises.yml @@ -1,70 +1,70 @@ -# The best way to use this is with /savedisguise or /saveskin -# /saveskin MyCustomSkin - Where can be an url, file in LibsDisguises/skins or player name -# Then use /disguise player MyCustomSkin - To test it - -# You can also use /savedisguise MyCustomDisguise player KingKiller setskin - With the same 3 types of skin -# as above - -# It is strongly recommended you use /savedisguise instead of editing this file! -# You can use that command in console or ingame! This helps eliminate user error! - -# Here you can create your own disguises and disguise into them using the normal disguise commands -# To create them is super simple, you're using it just like you would in a command. The only tricky thing is that it must be valid yaml. TIP: Enclose the strings in ' -# Please note that this is parsed exactly like a command, no spaces in your playername. Bypass by quoting with "! - -# You can use /grabskin - To get the skin data from a file, another player or website. -# /savedisguise ingame will save a custom disguise in this config, including skin data. -# You can also provide a file or url for 'setSkin'! Just as you would for /grabskin. -# The setSkin argument will be automatically done for all /savedisguise usages, this way the skin never changes. -# /copydisguise will give you the disguise in a usable string - -# You can also use placeholders in the disguises to create disguises that have the command users skin - -# %name% - Replaces %name% with the command user's name. -# %skin% - Replaces %skin% with the command user's skin for use with player disguises. -# %displayname% - Replaces %displayname% with the command users displayname - -# %target-name% - Finds first viable name from: Player name, entity custom nametag, then entity type (Pig, Horse, Cow) -# %target-skin% - If target is a player, replaces %target-skin% with their skin for use with player disguises -# %target-displayname% - Similar as above -# If target is not a player, will silently fail - -# %held-item% - The currently held item in the main item slot -# %offhand-item% - The offhand item -# %armor% - The armor in ,,, format -# %helmet% %chestplate% %leggings% %boots% - Obvious. -# These are best used in armor slots, or in settings that accept items. Can also be used alongside /copydisguise -# to get the string format of an item. By /disguise zombie setiteminmainhand %held-item% - Then /copydisguise. -# But the plugin will attempt to parse to the "simplest" format. So best used with an item that has more custom data -# than just the amount. - -# These can be used again for the 'target' by prepending 'target-' to the above. So %target-armor% %target-held-item% -# Finally, you can use %libraryaddict-name% to do all this, but fetch it from the ONLINE player libraryaddict! Case sensitive. - -# The below disguise would give a disguised sheep the nametag; Me: libraryaddict, Them: Sheep -# Example: 'cow setCustomName "Me: %user-name%, Them: %target-name%"' -# -# This would give the disguised target a player disguise of their own name, but using the skin of the command user -# Example2: 'player %target-name% setSkin %user-skin%' - -# The following disguises will work if you remove the '#' at the beginning of the line, this creates a disguise which you can use by /disguise libraryaddict -Disguises: - libraryaddict: 'player libraryaddict setArmor GOLDEN_BOOTS,GOLDEN_LEGGINGS,GOLDEN_CHESTPLATE,GOLDEN_HELMET setItemInMainHand WRITTEN_BOOK setGlowing setSkin {"id":"a149f81bf7844f8987c554afdd4db533","name":"libraryaddict","properties":[{"signature":"afoGOO45t3iGvTyQ732AlugPOvj13/RNjM0/utYlD4PZ4ab4Jopbzr8Px75+ALdkyegoKNcfaH4aXzylMvL6mIwaRdL0af7pfGibMMCMJ8F1RAMl2WqRslKBKXHGS1OXxMweoXW+RRatGgZsUC1BjxHMwd4RuXxrV9ZZ7x1r4xouUXmMzn19wqNO9EeG2q8AgF/hZdrnJPdTTrqJs04r4vCQiFiQsTWiY/B5CBOTh6fw4NpOHeeiJwHOLvN+6xKnAm77nKawaKCSciDwt54EeZoE/Q5ReQUEFgj++jdyHb5PJbhGytr//mazpTVzvlDnO06CZqigbiueV2/ush2gKSXQeimCXeNZzcj/CFgqAmMSEZQW3qHp+DgoqqtBNabJa0FBzpbQQ/jQWzoHfmUC/hTf0A0+hgOe4NqDc+xXYf4A9M/6/0JHz0voWhQJi8QriM699DeeUa31bVdTdKjcyK6Zw6/HIOJt++eFnkf++/zKt0fMiqfdRamSqR/K3w+Kk7cs2D345BNubl5L83YWmLbebUcAPKaza5gi17lUW+h/FitzfKAJZ+xsfSdj27nQLa24xYsyB3Fi5DcFLI2oQt5BYAvViT37sabGOXbDBsrijS4t3++mIbC+pCDiKi0hwZzvy0TPRTle2RMhJ6D66DmpykwqBOxzD73fEsieWX4=","name":"textures","value":"eyJ0aW1lc3RhbXAiOjE0ODA1MjA3NjAxNTksInByb2ZpbGVJZCI6ImExNDlmODFiZjc4NDRmODk4N2M1NTRhZmRkNGRiNTMzIiwicHJvZmlsZU5hbWUiOiJsaWJyYXJ5YWRkaWN0Iiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84ZTQ5NDVkMzZjZjVhNjI1OGZjOGY4ZTM5NmZlZWYzMzY1ZjM2MjgyYjE2MjY0OWI2M2NmZWQzNzNmNzY1OSJ9LCJDQVBFIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWZkNjFjM2M0YWM4OGYxYTM0NjhmYmRlZWY0NWNlYzg5ZTVhZmI4N2I5N2ExYTg0NWJmYjNjNjRmZDBiODgzIn19fQ=="}]}' -# Warrior: 'zombie setArmor DIAMOND_BOOTS,DIAMOND_LEGGINGS,DIAMOND_CHESTPLATE,DIAMOND_HELMET setItemInMainHand DIAMOND_SWORD setItemInOffHand SHIELD' -# Topsy: 'player Dinnerbone setSkin %target-skin%' - -# This is not recommended for use! It's mainly useful if you want custom entities and the client has a mod installed! -# If an option is missing, then it means Lib's Disguises will not do sanity checks for that. -# No mod = Everyone gets sent it, otherwise only those with the mod will get the disguise. -# You MUST restart the server after adding anything! -# To repeat, this is for forge mod entities! -Custom-Entities: -# Librarian: -# Name: libaddict:librarian # Must be a minecraft:sheep type of name, if invalid will not load -# Register: true # This means Lib's Disguises should register the EntityType in nms, not another plugin -# Type: LIVING # MISC, LIVING - What type of disguise type, doesn't support custom packets -# Mod: LibAttacks # The mod they need installed -# If exists, will prevent anyone without the mod from joining with this error -# Required: 'Install LibAttacks! Download it from our site!' -# Channels: librarian:channel|1 # Sometimes a mod needs a channel enabled.. Seperate each channel with a comma. -# The channels also want a protocol version, which is normally 1 or 1.0 +# The best way to use this is with /savedisguise or /saveskin +# /saveskin MyCustomSkin - Where can be an url, file in LibsDisguises/skins or player name +# Then use /disguise player MyCustomSkin - To test it + +# You can also use /savedisguise MyCustomDisguise player KingKiller setskin - With the same 3 types of skin +# as above + +# It is strongly recommended you use /savedisguise instead of editing this file! +# You can use that command in console or ingame! This helps eliminate user error! + +# Here you can create your own disguises and disguise into them using the normal disguise commands +# To create them is super simple, you're using it just like you would in a command. The only tricky thing is that it must be valid yaml. TIP: Enclose the strings in ' +# Please note that this is parsed exactly like a command, no spaces in your playername. Bypass by quoting with "! + +# You can use /grabskin - To get the skin data from a file, another player or website. +# /savedisguise ingame will save a custom disguise in this config, including skin data. +# You can also provide a file or url for 'setSkin'! Just as you would for /grabskin. +# The setSkin argument will be automatically done for all /savedisguise usages, this way the skin never changes. +# /copydisguise will give you the disguise in a usable string + +# You can also use placeholders in the disguises to create disguises that have the command users skin + +# %name% - Replaces %name% with the command user's name. +# %skin% - Replaces %skin% with the command user's skin for use with player disguises. +# %displayname% - Replaces %displayname% with the command users displayname + +# %target-name% - Finds first viable name from: Player name, entity custom nametag, then entity type (Pig, Horse, Cow) +# %target-skin% - If target is a player, replaces %target-skin% with their skin for use with player disguises +# %target-displayname% - Similar as above +# If target is not a player, will silently fail + +# %held-item% - The currently held item in the main item slot +# %offhand-item% - The offhand item +# %armor% - The armor in ,,, format +# %helmet% %chestplate% %leggings% %boots% - Obvious. +# These are best used in armor slots, or in settings that accept items. Can also be used alongside /copydisguise +# to get the string format of an item. By /disguise zombie setiteminmainhand %held-item% - Then /copydisguise. +# But the plugin will attempt to parse to the "simplest" format. So best used with an item that has more custom data +# than just the amount. + +# These can be used again for the 'target' by prepending 'target-' to the above. So %target-armor% %target-held-item% +# Finally, you can use %libraryaddict-name% to do all this, but fetch it from the ONLINE player libraryaddict! Case sensitive. + +# The below disguise would give a disguised sheep the nametag; Me: libraryaddict, Them: Sheep +# Example: 'cow setCustomName "Me: %user-name%, Them: %target-name%"' +# +# This would give the disguised target a player disguise of their own name, but using the skin of the command user +# Example2: 'player %target-name% setSkin %user-skin%' + +# The following disguises will work if you remove the '#' at the beginning of the line, this creates a disguise which you can use by /disguise libraryaddict +Disguises: + libraryaddict: 'player libraryaddict setArmor GOLDEN_BOOTS,GOLDEN_LEGGINGS,GOLDEN_CHESTPLATE,GOLDEN_HELMET setItemInMainHand WRITTEN_BOOK setGlowing setSkin {"id":"a149f81bf7844f8987c554afdd4db533","name":"libraryaddict","properties":[{"signature":"afoGOO45t3iGvTyQ732AlugPOvj13/RNjM0/utYlD4PZ4ab4Jopbzr8Px75+ALdkyegoKNcfaH4aXzylMvL6mIwaRdL0af7pfGibMMCMJ8F1RAMl2WqRslKBKXHGS1OXxMweoXW+RRatGgZsUC1BjxHMwd4RuXxrV9ZZ7x1r4xouUXmMzn19wqNO9EeG2q8AgF/hZdrnJPdTTrqJs04r4vCQiFiQsTWiY/B5CBOTh6fw4NpOHeeiJwHOLvN+6xKnAm77nKawaKCSciDwt54EeZoE/Q5ReQUEFgj++jdyHb5PJbhGytr//mazpTVzvlDnO06CZqigbiueV2/ush2gKSXQeimCXeNZzcj/CFgqAmMSEZQW3qHp+DgoqqtBNabJa0FBzpbQQ/jQWzoHfmUC/hTf0A0+hgOe4NqDc+xXYf4A9M/6/0JHz0voWhQJi8QriM699DeeUa31bVdTdKjcyK6Zw6/HIOJt++eFnkf++/zKt0fMiqfdRamSqR/K3w+Kk7cs2D345BNubl5L83YWmLbebUcAPKaza5gi17lUW+h/FitzfKAJZ+xsfSdj27nQLa24xYsyB3Fi5DcFLI2oQt5BYAvViT37sabGOXbDBsrijS4t3++mIbC+pCDiKi0hwZzvy0TPRTle2RMhJ6D66DmpykwqBOxzD73fEsieWX4=","name":"textures","value":"eyJ0aW1lc3RhbXAiOjE0ODA1MjA3NjAxNTksInByb2ZpbGVJZCI6ImExNDlmODFiZjc4NDRmODk4N2M1NTRhZmRkNGRiNTMzIiwicHJvZmlsZU5hbWUiOiJsaWJyYXJ5YWRkaWN0Iiwic2lnbmF0dXJlUmVxdWlyZWQiOnRydWUsInRleHR1cmVzIjp7IlNLSU4iOnsidXJsIjoiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS84ZTQ5NDVkMzZjZjVhNjI1OGZjOGY4ZTM5NmZlZWYzMzY1ZjM2MjgyYjE2MjY0OWI2M2NmZWQzNzNmNzY1OSJ9LCJDQVBFIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZWZkNjFjM2M0YWM4OGYxYTM0NjhmYmRlZWY0NWNlYzg5ZTVhZmI4N2I5N2ExYTg0NWJmYjNjNjRmZDBiODgzIn19fQ=="}]}' +# Warrior: 'zombie setArmor DIAMOND_BOOTS,DIAMOND_LEGGINGS,DIAMOND_CHESTPLATE,DIAMOND_HELMET setItemInMainHand DIAMOND_SWORD setItemInOffHand SHIELD' +# Topsy: 'player Dinnerbone setSkin %target-skin%' + +# This is not recommended for use! It's mainly useful if you want custom entities and the client has a mod installed! +# If an option is missing, then it means Lib's Disguises will not do sanity checks for that. +# No mod = Everyone gets sent it, otherwise only those with the mod will get the disguise. +# You MUST restart the server after adding anything! +# To repeat, this is for forge mod entities! +Custom-Entities: +# Librarian: +# Name: libaddict:librarian # Must be a minecraft:sheep type of name, if invalid will not load +# Register: true # This means Lib's Disguises should register the EntityType in nms, not another plugin +# Type: LIVING # MISC, LIVING - What type of disguise type, doesn't support custom packets +# Mod: LibAttacks # The mod they need installed +# If exists, will prevent anyone without the mod from joining with this error +# Required: 'Install LibAttacks! Download it from our site!' +# Channels: librarian:channel|1 # Sometimes a mod needs a channel enabled.. Seperate each channel with a comma. +# The channels also want a protocol version, which is normally 1 or 1.0 diff --git a/src/main/resources/configs/features.yml b/src/main/resources/configs/features.yml new file mode 100644 index 00000000..1b3298cb --- /dev/null +++ b/src/main/resources/configs/features.yml @@ -0,0 +1,42 @@ +# This config file is for features that are something the server might want to customize! + +# Disguises have a 'setExpires' option which removes the disguise after a set amount of time +# By default, this is set to false which means it expires 9 minutes afterwards, even if they logged off. +# If true, it means they will experience the full 9 minutes, even if they log on for just a minute per day +# Expired message can be hidden with an empty translation message +DynamicExpiry: false + +# THIS IS A PREMIUM ONLY FEATURE. TO USE IT, PURCHASE THE PLUGIN. +# Saves disguises so that they persist after server shutdown, chunks unload, player logouts and so on. +# As such, this completely replaces the KeepDisguises aspect which has been removed except for the player death. +# Players - Are player disguises saved +# Entities - Are entities disguises saved (This is everything that's not a player) +# If you are using the dev builds, place your premium version of Lib's Disguises.jar inside the LibsDisguises folder +# This will enable premium only features for the dev builds. +# The saved disguises are saved in a json file format inside the plugin folder, there will be no other formats +SaveDisguises: + Players: false + Entities: false + +# Does the player keep their disguise after they die? +KeepDisguises: + PlayerDeath: false + +# Shall I disguise the sounds? +# This turns your damage sound into a MOOOO +DisguiseSounds: true + +# Turn this to true to have players undisguised when switching worlds +UndisguiseOnWorldChange: false + + +# When disguised, should a message be displayed to the player? If so, where? +# The message can be customized in translations +# BOSS_BAR is not supported in 1.12! +# NONE, BOSS_BAR, ACTION_BAR +NotifyBar: ACTION_BAR +# If using boss bar, these two options come into play +# https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/boss/BarColor.html +BossBarColor: GREEN +# https://hub.spigotmc.org/javadocs/bukkit/org/bukkit/boss/BarStyle.html +BossBarStyle: SOLID diff --git a/src/main/resources/configs/libsdisguises.yml b/src/main/resources/configs/libsdisguises.yml new file mode 100644 index 00000000..107b4b15 --- /dev/null +++ b/src/main/resources/configs/libsdisguises.yml @@ -0,0 +1,30 @@ +# This config is for options that are about Libs Disguises itself, not the disguises. + +# Contact Mojang's servers? Disabling this option will disable player disguises if there's no skin to use! +ContactMojangServers: true + +# Should the plugin use translations? Note that a player must see the message before it will appear in translations.yml +Translations: false + +# Shall I notify those with the correct permission when there's a LibsDisguises update? +# Disabling this will also disable notifications when the plugin updated +NotifyUpdate: true +# Should the plugin automatically update? +AutoUpdate: true + +# Where should the plugin check for updates? +# SAME_BUILDS - Will check snapshots if you're not using a release build +# RELEASES - Only check for actual releases +# SNAPSHOTS - Only check for new snapshots +UpdatesBranch: SAME_BUILDS + +# You can also get this information through /libsdisguises config +# Should the plugin output missing config options instead of just counting them +VerboseConfig: false + +# Should the plugin output changed config options? Will also list unknown extra options +ChangedConfig: false + +# Should the config automatically update itself each time there's a config entry missing? +# The old config will have any custom comments or invalid config entries wiped. +UpdateConfig: true \ No newline at end of file diff --git a/src/main/resources/configs/nametags.yml b/src/main/resources/configs/nametags.yml new file mode 100644 index 00000000..6e6c313d --- /dev/null +++ b/src/main/resources/configs/nametags.yml @@ -0,0 +1,49 @@ +# This config file is about the names that appear over heads! A fair bit of player disguise stuff is in players.yml however + +# This is only called into action when the disguise is constructed using the commands. +# And when the disguise supports that. This will not be used at all for plugins constructing the disguises for instance. +# Such as prophunt. Its also false because its kind of a retarded feature. +# This is pretty simple. It shows the players displayname (Name as it appears in chat) above their head. +# This also overrides any custom name they have set in their disguise options. +# This does not take effect on player disguises +# Permission to disable is libsdisguises.disablename +ShowNamesAboveDisguises: false + +# This supports the above option. +# If this is true, then the name shown above the head appears regardless of if you are looking at the disguise directly or not. +NameAboveHeadAlwaysVisible: true + +# What should the name be shown as? +# Two placeholders can be used. +# %simple% = The very basic name, 'libraryaddict' +# %complex% = Name will be grabbed from scoreboard or display name if scoreboard fails. +NameAboveDisguise: '%complex%' + +# There are four options you can use +# VANILLA - Names are limited to 16 chars but can't be changed without resending disguise +# TEAMS - Names are limited to 32 chars but can be changed willy nilly +# EXTENDED - Names are limited to 48 chars but can't be changed without resending disguise +# ARMORSTANDS - Names are limited to 256 chars, uses a mix of armorstands and teams to do this. Slightly hacky. +# Downside of armorstand names is that there's a chance of it becoming desynced from the player disguise +# And names will always display even if the entity is invisible using potion effects +# With ArmorStands & the Premium version, you can also use multiple lines in the nametag, use \n as a seperator. +# Read the next option for more information. +PlayerNames: TEAMS + +# If doing ARMORSTANDS in the above option, should CustomNames for non-player disguises be overridden to use armorstands too? +# This allows multiline names if you have purchased the plugin +# Use \n for a new line, though if you're doing it in a config you may need to use \\n as " and ' are treated differently. +OverrideCustomNames: true + +# More options in case you want to disable a specific setting of the scoreboard +Scoreboard: + # Should it modify the scoreboard to turn collisions off? + Collisions: true + # Should it modify the scoreboard teams to disable seeing friendly invisibles? + DisableFriendlyInvisibles: true + # Should the scoreboard warn you if it detects a potential conflict? + # If self disguises are disabled, or the scoreboard is using IGNORE_SCOREBOARD then this does nothing. + WarnConflict: true + # When disguising as a player, should the prefix/suffix of the player disguise name copy the team info? + # Only takes effect if using PlayerNames TEAMS or ARMORSTANDS + CopyPlayerTeamInfo: true \ No newline at end of file diff --git a/src/main/resources/configs/players.yml b/src/main/resources/configs/players.yml new file mode 100644 index 00000000..d2923156 --- /dev/null +++ b/src/main/resources/configs/players.yml @@ -0,0 +1,45 @@ +# This config file is for settings that are about the players themselves, and the player disguises! + +# Shall the players view their disguises? +# Best used when viewing yourself in 3rd person +ViewSelfDisguises: true + +# Are self disguises enabled by default +# Default is true +ViewSelfDisguisesDefault: true + +# Shall the disguised hear their disguise sounds or their damage sounds. +# I disable this as it can be a little confusing when not used with self disguises +HearSelfDisguise: true + +# Some disguises are rather big and tall and block your vision +# By default those disguises are enabled despite misgivings, such as zombies, players, etc. +# The baby versions however, should be short enough that it's a non-issue +TallSelfDisguises: true + +# How should the plugin handle self disguises scoreboards? It disables pushing in whichever team they're assigned. +# If you want them to be able to push again when they undisguise, set this to CREATE_SCOREBOARD +# I have to disable pushing or you will be pushed around by your own self disguise +# MODIFY_SCOREBOARD - Modifies the player's current team if possible, otherwise assigns them to a new scoreboard team. +# IGNORE_SCOREBOARD - Doesn't touch scoreboards at all, effectively means that if you didn't disable pushing in their scoreboard team; They will still be pushed around +# CREATE_SCOREBOARD - Creates a new team which copies the attributes of their previous scoreboard team which they are then assigned to. This means they keep nametag color and other options. +SelfDisguisesScoreboard: MODIFY_SCOREBOARD + +# Hide players in tab when disguised? This means a disguised player cannot be seen when you press tab! This can be toggled on/off per disguise +HideDisguisedPlayersFromTab: false + +# Always show player disguises in tab? The names will continue to appear in tab until the disguise is removed. +ShowPlayerDisguisesInTab: false + +# On player disguise, a fake player is added to tablist so the skin can load properly. +# This option is ignored if 'ShowPlayerDisguisesInTab' is enabled. +# 3 ticks should easily be enough. +PlayerDisguisesTablistExpires: 3 + +# How many ticks before tab packet is sent to remove from tablist. This shouldn't need to be touched +TablistRemoveDelay: 3 + +# To prevent skins from defaulting to alex/steve, there is a timer that only expires after X ticks or when the player moves +# You shouldn't actually touch this, but eh. Your server. +# Default is 5 seconds +PlayerDisguisesTablistExpiresMove: 100 \ No newline at end of file diff --git a/src/main/resources/configs/protocol.yml b/src/main/resources/configs/protocol.yml new file mode 100644 index 00000000..556ebbbc --- /dev/null +++ b/src/main/resources/configs/protocol.yml @@ -0,0 +1,74 @@ +# This config is for options that should only be touched if you're having compatibility issues with other plugins + +# Some players have issues with conflicting plugins where disguised entities will show the wrong armor +# This should be left alone unless you're trying to solve this issue. Such as MM and stone blocks. +# When true, the plugin will hide player disguises armor to prevent a minor visual bug for half a second +PlayerHideArmor: true + +# Some disguises have randomized options on disguise, such as a fox type or a villager breed. +# This may be problematic for some server owners, so you can disable it below +RandomDisguiseOptions: true + +# For self disguises, they need to have the armor and the held item removed +# Else they see floating armor, floating held items. +# This turns the items invisible in the disguised players inventory. It does not actually remove them! +# Be warned that in creative this can actually delete the item from the inventory due to a weird bug +RemoveArmor: true +RemoveHeldItem: false + +# If you set a disguise to burning, it will no longer be able to be shown as sneaking or invisible. +# Set this to true if you want the disguise to get the animations of the disguised entity. Such as invisible, on fire, sprinting, sneaking, blocking +# This is only valid if you set a animation on the disguise itself. Because the entity's animations are applied otherwise. +AddEntityAnimations: true + +# This controls if a entity's max health is determined by the entity, or by the disguise. +# Wither is 200, a player is 20. With this enabled, a player disguised as a wither will have the boss bar health accurate to the players health. +# Else it will be 1/20 of the boss bar when they are full health. +# Setting this in LivingWatcher overrides both values. +MaxHealthDeterminedByEntity: true + +# This here is a option to turn off misc disguises. +# This means you can not have a living entity disguise as a non-living entity. +# This disables the Attributes packet, Non-living entities can still disguise as other non-living +# This means that the above option will not work as it uses the attribute packet. +MiscDisguisesForLiving: 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 + +# This will help performance, especially with CPU +# Due to safety reasons, self disguises can never have their packets disabled. +PacketsEnabled: + # This disables the animation packet. If a disguised entity sends a animation packet and they are using a non-living disguise. People will crash. + # Disabling this also means that if a player disguised as a non-player leaves a bug. People will crash + Animation: true + # This disguises the collect packet. If a living entity disguised as a non-living entity picks up a item. People will crash. This fixes it + # This also fixes people crashing if a item disguised as a sleeping player is picked up - Only true if Bed is enabled as well + Collect: true + # This disables a fix for when a disguised entity wearing armor dies, if the disguise can wear armor. It drops unpickupable items to anyone watching. + EntityStatus: true + # Entity equipment is the packets that are sent to ensure that a disguise has or doesn't have armor, and their held item. + # Disabling this means that any disguises which can wear armor or hold items will show the armor/held item that the disguised is wearing. + Equipment: true + # This doesn't actually disable the packet. It would introduce problems. Instead it does the next best thing and caches the data. + # This means that entity metadata will not change, and will only be sent in the spawn packet. + # This is good if performance is extremely in need. + # This is bad to disable unless you are ONLY going to use the disguises for decorations. + # To be honest. This is basically "Disable entity animations". That option is called 'AddEntityAnimations' in the config but unlike that, this is always in effect. + # Animations set by use of the api or through the disguise command are still in effect. + Metadata: true + # Movement packets are the biggest cpu hit. These are majorly used to ensure that the disguises facing direction isn't bugged up. + # If you are using the Item_Frame disguise, when a packet is sent (Roughly every 2min) the disguise will bug up until they move. + Movement: true + # Disable this if you don't mind crashing everytime you see someone riding something disguised as a non-living entity + Riding: true + # When disguised as a wither skull, it sends a look packet every tick so that the wither skull is facing the right way. + WitherSkull: true + # This is only used when using a modded disguises thingy, check disguises.yml for more info + # This is used as a hack to bypass bungeecord issues + LoginPayload: true + +# Added to support a Chinese Minecraft Server which uses their own skin server unless the UUID is not version 4. +# Changing this from 4 to say, 3. Means their server will fetch skins from Mojang instead. +UUIDVersion: 4 diff --git a/src/main/resources/configs/sanity.yml b/src/main/resources/configs/sanity.yml new file mode 100644 index 00000000..12dfe20f --- /dev/null +++ b/src/main/resources/configs/sanity.yml @@ -0,0 +1,41 @@ +# This config is called sanity, because you shouldn't need to change the stuff in here + +#Stop shulker disguises from moving, they're weird. This option only effects PLAYERS that are disguised, other entities disguised as shulkers will NOT be effected! +StopShulkerDisguisesFromMoving: true + +# This means that the plugin doesn't need to constantly call Mojang just to find a skin for an offline player +# However some people may prefer to disable this. +# Even if you disable this, if there was disguises in the cache already then it will use them +SaveGameProfiles: true + +# This option is useless if you don't enable SaveGameProfiles! +# If a player has been disguised before and their skin saved into the cache +# When they join the server will automatically update the cache in case they changed their skin +UpdateGameProfiles: true + +# This modifies the bounding box, This is stuff like can a arrow hit them. +# If you turn this to true, arrows will act like they hit the disguise in the right place! +# Clients will not see any difference in the hitboxes they are attacking, this is a server-sided calculation! +# So someone disguised as a enderdragon will easily get shot down by arrows! +# This WILL conflict with NoCheatPlus. Other plugins may also get problems. +# This shouldn't really be enabled for players as it also interferes with their movement because the server thinks +# the player is larger than they really are. +# That makes the player unable to approach this building because the server thinks they are trying to glitch inside +# blocks. +# This feature is highly experimental and is guaranteed to cause problems for players who are disguised +ModifyBoundingBox: false + +# When a sheep or wolf is right clicked with dye. The client automatically assumes it was successful and displays the sheep's wool or the wolfs collar as dyed. +# This is a option that either prevents that happening, or it changes their color officially in the plugin so that everyone sees it changed. +# Its currently set to false which means that the color is not changed and will refresh itself to the player. +# Please note that this will not remove the dye from their hands. This also does not check if the disguised entity is actually a sheep/wolf and wants a say in its color. +DyeableSheep: false +DyeableWolf: false +DyeableCat: false + +# Can a player interact with a llama with carpet to set or change their carpet color? +CarpetableLlama: false + +# Can a player interact with a non-saddled horse of any type, to give it a saddle? +# This does not change what you can ride or control! +SaddleableHorse: false \ No newline at end of file diff --git a/src/main/resources/sounds.yml b/src/main/resources/configs/sounds.yml similarity index 100% rename from src/main/resources/sounds.yml rename to src/main/resources/configs/sounds.yml