From 3e90349551ed6d3876ad1f117c83c618c061408b Mon Sep 17 00:00:00 2001 From: TheBusyBiscuit Date: Thu, 26 Mar 2020 18:56:14 +0100 Subject: [PATCH] Refactored some things --- CHANGELOG.md | 2 + README.md | 10 +- lib/ExoticGarden v1.2.0.jar | Bin 48854 -> 0 bytes pom.xml | 58 ++++++++-- .../slimefun4/api/ErrorReport.java | 4 +- .../slimefun4/api/MinecraftVersion.java | 2 +- .../slimefun4/api/SlimefunBranch.java | 2 +- .../core/attributes/MachineTier.java | 2 +- .../core/attributes/MachineType.java | 2 +- .../core/attributes/Radioactivity.java | 2 +- .../core/guide/SlimefunGuideSettings.java | 2 +- .../localization/EmbeddedLanguage.java | 2 +- .../core/services/plugins/ClearLagHook.java | 3 +- .../plugins/ThirdPartyPluginService.java | 20 +++- .../guide/ChestSlimefunGuide.java | 14 ++- .../items/androids/AdvancedFarmerAndroid.java | 13 ++- .../items/androids/ScriptAction.java | 2 +- .../items/blocks/InfusedHopper.java | 12 ++- .../items/magical/StormStaff.java | 3 +- .../listeners/AncientAltarListener.java | 5 +- .../listeners/ButcherAndroidListener.java | 3 +- .../listeners/ItemPickupListener.java | 6 +- .../implementation/tasks/MagnetTask.java | 14 ++- .../tasks/SlimefunStartupTask.java | 101 ++++++++++++++++++ .../implementation/tasks/TickerTask.java | 12 +++ .../slimefun4/utils/SlimefunUtils.java | 29 +++++ .../Slimefun/SlimefunPlugin.java | 91 ++-------------- 27 files changed, 291 insertions(+), 125 deletions(-) delete mode 100644 lib/ExoticGarden v1.2.0.jar create mode 100644 src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e2d31448..c0e57560f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ * Salt now only requires 2 blocks of Sand * Fireworks from researching no longer damages entities * Very slight performance improvements for Cargo networks +* 4K-carat gold ingots can now be used in a workbench by default (overridden by Items.yml) +* The project license is now included in every build #### Fixes * Fixed some languages showing numbers larger than 100% diff --git a/README.md b/README.md index 69453ee24..5e41b65dc 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ Check out our [Addons](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Addons), * **[Wiki](https://github.com/TheBusyBiscuit/Slimefun4/wiki)** ## Download Slimefun 4 -Slimefun 4 can be downloaded for free on our builds page.
+(See also: [How to install Slimefun](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Installing-Slimefun))
+Slimefun 4 can be downloaded **for free** on our builds page.
We currently provide two versions of Slimefun, development builds and "stable" builds.
Here is a full summary of the differences between these two versions of Slimefun. @@ -30,7 +31,7 @@ Here is a full summary of the differences between these two versions of Slimefun | **Bug Reports** | :heavy_check_mark: | :x: | | **frequent updates & fast patches** | :heavy_check_mark: | :x: | | **change logs** | :x: | :memo: **[change log](https://github.com/TheBusyBiscuit/Slimefun4/blob/master/CHANGELOG.md)** | -| **Download** | :package: **[download development build](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/master/)** | :package: **[download "stable" build](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/)** | +| **Download link** | :package: **[download development build](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/master/)** | :package: **[download "stable" build](https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/)** | **We wholeheartedly recommend you to use development builds.**
But we can understand the use of "stable" builds if your server's livelihood heavily depends on Slimefun.
@@ -80,9 +81,10 @@ https://github.com/TheBusyBiscuit/Slimefun4/wiki * [Common issues](https://github.com/TheBusyBiscuit/Slimefun4/wiki/Common-Issues) ## Contributing to this project -Slimefun 4 is licensed under +Slimefun 4 is an Open-Source project and licensed under [GNU GPLv3](https://github.com/TheBusyBiscuit/Slimefun4/blob/master/LICENSE).
-Over 100 people have already contributed to this amazing project. You guys are awesome. +Over 100 people have already contributed to this amazing project. You guys are awesome.
+Please consider helping us maintain this project too, your engagement keeps the project alive <3.

diff --git a/lib/ExoticGarden v1.2.0.jar b/lib/ExoticGarden v1.2.0.jar deleted file mode 100644 index 67acb61f622aafe78409f34def41bfa665a8a060..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 48854 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 diff --git a/pom.xml b/pom.xml index e9a21a165..11eb5f36f 100644 --- a/pom.xml +++ b/pom.xml @@ -4,12 +4,20 @@ 4.0.0 me.mrCookieSlime Slimefun + + + UNOFFICIAL 1.8 1.8 UTF-8 + + + TheBusyBiscuit_Slimefun4 + thebusybiscuit-github + https://sonarcloud.io @@ -30,7 +38,7 @@ https://maven.sk89q.com/repo/ - CodeMC + bStats-repo https://repo.codemc.org/repository/maven-public @@ -50,6 +58,8 @@ 3.8.1 + + **/package-info.java @@ -75,6 +85,8 @@ 3.2.2 + + org.bstats @@ -85,6 +97,16 @@ me.mrCookieSlime.Slimefun.cscorelib2 + + + + + *:* + + META-INF/* + + + @@ -101,16 +123,22 @@ org.apache.maven.plugins maven-javadoc-plugin 3.2.0 + ${project.basedir} docs + Slimefun4 - Javadocs Slimefun4 - Javadocs false -html5 + + https://hub.spigotmc.org/javadocs/bukkit/ + + Slimefun4 - API @@ -138,6 +166,8 @@ + + ${basedir}/src/main/resources true @@ -147,10 +177,20 @@ languages/* + + + + ${basedir} + + + LICENSE + + + org.bukkit bukkit @@ -163,6 +203,8 @@ 8081bb4fe4 provided + + com.github.thebusybiscuit CS-CoreLib2 @@ -175,6 +217,8 @@ 1.7 compile + + com.sk89q.worldedit worldedit-bukkit @@ -184,9 +228,12 @@ me.clip placeholderapi - 2.10.4 + 2.10.5 provided + + + me.minebuilders clearlag-core @@ -201,12 +248,5 @@ system ${project.basedir}/lib/EmeraldEnchants v2.0.jar - - me.mrCookieSlime - ExoticGarden - 1.2.0 - system - ${project.basedir}/lib/ExoticGarden v1.2.0.jar - diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java index 3f7e27d73..e22efd4db 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java @@ -159,7 +159,7 @@ public class ErrorReport { }); } - private void scanPlugins(List plugins, List addons) { + private static void scanPlugins(List plugins, List addons) { String dependency = "Slimefun"; for (Plugin plugin : Bukkit.getPluginManager().getPlugins()) { @@ -180,7 +180,7 @@ public class ErrorReport { } } - private File getNewFile() { + private static File getNewFile() { String path = "plugins/Slimefun/error-reports/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date()); File newFile = new File(path + ".err"); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java index 8aba6164a..b9d67d5d2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/MinecraftVersion.java @@ -33,7 +33,7 @@ public enum MinecraftVersion { private final String name; private final String prefix; - private MinecraftVersion(String name) { + MinecraftVersion(String name) { this.name = name; this.prefix = name().replace("MINECRAFT_", "v") + '_'; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunBranch.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunBranch.java index 05c1d6ea1..36112f677 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunBranch.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/SlimefunBranch.java @@ -33,7 +33,7 @@ public enum SlimefunBranch { private final String name; private final boolean official; - private SlimefunBranch(String name, boolean official) { + SlimefunBranch(String name, boolean official) { this.name = name; this.official = official; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineTier.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineTier.java index 485e113d6..5d1cd6aba 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineTier.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineTier.java @@ -11,7 +11,7 @@ public enum MachineTier { private final String prefix; - private MachineTier(String prefix) { + MachineTier(String prefix) { this.prefix = prefix; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineType.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineType.java index 9e83eec6c..6eaa22301 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineType.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/MachineType.java @@ -8,7 +8,7 @@ public enum MachineType { private final String suffix; - private MachineType(String suffix) { + MachineType(String suffix) { this.suffix = suffix; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java index 73f7a41c1..4c25a67f8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/Radioactivity.java @@ -47,7 +47,7 @@ public enum Radioactivity { private final ChatColor color; - private Radioactivity(ChatColor color) { + Radioactivity(ChatColor color) { this.color = color; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideSettings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideSettings.java index bd941bf5e..b1f9047e4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideSettings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuideSettings.java @@ -184,7 +184,7 @@ public final class SlimefunGuideSettings { Language language = SlimefunPlugin.getLocal().getLanguage(p); String languageName = language.isDefault() ? (SlimefunPlugin.getLocal().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")") : SlimefunPlugin.getLocal().getMessage(p, "languages." + language.getID()); - menu.addItem(i, new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7messages, not items.", "", "&7\u21E8 &eClick to change your language"), (pl, slot, item, action) -> { + menu.addItem(i, new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7some messages, not items.", "&7&oThis feature is still being worked on", "", "&7\u21E8 &eClick to change your language"), (pl, slot, item, action) -> { openLanguages(pl); return false; }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/EmbeddedLanguage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/EmbeddedLanguage.java index d438eddfc..b8723f3da 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/EmbeddedLanguage.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/EmbeddedLanguage.java @@ -53,7 +53,7 @@ enum EmbeddedLanguage { private final String id; private final String textureHash; - private EmbeddedLanguage(String id, String textureHash) { + EmbeddedLanguage(String id, String textureHash) { this.id = id; this.textureHash = textureHash; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ClearLagHook.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ClearLagHook.java index 607b12934..74a5c4128 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ClearLagHook.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ClearLagHook.java @@ -7,6 +7,7 @@ import org.bukkit.entity.Item; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.minebuilders.clearlag.events.EntityRemoveEvent; import me.mrCookieSlime.Slimefun.SlimefunPlugin; @@ -23,7 +24,7 @@ class ClearLagHook implements Listener { while (iterator.hasNext()) { Entity n = iterator.next(); - if (n instanceof Item && n.hasMetadata("no_pickup")) { + if (n instanceof Item && SlimefunUtils.hasNoPickupFlag((Item) n)) { iterator.remove(); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java index 54ec314fc..b621daabf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/plugins/ThirdPartyPluginService.java @@ -1,7 +1,11 @@ package io.github.thebusybiscuit.slimefun4.core.services.plugins; +import java.util.Optional; +import java.util.function.Function; import java.util.logging.Level; +import org.bukkit.block.Block; +import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.Plugin; import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon; @@ -28,6 +32,8 @@ public class ThirdPartyPluginService { private boolean isEmeraldEnchantsInstalled = false; private boolean isCoreProtectInstalled = false; private boolean isPlaceholderAPIInstalled = false; + + private Function> exoticGardenIntegration; public ThirdPartyPluginService(SlimefunPlugin plugin) { this.plugin = plugin; @@ -48,8 +54,7 @@ public class ThirdPartyPluginService { if (isPluginInstalled("ClearLag")) { new ClearLagHook(plugin); } - - isExoticGardenInstalled = isPluginInstalled("ExoticGarden"); + isChestTerminalInstalled = isPluginInstalled("ChestTerminal"); isEmeraldEnchantsInstalled = isPluginInstalled("EmeraldEnchants"); @@ -78,6 +83,13 @@ public class ThirdPartyPluginService { return false; } } + + public void loadExoticGarden(Plugin plugin, Function> method) { + if (plugin.getName().equals("ExoticGarden")) { + isExoticGardenInstalled = true; + exoticGardenIntegration = method; + } + } public boolean isExoticGardenInstalled() { return isExoticGardenInstalled; @@ -99,4 +111,8 @@ public class ThirdPartyPluginService { return isPlaceholderAPIInstalled; } + public Optional harvestExoticGardenPlant(Block block) { + return exoticGardenIntegration.apply(block); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java index 7e87f4964..cbf47f73e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/ChestSlimefunGuide.java @@ -451,7 +451,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { ChestMenu menu = create(p); Optional wiki = item.getWikipage(); - + if (wiki.isPresent()) { menu.addItem(8, new CustomItem(Material.KNOWLEDGE_BOOK, ChatColor.RESET + SlimefunPlugin.getLocal().getMessage(p, "guide.tooltips.wiki"), "", ChatColor.GRAY + "\u21E8 " + ChatColor.GREEN + SlimefunPlugin.getLocal().getMessage(p, "guide.tooltips.open-category"))); menu.addMenuClickHandler(8, (pl, slot, itemstack, action) -> { @@ -614,7 +614,17 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { int outputs = 45; for (int i = 0; i < 18; i++) { - int slot = i % 2 == 0 ? inputs++ : outputs++; + int slot; + + if (i % 2 == 0) { + slot = inputs; + inputs++; + } + else { + slot = outputs; + outputs++; + } + addDisplayRecipe(menu, profile, recipes, slot, i, page); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java index d64cff810..1c94c55e2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AdvancedFarmerAndroid.java @@ -1,11 +1,12 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids; +import java.util.Optional; + import org.bukkit.Effect; import org.bukkit.block.Block; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import me.mrCookieSlime.ExoticGarden.ExoticGarden; import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -38,11 +39,15 @@ public abstract class AdvancedFarmerAndroid extends FarmerAndroid { farm(menu, block); if (SlimefunPlugin.getThirdPartySupportService().isExoticGardenInstalled()) { - ItemStack drop = ExoticGarden.harvestPlant(block); + Optional result = SlimefunPlugin.getThirdPartySupportService().harvestExoticGardenPlant(block); - if (drop != null && menu.fits(drop, getOutputSlots())) { + if (result.isPresent()) { + ItemStack drop = result.get(); menu.pushItem(drop, getOutputSlots()); - block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); + + if (menu.fits(drop, getOutputSlots())) { + block.getWorld().playEffect(block.getLocation(), Effect.STEP_SOUND, block.getType()); + } } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ScriptAction.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ScriptAction.java index 1759fd11c..45138b81b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ScriptAction.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ScriptAction.java @@ -56,7 +56,7 @@ enum ScriptAction { private final ItemStack item; private final AndroidType type; - private ScriptAction(AndroidType type, String texture) { + ScriptAction(AndroidType type, String texture) { this.type = type; this.item = SkullItem.fromHash(texture); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/InfusedHopper.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/InfusedHopper.java index 99a1ec638..a3c2b680b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/InfusedHopper.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/InfusedHopper.java @@ -9,6 +9,7 @@ import org.bukkit.entity.Item; import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; @@ -41,7 +42,7 @@ public class InfusedHopper extends SimpleSlimefunItem { Location l = b.getLocation().add(0.5, 1.2, 0.5); boolean sound = false; - for (Entity item : b.getWorld().getNearbyEntities(l, 3.5D, 3.5D, 3.5D, n -> n instanceof Item && n.isValid() && !n.hasMetadata("no_pickup") && n.getLocation().distanceSquared(l) > 0.25)) { + for (Entity item : b.getWorld().getNearbyEntities(l, 3.5D, 3.5D, 3.5D, n -> isValidItem(l, n))) { item.setVelocity(new Vector(0, 0.1, 0)); item.teleport(l); sound = true; @@ -58,4 +59,13 @@ public class InfusedHopper extends SimpleSlimefunItem { } }; } + + private boolean isValidItem(Location l, Entity entity) { + if (entity instanceof Item && entity.isValid()) { + Item item = (Item) entity; + return !SlimefunUtils.hasNoPickupFlag(item) && item.getLocation().distanceSquared(l) > 0.25; + } + + return false; + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/StormStaff.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/StormStaff.java index ff12e2ea2..a6d03718c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/StormStaff.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/StormStaff.java @@ -94,7 +94,8 @@ public class StormStaff extends SimpleSlimefunItem { item.setAmount(0); } else { - itemMeta.getPersistentDataContainer().set(usageKey, PersistentDataType.INTEGER, --currentUses); + currentUses--; + itemMeta.getPersistentDataContainer().set(usageKey, PersistentDataType.INTEGER, currentUses); itemLore.set(4, ChatColor.translateAlternateColorCodes('&', "&e" + currentUses + ' ' + (currentUses > 1 ? "Uses" : "Use") + " &7left")); itemMeta.setLore(itemLore); item.setItemMeta(itemMeta); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java index c5521e2a2..4235ea6ac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java @@ -25,7 +25,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.util.Vector; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; @@ -135,7 +134,7 @@ public class AncientAltarListener implements Listener { p.playSound(pedestal.getLocation(), Sound.ENTITY_ITEM_PICKUP, 1F, 1F); } } - + private void useAltar(Block b, Player p) { ItemStack catalyst = new CustomItem(p.getInventory().getItemInMainHand(), 1); List pedestals = getPedestals(b); @@ -258,7 +257,7 @@ public class AncientAltarListener implements Listener { String nametag = ItemUtils.getItemName(stack); Item entity = b.getWorld().dropItem(b.getLocation().add(0.5, 1.2, 0.5), new CustomItem(stack, "&5&dALTAR &3Probe - &e" + System.nanoTime())); entity.setVelocity(new Vector(0, 0.1, 0)); - entity.setMetadata("no_pickup", new FixedMetadataValue(SlimefunPlugin.instance, "altar_item")); + SlimefunUtils.markAsNoPickup(entity, "altar_item"); entity.setCustomNameVisible(true); entity.setCustomName(nametag); p.playSound(b.getLocation(), Sound.ENTITY_ITEM_PICKUP, 0.3F, 0.3F); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java index cb482b79e..d5feaaccd 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ButcherAndroidListener.java @@ -18,6 +18,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.AndroidInstance; import io.github.thebusybiscuit.slimefun4.implementation.items.androids.ButcherAndroid; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.api.Slimefun; @@ -43,7 +44,7 @@ public class ButcherAndroidListener implements Listener { List items = new ArrayList<>(); for (Entity n : e.getEntity().getNearbyEntities(0.5D, 0.5D, 0.5D)) { - if (n instanceof Item && !n.hasMetadata("no_pickup")) { + if (n instanceof Item && n.isValid() && !SlimefunUtils.hasNoPickupFlag((Item) n)) { items.add(((Item) n).getItemStack()); n.remove(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java index aab28e4de..1a3abb542 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/ItemPickupListener.java @@ -6,6 +6,7 @@ import org.bukkit.event.entity.EntityPickupItemEvent; import org.bukkit.event.inventory.InventoryPickupItemEvent; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.SlimefunPlugin; /** @@ -15,7 +16,6 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin; */ public class ItemPickupListener implements Listener { - private static final String METADATA_JEY = "no_pickup"; private static final String ITEM_PREFIX = ChatColors.color("&5&dALTAR &3Probe - &e"); public ItemPickupListener(SlimefunPlugin plugin) { @@ -24,7 +24,7 @@ public class ItemPickupListener implements Listener { @EventHandler public void onEntityPickup(EntityPickupItemEvent e) { - if (e.getItem().hasMetadata(METADATA_JEY)) { + if (SlimefunUtils.hasNoPickupFlag(e.getItem())) { e.setCancelled(true); } else if (e.getItem().getItemStack().hasItemMeta() && e.getItem().getItemStack().getItemMeta().hasDisplayName() && e.getItem().getItemStack().getItemMeta().getDisplayName().startsWith(ITEM_PREFIX)) { @@ -35,7 +35,7 @@ public class ItemPickupListener implements Listener { @EventHandler public void onHopperPickup(InventoryPickupItemEvent e) { - if (e.getItem().hasMetadata(METADATA_JEY)) { + if (SlimefunUtils.hasNoPickupFlag(e.getItem())) { e.setCancelled(true); } else if (e.getItem().getItemStack().hasItemMeta() && e.getItem().getItemStack().getItemMeta().hasDisplayName() && e.getItem().getItemStack().getItemMeta().getDisplayName().startsWith(ITEM_PREFIX)) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java index 9ec59e8e5..185715ab7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java @@ -6,6 +6,8 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.Item; import org.bukkit.entity.Player; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; + public class MagnetTask extends SlimefunTask { public MagnetTask(Player p) { @@ -14,10 +16,14 @@ public class MagnetTask extends SlimefunTask { @Override public void executeTask() { - for (Entity item : p.getNearbyEntities(6D, 6D, 6D)) { - if (item instanceof Item && !item.hasMetadata("no_pickup") && ((Item) item).getPickupDelay() <= 0) { - item.teleport(p.getEyeLocation()); - p.getWorld().playSound(p.getEyeLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 2F); + for (Entity n : p.getNearbyEntities(6D, 6D, 6D)) { + if (n instanceof Item) { + Item item = (Item) n; + + if (!SlimefunUtils.hasNoPickupFlag(item) && item.getPickupDelay() <= 0) { + item.teleport(p.getEyeLocation()); + p.getWorld().playSound(p.getEyeLocation(), Sound.ENTITY_ENDERMAN_TELEPORT, 1F, 2F); + } } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java new file mode 100644 index 000000000..b83690daa --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunStartupTask.java @@ -0,0 +1,101 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks; + +import org.bukkit.Bukkit; +import org.bukkit.World; + +import io.github.thebusybiscuit.slimefun4.implementation.listeners.ButcherAndroidListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.TeleporterListener; +import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener; +import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.api.BlockStorage; + +/** + * This Task initializes all items, some listeners and various other stuff. + * This has been moved to its own class to make timings log easier to read, so + * they say "SlimefunStartupTask" instead of "Slimefun:lambda:123456789". + * + * @author TheBusyBiscuit + * + */ +public class SlimefunStartupTask implements Runnable { + + private final SlimefunPlugin plugin; + private final Runnable runnable; + + /** + * This initializes our {@link SlimefunStartupTask} for the given {@link SlimefunPlugin}. + * + * @param plugin + * The main instance of our {@link SlimefunPlugin} + * @param runnable + * A {@link Runnable} containing additional operations that need to be run + */ + public SlimefunStartupTask(SlimefunPlugin plugin, Runnable runnable) { + this.plugin = plugin; + this.runnable = runnable; + } + + @Override + public void run() { + runnable.run(); + + // Load all items + PostSetup.loadItems(); + + // Load all worlds + for (World world : Bukkit.getWorlds()) { + new BlockStorage(world); + } + + // Load all listeners that depend on items to be enabled + + if (isEnabled("ANCIENT_ALTAR")) { + SlimefunPlugin.getAncientAltarListener().load(plugin); + } + + if (isEnabled("GRAPPLING_HOOK")) { + SlimefunPlugin.getGrapplingHookListener().load(plugin); + } + + if (isEnabled("BLADE_OF_VAMPIRES")) { + new VampireBladeListener(plugin); + } + + if (isEnabled("COOLER")) { + new CoolerListener(plugin); + } + + if (isEnabled("SEISMIC_AXE")) { + new SeismicAxeListener(plugin); + } + + if (isEnabled("ELEVATOR_PLATE", "GPS_ACTIVATION_DEVICE_SHARED", "GPS_ACTIVATION_DEVICE_PERSONAL")) { + new TeleporterListener(plugin); + } + + if (isEnabled("PROGRAMMABLE_ANDROID_BUTCHER", "PROGRAMMABLE_ANDROID_2_BUTCHER", "PROGRAMMABLE_ANDROID_3_BUTCHER")) { + new ButcherAndroidListener(plugin); + } + + if (isEnabled("ENERGY_REGULATOR", "CARGO_MANAGER")) { + new NetworkListener(plugin); + } + } + + private boolean isEnabled(String... itemIds) { + for (String id : itemIds) { + SlimefunItem item = SlimefunItem.getByID(id); + + if (item != null && !item.isDisabled()) { + return true; + } + } + return false; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java index b627810d4..73c4dc266 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java @@ -333,4 +333,16 @@ public class TickerTask implements Runnable { delete.put(l, destroy); } + public void start(SlimefunPlugin plugin) { + plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, () -> { + try { + run(); + } + catch (Throwable x) { + plugin.getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + SlimefunPlugin.getVersion()); + abortTick(); + } + }, 100L, SlimefunPlugin.getCfg().getInt("URID.custom-ticker-delay")); + } + } 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 3f5502105..d0f976872 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -5,12 +5,15 @@ import java.util.Optional; import org.bukkit.ChatColor; import org.bukkit.Material; +import org.bukkit.entity.Item; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.metadata.FixedMetadataValue; import io.github.thebusybiscuit.cscorelib2.item.ImmutableItemMeta; import io.github.thebusybiscuit.slimefun4.core.attributes.Soulbound; +import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import me.mrCookieSlime.EmeraldEnchants.EmeraldEnchants; import me.mrCookieSlime.EmeraldEnchants.ItemEnchantment; import me.mrCookieSlime.Slimefun.SlimefunPlugin; @@ -31,9 +34,35 @@ public final class SlimefunUtils { private static final String EMERALDENCHANTS_LORE = ChatColor.YELLOW.toString() + ChatColor.YELLOW.toString() + ChatColor.GRAY.toString(); private static final String SOULBOUND_LORE = ChatColor.GRAY + "Soulbound"; + private static final String NO_PICKUP_METADATA = "no_pickup"; private SlimefunUtils() {} + /** + * This method quickly returns whether an {@link Item} was marked as "no_pickup" by + * a Slimefun device. + * + * @param item + * The {@link Item} to query + * @return Whether the {@link Item} is excluded from being picked up + */ + public static boolean hasNoPickupFlag(Item item) { + return !item.hasMetadata(NO_PICKUP_METADATA); + } + + /** + * This will prevent the given {@link Item} from being picked up. + * This is useful for display items which the {@link AncientPedestal} uses. + * + * @param item + * The {@link Item} to prevent from being picked up + * @param context + * The context in which this {@link Item} was flagged + */ + public static void markAsNoPickup(Item item, String context) { + item.setMetadata(NO_PICKUP_METADATA, new FixedMetadataValue(SlimefunPlugin.instance, context)); + } + /** * This method checks whether the given {@link ItemStack} is considered {@link Soulbound}. * diff --git a/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java b/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java index 95c79bbac..ecc0d0427 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java @@ -16,6 +16,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.java.JavaPlugin; import io.github.thebusybiscuit.cscorelib2.config.Config; +import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; import io.github.thebusybiscuit.cscorelib2.protection.ProtectionManager; import io.github.thebusybiscuit.cscorelib2.reflection.ReflectionUtils; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; @@ -41,8 +42,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarL import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BlockPhysicsListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.ButcherAndroidListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DeathpointListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DebugFishListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.DispenserListener; @@ -55,9 +54,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.GrapplingHook import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.ItemPickupListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.PlayerProfileListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.SeismicAxeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBootsListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunBowListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunGuideListener; @@ -65,8 +62,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunItemC import io.github.thebusybiscuit.slimefun4.implementation.listeners.SlimefunItemListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.SoulboundListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.TalismanListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.TeleporterListener; -import io.github.thebusybiscuit.slimefun4.implementation.listeners.VampireBladeListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.VanillaMachinesListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WitherListener; import io.github.thebusybiscuit.slimefun4.implementation.listeners.WorldListener; @@ -75,9 +70,9 @@ import io.github.thebusybiscuit.slimefun4.implementation.setup.PostSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunItemSetup; import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.SlimefunStartupTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AReactor; @@ -135,6 +130,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { @Override public void onEnable() { if (getServer().getPluginManager().isPluginEnabled("CS-CoreLib")) { + long timestamp = System.nanoTime(); // We wanna ensure that the Server uses a compatible version of Minecraft if (isVersionUnsupported()) { @@ -256,52 +252,9 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { new PlayerProfileListener(this); // Initiating various Stuff and all Items with a slightly delay (0ms after the Server finished loading) - Slimefun.runSync(() -> { - textureService.register(registry.getAllSlimefunItems()); - permissionsService.register(registry.getAllSlimefunItems()); - recipeService.load(); - + Slimefun.runSync(new SlimefunStartupTask(this, () -> { protections = new ProtectionManager(getServer()); - - PostSetup.loadItems(); - - for (World world : Bukkit.getWorlds()) { - new BlockStorage(world); - } - - if (isEnabled("ANCIENT_ALTAR")) { - ancientAltarListener.load(this); - } - - if (isEnabled("GRAPPLING_HOOK")) { - grapplingHookListener.load(this); - } - - if (isEnabled("BLADE_OF_VAMPIRES")) { - new VampireBladeListener(this); - } - - if (isEnabled("COOLER")) { - new CoolerListener(this); - } - - if (isEnabled("SEISMIC_AXE")) { - new SeismicAxeListener(this); - } - - if (isEnabled("ELEVATOR_PLATE", "GPS_ACTIVATION_DEVICE_SHARED", "GPS_ACTIVATION_DEVICE_PERSONAL")) { - new TeleporterListener(this); - } - - if (isEnabled("PROGRAMMABLE_ANDROID_BUTCHER", "PROGRAMMABLE_ANDROID_2_BUTCHER", "PROGRAMMABLE_ANDROID_3_BUTCHER")) { - new ButcherAndroidListener(this); - } - - if (isEnabled("ENERGY_REGULATOR", "CARGO_MANAGER")) { - new NetworkListener(this); - } - - }, 0); + }), 0); // Setting up the command /sf and all subcommands command.register(); @@ -312,26 +265,15 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } autoSavingService.start(this, config.getInt("options.auto-save-delay-in-minutes")); - - // Starting all ASYNC Tasks - getServer().getScheduler().runTaskTimerAsynchronously(this, () -> { - try { - ticker.run(); - } - catch (Throwable x) { - getLogger().log(Level.SEVERE, x, () -> "An Exception was caught while ticking the Block Tickers Task for Slimefun v" + getVersion()); - ticker.abortTick(); - } - }, 100L, config.getInt("URID.custom-ticker-delay")); - + ticker.start(this); + thirdPartySupportService.start(); gitHubService.start(this); - // Hooray! - getLogger().log(Level.INFO, "Finished!"); - thirdPartySupportService.start(); - - // Do not show /sf elevator command in our Log, it could get quite spammy + // Exclude the command /sf elevator from our server log, it could get quite spammy CSCoreLib.getLib().filterLog("([A-Za-z0-9_]{3,16}) issued server command: /sf elevator (.{0,})"); + + // Hooray! + getLogger().log(Level.INFO, "Slimefun has finished loading in {0}ms", DoubleHandler.fixDouble((System.nanoTime() - timestamp) / 1000000.0)); } else { getLogger().log(Level.INFO, "#################### - INFO - ####################"); @@ -349,17 +291,6 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { } } - private boolean isEnabled(String... itemIds) { - for (String id : itemIds) { - SlimefunItem item = SlimefunItem.getByID(id); - - if (item != null && !item.isDisabled()) { - return true; - } - } - return false; - } - private boolean isVersionUnsupported() { String currentVersion = ReflectionUtils.getVersion();