From 47fc0375363ebc585384c85c7fd9379bacee9b52 Mon Sep 17 00:00:00 2001 From: TheBusyBiscuit Date: Sun, 10 Jan 2021 17:32:47 +0100 Subject: [PATCH] [CI skip] Lots of refactoring and documentation * Moved the ProtectionManager to the IntegrationsManager * Refactored static NamespacedKeys to be non-static * Added some documentation --- .../slimefun4/core/SlimefunRegistry.java | 21 ++++++- .../core/attributes/RechargeableHelper.java | 7 ++- .../core/services/CustomItemDataService.java | 3 + .../implementation/SlimefunPlugin.java | 61 +++++++++++++++---- .../integrations/IntegrationsManager.java | 32 ++++++++++ .../slimefun4/utils/SlimefunUtils.java | 10 +-- 6 files changed, 114 insertions(+), 20 deletions(-) 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 e3af4f416..43cc9d4ae 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -14,6 +14,7 @@ import java.util.concurrent.ConcurrentHashMap; import javax.annotation.Nonnull; import org.apache.commons.lang.Validate; +import org.bukkit.NamespacedKey; import org.bukkit.Server; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -28,6 +29,7 @@ import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideImplementation import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; import io.github.thebusybiscuit.slimefun4.core.multiblocks.MultiBlock; import io.github.thebusybiscuit.slimefun4.core.researching.Research; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.guide.BookSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.CheatSheetSlimefunGuide; import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuide; @@ -71,6 +73,9 @@ public final class SlimefunRegistry { private final Set radioactive = new HashSet<>(); private final Set barterDrops = new HashSet<>(); + private NamespacedKey soulboundKey; + private NamespacedKey itemChargeKey; + private final KeyMap geoResources = new KeyMap<>(); private final Map profiles = new ConcurrentHashMap<>(); @@ -84,9 +89,13 @@ public final class SlimefunRegistry { private final Map, Set> globalItemHandlers = new HashMap<>(); private final Map blockHandlers = new HashMap<>(); - public void load(@Nonnull Config cfg) { + public void load(@Nonnull SlimefunPlugin plugin, @Nonnull Config cfg) { + 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"); + boolean showVanillaRecipes = cfg.getBoolean("guide.show-vanilla-recipes"); layouts.put(SlimefunGuideLayout.CHEST, new ChestSlimefunGuide(showVanillaRecipes)); @@ -262,4 +271,14 @@ public final class SlimefunRegistry { return logDuplicateBlockEntries; } + @Nonnull + public NamespacedKey getSoulboundDataKey() { + return soulboundKey; + } + + @Nonnull + public NamespacedKey getItemChargeDataKey() { + return itemChargeKey; + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java index b0e47b1a5..65ea56133 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/RechargeableHelper.java @@ -28,7 +28,6 @@ import net.md_5.bungee.api.ChatColor; */ final class RechargeableHelper { - private static final NamespacedKey CHARGE_KEY = new NamespacedKey(SlimefunPlugin.instance(), "item_charge"); private static final String LORE_PREFIX = ChatColors.color("&8\u21E8 &e\u26A1 &7"); private static final Pattern REGEX = Pattern.compile(ChatColors.color("(&c&o)?" + LORE_PREFIX) + "[0-9.]+ / [0-9.]+ J"); @@ -38,7 +37,8 @@ final class RechargeableHelper { BigDecimal decimal = BigDecimal.valueOf(charge).setScale(2, RoundingMode.HALF_UP); float value = decimal.floatValue(); - meta.getPersistentDataContainer().set(CHARGE_KEY, PersistentDataType.FLOAT, value); + NamespacedKey key = SlimefunPlugin.getRegistry().getItemChargeDataKey(); + meta.getPersistentDataContainer().set(key, PersistentDataType.FLOAT, value); List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>(); for (int i = 0; i < lore.size(); i++) { @@ -56,7 +56,8 @@ final class RechargeableHelper { } static float getCharge(@Nonnull ItemMeta meta) { - Float value = meta.getPersistentDataContainer().get(CHARGE_KEY, PersistentDataType.FLOAT); + NamespacedKey key = SlimefunPlugin.getRegistry().getItemChargeDataKey(); + Float value = meta.getPersistentDataContainer().get(key, PersistentDataType.FLOAT); // If persistent data is available, we just return this value if (value != null) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java index 6100fb821..dceed3241 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomItemDataService.java @@ -30,6 +30,9 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; */ public class CustomItemDataService implements Keyed { + /** + * This is the {@link NamespacedKey} used to store/read data. + */ private final NamespacedKey namespacedKey; /** 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 0eedaf9e5..0788a5e08 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -153,11 +153,10 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { private final IntegrationsManager integrations = new ThirdPartyPluginService(this); private final SlimefunProfiler profiler = new SlimefunProfiler(); - private LocalizationService local; + private LocalizationService local; private GPSNetwork gpsNetwork; private NetworkManager networkManager; - private ProtectionManager protections; // Important config files for Slimefun private final Config config = new Config(this); @@ -228,6 +227,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { getLogger().log(Level.INFO, "Please download and install CS-CoreLib manually:"); getLogger().log(Level.INFO, "https://thebusybiscuit.github.io/builds/TheBusyBiscuit/CS-CoreLib/master/"); + // Send a message upon doing /slimefun getCommand("slimefun").setExecutor((sender, cmd, label, args) -> { sender.sendMessage("You have forgotten to install CS-CoreLib! Slimefun is disabled."); sender.sendMessage("https://thebusybiscuit.github.io/builds/TheBusyBiscuit/CS-CoreLib/master/"); @@ -244,7 +244,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { gpsNetwork = new GPSNetwork(); networkManager = new NetworkManager(200); command.register(); - registry.load(config); + registry.load(this, config); loadTags(); } @@ -271,7 +271,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { // Creating all necessary Folders getLogger().log(Level.INFO, "Creating directories..."); createDirectories(); - registry.load(config); + registry.load(this, config); // Set up localization getLogger().log(Level.INFO, "Loading language files..."); @@ -321,7 +321,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { // Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading) runSync(new SlimefunStartupTask(this, () -> { - protections = new ProtectionManager(getServer()); textureService.register(registry.getAllSlimefunItems(), true); permissionsService.register(registry.getAllSlimefunItems(), true); @@ -347,9 +346,11 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { getServer().getScheduler().runTaskTimerAsynchronously(this, new ArmorTask(radioactiveFire), 0L, config.getInt("options.armor-update-interval") * 20L); } + // Starting our tasks autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes")); ticker.start(this); + // Loading integrations getLogger().log(Level.INFO, "Loading Third-Party plugin integrations..."); integrations.start(); gitHubService.start(this); @@ -405,6 +406,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + // Save all "universal" inventories (ender chests for example) for (UniversalBlockMenu menu : registry.getUniversalInventories().values()) { menu.save(); } @@ -443,6 +445,14 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { instance = pluginInstance; } + /** + * This returns the time it took to load Slimefun (given a starting point). + * + * @param timestamp + * The time at which we started to load Slimefun. + * + * @return The total time it took to load Slimefun (in ms or s) + */ @Nonnull private String getStartupTime(long timestamp) { long ms = (System.nanoTime() - timestamp) / 1000000; @@ -534,6 +544,18 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This private method gives us a {@link Collection} of every {@link MinecraftVersion} + * that Slimefun is compatible with (as a {@link String} representation). + *

+ * Example: + * + *

+     * { 1.14.x, 1.15.x, 1.16.x }
+     * 
+ * + * @return A {@link Collection} of all compatible minecraft versions as strings + */ @Nonnull private Collection getSupportedVersions() { List list = new ArrayList<>(); @@ -547,6 +569,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return list; } + /** + * This method creates all necessary directories (and sub directories) for Slimefun. + */ private void createDirectories() { String[] storageFolders = { "Players", "blocks", "stored-blocks", "stored-inventories", "stored-chunks", "universal-inventories", "waypoints", "block-backups" }; String[] pluginFolders = { "scripts", "error-reports", "cache/github", "world-settings" }; @@ -642,6 +667,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new PlayerProfileListener(this); } + /** + * This (re)loads every {@link SlimefunTag}. + */ private void loadTags() { for (SlimefunTag tag : SlimefunTag.valuesCache) { try { @@ -655,6 +683,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This loads all of our items. + */ private void loadItems() { try { SlimefunItemSetup.setup(this); @@ -663,6 +694,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } + /** + * This loads our researches. + */ private void loadResearches() { try { ResearchSetup.setupResearches(); @@ -760,12 +794,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance.local; } - @Nonnull - public static ProtectionManager getProtectionManager() { - validateInstance(); - return instance.protections; - } - @Nonnull public static MinecraftRecipeService getMinecraftRecipeService() { validateInstance(); @@ -826,6 +854,17 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return instance.integrations; } + /** + * This returns out instance of the {@link ProtectionManager}. + * This bridge is used to hook into any third-party protection {@link Plugin}. + * + * @return Our instanceof of the {@link ProtectionManager} + */ + @Nonnull + public static ProtectionManager getProtectionManager() { + return getIntegrations().getProtectionManager(); + } + /** * This method returns the {@link UpdaterService} of Slimefun. * It is used to handle automatic updates. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java index d08390f3e..37c88ad6b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/integrations/IntegrationsManager.java @@ -14,6 +14,7 @@ import org.bukkit.plugin.Plugin; import com.gmail.nossr50.events.fake.FakeBlockBreakEvent; import dev.lone.itemsadder.api.ItemsAdder; +import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -35,6 +36,11 @@ public class IntegrationsManager { */ protected final SlimefunPlugin plugin; + /** + * Our {@link ProtectionManager} instance. + */ + private ProtectionManager protectionManager; + /** * This boolean determines whether {@link #start()} was run. */ @@ -126,10 +132,25 @@ public class IntegrationsManager { * This method is called when the {@link Server} has finished loading all its {@link Plugin Plugins}. */ private void onServerStart() { + try { + // Load Protection plugin integrations + protectionManager = new ProtectionManager(plugin.getServer()); + } catch (Exception | LinkageError x) { + SlimefunPlugin.logger().log(Level.WARNING, x, () -> "Failed to load Protection plugin integrations for Slimefun v" + SlimefunPlugin.getVersion()); + } + isChestTerminalInstalled = isAddonInstalled("ChestTerminal"); isExoticGardenInstalled = isAddonInstalled("ExoticGarden"); } + /** + * This method checks if the given addon is installed. + * + * @param addon + * The name of the addon + * + * @return Whether that addon is installed on the {@link Server} + */ private boolean isAddonInstalled(@Nonnull String addon) { if (plugin.getServer().getPluginManager().isPluginEnabled(addon)) { SlimefunPlugin.logger().log(Level.INFO, "Hooked into Slimefun Addon: {0}", addon); @@ -165,6 +186,17 @@ public class IntegrationsManager { } } + /** + * This returns out instance of the {@link ProtectionManager}. + * This bridge is used to hook into any third-party protection {@link Plugin}. + * + * @return Our instanceof of the {@link ProtectionManager} + */ + @Nonnull + public ProtectionManager getProtectionManager() { + return protectionManager; + } + /** * This checks if one of our third party integrations faked an {@link Event}. * Faked {@link Event Events} should be ignored in our logic. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java index 2369a6898..8b6eff1ac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -47,8 +47,6 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public final class SlimefunUtils { private static final String NO_PICKUP_METADATA = "no_pickup"; - - private static final NamespacedKey SOULBOUND_KEY = new NamespacedKey(SlimefunPlugin.instance(), "soulbound"); private static final String SOULBOUND_LORE = ChatColor.GRAY + "Soulbound"; private SlimefunUtils() {} @@ -110,8 +108,9 @@ public final class SlimefunUtils { private static boolean hasSoulboundFlag(@Nullable ItemMeta meta) { if (meta != null) { PersistentDataContainer container = meta.getPersistentDataContainer(); + NamespacedKey key = SlimefunPlugin.getRegistry().getSoulboundDataKey(); - if (container.has(SOULBOUND_KEY, PersistentDataType.BYTE)) { + if (container.has(key, PersistentDataType.BYTE)) { return true; } } @@ -142,13 +141,14 @@ public final class SlimefunUtils { ItemMeta meta = item.getItemMeta(); PersistentDataContainer container = meta.getPersistentDataContainer(); + NamespacedKey key = SlimefunPlugin.getRegistry().getSoulboundDataKey(); if (makeSoulbound && !isSoulbound) { - container.set(SOULBOUND_KEY, PersistentDataType.BYTE, (byte) 1); + container.set(key, PersistentDataType.BYTE, (byte) 1); } if (!makeSoulbound && isSoulbound) { - container.remove(SOULBOUND_KEY); + container.remove(key); } List lore = meta.hasLore() ? meta.getLore() : new ArrayList<>();