Large config rewrite, updating creates incompatibility with older versions of LD. Probably need to clean up configs a bit more.
This commit is contained in:
		@@ -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;
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<TargetedDisguise> 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<String> doOutput(boolean informChangedUnknown, boolean informMissing) {
 | 
			
		||||
        return doOutput(new ConfigLoader().load(), informChangedUnknown, informMissing);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ArrayList<String> doOutput(ConfigurationSection config, boolean informChangedUnknown, boolean informMissing) {
 | 
			
		||||
        HashMap<String, Object> configs = new HashMap<>();
 | 
			
		||||
        ConfigurationSection defaultSection = config.getDefaultSection();
 | 
			
		||||
 | 
			
		||||
        if (defaultSection == null) {
 | 
			
		||||
            defaultSection = new ConfigLoader().loadDefaults();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        ArrayList<String> 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;
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Class<? extends Entity>> 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")) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String> returns = DisguiseConfig.doOutput(LibsDisguises.getInstance().getConfig(), true, true);
 | 
			
		||||
        ArrayList<String> returns = DisguiseConfig.doOutput(true, true);
 | 
			
		||||
 | 
			
		||||
        if (returns.isEmpty()) {
 | 
			
		||||
            LibsMsg.USING_DEFAULT_CONFIG.send(sender);
 | 
			
		||||
 
 | 
			
		||||
@@ -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<File> 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<String> modified =
 | 
			
		||||
                                DisguiseConfig.doOutput(LibsDisguises.getInstance().getConfig(), true, true);
 | 
			
		||||
                        ArrayList<String> 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
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Entity> 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<String> 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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -161,7 +161,7 @@ public class DisguiseUtilities {
 | 
			
		||||
    private static final HashSet<UUID> selfDisguised = new HashSet<>();
 | 
			
		||||
    private static final HashMap<UUID, String> preDisguiseTeam = new HashMap<>();
 | 
			
		||||
    private static final HashMap<UUID, String> 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) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String> 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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -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<String, DisguiseCommand> 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();
 | 
			
		||||
 
 | 
			
		||||
@@ -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.");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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) {
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
 
 | 
			
		||||
@@ -22,8 +22,31 @@ public class ClassGetter {
 | 
			
		||||
        return getClassesForPackage(Entity.class, pkgname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ArrayList<String> getEntriesForPackage(String pkgname) {
 | 
			
		||||
        return getEntriesForPackage(Entity.class, pkgname);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static ArrayList<Class<?>> getClassesForPackage(Class runFrom, String pkgname) {
 | 
			
		||||
        ArrayList<Class<?>> classes = new ArrayList<>();
 | 
			
		||||
        ArrayList<String> list = getEntriesForPackage(runFrom, pkgname);
 | 
			
		||||
        ArrayList<Class<?>> 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<String> getEntriesForPackage(Class runFrom, String pkgname) {
 | 
			
		||||
        ArrayList<String> 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<Class<?>> classes) {
 | 
			
		||||
    private static void processJarfile(URL resource, String pkgname, ArrayList<String> 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();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -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<String> list = section.getStringList(
 | 
			
		||||
                        type.name().charAt(0) + type.name().substring(1).toLowerCase(Locale.ENGLISH));
 | 
			
		||||
                List<String> 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;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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..");
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
							
								
								
									
										29
									
								
								src/main/resources/configs/combat.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/main/resources/configs/combat.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										54
									
								
								src/main/resources/configs/commands.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/main/resources/configs/commands.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
@@ -1,70 +1,70 @@
 | 
			
		||||
# The best way to use this is with /savedisguise or /saveskin
 | 
			
		||||
# /saveskin MyCustomSkin <SkinName> - Where <SkinName> 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 <SkinName> - 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 <Target> <Optional Name> - 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 <Optional Target Name/UUID> 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 <Item>,<Item>,<Item>,<Item> 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 <SkinName> - Where <SkinName> 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 <SkinName> - 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 <Target> <Optional Name> - 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 <Optional Target Name/UUID> 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 <Item>,<Item>,<Item>,<Item> 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
 | 
			
		||||
							
								
								
									
										42
									
								
								src/main/resources/configs/features.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								src/main/resources/configs/features.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										30
									
								
								src/main/resources/configs/libsdisguises.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								src/main/resources/configs/libsdisguises.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										49
									
								
								src/main/resources/configs/nametags.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/main/resources/configs/nametags.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										45
									
								
								src/main/resources/configs/players.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/main/resources/configs/players.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										74
									
								
								src/main/resources/configs/protocol.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								src/main/resources/configs/protocol.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
							
								
								
									
										41
									
								
								src/main/resources/configs/sanity.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								src/main/resources/configs/sanity.yml
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user