diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b71539c40..6efb3a7318 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ * Added "2 magma blocks -> slime block" recipe to the Freezer * Added configurable enchantment level limit for both auto enchanter and auto disenchanter * (API) Added AutoEnchantEvent +* Added /sf reload #### Changes * Changed item order in guide for the Villager Rune and Nether Goo (All runes are now grouped together) diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java index 664498a26f..0721c9e0ac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java @@ -141,13 +141,16 @@ protected String getErrorMessage() { * This method is called by a {@link SlimefunItem} which wants to load its {@link ItemSetting} * from the {@link Config} file. * + * + * @return Whether the value was successfully updated or misconfigured */ @SuppressWarnings("unchecked") - public void reload() { + public boolean reload() { Validate.notNull(item, "Cannot apply settings for a non-existing SlimefunItem"); - SlimefunPlugin.getItemCfg().setDefaultValue(item.getId() + '.' + getKey(), getDefaultValue()); - Object configuredValue = SlimefunPlugin.getItemCfg().getValue(item.getId() + '.' + getKey()); + Config config = SlimefunPlugin.getConfigManager().getItemsConfig(); + config.setDefaultValue(item.getId() + '.' + getKey(), getDefaultValue()); + Object configuredValue = config.getValue(item.getId() + '.' + getKey()); if (defaultValue.getClass().isInstance(configuredValue)) { // We can do an unsafe cast here, we did an isInstance(...) check before! @@ -155,6 +158,7 @@ public void reload() { if (validateInput(newValue)) { this.value = newValue; + return true; } else { // @formatter:off item.warn( @@ -164,6 +168,7 @@ public void reload() { "\n" + getErrorMessage() ); // @formatter:on + return false; } } else { this.value = defaultValue; @@ -177,6 +182,7 @@ public void reload() { "\n Expected \"" + defaultValue.getClass().getSimpleName() + "\" but found: \"" + found + "\"" ); // @formatter:on + return false; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java index 9763f6a9a2..f486cdd7f3 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -27,6 +27,7 @@ import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.config.SlimefunConfigManager; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideMode; @@ -64,19 +65,12 @@ public final class SlimefunRegistry { private final List researchRanks = new ArrayList<>(); private final Set researchingPlayers = Collections.synchronizedSet(new HashSet<>()); - // TODO: Move this all into a proper "config cache" class - private boolean backwardsCompatibility; - private boolean automaticallyLoadItems; - private boolean enableResearches; - private boolean freeCreativeResearches; - private boolean researchFireworks; - private boolean logDuplicateBlockEntries; - private boolean talismanActionBarMessages; - private final Set tickers = new HashSet<>(); private final Set radioactive = new HashSet<>(); private final Set barterDrops = new HashSet<>(); + private boolean automaticallyLoadItems; + private NamespacedKey soulboundKey; private NamespacedKey itemChargeKey; private NamespacedKey guideKey; @@ -94,25 +88,18 @@ public final class SlimefunRegistry { private final Map, Set> globalItemHandlers = new HashMap<>(); private final Map blockHandlers = new HashMap<>(); - public void load(@Nonnull SlimefunPlugin plugin, @Nonnull Config cfg) { + public void load(@Nonnull SlimefunPlugin plugin) { Validate.notNull(plugin, "The Plugin cannot be null!"); - Validate.notNull(cfg, "The Config cannot be null!"); soulboundKey = new NamespacedKey(plugin, "soulbound"); itemChargeKey = new NamespacedKey(plugin, "item_charge"); guideKey = new NamespacedKey(plugin, "slimefun_guide_mode"); - boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); - guides.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide(showVanillaRecipes)); + guides.put(SlimefunGuideMode.SURVIVAL_MODE, new SurvivalSlimefunGuide()); guides.put(SlimefunGuideMode.CHEAT_MODE, new CheatSheetSlimefunGuide()); + Config cfg = SlimefunPlugin.getConfigManager().getPluginConfig(); researchRanks.addAll(cfg.getStringList("research-ranks")); - - backwardsCompatibility = cfg.getBoolean("options.backwards-compatibility"); - freeCreativeResearches = cfg.getBoolean("researches.free-in-creative-mode"); - researchFireworks = cfg.getBoolean("researches.enable-fireworks"); - logDuplicateBlockEntries = cfg.getBoolean("options.log-duplicate-block-entries"); - talismanActionBarMessages = cfg.getBoolean("talismans.use-actionbar"); } /** @@ -127,29 +114,6 @@ public boolean isAutoLoadingEnabled() { return automaticallyLoadItems; } - /** - * This method returns whether backwards-compatibility is enabled. - * Backwards compatibility allows Slimefun to recognize items from older versions but comes - * at a huge performance cost. - * - * @return Whether backwards compatibility is enabled - */ - public boolean isBackwardsCompatible() { - return backwardsCompatibility; - } - - /** - * This method sets the status of backwards compatibility. - * Backwards compatibility allows Slimefun to recognize items from older versions but comes - * at a huge performance cost. - * - * @param compatible - * Whether backwards compatibility should be enabled - */ - public void setBackwardsCompatible(boolean compatible) { - backwardsCompatibility = compatible; - } - /** * This method will make any {@link SlimefunItem} which is registered automatically * call {@link SlimefunItem#load()}. @@ -220,26 +184,6 @@ public List getResearchRanks() { return researchRanks; } - public void setResearchingEnabled(boolean enabled) { - enableResearches = enabled; - } - - public boolean isResearchingEnabled() { - return enableResearches; - } - - public void setFreeCreativeResearchingEnabled(boolean enabled) { - freeCreativeResearches = enabled; - } - - public boolean isFreeCreativeResearchingEnabled() { - return freeCreativeResearches; - } - - public boolean isResearchFireworkEnabled() { - return researchFireworks; - } - /** * This method returns a {@link List} of every enabled {@link MultiBlock}. * @@ -354,14 +298,6 @@ public KeyMap getGEOResources() { return geoResources; } - public boolean logDuplicateBlockEntries() { - return logDuplicateBlockEntries; - } - - public boolean useActionbarForTalismans() { - return talismanActionBarMessages; - } - @Nonnull public NamespacedKey getSoulboundDataKey() { return soulboundKey; @@ -377,4 +313,30 @@ public NamespacedKey getGuideDataKey() { return guideKey; } + /** + * This has been moved. + * Our metrics module accesses this though. + * + * @deprecated Please use {@link SlimefunConfigManager#isFreeCreativeResearchingEnabled()} + * + * @return free research in creative? + */ + @Deprecated + public boolean isFreeCreativeResearchingEnabled() { + return SlimefunPlugin.getConfigManager().isFreeCreativeResearchingEnabled(); + } + + /** + * This has been moved. + * Our metrics module accesses this though. + * + * @deprecated Please use {@link SlimefunConfigManager#isBackwardsCompatible()} + * + * @return backwards compat? + */ + @Deprecated + public boolean isBackwardsCompatible() { + return SlimefunPlugin.getConfigManager().isBackwardsCompatible(); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java index dc3e4f00d9..58cb2e19d2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/GiveCommand.java @@ -62,7 +62,9 @@ private void giveItem(CommandSender sender, Player p, SlimefunItem sfItem, Strin if (amount > 0) { SlimefunPlugin.getLocalization().sendMessage(p, "messages.given-item", true, msg -> msg.replace(PLACEHOLDER_ITEM, sfItem.getItemName()).replace(PLACEHOLDER_AMOUNT, String.valueOf(amount))); Map excess = p.getInventory().addItem(new CustomItem(sfItem.getItem(), amount)); - if (SlimefunPlugin.getCfg().getBoolean("options.drop-excess-sf-give-items") && !excess.isEmpty()) { + + // Check whether we should drop excess items to the ground + if (SlimefunPlugin.getConfigManager().isExcessCommandItemsDroppingEnabled() && !excess.isEmpty()) { for (ItemStack is : excess.values()) { p.getWorld().dropItem(p.getLocation(), is); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ReloadCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ReloadCommand.java new file mode 100644 index 0000000000..7aa03906ba --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/ReloadCommand.java @@ -0,0 +1,41 @@ +package io.github.thebusybiscuit.slimefun4.core.commands.subcommands; + +import org.bukkit.command.CommandSender; + +import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; +import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; + +class ReloadCommand extends SubCommand { + + ReloadCommand(SlimefunPlugin plugin, SlimefunCommand cmd) { + super(plugin, cmd, "reload", false); + } + + @Override + protected String getDescription() { + return "commands.reload.description"; + } + + @Override + public void onExecute(CommandSender sender, String[] args) { + if (sender.hasPermission("slimefun.command.reload")) { + SlimefunPlugin.getLocalization().sendMessage(sender, "guide.work-in-progress", true); + boolean reloaded = SlimefunPlugin.getConfigManager().reload(); + boolean isRestartRequired = SlimefunPlugin.getConfigManager().isRestartRequired(); + + if (reloaded) { + if (isRestartRequired) { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.reload.restart-required", true); + } else { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.reload.success", true); + } + } else { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.reload.errors", true); + } + } else { + SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); + } + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java index 10378c3ff2..4fce51d51b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/SlimefunSubCommands.java @@ -4,6 +4,8 @@ import java.util.LinkedList; import java.util.List; +import javax.annotation.Nonnull; + import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -20,7 +22,8 @@ public final class SlimefunSubCommands { private SlimefunSubCommands() {} - public static Collection getAllCommands(SlimefunCommand cmd) { + @Nonnull + public static Collection getAllCommands(@Nonnull SlimefunCommand cmd) { SlimefunPlugin plugin = cmd.getPlugin(); List commands = new LinkedList<>(); @@ -38,6 +41,7 @@ public static Collection getAllCommands(SlimefunCommand cmd) { commands.add(new DebugFishCommand(plugin, cmd)); commands.add(new BackpackCommand(plugin, cmd)); commands.add(new ChargeCommand(plugin, cmd)); + commands.add(new ReloadCommand(plugin, cmd)); return commands; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java index 63d9f13e9a..018090a066 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/VersionsCommand.java @@ -67,7 +67,7 @@ public void onExecute(@Nonnull CommandSender sender, @Nonnull String[] args) { addJavaVersion(builder); - if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) { + if (SlimefunPlugin.getConfigManager().isBackwardsCompatible()) { // @formatter:off HoverEvent hoverEvent = new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text( "Backwards compatibility has a negative impact on performance!\n" + diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java new file mode 100644 index 0000000000..4527322eb4 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/SlimefunConfigManager.java @@ -0,0 +1,275 @@ +package io.github.thebusybiscuit.slimefun4.core.config; + +import java.util.function.Supplier; +import java.util.logging.Level; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.apache.commons.lang.Validate; +import org.bukkit.NamespacedKey; +import org.bukkit.Server; +import org.bukkit.plugin.Plugin; + +import io.github.thebusybiscuit.cscorelib2.config.Config; +import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; +import io.github.thebusybiscuit.slimefun4.core.researching.Research; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This class manages our {@link Config}, it caches values for faster access + * and provides means to reload it. + * + * @author TheBusyBiscuit + * + */ +public final class SlimefunConfigManager { + + /** + * Our {@link SlimefunPlugin} instance + */ + private final SlimefunPlugin plugin; + + /** + * Our {@link Plugin} {@link Config} (config.yml) + */ + private final Config pluginConfig; + + /** + * Our {@link SlimefunItem} {@link Config} (Items.yml) + */ + private final Config itemsConfig; + + /** + * Our {@link Research} {@link Config} (Researches.yml) + */ + private final Config researchesConfig; + + /** + * This flag marks whether we require a {@link Server} restart to + * apply the latest changes. + */ + private boolean isRestartRequired = false; + + // Various booleans we want to cache instead of re-parsing everytime + private boolean enableBackwardsCompatibility; + private boolean enableResearching; + private boolean enableFreeCreativeResearches; + private boolean enableResearchFireworks; + private boolean enableDuplicateBlockLogging; + private boolean enableVanillaRecipesInGuide; + private boolean enableGuideOnJoin; + private boolean enableUpdater; + private boolean enableActionbarTalismanMessages; + private boolean enableCommandItemDropExcess; + + /** + * This constructs a new {@link SlimefunConfigManager} for the given instance + * of {@link SlimefunPlugin}. + * + * @param plugin + * The {@link SlimefunPlugin} instance + */ + public SlimefunConfigManager(@Nonnull SlimefunPlugin plugin) { + Validate.notNull(plugin, "The Plugin instance cannot be null"); + + this.plugin = plugin; + pluginConfig = getConfig(plugin, "config", () -> new Config(plugin)); + itemsConfig = getConfig(plugin, "Items", () -> new Config(plugin, "Items.yml")); + researchesConfig = getConfig(plugin, "Researches", () -> new Config(plugin, "Researches.yml")); + } + + @Nullable + @ParametersAreNonnullByDefault + private Config getConfig(SlimefunPlugin plugin, String name, Supplier supplier) { + try { + return supplier.get(); + } catch (Exception x) { + plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was thrown while loading the config file \"" + name + ".yml\" for Slimefun v" + plugin.getDescription().getVersion()); + return null; + } + } + + /** + * This method (re)loads all relevant config values into our cache. + *

+ * Note that this method is not guaranteed to reload all settings. + * + * @return Whether the reloading was successful and completed without any errors + */ + public boolean reload() { + boolean isSuccessful = true; + + try { + pluginConfig.reload(); + itemsConfig.reload(); + researchesConfig.reload(); + + researchesConfig.setDefaultValue("enable-researching", true); + + enableBackwardsCompatibility = pluginConfig.getBoolean("options.backwards-compatibility"); + enableResearching = researchesConfig.getBoolean("enable-researching"); + enableFreeCreativeResearches = pluginConfig.getBoolean("researches.free-in-creative-mode"); + enableResearchFireworks = pluginConfig.getBoolean("researches.enable-fireworks"); + enableDuplicateBlockLogging = pluginConfig.getBoolean("options.log-duplicate-block-entries"); + enableVanillaRecipesInGuide = pluginConfig.getBoolean("guide.show-vanilla-recipes"); + enableGuideOnJoin = pluginConfig.getBoolean("guide.receive-on-first-join"); + enableUpdater = pluginConfig.getBoolean("options.auto-update"); + enableActionbarTalismanMessages = pluginConfig.getBoolean("talismans.use-actionbar"); + enableCommandItemDropExcess = pluginConfig.getBoolean("options.drop-excess-sf-give-items"); + } catch (Exception x) { + plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while (re)loading the config files for Slimefun v" + plugin.getDescription().getVersion()); + isSuccessful = false; + } + + // Reload Research costs + for (Research research : SlimefunPlugin.getRegistry().getResearches()) { + try { + NamespacedKey key = research.getKey(); + int cost = researchesConfig.getInt(key.getNamespace() + '.' + key.getKey() + ".cost"); + research.setCost(cost); + + if (!researchesConfig.getBoolean(key.getNamespace() + '.' + key.getKey() + ".enabled")) { + // Disabling a research requires a restart (for now) + isRestartRequired = true; + } + } catch (Exception x) { + plugin.getLogger().log(Level.SEVERE, x, () -> "Something went wrong while trying to update the cost of a research: " + research); + isSuccessful = false; + } + } + + for (SlimefunItem item : SlimefunPlugin.getRegistry().getAllSlimefunItems()) { + if (item.isDisabled() != !itemsConfig.getBoolean(item.getId() + ".enabled")) { + // Enabling/Disabling an item requires a restart (for now) + isRestartRequired = true; + } + + // Reload Item Settings + try { + for (ItemSetting setting : item.getItemSettings()) { + // Make sure that the setting was loaded properly + if (!setting.reload()) { + isSuccessful = false; + } + } + } catch (Exception x) { + item.error("Something went wrong while updating the settings for this item!", x); + isSuccessful = false; + } + + // Reload permissions + try { + SlimefunPlugin.getPermissionsService().update(item, false); + } catch (Exception x) { + item.error("Something went wrong while updating the permission node for this item!", x); + isSuccessful = false; + } + } + + return isSuccessful; + } + + /** + * This method returns whether the {@link Server} should be restarted to apply the latest changes. + * + * @return Whether a restart is required. + */ + public boolean isRestartRequired() { + return isRestartRequired; + } + + @Nonnull + public Config getPluginConfig() { + return pluginConfig; + } + + @Nonnull + public Config getItemsConfig() { + return itemsConfig; + } + + @Nonnull + public Config getResearchConfig() { + return researchesConfig; + } + + /** + * This method saves all our {@link Config} files. + */ + public void saveFiles() { + pluginConfig.save(); + itemsConfig.save(); + researchesConfig.save(); + } + + /** + * This method returns whether backwards-compatibility is enabled. + * Backwards compatibility allows Slimefun to recognize items from older versions but comes + * at a huge performance cost. + * + * @return Whether backwards compatibility is enabled + */ + public boolean isBackwardsCompatible() { + return enableBackwardsCompatibility; + } + + /** + * This method sets the status of backwards compatibility. + * Backwards compatibility allows Slimefun to recognize items from older versions but comes + * at a huge performance cost. + * + * @param compatible + * Whether backwards compatibility should be enabled + */ + public void setBackwardsCompatible(boolean compatible) { + enableBackwardsCompatibility = compatible; + } + + public void setResearchingEnabled(boolean enabled) { + enableResearching = enabled; + } + + public boolean isResearchingEnabled() { + return enableResearching; + } + + public void setFreeCreativeResearchingEnabled(boolean enabled) { + enableFreeCreativeResearches = enabled; + } + + public boolean isFreeCreativeResearchingEnabled() { + return enableFreeCreativeResearches; + } + + public boolean isResearchFireworkEnabled() { + return enableResearchFireworks; + } + + public boolean isDuplicateBlockLoggingEnabled() { + return enableDuplicateBlockLogging; + } + + public boolean isVanillaRecipeShown() { + return enableVanillaRecipesInGuide; + } + + public boolean isSlimefunGuideGivenOnJoin() { + return enableGuideOnJoin; + } + + public boolean isUpdaterEnabled() { + return enableUpdater; + } + + public boolean isTalismanMessageInActionbar() { + return enableActionbarTalismanMessages; + } + + public boolean isExcessCommandItemsDroppingEnabled() { + return enableCommandItemDropExcess; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/package-info.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/package-info.java new file mode 100644 index 0000000000..b2554606da --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/config/package-info.java @@ -0,0 +1,6 @@ +/** + * This package houses our {@link io.github.thebusybiscuit.slimefun4.core.config.SlimefunConfigManager}. + * This class is responsible for managing and caching our {@link io.github.thebusybiscuit.cscorelib2.config.Config} + * settings. + */ +package io.github.thebusybiscuit.slimefun4.core.config; \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java index 873ce51050..d0ea1e3693 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideImplementation.java @@ -59,7 +59,7 @@ public interface SlimefunGuideImplementation { default void unlockItem(Player p, SlimefunItem sfitem, Consumer callback) { Research research = sfitem.getResearch(); - if (p.getGameMode() == GameMode.CREATIVE && SlimefunPlugin.getRegistry().isFreeCreativeResearchingEnabled()) { + if (p.getGameMode() == GameMode.CREATIVE && SlimefunPlugin.getConfigManager().isFreeCreativeResearchingEnabled()) { research.unlock(p, true, callback); } else { p.setLevel(p.getLevel() - research.getCost()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java index 25465c92df..146c8a1aa7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/options/FireworksOption.java @@ -26,7 +26,7 @@ public NamespacedKey getKey() { @Override public Optional getDisplayItem(Player p, ItemStack guide) { - if (SlimefunPlugin.getRegistry().isResearchFireworkEnabled()) { + if (SlimefunPlugin.getConfigManager().isResearchFireworkEnabled()) { boolean enabled = getSelectedOption(p, guide).orElse(true); ItemStack item = new CustomItem(Material.FIREWORK_ROCKET, "&bFireworks: &" + (enabled ? "aYes" : "4No"), "", "&7You can now toggle whether you", "&7will be presented with a big firework", "&7upon researching an item.", "", "&7\u21E8 &eClick to " + (enabled ? "disable" : "enable") + " your fireworks"); return Optional.of(item); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/PlayerResearchTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/PlayerResearchTask.java index 305d821038..d29a67c4b0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/PlayerResearchTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/PlayerResearchTask.java @@ -109,7 +109,7 @@ private void unlockResearch(@Nonnull Player p, @Nonnull PlayerProfile profile) { onFinish(p); // Check if the Server and the Player have enabled fireworks for researches - if (SlimefunPlugin.getRegistry().isResearchFireworkEnabled() && SlimefunGuideSettings.hasFireworksEnabled(p)) { + if (SlimefunPlugin.getConfigManager().isResearchFireworkEnabled() && SlimefunGuideSettings.hasFireworksEnabled(p)) { FireworkUtils.launchRandom(p, 1); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/Research.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/Research.java index 99950d5d49..242fd9cb6b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/Research.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/researching/Research.java @@ -18,6 +18,7 @@ import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.api.events.PlayerPreResearchEvent; import io.github.thebusybiscuit.slimefun4.api.events.ResearchUnlockEvent; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; @@ -88,7 +89,7 @@ public NamespacedKey getKey() { * @return Whether this {@link Research} is enabled or not */ public boolean isEnabled() { - return SlimefunPlugin.getRegistry().isResearchingEnabled() && enabled; + return SlimefunPlugin.getConfigManager().isResearchingEnabled() && enabled; } /** @@ -239,7 +240,7 @@ public boolean canUnlock(@Nonnull Player p) { return true; } - boolean creativeResearch = p.getGameMode() == GameMode.CREATIVE && SlimefunPlugin.getRegistry().isFreeCreativeResearchingEnabled(); + boolean creativeResearch = p.getGameMode() == GameMode.CREATIVE && SlimefunPlugin.getConfigManager().isFreeCreativeResearchingEnabled(); return creativeResearch || p.getLevel() >= cost; } @@ -273,10 +274,10 @@ public void unlock(@Nonnull Player p, boolean isInstant, @Nullable Consumer(items)) { if (item != null) { item.setResearch(null); @@ -287,10 +288,10 @@ public void register() { return; } - SlimefunPlugin.getResearchCfg().setDefaultValue(path + ".cost", getCost()); - SlimefunPlugin.getResearchCfg().setDefaultValue(path + ".enabled", true); + config.setDefaultValue(path + ".cost", getCost()); + config.setDefaultValue(path + ".enabled", true); - setCost(SlimefunPlugin.getResearchCfg().getInt(path + ".cost")); + setCost(config.getInt(path + ".cost")); enabled = true; SlimefunPlugin.getRegistry().getResearches().add(this); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java index 5577c0a64d..b0ffcc5ee7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java @@ -57,7 +57,7 @@ public LocalizationService(@Nonnull SlimefunPlugin plugin, @Nullable String pref languageKey = new NamespacedKey(plugin, LANGUAGE_PATH); if (serverDefaultLanguage != null) { - translationsEnabled = SlimefunPlugin.getCfg().getBoolean("options.enable-translations"); + translationsEnabled = SlimefunPlugin.getConfigManager().getPluginConfig().getBoolean("options.enable-translations"); defaultLanguage = new Language(serverDefaultLanguage, "11b3188fd44902f72602bd7c2141f5a70673a411adb3d81862c69e536166b"); defaultLanguage.setMessagesFile(getConfig().getConfiguration()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PermissionsService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PermissionsService.java index e32ce2428e..b4d7f379be 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PermissionsService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PermissionsService.java @@ -37,15 +37,10 @@ public PermissionsService(@Nonnull SlimefunPlugin plugin) { config.getConfiguration().options().copyHeader(true); } - public void register(@Nonnull Iterable items, boolean save) { + public void update(@Nonnull Iterable items, boolean save) { for (SlimefunItem item : items) { if (item != null) { - String path = item.getId() + ".permission"; - - config.setDefaultValue(path, "none"); - config.setDefaultValue(item.getId() + ".lore", new String[] { "&rYou do not have the permission", "&rto access this item." }); - - permissions.put(item.getId(), config.getString(path)); + update(item, false); } } @@ -54,6 +49,21 @@ public void register(@Nonnull Iterable items, boolean save) { } } + public void update(@Nonnull SlimefunItem item, boolean save) { + Validate.notNull(item, "The Item should not be null!"); + + String path = item.getId() + ".permission"; + + config.setDefaultValue(path, "none"); + config.setDefaultValue(item.getId() + ".lore", new String[] { "&rYou do not have the permission", "&rto access this item." }); + + permissions.put(item.getId(), config.getString(path)); + + if (save) { + config.save(); + } + } + /** * This method checks whether the given {@link Permissible} has the {@link Permission} * to access the given {@link SlimefunItem}. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java index b323d3f2f1..2886e9a379 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/UpdaterService.java @@ -135,7 +135,7 @@ public void start() { * @return Whether the {@link Updater} is enabled */ public boolean isEnabled() { - return SlimefunPlugin.getCfg().getBoolean("options.auto-update") && updater != null; + return SlimefunPlugin.getConfigManager().isUpdaterEnabled() && updater != null; } /** diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java index c76cdaa4d1..77275e59e5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -22,7 +22,9 @@ import org.bukkit.command.Command; import org.bukkit.entity.Player; import org.bukkit.event.Listener; +import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; +import org.bukkit.permissions.Permission; import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; @@ -39,6 +41,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.SlimefunRegistry; import io.github.thebusybiscuit.slimefun4.core.commands.SlimefunCommand; +import io.github.thebusybiscuit.slimefun4.core.config.SlimefunConfigManager; import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager; import io.github.thebusybiscuit.slimefun4.core.services.AutoSavingService; import io.github.thebusybiscuit.slimefun4.core.services.BackupService; @@ -125,6 +128,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; /** @@ -137,7 +141,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { /** * Our static instance of {@link SlimefunPlugin}. - * Make sure to clean this up in {@link #onDisable()} ! + * Make sure to clean this up in {@link #onDisable()}! */ private static SlimefunPlugin instance; @@ -171,6 +175,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { private final HologramsService hologramsService = new HologramsService(this); // Some other things we need + private final SlimefunConfigManager configManager = new SlimefunConfigManager(this); private final IntegrationsManager integrations = new IntegrationsManager(this); private final SlimefunProfiler profiler = new SlimefunProfiler(); private final GPSNetwork gpsNetwork = new GPSNetwork(this); @@ -179,11 +184,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { private NetworkManager networkManager; private LocalizationService local; - // Important config files for Slimefun - private final Config config = new Config(this); - private final Config items = new Config(this, "Items.yml"); - private final Config researches = new Config(this, "Researches.yml"); - // Listeners that need to be accessed elsewhere private final GrapplingHookListener grapplingHookListener = new GrapplingHookListener(); private final BackpackListener backpackListener = new BackpackListener(); @@ -242,7 +242,8 @@ private void onUnitTestStart() { local = new LocalizationService(this, "", null); networkManager = new NetworkManager(200); command.register(); - registry.load(this, config); + configManager.reload(); + registry.load(this); loadTags(); } @@ -261,8 +262,8 @@ private void onPluginStart() { // Disabling backwards-compatibility for fresh Slimefun installs if (!new File("data-storage/Slimefun").exists()) { - config.setValue("options.backwards-compatibility", false); - config.save(); + configManager.getPluginConfig().setValue("options.backwards-compatibility", false); + configManager.getPluginConfig().save(); isNewlyInstalled = true; } @@ -270,10 +271,12 @@ private void onPluginStart() { // Creating all necessary Folders getLogger().log(Level.INFO, "Creating directories..."); createDirectories(); - registry.load(this, config); + configManager.reload(); + registry.load(this); // Set up localization getLogger().log(Level.INFO, "Loading language files..."); + Config config = configManager.getPluginConfig(); local = new LocalizationService(this, config.getString("options.chat-prefix"), config.getString("options.language")); int networkSize = config.getInt("networks.max-size"); @@ -290,7 +293,7 @@ private void onPluginStart() { new Thread(metricsService::start, "Slimefun Metrics").start(); // Starting the Auto-Updater - if (config.getBoolean("options.auto-update")) { + if (updaterService.isEnabled()) { getLogger().log(Level.INFO, "Starting Auto-Updater..."); updaterService.start(); } else { @@ -310,7 +313,7 @@ private void onPluginStart() { getLogger().log(Level.INFO, "Loading researches..."); loadResearches(); - registry.setResearchingEnabled(getResearchCfg().getBoolean("enable-researching")); + // Load our wiki entries PostSetup.setupWiki(); getLogger().log(Level.INFO, "Registering listeners..."); @@ -319,7 +322,7 @@ private void onPluginStart() { // Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading) runSync(new SlimefunStartupTask(this, () -> { textureService.register(registry.getAllSlimefunItems(), true); - permissionsService.register(registry.getAllSlimefunItems(), true); + permissionsService.update(registry.getAllSlimefunItems(), true); // This try/catch should prevent buggy Spigot builds from blocking item loading try { @@ -669,7 +672,7 @@ private void registerListeners() { backpackListener.register(this); // Handle Slimefun Guide being given on Join - new SlimefunGuideListener(this, config.getBoolean("guide.receive-on-first-join")); + new SlimefunGuideListener(this, configManager.isSlimefunGuideGivenOnJoin()); // Clear the Slimefun Guide History upon Player Leaving new PlayerProfileListener(this); @@ -762,21 +765,48 @@ public static String getVersion() { } @Nonnull - public static Config getCfg() { + public static SlimefunConfigManager getConfigManager() { validateInstance(); - return instance.config; + return instance.configManager; } + /** + * This returns the config. + * + * @deprecated Use {@link #getConfigManager()} instead. + * + * @return the {@link Config} + */ + @Deprecated + @Nonnull + public static Config getCfg() { + return getConfigManager().getPluginConfig(); + } + + /** + * This returns the research config. + * + * @deprecated Use {@link #getConfigManager()} instead. + * + * @return the {@link Config} or researches + */ + @Deprecated @Nonnull public static Config getResearchCfg() { - validateInstance(); - return instance.researches; + return getConfigManager().getResearchConfig(); } + /** + * This returns the items config. + * + * @deprecated Use {@link #getConfigManager()} instead. + * + * @return the {@link Config} for items + */ + @Deprecated @Nonnull public static Config getItemCfg() { - validateInstance(); - return instance.items; + return getConfigManager().getItemsConfig(); } /** @@ -810,7 +840,7 @@ public static LocalizationService getLocalization() { } /** - * This method returns out {@link MinecraftRecipeService} for Slimefun. + * This method returns our {@link MinecraftRecipeService} for Slimefun. * This service is responsible for finding/identifying {@link Recipe Recipes} * from vanilla Minecraft. * @@ -822,18 +852,40 @@ public static MinecraftRecipeService getMinecraftRecipeService() { return instance.recipeService; } + /** + * This returns our {@link CustomItemDataService}. + * The service is responsible for assigning/reading custom persistent data to/from + * an {@link ItemStack}. + *

+ * We use it to store our {@link SlimefunItem} ids on the {@link ItemStack}. + * + * @return Our {@link CustomItemDataService} instance + */ @Nonnull public static CustomItemDataService getItemDataService() { validateInstance(); return instance.itemDataService; } + /** + * This returns our instance of {@link CustomTextureService}. + * This service assigns every {@link SlimefunItemStack} the corresponding + * custom model data as defined in the {@link Config}. + * + * @return Our {@link CustomTextureService} instance + */ @Nonnull public static CustomTextureService getItemTextureService() { validateInstance(); return instance.textureService; } + /** + * This method returns our {@link PermissionsService}. + * This service handles any configured {@link Permission} for a {@link SlimefunItem}. + * + * @return Our {@link PermissionsService} + */ @Nonnull public static PermissionsService getPermissionsService() { validateInstance(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java index f3594dcd80..c4079a0a85 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/CheatSheetSlimefunGuide.java @@ -33,8 +33,7 @@ public class CheatSheetSlimefunGuide extends SurvivalSlimefunGuide { private final ItemStack item; public CheatSheetSlimefunGuide() { - super(false); - + super(); item = new SlimefunGuideItem(this, "&cSlimefun Guide &4(Cheat Sheet)"); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java index a986df51d4..0bb39ed3f7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/SurvivalSlimefunGuide.java @@ -71,10 +71,8 @@ public class SurvivalSlimefunGuide implements SlimefunGuideImplementation { private final int[] recipeSlots = { 3, 4, 5, 12, 13, 14, 21, 22, 23 }; private final ItemStack item; - private final boolean showVanillaRecipes; - public SurvivalSlimefunGuide(boolean showVanillaRecipes) { - this.showVanillaRecipes = showVanillaRecipes; + public SurvivalSlimefunGuide() { item = new SlimefunGuideItem(this, "&aSlimefun Guide &7(Chest GUI)"); } @@ -395,7 +393,7 @@ public void displayItem(PlayerProfile profile, ItemStack item, int index, boolea return; } - if (!showVanillaRecipes) { + if (!SlimefunPlugin.getConfigManager().isVanillaRecipeShown()) { return; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java index 8c9f34f6f1..cabc51f4d6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/talismans/Talisman.java @@ -274,7 +274,7 @@ public void sendMessage(@Nonnull Player p) { try { String messageKey = "messages.talisman." + getMessageSuffix(); - if (SlimefunPlugin.getRegistry().useActionbarForTalismans()) { + if (SlimefunPlugin.getConfigManager().isTalismanMessageInActionbar()) { // Use the actionbar SlimefunPlugin.getLocalization().sendActionbarMessage(p, messageKey, false); } else { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java index 874c07ad3f..30ec90d308 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/OreCrusher.java @@ -200,35 +200,43 @@ public void update(Boolean newValue) { } @Override - public void reload() { - super.reload(); + public boolean reload() { + boolean isSuccessful = super.reload(); apply(getValue()); + return isSuccessful; } + @Nonnull public ItemStack getCoal() { return coal; } + @Nonnull public ItemStack getLapisLazuli() { return lapis; } + @Nonnull public ItemStack getRedstone() { return redstone; } + @Nonnull public ItemStack getDiamond() { return diamond; } + @Nonnull public ItemStack getEmerald() { return emerald; } + @Nonnull public ItemStack getNetherQuartz() { return quartz; } + @Nonnull public ItemStack getGoldNuggets() { return goldNuggets; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java index b44b87c03f..fcc222bf86 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/PostSetup.java @@ -107,8 +107,7 @@ public static void loadItems() { sender.sendMessage(""); - SlimefunPlugin.getItemCfg().save(); - SlimefunPlugin.getResearchCfg().save(); + SlimefunPlugin.getConfigManager().saveFiles(); SlimefunPlugin.getRegistry().setAutoLoadingMode(true); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java index 510dfc07d4..b8f2de2bd9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java @@ -131,7 +131,7 @@ private void handleSlimefunArmor(Player p, ItemStack[] armor, HashedArmorpiece[] private void checkForSolarHelmet(@Nonnull Player p) { ItemStack helmet = p.getInventory().getHelmet(); - if (SlimefunPlugin.getRegistry().isBackwardsCompatible() && !SlimefunUtils.isItemSimilar(helmet, SlimefunItems.SOLAR_HELMET, true, false)) { + if (SlimefunPlugin.getConfigManager().isBackwardsCompatible() && !SlimefunUtils.isItemSimilar(helmet, SlimefunItems.SOLAR_HELMET, true, false)) { // Performance saver for slow backwards-compatible versions of Slimefun return; } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java index 015a4280cf..e9d6586b45 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/SlimefunItem.java @@ -23,6 +23,7 @@ import org.bukkit.permissions.Permission; import io.github.thebusybiscuit.cscorelib2.collections.OptionalMap; +import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; @@ -455,13 +456,15 @@ public void register(@Nonnull SlimefunAddon addon) { SlimefunPlugin.getRegistry().getAllSlimefunItems().add(this); SlimefunPlugin.getRegistry().getSlimefunItemIds().put(id, this); + Config config = SlimefunPlugin.getConfigManager().getItemsConfig(); + // Items that are "not-configurable" cannot be configured. if (!(this instanceof NotConfigurable)) { - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".enabled", true); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".can-be-used-in-workbenches", useableInWorkbench); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".hide-in-guide", hidden); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".allow-enchanting", enchantable); - SlimefunPlugin.getItemCfg().setDefaultValue(id + ".allow-disenchanting", disenchantable); + config.setDefaultValue(id + ".enabled", true); + config.setDefaultValue(id + ".can-be-used-in-workbenches", useableInWorkbench); + config.setDefaultValue(id + ".hide-in-guide", hidden); + config.setDefaultValue(id + ".allow-enchanting", enchantable); + config.setDefaultValue(id + ".allow-disenchanting", disenchantable); // Load all item settings for (ItemSetting setting : itemSettings) { @@ -469,7 +472,7 @@ public void register(@Nonnull SlimefunAddon addon) { } } - if (ticking && !SlimefunPlugin.getCfg().getBoolean("URID.enable-tickers")) { + if (ticking && !SlimefunPlugin.getConfigManager().getPluginConfig().getBoolean("URID.enable-tickers")) { state = ItemState.DISABLED; return; } @@ -480,13 +483,13 @@ public void register(@Nonnull SlimefunAddon addon) { * Any other settings will remain as default. */ state = ItemState.ENABLED; - } else if (SlimefunPlugin.getItemCfg().getBoolean(id + ".enabled")) { + } else if (config.getBoolean(id + ".enabled")) { // The item has been enabled. state = ItemState.ENABLED; - useableInWorkbench = SlimefunPlugin.getItemCfg().getBoolean(id + ".can-be-used-in-workbenches"); - hidden = SlimefunPlugin.getItemCfg().getBoolean(id + ".hide-in-guide"); - enchantable = SlimefunPlugin.getItemCfg().getBoolean(id + ".allow-enchanting"); - disenchantable = SlimefunPlugin.getItemCfg().getBoolean(id + ".allow-disenchanting"); + useableInWorkbench = config.getBoolean(id + ".can-be-used-in-workbenches"); + hidden = config.getBoolean(id + ".hide-in-guide"); + enchantable = config.getBoolean(id + ".allow-enchanting"); + disenchantable = config.getBoolean(id + ".allow-disenchanting"); } else if (this instanceof VanillaItem) { // This item is a vanilla "mock" but was disabled. state = ItemState.VANILLA_FALLBACK; @@ -780,7 +783,7 @@ public boolean isItem(@Nullable ItemStack item) { } // Backwards compatibility - if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) { + if (SlimefunPlugin.getConfigManager().isBackwardsCompatible()) { boolean loreInsensitive = this instanceof Rechargeable || this instanceof SlimefunBackpack || id.equals("BROKEN_SPAWNER") || id.equals("REINFORCED_SPAWNER"); return SlimefunUtils.isItemSimilar(item, this.itemStackTemplate, !loreInsensitive); } else { @@ -1171,7 +1174,7 @@ public static SlimefunItem getByItem(@Nullable ItemStack item) { } // Backwards compatibility - if (SlimefunPlugin.getRegistry().isBackwardsCompatible()) { + if (SlimefunPlugin.getConfigManager().isBackwardsCompatible()) { // This wrapper improves the heavy ItemStack#getItemMeta() call by caching it. ItemStackWrapper wrapper = new ItemStackWrapper(item); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java index 5c75ac8636..f1f853e67a 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java @@ -140,7 +140,7 @@ private void loadBlocks(File directory) { long done = 0; long timestamp = System.currentTimeMillis(); long totalBlocks = 0; - int delay = SlimefunPlugin.getCfg().getInt("URID.info-delay"); + int delay = SlimefunPlugin.getConfigManager().getPluginConfig().getInt("URID.info-delay"); try { for (File file : directory.listFiles()) { @@ -195,7 +195,7 @@ private void loadBlock(File file, FileConfiguration cfg, String key) { * Ignore the new entry if a block is already present and print an * error to the console (if enabled). */ - if (SlimefunPlugin.getRegistry().logDuplicateBlockEntries()) { + if (SlimefunPlugin.getConfigManager().isDuplicateBlockLoggingEnabled()) { SlimefunPlugin.logger().log(Level.INFO, "Ignoring duplicate block @ {0}, {1}, {2} ({3} -> {4})", new Object[] { l.getBlockX(), l.getBlockY(), l.getBlockZ(), blockInfo.getString("id"), storage.get(l).getString("id") }); } diff --git a/src/main/resources/languages/messages_en.yml b/src/main/resources/languages/messages_en.yml index 6f1daac08e..ad3888c86d 100644 --- a/src/main/resources/languages/messages_en.yml +++ b/src/main/resources/languages/messages_en.yml @@ -14,6 +14,12 @@ commands: reset: '&cYou have reset %player%''s Knowledge' reset-target: '&cYour Knowledge has been reset' + reload: + description: Reloads our config files + restart-required: '&eYour changes have been saved. But some of your changes require a restart to get applied!' + success: '&aYour configuration files have been successfully reloaded!' + errors: '&cYour configuration files have been reloaded, but some errors have been found! Please check your console for more info.' + backpack: description: Retrieve a copy of an existing backpack invalid-id: '&4The id must be a non-negative number!' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index f6bc1c3e2b..3617d76fd8 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -83,3 +83,6 @@ permissions: slimefun.debugging: description: Allows you to use the debugging tool from Slimefun default: op + slimefun.command.reload: + description: Allows you to do /sf reload + default: op diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestResearchCommand.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestResearchCommand.java index 7afd2665d3..b8a78c9bde 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestResearchCommand.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/commands/TestResearchCommand.java @@ -42,7 +42,7 @@ public static void unload() { @Test @DisplayName("Test /sf research all") void testResearchAll() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -55,7 +55,7 @@ void testResearchAll() throws InterruptedException { @Test @DisplayName("Test /sf research ") void testResearchSpecific() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -68,7 +68,7 @@ void testResearchSpecific() throws InterruptedException { @Test @DisplayName("Test /sf research reset") void testResearchReset() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/TestSlimefunItem.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/TestSlimefunItem.java index 343303f1a4..6c191e85dd 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/TestSlimefunItem.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/TestSlimefunItem.java @@ -120,13 +120,13 @@ void testIsItem(boolean compatibility) { Assertions.assertFalse(sfItem.isItem(new CustomItem(Material.REDSTONE, "&cTest"))); if (compatibility) { - SlimefunPlugin.getRegistry().setBackwardsCompatible(true); + SlimefunPlugin.getConfigManager().setBackwardsCompatible(true); Assertions.assertEquals(sfItem, SlimefunItem.getByItem(item)); Assertions.assertTrue(sfItem.isItem(item)); Assertions.assertTrue(sfItem.isItem(new CustomItem(Material.BEACON, "&cItem Test"))); - SlimefunPlugin.getRegistry().setBackwardsCompatible(false); + SlimefunPlugin.getConfigManager().setBackwardsCompatible(false); } else { Assertions.assertFalse(sfItem.isItem(item)); Assertions.assertFalse(sfItem.isItem(new CustomItem(Material.BEACON, "&cItem Test"))); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCargoNodeListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCargoNodeListener.java index 66576a915a..193c81a932 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCargoNodeListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestCargoNodeListener.java @@ -100,7 +100,7 @@ void testGrassPlacement() { @Test @DisplayName("Test non-Cargo node not being affected") void testNonCargoNode() { - SlimefunPlugin.getRegistry().setBackwardsCompatible(true); + SlimefunPlugin.getConfigManager().setBackwardsCompatible(true); Player player = server.addPlayer(); Location l = new Location(player.getWorld(), 190, 50, 400); Block b = l.getBlock(); @@ -111,7 +111,7 @@ void testNonCargoNode() { BlockPlaceEvent event = new BlockPlaceEvent(b, b.getState(), against, item, player, true, EquipmentSlot.HAND); listener.onCargoNodePlace(event); Assertions.assertFalse(event.isCancelled()); - SlimefunPlugin.getRegistry().setBackwardsCompatible(false); + SlimefunPlugin.getConfigManager().setBackwardsCompatible(false); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java index bb0aadca7b..34cafc8c8d 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/registration/TestCategories.java @@ -173,7 +173,7 @@ void testLockedCategoriesUnlocking() throws InterruptedException { item.register(plugin); item.load(); - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Research research = new Research(new NamespacedKey(plugin, "cant_touch_this"), 432432, "MC Hammer", 90); research.addItems(item); research.register(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java index e853406021..0b90a05622 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestProfileResearches.java @@ -36,7 +36,7 @@ public static void unload() { @Test @DisplayName("Test setting a Research as unlocked") void testSetResearched() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -57,7 +57,7 @@ void testSetResearched() throws InterruptedException { @Test @DisplayName("Test checking if Research is unlocked") void testHasUnlocked() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -76,14 +76,14 @@ void testHasUnlocked() throws InterruptedException { // Researches are disabled now, so this method should pass // Whether Research#isEnabled() works correctly is covered elsewhere - SlimefunPlugin.getRegistry().setResearchingEnabled(false); + SlimefunPlugin.getConfigManager().setResearchingEnabled(false); Assertions.assertTrue(profile.hasUnlocked(research)); } @Test @DisplayName("Test getting all unlocked Researches") void testGetResearches() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java index 1af5501a10..f560d28a87 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchSetup.java @@ -42,7 +42,7 @@ void testForExceptions() { // Not really ideal but still important to test. // Research amount is variable, so we can't test for that. // We are really only concerned about any runtime exceptions here. - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Assertions.assertDoesNotThrow(() -> ResearchSetup.setupResearches()); // Running it a second time should NOT be allowed. diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java index 9f4f88bac2..13cceb59df 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearchUnlocking.java @@ -55,7 +55,7 @@ private Player awaitUnlock(Player player, Research research, boolean instant) th @DisplayName("Test Unlocking Researches") @ValueSource(booleans = { true, false }) void testUnlock(boolean instant) throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); Research research = new Research(new NamespacedKey(plugin, "unlock_me"), 1842, "Unlock me", 500); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java index 9c6dd4b215..3ae786258e 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/researches/TestResearches.java @@ -81,7 +81,7 @@ void testResearchRegistration() { research.addItems(item, null); research.register(); - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Assertions.assertTrue(research.isEnabled()); Assertions.assertEquals(research, item.getResearch()); @@ -100,7 +100,7 @@ void testDisabledResearch() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "RESEARCH_TEST", new CustomItem(Material.TORCH, "&bResearch Test")); research.addItems(item); - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); SlimefunPlugin.getResearchCfg().setValue(key.getNamespace() + '.' + key.getKey() + ".enabled", false); research.register(); @@ -114,11 +114,11 @@ void testResearchGloballyDisabled() { NamespacedKey key = new NamespacedKey(plugin, "globally_disabled_research"); Research research = new Research(key, 3, "Test", 100); - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Assertions.assertTrue(research.isEnabled()); - SlimefunPlugin.getRegistry().setResearchingEnabled(false); + SlimefunPlugin.getConfigManager().setResearchingEnabled(false); Assertions.assertFalse(research.isEnabled()); - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); } @Test @@ -137,7 +137,7 @@ void testAddItems() { @Test void testPlayerCanUnlockDisabledResearch() { - SlimefunPlugin.getRegistry().setResearchingEnabled(false); + SlimefunPlugin.getConfigManager().setResearchingEnabled(false); Player player = server.addPlayer(); NamespacedKey key = new NamespacedKey(plugin, "disabled_unlockable_research"); @@ -145,19 +145,19 @@ void testPlayerCanUnlockDisabledResearch() { Assertions.assertTrue(research.canUnlock(player)); - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); } @Test @DisplayName("Test 'free creative researching' option") void testFreeCreativeResearch() { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); Player player = server.addPlayer(); NamespacedKey key = new NamespacedKey(plugin, "free_creative_research"); Research research = new Research(key, 153, "Test", 100); - SlimefunPlugin.getRegistry().setFreeCreativeResearchingEnabled(false); + SlimefunPlugin.getConfigManager().setFreeCreativeResearchingEnabled(false); player.setGameMode(GameMode.SURVIVAL); Assertions.assertFalse(research.canUnlock(player)); @@ -165,7 +165,7 @@ void testFreeCreativeResearch() { player.setGameMode(GameMode.CREATIVE); Assertions.assertFalse(research.canUnlock(player)); - SlimefunPlugin.getRegistry().setFreeCreativeResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setFreeCreativeResearchingEnabled(true); player.setGameMode(GameMode.SURVIVAL); Assertions.assertFalse(research.canUnlock(player)); @@ -189,7 +189,7 @@ void testUnlockableResearch() { @Test @DisplayName("Test PlayerPreResearchEvent") void testPreCanUnlockResearchEvent() throws InterruptedException { - SlimefunPlugin.getRegistry().setResearchingEnabled(true); + SlimefunPlugin.getConfigManager().setResearchingEnabled(true); NamespacedKey key = new NamespacedKey(plugin, "simple_research"); Research research = new Research(key, 250, "Test", 10); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestPermissionsService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestPermissionsService.java index 994eada909..f7dfa74a75 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestPermissionsService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestPermissionsService.java @@ -47,7 +47,7 @@ void testDefaultPermission(boolean registered) { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "PERMISSIONS_TEST", new CustomItem(Material.EMERALD, "&bBad omen")); if (registered) { - service.register(Arrays.asList(item), false); + service.update(Arrays.asList(item), false); } Optional permission = service.getPermission(item);