diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 000000000..9a7a08c38 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,7 @@ +# Modifications to the source code should be handled by the review team +*.java @Slimefun/code-reviewers + +# Modifications to sensitive files should be reviewed by maintainers +/.github/ @Slimefun/slimefun4-maintainers +pom.xml @Slimefun/slimefun4-maintainers +CONTRIBUTING.md @Slimefun/slimefun4-maintainers diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 1bfbe1872..0a2e28521 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -19,7 +19,7 @@ We generally expect users to engage in the Issues section by reporting bugs or c Pull Requests are very much welcome and encouraged! They keep the project alive, so if you see an Issue and know how to fix it, feel free to create a Pull Request! Issues that are considered "good first issues", indicated by the [good first issue](https://github.com/Slimefun/Slimefun4/labels/good%20first%20issue) label, are generally expected to be beginner-friendly. -And even if you shouldn't know where to start or how to proceed, our [Discord Server](https://github.com/Slimefun/Slimefun4#discord) and its community will be there for you! +And even if you shouldn't know where to start or how to proceed, our [Discord Server](https://discord.gg/slimefun) and its community will be there for you! When commenting, please keep in mind that this software is offered for **free**. Don't expect to receive lightning-fast replies 24 hours a day. Everyone here works on this project in their free time and usually has work, school, university or family to take care of, so we appreciate patience and understanding. @@ -59,7 +59,7 @@ https://github.com/orgs/Slimefun/people ## :wrench: Enforcement Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the community leaders (labelled on Discord as "Admins" or "Moderators") responsible for enforcement on our [Discord Server](https://github.com/Slimefun/Slimefun4#discord). +reported to the community leaders (labelled on Discord as "Admins" or "Moderators") responsible for enforcement on our [Discord Server](discord.gg/slimefun). If you want your issue to be handled discreetly, message `TheBusyBiscuit#2610` or `Walshy#9709` privately on Discord and state your concerns. All complaints will be reviewed and investigated promptly and fairly. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ab1fd5077..b14ef722f 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -7,5 +7,5 @@ contact_links: url: https://github.com/Slimefun/Slimefun4/wiki/How-to-report-bugs about: Guidelines on how to make good Bug reports - name: Discord Server (for Questions and Suggestions) - url: https://discord.gg/fsD4Bkh + url: https://discord.gg/slimefun about: Please ask and answer questions here. diff --git a/.github/ISSUE_TEMPLATE/hacktoberfest-issue.md b/.github/ISSUE_TEMPLATE/hacktoberfest-issue.md index 5e898bd67..9a30df81c 100644 --- a/.github/ISSUE_TEMPLATE/hacktoberfest-issue.md +++ b/.github/ISSUE_TEMPLATE/hacktoberfest-issue.md @@ -45,10 +45,10 @@ If you need help on how to get started, maybe try looking into the following res * [Hacktoberfest FAQ](https://hacktoberfest.digitalocean.com/faq) * GitHub/Open-Source * [How to contribute to Open-Source](https://opensource.guide/how-to-contribute/) - * [Working with forks](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/working-with-forks) - * [Creating a Pull Request](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) + * [Working with forks](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/working-with-forks) + * [Creating a Pull Request](https://docs.github.com/en/free-pro-team@latest/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request-from-a-fork) * Slimefun - * [Contributing to Slimefun](https://github.com/Slimefun/Slimefun4/blob/master/.github/CONTRIBUTING.md) + * [Contributing to Slimefun](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md) * [Code of Conduct](https://github.com/Slimefun/Slimefun4/blob/master/.github/CODE_OF_CONDUCT.md)
diff --git a/.github/workflows/url-checker.yml b/.github/workflows/url-checker.yml index 3fb71f773..e0e150008 100644 --- a/.github/workflows/url-checker.yml +++ b/.github/workflows/url-checker.yml @@ -23,4 +23,4 @@ jobs: print_all: False retry_count: 2 ## These URLs will always be correct, even if their services may be offline right now - white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349 + white_listed_patterns: http://textures.minecraft.net/texture/,https://pastebin.com/,https://www.spigotmc.org/threads/spigot-bungeecord-1-16-1.447405/#post-3852349,https://gitlocalize.com/repo/3841 diff --git a/CHANGELOG.md b/CHANGELOG.md index d1119161b..99252737f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,9 +27,16 @@ #### Additions * Added /sf charge * Added Energized Energy Capacitor +* Added various new fuel types to the Coal Generator +* Added a config option for Grappling Hooks to not be consumed on use +* Added Talisman of the Caveman +* You can now convert any gold ingot into gold dust with slightly less returns +* (API) Added SlimefunGuideOpenEvent #### Changes * Improved Auto-Updater (Multi-Threading and more) +* General performance improvements +* /sf cheat now shows seasonal categories all year through #### Fixes * Fixed #2300 @@ -41,6 +48,16 @@ * Fixed #2325 * Fixed Climbing Pick having no animation in creative mode * Fixed #2322 +* Fixed some cargo incompatibilities with overflowing inventories +* Fixed #2353 +* Fixed #2359 +* Fixed #2356 +* Fixed #2358 +* Fixed #2360 +* Fixed #2351 +* Fixed #2357 +* Fixed Auto Enchanters being unaffected by speed modifications from addons +* Fixed Auto Disenchanters being unaffected by speed modifications from addons ## Release Candidate 16 (07 Sep 2020) https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#16 diff --git a/.github/CONTRIBUTING.md b/CONTRIBUTING.md similarity index 93% rename from .github/CONTRIBUTING.md rename to CONTRIBUTING.md index 816159b8a..e9d1e9120 100644 --- a/.github/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ You can also comment on the existing Issue, proposing your idea or communicating ## :wrench: 3. Pull Requests: Additions/Changes Slimefun is an Open-Source project and anyone is allowed to make changes or add content to this plugin! -Please visit our [Discord Server](https://github.com/Slimefun/Slimefun4#discord) and share your ideas first, we hate to reject changes because the community disagrees.
+Please visit our [Discord Server](https://discord.gg/slimefun) and share your ideas first, we hate to reject changes because the community disagrees.
So communicating your intended changes before-hand will ensure that you don't put too much work into something that might get rejected. We also have a suggestions section in our Discord Server too. Suggestions can be placed in the `#suggestions` channel and community members can vote on a suggestion. @@ -58,11 +58,11 @@ You can find a tutorial on how to contribute to our wiki right here:
https://github.com/Slimefun/Slimefun4/wiki/Expanding-the-Wiki ## :star: 6. Pull Requests: Code Quality -Slimefun uses [sonarcloud.io](https://sonarcloud.io/dashboard?id=TheBusyBiscuit_Slimefun4) to monitor Code Quality. +Slimefun uses [sonarcloud.io](https://sonarcloud.io/dashboard?id=Slimefun_Slimefun4) to monitor Code Quality. -We always welcome quality improvements to the code and the "Code Smells" section on [sonarcloud.io](https://sonarcloud.io/dashboard?id=TheBusyBiscuit_Slimefun4) is a great place to start. +We always welcome quality improvements to the code and the "Code Smells" section on [sonarcloud.io](https://sonarcloud.io/dashboard?id=Slimefun_Slimefun4) is a great place to start. But please keep in mind that some design patterns may not be changed too abruptly if an addon depends on them. -To prevent any accidents from happening, please contact us on our [Discord Server](https://github.com/Slimefun/Slimefun4#discord) before-hand and state your intended changes. +To prevent any accidents from happening, please contact us on our [Discord Server](https://discord.gg/slimefun) before-hand and state your intended changes. #### Documentation Code documentation is also a great way to improve the maintainability of the project. @@ -92,5 +92,5 @@ To compile Slimefun yourself, follow these steps: If you are already using an IDE, make sure to import the project via git and set it up as a *Maven project*. Then you should be able build it via Maven using the goals `clean package`. -If you have any further questions, then please join our [Discord Support Server](#discord) and ask your questions in the `#programming-help` channel.
+If you have any further questions, then please join our [Discord Support Server](https://discord.gg/slimefun) and ask your questions in the `#programming-help` channel.
**Note that we will not accept any bug reports from custom-compiled versions of Slimefun**. diff --git a/README.md b/README.md index 4e1a17550..80f30248b 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Check out our [Addons](https://github.com/Slimefun/Slimefun4/wiki/Addons), you m * **[Bug Tracker](https://github.com/Slimefun/Slimefun4/issues)** * **[Wiki](https://github.com/Slimefun/Slimefun4/wiki)** * **[FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)** -* **[How to contribute](https://github.com/Slimefun/Slimefun4/blob/master/.github/CONTRIBUTING.md)** +* **[How to contribute](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md)** ## Download Slimefun 4 (See also: [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun)) @@ -76,10 +76,9 @@ Due to the sheer size of this discord server, we need to enforce some [important Not following these rules can lead to a kick or even a ban from the server.

- - Discord Invite -
- (Click the badge to join) + + Discord Invite +

## Wiki @@ -106,7 +105,7 @@ Slimefun 4 is an Open-Source project and licensed under Over 150+ 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. -You can find more info on how to contribute to this project in our [CONTRIBUTING.md](https://github.com/Slimefun/Slimefun4/blob/master/.github/CONTRIBUTING.md). +You can find more info on how to contribute to this project in our [CONTRIBUTING.md](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md). ## Disclaimers Slimefun4 uses various systems that collect usage information or download automatic updates as well as the latest information about the project. diff --git a/pom.xml b/pom.xml index 3b8ebbf3c..70a205a84 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - com.github.thebusybiscuit + com.github.slimefun Slimefun @@ -26,8 +26,8 @@ https://hub.spigotmc.org/javadocs/spigot/ - TheBusyBiscuit_Slimefun4 - thebusybiscuit-github + Slimefun_Slimefun4 + slimefun https://sonarcloud.io DEBUG src/main/java/me/mrCookieSlime/Slimefun/bstats/bukkit/Metrics.java @@ -77,6 +77,7 @@ ${project.basedir}/src/main/java ${project.basedir}/src/test/java + clean package ${project.name} v${project.version} @@ -213,7 +214,7 @@ ${spigot.javadocs} - + Slimefun4 - API @@ -309,7 +310,7 @@ com.github.seeseemelk MockBukkit-v1.16 - 0.5.2 + 0.6.0 test @@ -323,7 +324,7 @@ org.mockito mockito-core - 3.5.11 + 3.5.13 test @@ -343,7 +344,7 @@ com.konghq unirest-java - 3.10.00 + 3.11.00 compile 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 edaf225ce..873f5e221 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java @@ -27,7 +27,6 @@ import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This class represents an {@link ErrorReport}. @@ -53,7 +52,7 @@ public class ErrorReport { this.throwable = throwable; this.addon = addon; - Slimefun.runSync(() -> print(printer)); + SlimefunPlugin.runSync(() -> print(printer)); } @ParametersAreNonnullByDefault diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncGeneratorProcessCompleteEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncGeneratorProcessCompleteEvent.java new file mode 100644 index 000000000..f3a1c792d --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncGeneratorProcessCompleteEvent.java @@ -0,0 +1,65 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This {@link Event} is fired whenever an {@link AGenerator} has completed its process. + * + * @author poma123 + * + */ +public class AsyncGeneratorProcessCompleteEvent extends AsyncMachineProcessCompleteEvent { + + private static final HandlerList handlers = new HandlerList(); + + private final AGenerator generator; + private final MachineFuel machineFuel; + + @ParametersAreNonnullByDefault + public AsyncGeneratorProcessCompleteEvent(Location l, AGenerator generator, MachineFuel machineFuel) { + super(l, null, null); + + this.generator = generator; + this.machineFuel = machineFuel; + } + + /** + * The {@link SlimefunItem} instance of the generator. + * + * @return The {@link SlimefunItem} instance of the generator + */ + @Nonnull + public AGenerator getGenerator() { + return generator; + } + + /** + * This returns the used {@link MachineFuel} in the process. + * + * @return The {@link MachineFuel} of the process + */ + @Nonnull + public MachineFuel getMachineFuel() { + return machineFuel; + } + + @Nonnull + public static HandlerList getHandlerList() { + return handlers; + } + + @Nonnull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncMachineProcessCompleteEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncMachineProcessCompleteEvent.java index 3091980e4..02d9412df 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncMachineProcessCompleteEvent.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncMachineProcessCompleteEvent.java @@ -1,14 +1,15 @@ package io.github.thebusybiscuit.slimefun4.api.events; import javax.annotation.Nonnull; -import javax.annotation.ParametersAreNonnullByDefault; +import javax.annotation.Nullable; -import org.bukkit.block.Block; +import org.bukkit.Location; import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** * This {@link Event} is fired whenever an {@link AContainer} has completed its process. @@ -20,33 +21,44 @@ public class AsyncMachineProcessCompleteEvent extends Event { private static final HandlerList handlers = new HandlerList(); - private final Block block; + private final Location location; + private final AContainer container; private final MachineRecipe machineRecipe; - @ParametersAreNonnullByDefault - public AsyncMachineProcessCompleteEvent(Block block, MachineRecipe machineRecipe) { + public AsyncMachineProcessCompleteEvent(@Nonnull Location l, @Nullable AContainer container, @Nullable MachineRecipe machineRecipe) { super(true); - this.block = block; + this.location = l; + this.container = container; this.machineRecipe = machineRecipe; } /** - * This method returns the {@link Block} of the machine. + * This returns the {@link Location} of the machine. * - * @return the {@link Block} of the machine + * @return The {@link Location} of the machine */ @Nonnull - public Block getMachine() { - return block; + public Location getLocation() { + return location; + } + + /** + * The {@link SlimefunItem} instance of the machine. + * + * @return The {@link SlimefunItem} instance of the machine + */ + @Nullable + public AContainer getMachine() { + return container; } /** * This returns the used {@link MachineRecipe} in the process. * - * @return the {@link MachineRecipe} of the process. + * @return The {@link MachineRecipe} of the process */ - @Nonnull + @Nullable public MachineRecipe getMachineRecipe() { return machineRecipe; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncReactorProcessCompleteEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncReactorProcessCompleteEvent.java new file mode 100644 index 000000000..6a4dd9dfb --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/AsyncReactorProcessCompleteEvent.java @@ -0,0 +1,65 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import org.bukkit.Location; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +import io.github.thebusybiscuit.slimefun4.implementation.items.electric.reactors.Reactor; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; + +/** + * This {@link Event} is fired whenever a {@link Reactor} has completed its process. + * + * @author poma123 + * + */ +public class AsyncReactorProcessCompleteEvent extends AsyncMachineProcessCompleteEvent { + + private static final HandlerList handlers = new HandlerList(); + + private final Reactor reactor; + private final MachineFuel machineFuel; + + @ParametersAreNonnullByDefault + public AsyncReactorProcessCompleteEvent(Location l, Reactor reactor, MachineFuel machineFuel) { + super(l, null, null); + + this.reactor = reactor; + this.machineFuel = machineFuel; + } + + /** + * The {@link SlimefunItem} instance of the reactor. + * + * @return The {@link SlimefunItem} instance of the reactor + */ + @Nonnull + public Reactor getReactor() { + return reactor; + } + + /** + * This returns the used {@link MachineFuel} in the process. + * + * @return The {@link MachineFuel} of the process + */ + @Nonnull + public MachineFuel getMachineFuel() { + return machineFuel; + } + + @Nonnull + public static HandlerList getHandlerList() { + return handlers; + } + + @Nonnull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java new file mode 100644 index 000000000..77026b0ae --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/SlimefunGuideOpenEvent.java @@ -0,0 +1,104 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import javax.annotation.Nonnull; + +import org.apache.commons.lang.Validate; +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; +import org.bukkit.inventory.ItemStack; + +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; + +/** + * This {@link Event} is called whenever a {@link Player} tries to open the Slimefun Guide book. + * + * @author Linox + * + * @see SlimefunGuideLayout + */ +public class SlimefunGuideOpenEvent extends Event implements Cancellable { + + private static final HandlerList handlers = new HandlerList(); + + private final Player player; + private final ItemStack guide; + private SlimefunGuideLayout layout; + private boolean cancelled; + + public SlimefunGuideOpenEvent(@Nonnull Player p, @Nonnull ItemStack guide, @Nonnull SlimefunGuideLayout layout) { + Validate.notNull(p, "The Player cannot be null"); + Validate.notNull(guide, "Guide cannot be null"); + Validate.notNull(layout, "Layout cannot be null"); + this.player = p; + this.guide = guide; + this.layout = layout; + } + + /** + * This returns the {@link Player} that tries to open + * the Slimefun Guide. + * + * @return The {@link Player} + */ + @Nonnull + public Player getPlayer() { + return player; + } + + /** + * This returns the {@link ItemStack} that {@link Player} + * tries to open the Slimefun Guide with. + * + * @return The {@link ItemStack} + */ + @Nonnull + public ItemStack getGuide() { + return guide; + } + + /** + * This returns the {@link SlimefunGuideLayout} of the Slimefun Guide + * that {@link Player} tries to open. + * + * @return The {@link SlimefunGuideLayout} + */ + @Nonnull + public SlimefunGuideLayout getGuideLayout() { + return layout; + } + + /** + * Changes the {@link SlimefunGuideLayout} that was tried to be opened with. + * + * @param layout + * The new {@link SlimefunGuideLayout} + */ + public void setGuideLayout(@Nonnull SlimefunGuideLayout layout) { + Validate.notNull(layout, "You must specify a layout that is not-null!"); + this.layout = layout; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancel) { + this.cancelled = cancel; + } + + @Nonnull + public static HandlerList getHandlerList() { + return handlers; + } + + @Nonnull + @Override + public HandlerList getHandlers() { + return getHandlerList(); + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java index d57d1bb20..e7507604e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/GPSNetwork.java @@ -37,7 +37,6 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link GPSNetwork} is a manager class for all {@link GPSTransmitter Transmitters} and waypoints. @@ -288,7 +287,7 @@ public class GPSNetwork { return; } - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { WaypointCreateEvent event = new WaypointCreateEvent(p, name, l); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java index 47e6f804e..32c4d485a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/gps/TeleportationManager.java @@ -27,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.papermc.lib.PaperLib; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; -import me.mrCookieSlime.Slimefun.api.Slimefun; public final class TeleportationManager { @@ -79,7 +78,7 @@ public final class TeleportationManager { index++; } - Slimefun.runSync(() -> menu.open(p)); + SlimefunPlugin.runSync(() -> menu.open(p)); }); } @@ -137,7 +136,7 @@ public final class TeleportationManager { source.getWorld().spawnParticle(Particle.PORTAL, source, progress * 2, 0.2F, 0.8F, 0.2F); source.getWorld().playSound(source, Sound.BLOCK_BEACON_AMBIENT, 1F, 0.6F); - Slimefun.runSync(() -> updateProgress(uuid, speed, progress + speed, source, destination, resistance), 10L); + SlimefunPlugin.runSync(() -> updateProgress(uuid, speed, progress + speed, source, destination, resistance), 10L); } } else { @@ -149,7 +148,7 @@ public final class TeleportationManager { private void onTeleport(Player p, Location destination, boolean success, boolean resistance) { // This needs to run on the main Thread so we force it, as the // async teleportation might happen on a separate Thread. - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { if (success) { // Apply Resistance Effect, if enabled if (resistance) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java index 21872a875..bc974b25b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/network/Network.java @@ -16,8 +16,8 @@ import org.bukkit.Particle; import org.bukkit.Particle.DustOptions; import io.github.thebusybiscuit.slimefun4.core.networks.NetworkManager; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.listeners.NetworkListener; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * An abstract Network class to manage networks in a stateful way @@ -217,7 +217,7 @@ public abstract class Network { * every {@link Location} that this {@link Network} is connected to. */ public void display() { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { DustOptions options = new DustOptions(Color.BLUE, 3F); for (Location l : connectedLocations) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerBackpack.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerBackpack.java index 581198d6e..3ef400fd8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerBackpack.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerBackpack.java @@ -10,9 +10,9 @@ import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.config.Config; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.SlimefunBackpack; import io.github.thebusybiscuit.slimefun4.implementation.listeners.BackpackListener; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This class represents the instance of a {@link SlimefunBackpack} that is ready to @@ -123,7 +123,7 @@ public class PlayerBackpack { * The players who this Backpack will be shown to */ public void open(Player... players) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { for (Player p : players) { p.openInventory(inventory); } 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 60a8a13f7..1b05dbcf1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/SlimefunRegistry.java @@ -11,7 +11,6 @@ import java.util.Set; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; -import org.bukkit.Location; import org.bukkit.Server; import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; @@ -70,7 +69,6 @@ public class SlimefunRegistry { private final Set tickers = new HashSet<>(); private final Set radioactive = new HashSet<>(); - private final Set activeChunks = ConcurrentHashMap.newKeySet(); private final Set barterDrops = new HashSet<>(); private final KeyMap geoResources = new KeyMap<>(); @@ -86,8 +84,6 @@ public class SlimefunRegistry { private final Map, Set> globalItemHandlers = new HashMap<>(); private final Map blockHandlers = new HashMap<>(); - private final Map> activeTickers = new ConcurrentHashMap<>(); - private final Map automatedCraftingChamberRecipes = new HashMap<>(); public void load(Config cfg) { @@ -226,10 +222,6 @@ public class SlimefunRegistry { return tickers; } - public Set getActiveChunks() { - return activeChunks; - } - public Map getSlimefunItemIds() { return slimefunIds; } @@ -262,10 +254,6 @@ public class SlimefunRegistry { return chunks; } - public Map> getActiveTickers() { - return activeTickers; - } - public KeyMap getGEOResources() { return geoResources; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java index 1b1478e30..20274c7e0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/commands/subcommands/BackpackCommand.java @@ -12,7 +12,6 @@ import io.github.thebusybiscuit.slimefun4.core.commands.SubCommand; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; -import me.mrCookieSlime.Slimefun.api.Slimefun; class BackpackCommand extends SubCommand { @@ -27,43 +26,48 @@ class BackpackCommand extends SubCommand { @Override public void onExecute(CommandSender sender, String[] args) { - if (!(sender instanceof Player) || !sender.hasPermission("slimefun.command.backpack")) { - SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); - return; - } + if (sender instanceof Player) { + if (sender.hasPermission("slimefun.command.backpack")) { + if (args.length != 3) { + SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf backpack ")); + return; + } - if (args.length != 3) { - SlimefunPlugin.getLocalization().sendMessage(sender, "messages.usage", true, msg -> msg.replace("%usage%", "/sf backpack ")); - return; - } + if (!PatternUtils.NUMERIC.matcher(args[2]).matches()) { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.invalid-id"); + return; + } - if (!PatternUtils.NUMERIC.matcher(args[2]).matches()) { - SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.invalid-id"); - return; - } + @SuppressWarnings("deprecation") + OfflinePlayer backpackOwner = Bukkit.getOfflinePlayer(args[1]); - @SuppressWarnings("deprecation") - OfflinePlayer backpackOwner = Bukkit.getOfflinePlayer(args[1]); + if (!(backpackOwner instanceof Player) && !backpackOwner.hasPlayedBefore()) { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.player-never-joined"); + return; + } - if (!(backpackOwner instanceof Player) && !backpackOwner.hasPlayedBefore()) { - SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.player-never-joined"); - return; - } + int id = Integer.parseInt(args[2]); - int id = Integer.parseInt(args[2]); + PlayerProfile.get(backpackOwner, profile -> { + if (!profile.getBackpack(id).isPresent()) { + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.backpack-does-not-exist"); + return; + } - PlayerProfile.get(backpackOwner, profile -> { - if (!profile.getBackpack(id).isPresent()) { - SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.backpack-does-not-exist"); - return; + SlimefunPlugin.runSync(() -> { + ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone(); + SlimefunPlugin.getBackpackListener().setBackpackId(backpackOwner, item, 2, id); + ((Player) sender).getInventory().addItem(item); + SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.restored-backpack-given"); + }); + }); } - - Slimefun.runSync(() -> { - ItemStack item = SlimefunItems.RESTORED_BACKPACK.clone(); - SlimefunPlugin.getBackpackListener().setBackpackId(backpackOwner, item, 2, id); - ((Player) sender).getInventory().addItem(item); - SlimefunPlugin.getLocalization().sendMessage(sender, "commands.backpack.restored-backpack-given"); - }); - }); + else { + SlimefunPlugin.getLocalization().sendMessage(sender, "messages.no-permission", true); + } + } + else { + SlimefunPlugin.getLocalization().sendMessage(sender, "messages.only-players", true); + } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java index cc15b1d1b..290be0f44 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/SlimefunGuide.java @@ -14,7 +14,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.guide.ChestSlimefunGuid import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This is a static utility class that provides convenient access to the methods @@ -73,7 +72,7 @@ public final class SlimefunGuide { } private static void openMainMenuAsync(Player player, SlimefunGuideLayout layout, int selectedPage) { - if (!PlayerProfile.get(player, profile -> Slimefun.runSync(() -> openMainMenu(profile, layout, selectedPage)))) { + if (!PlayerProfile.get(player, profile -> SlimefunPlugin.runSync(() -> openMainMenu(profile, layout, selectedPage)))) { SlimefunPlugin.getLocalization().sendMessage(player, "messages.opening-guide"); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java index c7fa6fcef..0b277ad30 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNet.java @@ -180,7 +180,7 @@ public class CargoNet extends ChestTerminalNetwork { SlimefunPlugin.getProfiler().scheduleEntries((terminals.isEmpty() ? 1 : 2) + inputs.size()); CargoNetworkTask runnable = new CargoNetworkTask(this, inputs, outputs, chestTerminalInputs, chestTerminalOutputs); - Slimefun.runSync(runnable); + SlimefunPlugin.runSync(runnable); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java index a65bdb25a..7ac5912ed 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoNetworkTask.java @@ -108,11 +108,18 @@ class CargoNetworkTask implements Runnable { Inventory inv = inventories.get(inputTarget.getLocation()); if (inv != null) { + // Check if the original slot hasn't been occupied in the meantime if (inv.getItem(previousSlot) == null) { inv.setItem(previousSlot, stack); } else { - inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), stack); + // Try to add the item into another available slot then + ItemStack rest = inv.addItem(stack).get(0); + + if (rest != null) { + // If the item still couldn't be inserted, simply drop it on the ground + inputTarget.getWorld().dropItem(inputTarget.getLocation().add(0, 1, 0), rest); + } } } else { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java index f10217f74..12127579b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/energy/EnergyNet.java @@ -27,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.utils.holograms.SimpleHologram; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link EnergyNet} is an implementation of {@link Network} that deals with @@ -229,7 +228,7 @@ public class EnergyNet extends Network { explodedBlocks.add(loc); BlockStorage.clearBlockInfo(loc); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { loc.getBlock().setType(Material.LAVA); loc.getWorld().createExplosion(loc, 0F, false); }); 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 63e69b884..907a390ff 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 @@ -26,7 +26,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.utils.FireworkUtils; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * Represents a research, which is bound to one @@ -230,7 +229,7 @@ public class Research implements Keyed { */ public void unlock(@Nonnull Player p, boolean instant, @Nonnull Consumer callback) { if (!instant) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F); SlimefunPlugin.getLocalization().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)).replace("%progress%", "0%")); }, 10L); @@ -238,7 +237,7 @@ public class Research implements Keyed { PlayerProfile.get(p, profile -> { if (!profile.hasUnlocked(this)) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { ResearchUnlockEvent event = new ResearchUnlockEvent(p, this); Bukkit.getPluginManager().callEvent(event); @@ -250,7 +249,7 @@ public class Research implements Keyed { SlimefunPlugin.getLocalization().sendMessage(p, "messages.research.start", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p))); playResearchAnimation(p); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { finishResearch(p, profile, callback); SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().remove(p.getUniqueId()); }, (RESEARCH_PROGRESS.length + 1) * 20L); @@ -275,7 +274,7 @@ public class Research implements Keyed { for (int i = 1; i < RESEARCH_PROGRESS.length + 1; i++) { int j = i; - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { p.playSound(p.getLocation(), Sound.ENTITY_BAT_TAKEOFF, 0.7F, 1F); SlimefunPlugin.getLocalization().sendMessage(p, "messages.research.progress", true, msg -> msg.replace(PLACEHOLDER_RESEARCH, getName(p)).replace("%progress%", RESEARCH_PROGRESS[j - 1] + "%")); }, i * 20L); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomTextureService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomTextureService.java index c84cd3830..d5ce5225b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomTextureService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/CustomTextureService.java @@ -51,6 +51,8 @@ public class CustomTextureService { config.setDefaultValue("SLIMEFUN_GUIDE", 0); config.setDefaultValue("_UI_BACKGROUND", 0); + config.setDefaultValue("_UI_INPUT_SLOT", 0); + config.setDefaultValue("_UI_OUTPUT_SLOT", 0); config.setDefaultValue("_UI_BACK", 0); config.setDefaultValue("_UI_MENU", 0); config.setDefaultValue("_UI_SEARCH", 0); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java index feaee4dc8..14277f7c4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/MetricsService.java @@ -22,7 +22,6 @@ import kong.unirest.HttpResponse; import kong.unirest.JsonNode; import kong.unirest.Unirest; import kong.unirest.UnirestException; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This Class represents a Metrics Service that sends data to https://bstats.org/ @@ -102,7 +101,7 @@ public class MetricsService { String version = metricsClass.getPackage().getImplementationVersion(); // This is required to be sync due to bStats. - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { try { start.invoke(null); plugin.getLogger().info("Metrics build #" + version + " started."); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PerWorldSettingsService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PerWorldSettingsService.java index f47323184..f3c9ebf3f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PerWorldSettingsService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/PerWorldSettingsService.java @@ -1,8 +1,6 @@ package io.github.thebusybiscuit.slimefun4.core.services; import java.io.File; -import java.io.IOException; -import java.nio.file.Files; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -12,8 +10,10 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.logging.Level; +import javax.annotation.Nonnull; + +import org.apache.commons.lang.Validate; import org.bukkit.Server; import org.bukkit.World; @@ -38,7 +38,7 @@ public class PerWorldSettingsService { private final Map> disabledAddons = new HashMap<>(); private final Set disabledWorlds = new HashSet<>(); - public PerWorldSettingsService(SlimefunPlugin plugin) { + public PerWorldSettingsService(@Nonnull SlimefunPlugin plugin) { this.plugin = plugin; } @@ -48,14 +48,7 @@ public class PerWorldSettingsService { * @param worlds * An {@link Iterable} of {@link World Worlds} to load */ - public void load(Iterable worlds) { - try { - migrate(); - } - catch (IOException e) { - plugin.getLogger().log(Level.WARNING, "An error occurred while migrating old world settings", e); - } - + public void load(@Nonnull Iterable worlds) { for (World world : worlds) { load(world); } @@ -67,41 +60,11 @@ public class PerWorldSettingsService { * @param world * The {@link World} to load */ - public void load(World world) { + public void load(@Nonnull World world) { + Validate.notNull(world, "Cannot load a world that is null"); disabledItems.putIfAbsent(world.getUID(), loadWorldFromConfig(world)); } - /** - * Temporary migration method for the old system - * - * @throws IOException - * This will be thrown if we failed to delete the old {@link File} - */ - private void migrate() throws IOException { - Config oldConfig = new Config(plugin, "whitelist.yml"); - - if (oldConfig.getFile().exists()) { - for (String world : oldConfig.getKeys()) { - Config newConfig = new Config(plugin, "world-settings/" + world + ".yml"); - newConfig.setDefaultValue("enabled", oldConfig.getBoolean(world + ".enabled")); - - for (String id : oldConfig.getKeys(world + ".enabled-items")) { - SlimefunItem item = SlimefunItem.getByID(id); - - if (item != null) { - String addon = item.getAddon().getName().toLowerCase(Locale.ROOT); - newConfig.setDefaultValue(addon + ".enabled", true); - newConfig.setDefaultValue(addon + '.' + id, oldConfig.getBoolean(world + ".enabled-items." + id)); - } - } - - newConfig.save(); - } - - Files.delete(oldConfig.getFile().toPath()); - } - } - /** * This method checks whether the given {@link SlimefunItem} is enabled in the given {@link World}. * @@ -112,7 +75,10 @@ public class PerWorldSettingsService { * * @return Whether the given {@link SlimefunItem} is enabled in that {@link World} */ - public boolean isEnabled(World world, SlimefunItem item) { + public boolean isEnabled(@Nonnull World world, @Nonnull SlimefunItem item) { + Validate.notNull(world, "The world cannot be null"); + Validate.notNull(item, "The SlimefunItem cannot be null"); + Set items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); if (disabledWorlds.contains(world.getUID())) { @@ -132,7 +98,10 @@ public class PerWorldSettingsService { * @param enabled * Whether the given {@link SlimefunItem} should be enabled in that world */ - public void setEnabled(World world, SlimefunItem item, boolean enabled) { + public void setEnabled(@Nonnull World world, @Nonnull SlimefunItem item, boolean enabled) { + Validate.notNull(world, "The world cannot be null"); + Validate.notNull(item, "The SlimefunItem cannot be null"); + Set items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); if (enabled) { @@ -151,7 +120,8 @@ public class PerWorldSettingsService { * @param enabled * Whether this {@link World} should be enabled or not */ - public void setEnabled(World world, boolean enabled) { + public void setEnabled(@Nonnull World world, boolean enabled) { + Validate.notNull(world, "null is not a valid World"); load(world); if (enabled) { @@ -170,7 +140,8 @@ public class PerWorldSettingsService { * * @return Whether this {@link World} is enabled */ - public boolean isWorldEnabled(World world) { + public boolean isWorldEnabled(@Nonnull World world) { + Validate.notNull(world, "null is not a valid World"); load(world); return !disabledWorlds.contains(world.getUID()); @@ -186,7 +157,9 @@ public class PerWorldSettingsService { * * @return Whether this addon is enabled in that {@link World} */ - public boolean isAddonEnabled(World world, SlimefunAddon addon) { + public boolean isAddonEnabled(@Nonnull World world, @Nonnull SlimefunAddon addon) { + Validate.notNull(world, "World cannot be null"); + Validate.notNull(addon, "Addon cannot be null"); return isWorldEnabled(world) && disabledAddons.getOrDefault(addon, Collections.emptySet()).contains(world.getName()); } @@ -198,7 +171,8 @@ public class PerWorldSettingsService { * @param world * The {@link World} to save */ - public void save(World world) { + public void save(@Nonnull World world) { + Validate.notNull(world, "Cannot save a World that does not exist"); Set items = disabledItems.computeIfAbsent(world.getUID(), id -> loadWorldFromConfig(world)); Config config = getConfig(world); @@ -213,7 +187,10 @@ public class PerWorldSettingsService { config.save(); } - private Set loadWorldFromConfig(World world) { + @Nonnull + private Set loadWorldFromConfig(@Nonnull World world) { + Validate.notNull(world, "Cannot load a World that does not exist"); + String name = world.getName(); Optional> optional = disabledItems.get(world.getUID()); @@ -231,6 +208,7 @@ public class PerWorldSettingsService { if (config.getBoolean("enabled")) { loadItemsFromWorldConfig(name, config, items); + // We don't actually wanna write to disk during a Unit test if (SlimefunPlugin.getMinecraftVersion() != MinecraftVersion.UNIT_TEST) { config.save(); } @@ -243,13 +221,14 @@ public class PerWorldSettingsService { } } - private void loadItemsFromWorldConfig(String worldName, Config config, Set items) { + private void loadItemsFromWorldConfig(@Nonnull String worldName, @Nonnull Config config, @Nonnull Set items) { for (SlimefunItem item : SlimefunPlugin.getRegistry().getEnabledSlimefunItems()) { if (item != null) { String addon = item.getAddon().getName().toLowerCase(Locale.ROOT); config.setDefaultValue(addon + ".enabled", true); config.setDefaultValue(addon + '.' + item.getID(), true); + // Whether the entire addon has been disabled boolean isAddonDisabled = config.getBoolean(addon + ".enabled"); if (isAddonDisabled) { @@ -264,7 +243,17 @@ public class PerWorldSettingsService { } } - private Config getConfig(World world) { + /** + * This method returns the relevant {@link Config} for the given {@link World} + * + * @param world + * Our {@link World} + * + * @return The corresponding {@link Config} + */ + @Nonnull + private Config getConfig(@Nonnull World world) { + Validate.notNull(world, "World cannot be null"); return new Config(plugin, "world-settings/" + world.getName() + ".yml"); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ActivityCallback.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ActivityCallback.java new file mode 100644 index 000000000..e02236e39 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ActivityCallback.java @@ -0,0 +1,22 @@ +package io.github.thebusybiscuit.slimefun4.core.services.github; + +import java.time.LocalDateTime; + +import javax.annotation.Nonnull; + +@FunctionalInterface +interface ActivityCallback { + + /** + * This method is called when the {@link GitHubActivityConnector} finished loading. + * + * @param forks + * The amount of forks + * @param stars + * The amount of stars + * @param date + * The {@link LocalDateTime} of the last activity + */ + void accept(int forks, int stars, @Nonnull LocalDateTime date); + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java index 0ee739265..1d3f43e80 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/ContributionsConnector.java @@ -61,14 +61,14 @@ class ContributionsConnector extends GitHubConnector { } @Override - public void onSuccess(JsonNode element) { + public void onSuccess(@Nonnull JsonNode response) { finished = true; - if (element.isArray()) { - computeContributors(element.getArray()); + if (response.isArray()) { + computeContributors(response.getArray()); } else { - Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", element); + Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response); } } @@ -96,7 +96,8 @@ class ContributionsConnector extends GitHubConnector { String profile = object.getString("html_url"); if (!blacklist.contains(name)) { - github.addContributor(aliases.getOrDefault(name, name), profile, role, commits); + String username = aliases.getOrDefault(name, name); + github.addContributor(username, profile, role, commits); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java index d48bbf8e5..82264255c 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Contributor.java @@ -40,15 +40,29 @@ public class Contributor { private Optional uuid = Optional.empty(); private boolean locked = false; - public Contributor(@Nonnull String username, @Nonnull String profile) { - Validate.notNull(username, "Username must never be null!"); + /** + * This creates a new {@link Contributor} with the given ingame name and GitHub profile. + * + * @param minecraftName + * The ingame name in Minecraft for this {@link Contributor} + * @param profile + * A link to their GitHub profile + */ + public Contributor(@Nonnull String minecraftName, @Nonnull String profile) { + Validate.notNull(minecraftName, "Username must never be null!"); Validate.notNull(profile, "The profile cannot be null!"); githubUsername = profile.substring(profile.lastIndexOf('/') + 1); - minecraftUsername = username; + minecraftUsername = minecraftName; profileLink = profile; } + /** + * This creates a new {@link Contributor} with the given username. + * + * @param username + * The username of this {@link Contributor} + */ public Contributor(@Nonnull String username) { Validate.notNull(username, "Username must never be null!"); @@ -57,8 +71,18 @@ public class Contributor { profileLink = null; } - public void setContribution(@Nonnull String role, int commits) { + /** + * This sets the amount of contributions of this {@link Contributor} for the + * specified role. + * + * @param role + * The role + * @param commits + * The amount of contributions made as that role + */ + public void setContributions(@Nonnull String role, int commits) { Validate.notNull(role, "The role cannot be null!"); + Validate.isTrue(commits >= 0, "Contributions cannot be negative"); if (!locked || role.startsWith("translator,")) { contributions.put(role, commits); @@ -66,9 +90,9 @@ public class Contributor { } /** - * Returns the name of this contributor. + * Returns the name of this {@link Contributor}. * - * @return the name of this contributor + * @return the name of this {@link Contributor} */ @Nonnull public String getName() { @@ -76,10 +100,10 @@ public class Contributor { } /** - * Returns the MC name of the contributor. - * This may be the same as {@link #getName()}. + * Returns the Minecraft username of the {@link Contributor}. + * This can be the same as {@link #getName()}. * - * @return The MC username of this contributor. + * @return The Minecraft username of this {@link Contributor}. */ @Nonnull public String getMinecraftName() { @@ -109,6 +133,7 @@ public class Contributor { * * @param role * The role for which to count the contributions. + * * @return The amount of contributions this {@link Contributor} submitted as the given role */ public int getContributions(@Nonnull String role) { @@ -137,7 +162,7 @@ public class Contributor { } /** - * Returns this Creator's head texture. + * Returns this contributor's head texture. * If no texture could be found, or it hasn't been pulled yet, * then it will return a placeholder texture. * @@ -171,10 +196,22 @@ public class Contributor { return headTexture.isComputed(); } + /** + * This sets the skin texture of this {@link Contributor} or clears it. + * + * @param skin + * The base64 skin texture or null + */ public void setTexture(@Nullable String skin) { headTexture.compute(skin); } + /** + * This returns the total amount of contributions towards this project for this + * {@link Contributor}. + * + * @return The total amount of contributions + */ public int getTotalContributions() { return contributions.values().stream().mapToInt(Integer::intValue).sum(); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java new file mode 100644 index 000000000..e55fc722e --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubActivityConnector.java @@ -0,0 +1,42 @@ +package io.github.thebusybiscuit.slimefun4.core.services.github; + +import java.time.LocalDateTime; + +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; +import kong.unirest.JsonNode; +import kong.unirest.json.JSONObject; + +class GitHubActivityConnector extends GitHubConnector { + + private final ActivityCallback callback; + + @ParametersAreNonnullByDefault + GitHubActivityConnector(GitHubService github, String repository, ActivityCallback callback) { + super(github, repository); + this.callback = callback; + } + + @Override + public void onSuccess(@Nonnull JsonNode response) { + JSONObject object = response.getObject(); + int forks = object.getInt("forks"); + int stars = object.getInt("stargazers_count"); + LocalDateTime lastPush = NumberUtils.parseGitHubDate(object.getString("pushed_at")); + + callback.accept(forks, stars, lastPush); + } + + @Override + public String getFileName() { + return "repo"; + } + + @Override + public String getURLSuffix() { + return ""; + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java index 2b563500e..46913f44e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubConnector.java @@ -10,6 +10,7 @@ import java.nio.charset.StandardCharsets; import java.util.logging.Level; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import kong.unirest.HttpResponse; @@ -19,8 +20,16 @@ import kong.unirest.UnirestException; import kong.unirest.json.JSONException; import me.mrCookieSlime.Slimefun.api.Slimefun; +/** + * The {@link GitHubConnector} is used to connect to the GitHub API service. + * It can be extended by subclasses, this just serves as an abstract super class for + * other connectors. + * + * @author TheBusyBiscuit + * @author Walshy + */ abstract class GitHubConnector { - + private static final String API_URL = "https://api.github.com/"; protected File file; @@ -33,12 +42,23 @@ abstract class GitHubConnector { this.repository = repository; } + @Nonnull public abstract String getFileName(); + @Nonnull public abstract String getURLSuffix(); - public abstract void onSuccess(JsonNode element); + /** + * This method is called when the connection finished successfully. + * + * @param response + * The response + */ + public abstract void onSuccess(@Nonnull JsonNode response); + /** + * This method is called when the connection has failed. + */ public void onFailure() { // Don't do anything by default } @@ -61,7 +81,7 @@ abstract class GitHubConnector { } else { if (github.isLoggingEnabled()) { - Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] {repository + getURLSuffix(), resp.getStatus(), resp.getBody()}); + Slimefun.getLogger().log(Level.WARNING, "Failed to fetch {0}: {1} - {2}", new Object[] { repository + getURLSuffix(), resp.getStatus(), resp.getBody() }); } // It has the cached file, let's just read that then @@ -94,12 +114,13 @@ abstract class GitHubConnector { } } + @Nullable private JsonNode readCacheFile() { try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8))) { return new JsonNode(reader.readLine()); } catch (IOException | JSONException e) { - Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] {file.getName(), e.getClass().getSimpleName(), e.getMessage()}); + Slimefun.getLogger().log(Level.WARNING, "Failed to read Github cache file: {0} - {1}: {2}", new Object[] { file.getName(), e.getClass().getSimpleName(), e.getMessage() }); return null; } } @@ -109,7 +130,7 @@ abstract class GitHubConnector { output.write(node.toString().getBytes(StandardCharsets.UTF_8)); } catch (IOException e) { - Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] {e.getClass().getSimpleName(), e.getMessage()}); + Slimefun.getLogger().log(Level.WARNING, "Failed to populate GitHub cache: {0} - {1}", new Object[] { e.getClass().getSimpleName(), e.getMessage() }); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesTracker.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java similarity index 72% rename from src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesTracker.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java index 4266e3c32..e30a6a623 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesTracker.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubIssuesConnector.java @@ -2,6 +2,7 @@ package io.github.thebusybiscuit.slimefun4.core.services.github; import java.util.logging.Level; +import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; import kong.unirest.JsonNode; @@ -9,20 +10,20 @@ import kong.unirest.json.JSONArray; import kong.unirest.json.JSONObject; import me.mrCookieSlime.Slimefun.api.Slimefun; -class GitHubIssuesTracker extends GitHubConnector { +class GitHubIssuesConnector extends GitHubConnector { - private final IssuesTrackerConsumer callback; + private final IssuesCallback callback; @ParametersAreNonnullByDefault - GitHubIssuesTracker(GitHubService github, String repository, IssuesTrackerConsumer callback) { + GitHubIssuesConnector(GitHubService github, String repository, IssuesCallback callback) { super(github, repository); this.callback = callback; } @Override - public void onSuccess(JsonNode element) { - if (element.isArray()) { - JSONArray array = element.getArray(); + public void onSuccess(@Nonnull JsonNode response) { + if (response.isArray()) { + JSONArray array = response.getArray(); int issues = 0; int pullRequests = 0; @@ -41,7 +42,7 @@ class GitHubIssuesTracker extends GitHubConnector { callback.accept(issues, pullRequests); } else { - Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", element); + Slimefun.getLogger().log(Level.WARNING, "Received an unusual answer from GitHub, possibly a timeout? ({0})", response); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubService.java index e2d85b40c..b7a2fc07d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubService.java @@ -16,9 +16,6 @@ import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; -import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; -import kong.unirest.JsonNode; -import kong.unirest.json.JSONObject; /** * This Service is responsible for grabbing every {@link Contributor} to this project @@ -39,11 +36,11 @@ public class GitHubService { private boolean logging = false; - private int issues = 0; - private int pullRequests = 0; - private int forks = 0; - private int stars = 0; private LocalDateTime lastUpdate = LocalDateTime.now(); + private int openIssues = 0; + private int pendingPullRequests = 0; + private int publicForks = 0; + private int stargazers = 0; /** * This creates a new {@link GitHubService} for the given repository. @@ -63,6 +60,11 @@ public class GitHubService { plugin.getServer().getScheduler().runTaskTimerAsynchronously(plugin, new GitHubTask(this), 80L, 60 * 60 * 20L); } + /** + * This method adds a few default {@link Contributor Contributors}. + * Think of them like honorable mentions that aren't listed through + * the usual methods. + */ private void addDefaultContributors() { addContributor("Fuffles_", "&dArtist"); addContributor("IMS_Art", "&dArtist"); @@ -73,7 +75,7 @@ public class GitHubService { private void addContributor(@Nonnull String name, @Nonnull String role) { Contributor contributor = new Contributor(name); - contributor.setContribution(role, 0); + contributor.setContributions(role, 0); contributor.setUniqueId(uuidCache.getUUID(name)); contributors.put(name, contributor); } @@ -83,7 +85,7 @@ public class GitHubService { String username = profileURL.substring(profileURL.lastIndexOf('/') + 1); Contributor contributor = contributors.computeIfAbsent(username, key -> new Contributor(minecraftName, profileURL)); - contributor.setContribution(role, commits); + contributor.setContributions(role, commits); contributor.setUniqueId(uuidCache.getUUID(minecraftName)); return contributor; } @@ -97,37 +99,22 @@ public class GitHubService { connectors.add(new ContributionsConnector(this, "code2", 2, repository, "developer")); // TheBusyBiscuit/Slimefun4-Wiki - connectors.add(new ContributionsConnector(this, "wiki", 1, "Slimefun/Slimefun-wiki", "wiki")); + connectors.add(new ContributionsConnector(this, "wiki", 1, "Slimefun/Wiki", "wiki")); // TheBusyBiscuit/Slimefun4-Resourcepack connectors.add(new ContributionsConnector(this, "resourcepack", 1, "Slimefun/Resourcepack", "resourcepack")); // Issues and Pull Requests - connectors.add(new GitHubIssuesTracker(this, repository, (openIssues, openPullRequests) -> { - this.issues = openIssues; - this.pullRequests = openPullRequests; + connectors.add(new GitHubIssuesConnector(this, repository, (issues, pullRequests) -> { + this.openIssues = issues; + this.pendingPullRequests = pullRequests; })); - connectors.add(new GitHubConnector(this, repository) { - - @Override - public void onSuccess(JsonNode element) { - JSONObject object = element.getObject(); - forks = object.getInt("forks"); - stars = object.getInt("stargazers_count"); - lastUpdate = NumberUtils.parseGitHubDate(object.getString("pushed_at")); - } - - @Override - public String getFileName() { - return "repo"; - } - - @Override - public String getURLSuffix() { - return ""; - } - }); + connectors.add(new GitHubActivityConnector(this, repository, (forks, stars, date) -> { + this.publicForks = forks; + this.stargazers = stars; + this.lastUpdate = date; + })); } @Nonnull @@ -155,7 +142,7 @@ public class GitHubService { * @return The amount of forks */ public int getForks() { - return forks; + return publicForks; } /** @@ -164,7 +151,7 @@ public class GitHubService { * @return The amount of people who starred the repository */ public int getStars() { - return stars; + return stargazers; } /** @@ -173,7 +160,7 @@ public class GitHubService { * @return The amount of open issues */ public int getOpenIssues() { - return issues; + return openIssues; } /** @@ -192,7 +179,7 @@ public class GitHubService { * @return The amount of pending pull requests */ public int getPendingPullRequests() { - return pullRequests; + return pendingPullRequests; } /** @@ -212,7 +199,6 @@ public class GitHubService { protected void saveCache() { for (Contributor contributor : contributors.values()) { Optional uuid = contributor.getUniqueId(); - uuid.ifPresent(value -> uuidCache.setValue(contributor.getName(), value)); if (contributor.hasTexture()) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java index 16251ef39..16e65d8f9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/GitHubTask.java @@ -8,6 +8,7 @@ import java.util.UUID; import java.util.logging.Level; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.bukkit.Bukkit; @@ -29,7 +30,6 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; class GitHubTask implements Runnable { private static final int MAX_REQUESTS_PER_MINUTE = 16; - private final GitHubService gitHubService; GitHubTask(@Nonnull GitHubService github) { @@ -39,7 +39,6 @@ class GitHubTask implements Runnable { @Override public void run() { gitHubService.getConnectors().forEach(GitHubConnector::pullFile); - grabTextures(); } @@ -112,12 +111,12 @@ class GitHubTask implements Runnable { return 0; } + @Nullable private String pullTexture(@Nonnull Contributor contributor, @Nonnull Map skins) throws TooManyRequestsException, IOException { Optional uuid = contributor.getUniqueId(); if (!uuid.isPresent()) { uuid = MinecraftAccount.getUUID(contributor.getMinecraftName()); - uuid.ifPresent(contributor::setUniqueId); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/IssuesTrackerConsumer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/IssuesCallback.java similarity index 72% rename from src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/IssuesTrackerConsumer.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/IssuesCallback.java index b0a52edd9..7d32f72da 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/IssuesTrackerConsumer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/IssuesCallback.java @@ -1,10 +1,10 @@ package io.github.thebusybiscuit.slimefun4.core.services.github; @FunctionalInterface -interface IssuesTrackerConsumer { +interface IssuesCallback { /** - * This method is called when the {@link GitHubIssuesTracker} finished loading. + * This method is called when the {@link GitHubIssuesConnector} finished loading. * * @param issues * The amount of open Issues diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java index a898e87e8..f423c97e6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunItems.java @@ -560,6 +560,7 @@ public final class SlimefunItems { public static final SlimefunItemStack TALISMAN_KNIGHT = new SlimefunItemStack("KNIGHT_TALISMAN", Material.EMERALD, "&aTalisman of the Knight", "", "&fWhile you have this Talisman", "&fin your Inventory it gives", "&fyou a 30% Chance for 5 Seconds of Regeneration", "&fwhenever You get hit", "&fbut will then be consumed"); public static final SlimefunItemStack TALISMAN_WHIRLWIND = new SlimefunItemStack("WHIRLWIND_TALISMAN", Material.EMERALD, "&aTalisman of the Whirlwind", "", "&fHaving this Talisman", "&fin your Inventory will reflect", "&f60% of any projectiles fired at you.", "&e&oOnly a thrown Trident can pierce", "&e&othrough this layer of protection"); public static final SlimefunItemStack TALISMAN_WIZARD = new SlimefunItemStack("WIZARD_TALISMAN", Material.EMERALD, "&aTalisman of the Wizard", "", "&fWhile you have this Talisman", "&fin your Inventory it allows you to", "&fobtain Fortune Level 4/5 however", "&fit also has a chance to lower the", "&fLevel of some Enchantments on your Item"); + public static final SlimefunItemStack TALISMAN_CAVEMAN = new SlimefunItemStack("CAVEMAN_TALISMAN", Material.EMERALD, "&aTalisman of the Caveman", "", "&fWhile you have this Talisman", "&fin your inventory it gives", "&fyou a 50% chance for a decent", "&fHaste buff when you mine any ore"); /* Staves */ public static final SlimefunItemStack STAFF_ELEMENTAL = new SlimefunItemStack("STAFF_ELEMENTAL", Material.STICK, "&6Elemental Staff"); 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 44e679c62..078f38c33 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/SlimefunPlugin.java @@ -13,6 +13,7 @@ import java.util.stream.Collectors; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; import org.bukkit.Server; import org.bukkit.command.Command; @@ -21,6 +22,7 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPluginLoader; +import org.bukkit.scheduler.BukkitTask; import io.github.thebusybiscuit.cscorelib2.config.Config; import io.github.thebusybiscuit.cscorelib2.math.DoubleHandler; @@ -102,7 +104,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.CSCoreLib; 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.Slimefun; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; /** @@ -242,7 +243,7 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { registerListeners(); // Initiating various Stuff and all items with a slight delay (0ms after the Server finished loading) - Slimefun.runSync(new SlimefunStartupTask(this, () -> { + runSync(new SlimefunStartupTask(this, () -> { protections = new ProtectionManager(getServer()); textureService.register(registry.getAllSlimefunItems(), true); permissionsService.register(registry.getAllSlimefunItems(), true); @@ -708,4 +709,63 @@ public final class SlimefunPlugin extends JavaPlugin implements SlimefunAddon { return "https://github.com/Slimefun/Slimefun4/issues"; } + /** + * This method schedules a delayed synchronous task for Slimefun. + * For Slimefun only, not for addons. + * + * This method should only be invoked by Slimefun itself. + * Addons must schedule their own tasks using their own {@link Plugin} instance. + * + * @param runnable + * The {@link Runnable} to run + * @param delay + * The delay for this task + * + * @return The resulting {@link BukkitTask} or null if Slimefun was disabled + */ + @Nullable + public static BukkitTask runSync(@Nonnull Runnable runnable, long delay) { + Validate.notNull(runnable, "Cannot run null"); + Validate.isTrue(delay >= 0, "The delay cannot be negative"); + + if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { + runnable.run(); + return null; + } + + if (instance == null || !instance.isEnabled()) { + return null; + } + + return instance.getServer().getScheduler().runTaskLater(instance, runnable, delay); + } + + /** + * This method schedules a synchronous task for Slimefun. + * For Slimefun only, not for addons. + * + * This method should only be invoked by Slimefun itself. + * Addons must schedule their own tasks using their own {@link Plugin} instance. + * + * @param runnable + * The {@link Runnable} to run + * + * @return The resulting {@link BukkitTask} or null if Slimefun was disabled + */ + @Nullable + public static BukkitTask runSync(@Nonnull Runnable runnable) { + Validate.notNull(runnable, "Cannot run null"); + + if (getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { + runnable.run(); + return null; + } + + if (instance == null || !instance.isEnabled()) { + return null; + } + + return instance.getServer().getScheduler().runTask(instance, runnable); + } + } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java index 79369acce..d15c1936e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/guide/BookSlimefunGuide.java @@ -80,7 +80,7 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { ChatComponent header = new ChatComponent(ChatColors.color("&b&l- " + SlimefunPlugin.getLocalization().getMessage(p, "guide.title.main") + " -\n\n")); header.setHoverEvent(new HoverEvent(ChestMenuUtils.getSearchButton(p))); - header.setClickEvent(new ClickEvent(guideSearch, player -> Slimefun.runSync(() -> { + header.setClickEvent(new ClickEvent(guideSearch, player -> SlimefunPlugin.runSync(() -> { SlimefunPlugin.getLocalization().sendMessage(player, "guide.search.message"); ChatInput.waitForPlayer(SlimefunPlugin.instance(), player, msg -> SlimefunGuide.openSearch(profile, msg, true, true)); }, 1))); @@ -234,13 +234,13 @@ public class BookSlimefunGuide implements SlimefunGuideImplementation { } component.setHoverEvent(new HoverEvent(lore)); - component.setClickEvent(new ClickEvent(key, player -> Slimefun.runSync(() -> displayItem(profile, item, true)))); + component.setClickEvent(new ClickEvent(key, player -> SlimefunPlugin.runSync(() -> displayItem(profile, item, true)))); items.add(component); } } private void research(Player p, PlayerProfile profile, SlimefunItem item, Research research, Category category, int page) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { if (!SlimefunPlugin.getRegistry().getCurrentlyResearchingPlayers().contains(p.getUniqueId())) { if (research.canUnlock(p)) { if (profile.hasUnlocked(research)) { 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 35f31305c..d02c04c7e 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 @@ -1,14 +1,23 @@ package io.github.thebusybiscuit.slimefun4.implementation.guide; +import javax.annotation.Nonnull; + +import java.util.LinkedList; +import java.util.List; + +import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.Recipe; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; +import io.github.thebusybiscuit.slimefun4.core.categories.FlexCategory; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.itemstack.SlimefunGuideItem; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; +import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; /** @@ -33,6 +42,29 @@ public class CheatSheetSlimefunGuide extends ChestSlimefunGuide { return false; } + /** + * Returns a {@link List} of visible {@link Category} instances that the {@link SlimefunGuide} would display. + * + * @param p + * The {@link Player} who opened his {@link SlimefunGuide} + * @param profile + * The {@link PlayerProfile} of the {@link Player} + * @return a {@link List} of visible {@link Category} instances + */ + @Nonnull + @Override + protected List getVisibleCategories(@Nonnull Player p, @Nonnull PlayerProfile profile) { + List categories = new LinkedList<>(); + + for (Category category : SlimefunPlugin.getRegistry().getCategories()) { + if (!(category instanceof FlexCategory)) { + categories.add(category); + } + } + + return categories; + } + @Override public SlimefunGuideLayout getLayout() { return SlimefunGuideLayout.CHEAT_SHEET; 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 33f3b0d16..4aacf3a40 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 @@ -1,5 +1,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.guide; +import javax.annotation.Nonnull; + import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedList; @@ -96,7 +98,17 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation { return true; } - private List getVisibleCategories(Player p, PlayerProfile profile) { + /** + * Returns a {@link List} of visible {@link Category} instances that the {@link SlimefunGuide} would display. + * + * @param p + * The {@link Player} who opened his {@link SlimefunGuide} + * @param profile + * The {@link PlayerProfile} of the {@link Player} + * @return a {@link List} of visible {@link Category} instances + */ + @Nonnull + protected List getVisibleCategories(@Nonnull Player p, @Nonnull PlayerProfile profile) { List categories = new LinkedList<>(); for (Category category : SlimefunPlugin.getRegistry().getCategories()) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java index 47bbb6724..a8a90354f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/AndroidFuelSource.java @@ -1,9 +1,11 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.androids; +import javax.annotation.Nonnull; + import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; -import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; /** * This enum covers all different fuel sources a {@link ProgrammableAndroid} can have. @@ -30,7 +32,7 @@ public enum AndroidFuelSource { private final String[] lore; - AndroidFuelSource(String... lore) { + AndroidFuelSource(@Nonnull String... lore) { this.lore = lore; } @@ -39,8 +41,9 @@ public enum AndroidFuelSource { * * @return An {@link ItemStack} to display */ + @Nonnull public ItemStack getItem() { - return new CustomItem(SlimefunItems.COAL_GENERATOR, "&8\u21E9 &cFuel Input &8\u21E9", lore); + return new CustomItem(HeadTexture.GENERATOR.getAsItemStack(), "&8\u21E9 &cFuel Input &8\u21E9", lore); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java index 096abbf8e..52fb2feb4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/androids/ProgrammableAndroid.java @@ -7,6 +7,9 @@ import java.util.Optional; import java.util.function.Predicate; import java.util.logging.Level; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + import org.apache.commons.lang.Validate; import org.bukkit.ChatColor; import org.bukkit.Location; @@ -55,7 +58,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemHandler; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -221,6 +223,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, }); } + @ParametersAreNonnullByDefault public void openScript(Player p, Block b, String sourceCode) { ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + SlimefunPlugin.getLocalization().getMessage(p, "android.scripts.editor")); menu.setEmptySlotsClickable(false); @@ -291,6 +294,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, menu.open(p); } + @ParametersAreNonnullByDefault private String addInstruction(String[] script, int index, Instruction instruction) { int i = 0; StringBuilder builder = new StringBuilder(Instruction.START.name() + '-'); @@ -311,7 +315,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, return builder.toString(); } - private String duplicateInstruction(String[] script, int index) { + private String duplicateInstruction(@Nonnull String[] script, int index) { int i = 0; StringBuilder builder = new StringBuilder(Instruction.START + "-"); @@ -437,13 +441,9 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, menu.open(p); } + @ParametersAreNonnullByDefault private void uploadScript(Player p, Block b, int page) { String code = getScript(b.getLocation()); - - if (code == null) { - return; - } - int nextId = 1; for (Script script : Script.getUploadedScripts(getAndroidType())) { @@ -542,12 +542,13 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, menu.open(p); } - protected String getScript(Location l) { + @Nonnull + protected String getScript(@Nonnull Location l) { String script = BlockStorage.getLocationInfo(l, "script"); return script != null ? script : DEFAULT_SCRIPT; } - protected void setScript(Location l, String script) { + protected void setScript(@Nonnull Location l, @Nonnull String script) { BlockStorage.addBlockInfo(l, "script", script); } @@ -784,10 +785,11 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, return false; } + @ParametersAreNonnullByDefault private void consumeFuel(Block b, BlockMenu menu) { ItemStack item = menu.getItemInSlot(43); - if (item != null) { + if (item != null && item.getType() != Material.AIR) { for (MachineFuel fuel : fuelTypes) { if (fuel.test(item)) { menu.consumeItem(43); @@ -804,12 +806,12 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, } } - private void constructMenu(BlockMenuPreset preset) { + private void constructMenu(@Nonnull BlockMenuPreset preset) { for (int i : BORDER) { - preset.addItem(i, new CustomItem(new ItemStack(Material.GRAY_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); } for (int i : OUTPUT_BORDER) { - preset.addItem(i, new CustomItem(new ItemStack(Material.ORANGE_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler()); } for (int i : getOutputSlots()) { @@ -848,7 +850,7 @@ public class ProgrammableAndroid extends SlimefunItem implements InventoryBlock, }); block.setBlockData(blockData); - Slimefun.runSync(() -> SkullBlock.setFromBase64(block, texture)); + SlimefunPlugin.runSync(() -> SkullBlock.setFromBase64(block, texture)); b.setType(Material.AIR); BlockStorage.moveBlockInfo(b.getLocation(), block.getLocation()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java index 225af96dd..d71d43ed8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/BlockPlacer.java @@ -32,7 +32,6 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -156,7 +155,7 @@ public class BlockPlacer extends SlimefunItem { dispenser.getInventory().removeItem(new CustomItem(item, 1)); } else { - Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L); } } }); @@ -171,7 +170,7 @@ public class BlockPlacer extends SlimefunItem { dispenser.getInventory().removeItem(new CustomItem(item, 1)); } else { - Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L); } } } @@ -209,7 +208,7 @@ public class BlockPlacer extends SlimefunItem { dispenser.getInventory().removeItem(new CustomItem(item, 1)); } else { - Slimefun.runSync(() -> dispenser.getInventory().removeItem(item), 2L); + SlimefunPlugin.runSync(() -> dispenser.getInventory().removeItem(item), 2L); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java index b7e490b6a..4ed2e7e3d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/blocks/Crucible.java @@ -4,6 +4,9 @@ import java.util.LinkedList; import java.util.List; import java.util.Optional; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.Material; import org.bukkit.Sound; import org.bukkit.Tag; @@ -24,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public class Crucible extends SimpleSlimefunItem implements RecipeDisplayItem { @@ -100,6 +102,7 @@ public class Crucible extends SimpleSlimefunItem implements Rec }; } + @ParametersAreNonnullByDefault private boolean craft(Player p, ItemStack input) { for (int i = 0; i < recipes.size(); i += 2) { ItemStack convert = recipes.get(i); @@ -116,7 +119,7 @@ public class Crucible extends SimpleSlimefunItem implements Rec return false; } - private void generateLiquid(Block block, boolean water) { + private void generateLiquid(@Nonnull Block block, boolean water) { if (block.getType() == (water ? Material.WATER : Material.LAVA)) { addLiquidLevel(block, water); } @@ -126,11 +129,11 @@ public class Crucible extends SimpleSlimefunItem implements Rec block.getWorld().playSound(block.getLocation(), Sound.BLOCK_LAVA_EXTINGUISH, 1F, 1F); } else { - Slimefun.runSync(() -> placeLiquid(block, water), 50L); + SlimefunPlugin.runSync(() -> placeLiquid(block, water), 50L); } } - private void addLiquidLevel(Block block, boolean water) { + private void addLiquidLevel(@Nonnull Block block, boolean water) { int level = ((Levelled) block.getBlockData()).getLevel(); if (level > 7) { @@ -142,11 +145,11 @@ public class Crucible extends SimpleSlimefunItem implements Rec } else { int finalLevel = 7 - level; - Slimefun.runSync(() -> runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, finalLevel), 50L); + SlimefunPlugin.runSync(() -> runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, finalLevel), 50L); } } - private void placeLiquid(Block block, boolean water) { + private void placeLiquid(@Nonnull Block block, boolean water) { if (block.getType() == Material.AIR || block.getType() == Material.CAVE_AIR || block.getType() == Material.VOID_AIR) { block.setType(water ? Material.WATER : Material.LAVA); } @@ -167,6 +170,7 @@ public class Crucible extends SimpleSlimefunItem implements Rec runPostTask(block, water ? Sound.ENTITY_PLAYER_SPLASH : Sound.BLOCK_LAVA_POP, 1); } + @ParametersAreNonnullByDefault private void runPostTask(Block block, Sound sound, int times) { if (!(block.getBlockData() instanceof Levelled)) { block.getWorld().playSound(block.getLocation(), Sound.BLOCK_METAL_BREAK, 1F, 1F); @@ -180,7 +184,7 @@ public class Crucible extends SimpleSlimefunItem implements Rec block.setBlockData(le, false); if (times < 8) { - Slimefun.runSync(() -> runPostTask(block, sound, times + 1), 50L); + SlimefunPlugin.runSync(() -> runPostTask(block, sound, times + 1), 50L); } else { block.getWorld().playSound(block.getLocation(), Sound.ENTITY_ARROW_HIT_PLAYER, 1F, 1F); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java index 667e2362f..ebd887788 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractCargoNode.java @@ -83,7 +83,7 @@ abstract class AbstractCargoNode extends SlimefunItem { menu.addMenuClickHandler(slotPrev, (p, slot, item, action) -> { int newChannel = channel - 1; - if (channel < 0) { + if (newChannel < 0) { if (isChestTerminalInstalled) { newChannel = 16; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java index 84e7c29fe..1f0499a61 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/generators/CoalGenerator.java @@ -10,6 +10,8 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +import javax.annotation.Nonnull; + public abstract class CoalGenerator extends AGenerator { public CoalGenerator(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { @@ -22,21 +24,62 @@ public abstract class CoalGenerator extends AGenerator { registerFuel(new MachineFuel(12, new ItemStack(Material.BLAZE_ROD))); registerFuel(new MachineFuel(20, new ItemStack(Material.DRIED_KELP_BLOCK))); + // Boats + for (Material mat : Tag.ITEMS_BOATS.getValues()) { + registerFuel(new MachineFuel(5, new ItemStack(mat))); + } + // Coal & Charcoal registerFuel(new MachineFuel(8, new ItemStack(Material.COAL))); registerFuel(new MachineFuel(8, new ItemStack(Material.CHARCOAL))); // Logs for (Material mat : Tag.LOGS.getValues()) { - registerFuel(new MachineFuel(2, new ItemStack(mat))); + registerFuel(new MachineFuel(4, new ItemStack(mat))); } // Wooden Planks for (Material mat : Tag.PLANKS.getValues()) { registerFuel(new MachineFuel(1, new ItemStack(mat))); } + + // Wooden Slabs + for (Material mat : Tag.WOODEN_SLABS.getValues()) { + registerFuel(new MachineFuel(1, new ItemStack(mat))); + } + + // Wooden Buttons + for (Material mat : Tag.WOODEN_BUTTONS.getValues()) { + registerFuel(new MachineFuel(1, new ItemStack(mat))); + } + + // Wooden Fences + for (Material mat : Tag.WOODEN_FENCES.getValues()) { + registerFuel(new MachineFuel(1, new ItemStack(mat))); + } + + // wooden Trapdoors + for (Material mat : Tag.WOODEN_TRAPDOORS.getValues()) { + registerFuel(new MachineFuel(3, new ItemStack(mat))); + } + + // Wooden Pressure Plates + for (Material mat : Tag.WOODEN_PRESSURE_PLATES.getValues()) { + registerFuel(new MachineFuel(2, new ItemStack(mat))); + } + + // Wooden Doors + for (Material mat : Tag.WOODEN_DOORS.getValues()) { + registerFuel(new MachineFuel(2, new ItemStack(mat))); + } + + // Signs + for (Material mat : Tag.SIGNS.getValues()) { + registerFuel(new MachineFuel(2, new ItemStack(mat))); + } } + @Nonnull @Override public ItemStack getProgressBar() { return new ItemStack(Material.FLINT_AND_STEEL); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java index d1de20267..0f4ff3ff0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AbstractEntityAssembler.java @@ -28,7 +28,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.UnregisterReason; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -206,7 +205,7 @@ public abstract class AbstractEntityAssembler extends SimpleSl removeCharge(b.getLocation(), getEnergyConsumption()); double offset = Double.parseDouble(BlockStorage.getLocationInfo(b.getLocation(), KEY_OFFSET)); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { Location loc = new Location(b.getWorld(), b.getX() + 0.5D, b.getY() + offset, b.getZ() + 0.5D); spawnEntity(loc); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDisenchanter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDisenchanter.java index 53c5e61b7..c7a145e0f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDisenchanter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoDisenchanter.java @@ -108,7 +108,7 @@ public class AutoDisenchanter extends AContainer { EmeraldEnchants.getInstance().getRegistry().applyEnchantment(disenchantedItem, ench.getEnchantment(), 0); } - MachineRecipe recipe = new MachineRecipe(90 * amount, new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book }); + MachineRecipe recipe = new MachineRecipe(90 * amount / this.getSpeed() , new ItemStack[] { target, item }, new ItemStack[] { disenchantedItem, book }); if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { return null; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoEnchanter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoEnchanter.java index 9b9a0fe97..95a3c8c68 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoEnchanter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/AutoEnchanter.java @@ -97,7 +97,7 @@ public class AutoEnchanter extends AContainer { EmeraldEnchants.getInstance().getRegistry().applyEnchantment(enchantedItem, ench.getEnchantment(), ench.getLevel()); } - MachineRecipe recipe = new MachineRecipe(75 * amount, new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) }); + MachineRecipe recipe = new MachineRecipe(75 * amount / this.getSpeed(), new ItemStack[] { target, item }, new ItemStack[] { enchantedItem, new ItemStack(Material.BOOK) }); if (!InvUtils.fitAll(menu.toInventory(), recipe.getOutput(), getOutputSlots())) { return null; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/NetherStarReactor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/NetherStarReactor.java index c8324f23f..227ecbde7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/NetherStarReactor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/NetherStarReactor.java @@ -13,11 +13,11 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.utils.holograms.ReactorHologram; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -43,7 +43,7 @@ public abstract class NetherStarReactor extends Reactor { @Override public void extraTick(@Nonnull Location l) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { ArmorStand hologram = ReactorHologram.getArmorStand(l, true); for (Entity entity : hologram.getNearbyEntities(5, 5, 5)) { if (entity instanceof LivingEntity && entity.isValid()) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java index 8a5ba74bb..e16f2d299 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/reactors/Reactor.java @@ -21,6 +21,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.api.events.AsyncReactorProcessCompleteEvent; import io.github.thebusybiscuit.slimefun4.api.events.ReactorExplodeEvent; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -37,7 +38,6 @@ import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -332,7 +332,7 @@ public abstract class Reactor extends AbstractEnergyProvider { boolean explosion = explosionsQueue.contains(l); if (explosion) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { ReactorExplodeEvent event = new ReactorExplodeEvent(l, Reactor.this); Bukkit.getPluginManager().callEvent(event); @@ -349,7 +349,7 @@ public abstract class Reactor extends AbstractEnergyProvider { } private void checkForWaterBlocks(Location l) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { // We will pick a surrounding block at random and see if this is water. // If it isn't, then we will make it explode. int index = ThreadLocalRandom.current().nextInt(WATER_BLOCKS.length); @@ -376,6 +376,8 @@ public abstract class Reactor extends AbstractEnergyProvider { } } + Bukkit.getPluginManager().callEvent(new AsyncReactorProcessCompleteEvent(l, Reactor.this, getProcessing(l))); + progress.remove(l); processing.remove(l); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java index 15d2d1c78..7f2592ed4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/Juice.java @@ -12,6 +12,7 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import io.github.thebusybiscuit.slimefun4.implementation.items.backpacks.Cooler; import io.github.thebusybiscuit.slimefun4.implementation.listeners.CoolerListener; @@ -19,7 +20,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -81,18 +81,18 @@ public class Juice extends SimpleSlimefunItem { private void removeGlassBottle(Player p, ItemStack item) { if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInMainHand(), true)) { if (p.getInventory().getItemInMainHand().getAmount() == 1) { - Slimefun.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0)); + SlimefunPlugin.runSync(() -> p.getEquipment().getItemInMainHand().setAmount(0)); } else { - Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); + SlimefunPlugin.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); } } else if (SlimefunUtils.isItemSimilar(item, p.getInventory().getItemInOffHand(), true)) { if (p.getInventory().getItemInOffHand().getAmount() == 1) { - Slimefun.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0)); + SlimefunPlugin.runSync(() -> p.getEquipment().getItemInOffHand().setAmount(0)); } else { - Slimefun.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); + SlimefunPlugin.runSync(() -> p.getInventory().removeItem(new ItemStack(Material.GLASS_BOTTLE, 1))); } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/MonsterJerky.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/MonsterJerky.java index 1766b481f..5f3b1c59d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/MonsterJerky.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/food/MonsterJerky.java @@ -5,10 +5,10 @@ import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemConsumptionHandler; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -27,7 +27,7 @@ public class MonsterJerky extends SimpleSlimefunItem { @Override public ItemConsumptionHandler getItemHandler() { - return (e, p, item) -> Slimefun.runSync(() -> { + return (e, p, item) -> SlimefunPlugin.runSync(() -> { if (p.hasPotionEffect(PotionEffectType.HUNGER)) { p.removePotionEffect(PotionEffectType.HUNGER); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java index e3eb557ca..275c94b4a 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/gps/ElevatorPlate.java @@ -34,7 +34,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.BlockStorage; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public class ElevatorPlate extends SimpleSlimefunItem { @@ -152,7 +151,7 @@ public class ElevatorPlate extends SimpleSlimefunItem { @ParametersAreNonnullByDefault private void teleport(Player player, String floorName, Block target) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { users.add(player.getUniqueId()); float yaw = player.getEyeLocation().getYaw() + 180; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java index d3ee4d37f..081636866 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/EnchantmentRune.java @@ -67,7 +67,7 @@ public class EnchantmentRune extends SimpleSlimefunItem { return (e, p, item) -> { if (isItem(item.getItemStack())) { if (Slimefun.hasUnlocked(p, this, true)) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { try { addRandomEnchantment(p, item); } @@ -124,7 +124,7 @@ public class EnchantmentRune extends SimpleSlimefunItem { // This lightning is just an effect, it deals no damage. l.getWorld().strikeLightningEffect(l); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { // Being sure entities are still valid and not picked up or whatsoever. if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java index 33f193ef0..775a970bd 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/magical/MagicalZombiePills.java @@ -11,7 +11,10 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; +import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; +import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler; +import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; @@ -31,10 +34,12 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; * @see EntityInteractHandler * */ -public class MagicalZombiePills extends SimpleSlimefunItem { +public class MagicalZombiePills extends SimpleSlimefunItem implements NotPlaceable { public MagicalZombiePills(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, ItemStack recipeOutput) { super(category, item, recipeType, recipe, recipeOutput); + + addItemHandler(onRightClick()); } @Override @@ -61,4 +66,12 @@ public class MagicalZombiePills extends SimpleSlimefunItem { return true; } - Slimefun.runSync(() -> activate(p, item), 20L); + SlimefunPlugin.runSync(() -> activate(p, item), 20L); return true; } @@ -76,7 +76,7 @@ public class SoulboundRune extends SimpleSlimefunItem { // This lightning is just an effect, it deals no damage. l.getWorld().strikeLightningEffect(l); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { // Being sure entities are still valid and not picked up or whatsoever. if (rune.isValid() && item.isValid() && itemStack.getAmount() == 1) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java index cd97b214f..189592597 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/ArmorForge.java @@ -84,7 +84,7 @@ public class ArmorForge extends MultiBlockMachine { for (int j = 0; j < 4; j++) { int current = j; - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { if (current < 3) { p.getWorld().playSound(p.getLocation(), Sound.BLOCK_ANVIL_USE, 1F, 2F); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/Compressor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/Compressor.java index 854e047e0..4d467b340 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/Compressor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/Compressor.java @@ -21,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public class Compressor extends MultiBlockMachine { @@ -83,7 +82,7 @@ public class Compressor extends MultiBlockMachine { for (int i = 0; i < 4; i++) { int j = i; - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { if (j < 3) { p.getWorld().playSound(p.getLocation(), j == 1 ? Sound.BLOCK_PISTON_CONTRACT : Sound.BLOCK_PISTON_EXTEND, 1F, j == 0 ? 1F : 2F); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java index 1b0de4047..5b6ed3bd8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/MagicWorkbench.java @@ -94,7 +94,7 @@ public class MagicWorkbench extends BackpackCrafter { private void startAnimation(Player p, Block b, Inventory inv, ItemStack output) { for (int j = 0; j < 4; j++) { int current = j; - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { p.getWorld().playEffect(b.getLocation(), Effect.MOBSPAWNER_FLAMES, 1); p.getWorld().playEffect(b.getLocation(), Effect.ENDER_SIGNAL, 1); 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 a1fd26c24..d0f93c00c 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 @@ -53,6 +53,36 @@ public class OreCrusher extends MultiBlockMachine { recipes.add(SlimefunItems.GOLD_4K); recipes.add(SlimefunItems.GOLD_DUST); + recipes.add(SlimefunItems.GOLD_6K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 2)); + + recipes.add(SlimefunItems.GOLD_8K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 2)); + + recipes.add(SlimefunItems.GOLD_10K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 3)); + + recipes.add(SlimefunItems.GOLD_12K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 3)); + + recipes.add(SlimefunItems.GOLD_14K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 4)); + + recipes.add(SlimefunItems.GOLD_16K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 4)); + + recipes.add(SlimefunItems.GOLD_18K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 5)); + + recipes.add(SlimefunItems.GOLD_20K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 5)); + + recipes.add(SlimefunItems.GOLD_22K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 6)); + + recipes.add(SlimefunItems.GOLD_24K); + recipes.add(new SlimefunItemStack(SlimefunItems.GOLD_DUST, 6)); + recipes.add(new ItemStack(Material.GRAVEL)); recipes.add(new ItemStack(Material.SAND)); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/PressureChamber.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/PressureChamber.java index b10c5fcbc..de4cedb38 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/PressureChamber.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/PressureChamber.java @@ -22,7 +22,6 @@ import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import io.papermc.lib.PaperLib; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public class PressureChamber extends MultiBlockMachine { @@ -75,7 +74,7 @@ public class PressureChamber extends MultiBlockMachine { for (int i = 0; i < 4; i++) { int j = i; - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { p.getWorld().playSound(b.getLocation(), Sound.ENTITY_TNT_PRIMED, 1, 1); p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4); p.getWorld().playEffect(b.getRelative(BlockFace.UP).getLocation(), Effect.SMOKE, 4); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java index 4ed3f3d72..06fc54f83 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/multiblocks/miner/ActiveMiner.java @@ -191,7 +191,7 @@ class ActiveMiner implements Runnable { ores++; // Repeat the same column when we hit an ore. - Slimefun.runSync(this, 4); + SlimefunPlugin.runSync(this, 4); return; } } @@ -232,7 +232,7 @@ class ActiveMiner implements Runnable { return; } - Slimefun.runSync(this, 5); + SlimefunPlugin.runSync(this, 5); } /** @@ -317,7 +317,7 @@ class ActiveMiner implements Runnable { } } } - + return 0; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java index 39df55419..9a6e23676 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/ClimbingPick.java @@ -36,7 +36,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.SimpleSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -151,7 +150,7 @@ public class ClimbingPick extends SimpleSlimefunItem implements power += efficiencyLevel * 0.1; } - Slimefun.runSync(() -> users.remove(p.getUniqueId()), 4L); + SlimefunPlugin.runSync(() -> users.remove(p.getUniqueId()), 4L); Vector velocity = new Vector(0, power * BASE_POWER, 0); ClimbingPickLaunchEvent event = new ClimbingPickLaunchEvent(p, velocity, this, item, block); Bukkit.getPluginManager().callEvent(event); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java index 2e7c09c60..0c7101673 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GoldPan.java @@ -15,6 +15,7 @@ import io.github.thebusybiscuit.cscorelib2.collections.RandomizedSet; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; +import io.github.thebusybiscuit.slimefun4.core.handlers.EntityInteractHandler; import io.github.thebusybiscuit.slimefun4.core.handlers.ItemUseHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -47,6 +48,7 @@ public class GoldPan extends SimpleSlimefunItem implements Recip drops.addAll(getGoldPanDrops()); addItemSetting(drops.toArray(new GoldPanDrop[0])); + addItemHandler(onEntityInteract()); } protected Material getInput() { @@ -115,6 +117,16 @@ public class GoldPan extends SimpleSlimefunItem implements Recip }; } + /** + * This method cancels {@link EntityInteractHandler} to prevent interacting {@link GoldPan} + * with entities. + * + * @return the {@link EntityInteractHandler} of this {@link SlimefunItem} + */ + public EntityInteractHandler onEntityInteract() { + return (e, item, offHand) -> e.setCancelled(true); + } + @Override public List getDisplayRecipes() { List recipes = new LinkedList<>(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GrapplingHook.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GrapplingHook.java index 8d0c68682..0a9b9cb8f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GrapplingHook.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/GrapplingHook.java @@ -22,12 +22,14 @@ import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; public class GrapplingHook extends SimpleSlimefunItem { + private final ItemSetting consumeOnUse = new ItemSetting<>("consume-on-use", true); private final ItemSetting despawnTicks = new ItemSetting<>("despawn-seconds", 60); public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); addItemSetting(despawnTicks); + addItemSetting(consumeOnUse); } @Override @@ -35,6 +37,7 @@ public class GrapplingHook extends SimpleSlimefunItem { return e -> { Player p = e.getPlayer(); UUID uuid = p.getUniqueId(); + boolean consumeOnUseValue = consumeOnUse.getValue(); if (!e.getClickedBlock().isPresent() && !SlimefunPlugin.getGrapplingHookListener().isGrappling(uuid)) { e.cancel(); @@ -47,7 +50,10 @@ public class GrapplingHook extends SimpleSlimefunItem { ItemStack item = e.getItem(); if (item.getType() == Material.LEAD) { - item.setAmount(item.getAmount() - 1); + //If consume on use is enabled, the if statement below will take 1 grappling hook out of player's hand + if (consumeOnUseValue) { + item.setAmount(item.getAmount() - 1); + } } Vector direction = p.getEyeLocation().getDirection().multiply(2.0); @@ -63,7 +69,7 @@ public class GrapplingHook extends SimpleSlimefunItem { bat.setLeashHolder(arrow); boolean state = item.getType() != Material.SHEARS; - SlimefunPlugin.getGrapplingHookListener().addGrapplingHook(p, arrow, bat, state, despawnTicks.getValue()); + SlimefunPlugin.getGrapplingHookListener().addGrapplingHook(p, arrow, bat, state, despawnTicks.getValue(), consumeOnUseValue); } }; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PortableCrafter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PortableCrafter.java index 4a9d02af4..e7ce34b01 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PortableCrafter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/PortableCrafter.java @@ -1,7 +1,10 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.tools; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.Sound; import org.bukkit.entity.Player; +import org.bukkit.inventory.CraftingInventory; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.core.attributes.NotPlaceable; @@ -11,8 +14,16 @@ import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; +/** + * The {@link PortableCrafter} is one of the oldest items in Slimefun. + * It allows a {@link Player} to open up the {@link CraftingInventory} via right click. + * + * @author TheBusyBiscuit + * + */ public class PortableCrafter extends SimpleSlimefunItem implements NotPlaceable { + @ParametersAreNonnullByDefault public PortableCrafter(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java index 919ddd8c1..c9fb3cd54 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/tools/TapeMeasure.java @@ -4,6 +4,9 @@ import java.text.DecimalFormat; import java.util.Optional; import java.util.UUID; +import javax.annotation.Nonnull; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.Location; import org.bukkit.NamespacedKey; import org.bukkit.block.Block; @@ -34,6 +37,7 @@ public class TapeMeasure extends SimpleSlimefunItem implements N private final NamespacedKey key = new NamespacedKey(SlimefunPlugin.instance(), "anchor"); private final DecimalFormat format = new DecimalFormat("##.###"); + @ParametersAreNonnullByDefault public TapeMeasure(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(category, item, recipeType, recipe); } @@ -56,6 +60,7 @@ public class TapeMeasure extends SimpleSlimefunItem implements N }; } + @ParametersAreNonnullByDefault private void setAnchor(Player p, ItemStack item, Block block) { ItemMeta meta = item.getItemMeta(); @@ -74,6 +79,8 @@ public class TapeMeasure extends SimpleSlimefunItem implements N } + @Nonnull + @ParametersAreNonnullByDefault private Optional getAnchor(Player p, ItemStack item) { ItemMeta meta = item.getItemMeta(); @@ -102,6 +109,7 @@ public class TapeMeasure extends SimpleSlimefunItem implements N } } + @ParametersAreNonnullByDefault private void measure(Player p, ItemStack item, Block block) { Optional anchor = getAnchor(p, item); 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 414559673..2c550defe 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 @@ -155,7 +155,7 @@ public class AncientAltarListener implements Listener { UUID uuid = entity.getUniqueId(); removedItems.add(uuid); - Slimefun.runSync(() -> removedItems.remove(uuid), 30L); + SlimefunPlugin.runSync(() -> removedItems.remove(uuid), 30L); entity.remove(); p.getInventory().addItem(pedestalItem.getOriginalItemStack(entity)); @@ -228,7 +228,7 @@ public class AncientAltarListener implements Listener { b.getWorld().playSound(b.getLocation(), Sound.ENTITY_ILLUSIONER_PREPARE_MIRROR, 1, 1); AncientAltarTask task = new AncientAltarTask(this, b, altarItem.getSpeed(), result.get(), pedestals, consumed, p); - Slimefun.runSync(task, 10L); + SlimefunPlugin.runSync(task, 10L); } else { altars.remove(b); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java index a1874ad55..29f421ed6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockPhysicsListener.java @@ -32,6 +32,7 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage; * @author VoidAngel * @author Poslovitch * @author TheBusyBiscuit + * @author AccelShark * */ public class BlockPhysicsListener implements Listener { @@ -54,21 +55,29 @@ public class BlockPhysicsListener implements Listener { @EventHandler public void onPistonExtend(BlockPistonExtendEvent e) { - for (Block b : e.getBlocks()) { - if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) { - e.setCancelled(true); - return; + if (BlockStorage.hasBlockInfo(e.getBlock())) { + e.setCancelled(true); + } + else { + for (Block b : e.getBlocks()) { + if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) { + e.setCancelled(true); + break; + } } } } @EventHandler public void onPistonRetract(BlockPistonRetractEvent e) { - if (e.isSticky()) { + if (BlockStorage.hasBlockInfo(e.getBlock())) { + e.setCancelled(true); + } + else if (e.isSticky()) { for (Block b : e.getBlocks()) { if (BlockStorage.hasBlockInfo(b) || (b.getRelative(e.getDirection()).getType() == Material.AIR && BlockStorage.hasBlockInfo(b.getRelative(e.getDirection())))) { e.setCancelled(true); - return; + break; } } } 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 f2de2473b..d2db858fc 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 @@ -23,7 +23,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; 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.api.Slimefun; /** * This {@link Listener} handles the collection of drops from an {@link Entity} that was @@ -45,7 +44,7 @@ public class ButcherAndroidListener implements Listener { if (e.getEntity().hasMetadata(METADATA_KEY)) { AndroidInstance obj = (AndroidInstance) e.getEntity().getMetadata(METADATA_KEY).get(0).value(); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { List items = new ArrayList<>(); // Collect any nearby dropped items diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CoolerListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CoolerListener.java index fa4becf8a..7794dd071 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CoolerListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CoolerListener.java @@ -23,8 +23,10 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.food.Juice; import me.mrCookieSlime.Slimefun.api.Slimefun; /** - * This {@link Listener} listens for a {@link FoodLevelChangeEvent} or an {@link EntityDamageEvent} for starvation damage - * and consumes a {@link Juice} from any {@link Cooler} that can be found in the {@link Inventory} of the given {@link Player}. + * This {@link Listener} listens for a {@link FoodLevelChangeEvent} or an {@link EntityDamageEvent} for starvation + * damage + * and consumes a {@link Juice} from any {@link Cooler} that can be found in the {@link Inventory} of the given + * {@link Player}. * * @author TheBusyBiscuit * @author Linox @@ -55,18 +57,18 @@ public class CoolerListener implements Listener { checkAndConsume(p); } } - + @EventHandler public void onHungerDamage(EntityDamageEvent e) { if (cooler == null || cooler.isDisabled() || !(e.getEntity() instanceof Player)) { return; } - + if (e.getCause() == DamageCause.STARVATION) { checkAndConsume((Player) e.getEntity()); } } - + private void checkAndConsume(@Nonnull Player p) { for (ItemStack item : p.getInventory().getContents()) { if (cooler.isItem(item)) { @@ -92,7 +94,7 @@ public class CoolerListener implements Listener { private void takeJuiceFromCooler(@Nonnull Player p, @Nonnull ItemStack cooler) { PlayerProfile.getBackpack(cooler, backpack -> { if (backpack != null) { - Slimefun.runSync(() -> consumeJuice(p, backpack)); + SlimefunPlugin.runSync(() -> consumeJuice(p, backpack)); } }); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java index ee99817e5..57cfa4c9b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookEntity.java @@ -15,13 +15,14 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; final class GrapplingHookEntity { private final boolean dropItem; - + private final boolean wasConsumed; private final Arrow arrow; private final Entity leashTarget; @ParametersAreNonnullByDefault - GrapplingHookEntity(Player p, Arrow arrow, Entity leashTarget, boolean dropItem) { + GrapplingHookEntity(Player p, Arrow arrow, Entity leashTarget, boolean dropItem, boolean wasConsumed) { this.arrow = arrow; + this.wasConsumed = wasConsumed; this.leashTarget = leashTarget; this.dropItem = p.getGameMode() != GameMode.CREATIVE && dropItem; } @@ -33,8 +34,11 @@ final class GrapplingHookEntity { public void drop(@Nonnull Location l) { if (dropItem) { - Item item = l.getWorld().dropItem(l, SlimefunItems.GRAPPLING_HOOK.clone()); - item.setPickupDelay(16); + //If a grappling hook was consumed, then the below if statement will be executed and will drop one grappling hook on the floor + if (wasConsumed) { + Item item = l.getWorld().dropItem(l, SlimefunItems.GRAPPLING_HOOK.clone()); + item.setPickupDelay(16); + } } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookListener.java index f44f8c98f..98b3d4668 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GrapplingHookListener.java @@ -10,6 +10,7 @@ import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import org.bukkit.Location; import org.bukkit.entity.Arrow; import org.bukkit.entity.Bat; @@ -24,11 +25,12 @@ import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.hanging.HangingBreakByEntityEvent; import org.bukkit.event.player.PlayerKickEvent; import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.entity.PlayerLeashEntityEvent; +import org.bukkit.inventory.ItemStack; import org.bukkit.util.Vector; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.tools.GrapplingHook; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This {@link Listener} is responsible for the mechanics behind the {@link GrapplingHook}. @@ -74,7 +76,7 @@ public class GrapplingHookListener implements Listener { return; } - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { if (e.getEntity() instanceof Arrow) { handleGrapplingHook((Arrow) e.getEntity()); } @@ -137,6 +139,23 @@ public class GrapplingHookListener implements Listener { } } + // Fixing Issue #2351 + @EventHandler + public void onLeash(PlayerLeashEntityEvent e) { + if (!isEnabled()) { + return; + } + + Player p = e.getPlayer(); + + ItemStack item = p.getInventory().getItemInMainHand(); + SlimefunItem slimeItem = SlimefunItem.getByItem(item); + + if (slimeItem instanceof GrapplingHook) { + e.setCancelled(true); + } + } + private void handleGrapplingHook(@Nullable Arrow arrow) { if (arrow != null && arrow.isValid() && arrow.getShooter() instanceof Player) { Player p = (Player) arrow.getShooter(); @@ -174,7 +193,7 @@ public class GrapplingHookListener implements Listener { p.setVelocity(velocity); hook.remove(); - Slimefun.runSync(() -> activeHooks.remove(p.getUniqueId()), 20L); + SlimefunPlugin.runSync(() -> activeHooks.remove(p.getUniqueId()), 20L); } } } @@ -184,21 +203,21 @@ public class GrapplingHookListener implements Listener { } @ParametersAreNonnullByDefault - public void addGrapplingHook(Player p, Arrow arrow, Bat bat, boolean dropItem, long despawnTicks) { - GrapplingHookEntity hook = new GrapplingHookEntity(p, arrow, bat, dropItem); + public void addGrapplingHook(Player p, Arrow arrow, Bat bat, boolean dropItem, long despawnTicks, boolean wasConsumed) { + GrapplingHookEntity hook = new GrapplingHookEntity(p, arrow, bat, dropItem, wasConsumed); UUID uuid = p.getUniqueId(); activeHooks.put(uuid, hook); // To fix issue #253 - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { GrapplingHookEntity entity = activeHooks.get(uuid); if (entity != null) { SlimefunPlugin.getBowListener().getProjectileData().remove(uuid); entity.remove(); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { activeHooks.remove(uuid); invulnerability.remove(uuid); }, 20L); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java index 7d6c8e9ef..351263132 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunBowListener.java @@ -21,7 +21,6 @@ import io.github.thebusybiscuit.slimefun4.core.handlers.BowShootHandler; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.weapons.SlimefunBow; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * This {@link Listener} is responsible for tracking {@link Arrow Arrows} fired from a @@ -64,7 +63,7 @@ public class SlimefunBowListener implements Listener { @EventHandler public void onArrowHit(ProjectileHitEvent e) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { if (e.getEntity().isValid() && e.getEntity() instanceof Arrow) { projectiles.remove(e.getEntity().getUniqueId()); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java index 9e15f33f9..e463df537 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/SlimefunGuideListener.java @@ -3,6 +3,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; import javax.annotation.Nonnull; import javax.annotation.ParametersAreNonnullByDefault; +import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.Event.Result; import org.bukkit.event.EventHandler; @@ -11,6 +12,7 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemStack; +import io.github.thebusybiscuit.slimefun4.api.events.SlimefunGuideOpenEvent; import io.github.thebusybiscuit.slimefun4.api.events.PlayerRightClickEvent; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuide; import io.github.thebusybiscuit.slimefun4.core.guide.SlimefunGuideLayout; @@ -45,23 +47,23 @@ public class SlimefunGuideListener implements Listener { public void onInteract(PlayerRightClickEvent e) { Player p = e.getPlayer(); - if (openGuide(e, SlimefunGuideLayout.BOOK) == Result.ALLOW) { + if (tryOpenGuide(p, e, SlimefunGuideLayout.BOOK) == Result.ALLOW) { if (p.isSneaking()) { SlimefunGuideSettings.openSettings(p, e.getItem()); } else { - SlimefunGuide.openGuide(p, SlimefunGuideLayout.BOOK); + openGuide(p, e, SlimefunGuideLayout.BOOK); } } - else if (openGuide(e, SlimefunGuideLayout.CHEST) == Result.ALLOW) { + else if (tryOpenGuide(p, e, SlimefunGuideLayout.CHEST) == Result.ALLOW) { if (p.isSneaking()) { SlimefunGuideSettings.openSettings(p, e.getItem()); } else { - SlimefunGuide.openGuide(p, SlimefunGuideLayout.CHEST); + openGuide(p, e, SlimefunGuideLayout.CHEST); } } - else if (openGuide(e, SlimefunGuideLayout.CHEAT_SHEET) == Result.ALLOW) { + else if (tryOpenGuide(p, e, SlimefunGuideLayout.CHEAT_SHEET) == Result.ALLOW) { if (p.isSneaking()) { SlimefunGuideSettings.openSettings(p, e.getItem()); } @@ -72,16 +74,24 @@ public class SlimefunGuideListener implements Listener { } } } + + @ParametersAreNonnullByDefault + private void openGuide(Player p, PlayerRightClickEvent e, SlimefunGuideLayout layout) { + SlimefunGuideOpenEvent event = new SlimefunGuideOpenEvent(p, e.getItem(), layout); + Bukkit.getPluginManager().callEvent(event); + + if (!event.isCancelled()) { + e.cancel(); + SlimefunGuide.openGuide(p, event.getGuideLayout()); + } + } @Nonnull @ParametersAreNonnullByDefault - private Result openGuide(PlayerRightClickEvent e, SlimefunGuideLayout layout) { - Player p = e.getPlayer(); + private Result tryOpenGuide(Player p, PlayerRightClickEvent e, SlimefunGuideLayout layout) { ItemStack item = e.getItem(); - if (SlimefunUtils.isItemSimilar(item, SlimefunGuide.getItem(layout), true, false)) { - e.cancel(); - + if (!SlimefunPlugin.getWorldSettingsService().isWorldEnabled(p.getWorld())) { SlimefunPlugin.getLocalization().sendMessage(p, "messages.disabled-item", true); return Result.DENY; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java index df17d39e0..abcfcca3d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/TalismanListener.java @@ -24,6 +24,7 @@ import org.bukkit.entity.Trident; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockDropItemEvent; import org.bukkit.event.enchantment.EnchantItemEvent; import org.bukkit.event.entity.EntityDamageByEntityEvent; @@ -45,7 +46,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.MagicianTalisman; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.Talisman; import io.github.thebusybiscuit.slimefun4.implementation.items.magical.talismans.TalismanEnchantment; -import me.mrCookieSlime.Slimefun.api.Slimefun; public class TalismanListener implements Listener { @@ -216,7 +216,7 @@ public class TalismanListener implements Listener { int itemSlot = slot; // Update the item forcefully - Slimefun.runSync(() -> inv.setItem(itemSlot, item), 1L); + SlimefunPlugin.runSync(() -> inv.setItem(itemSlot, item), 1L); } } @@ -285,6 +285,13 @@ public class TalismanListener implements Listener { } } + @EventHandler + public void onBlockBreak(BlockBreakEvent e) { + if (e.getBlock().getType().name().endsWith("_ORE")) { + Talisman.checkFor(e, SlimefunItems.TALISMAN_CAVEMAN); + } + } + private int getAmountWithFortune(@Nonnull Material type, int fortuneLevel) { if (fortuneLevel > 0) { Random random = ThreadLocalRandom.current(); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java index e9013fa04..b517efb0b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/VanillaMachinesListener.java @@ -41,8 +41,7 @@ public class VanillaMachinesListener implements Listener { @EventHandler(ignoreCancelled = true) public void onGrindstone(InventoryClickEvent e) { // The Grindstone was only ever added in MC 1.14 - MinecraftVersion minecraftVersion = SlimefunPlugin.getMinecraftVersion(); - if (!minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { return; } @@ -97,6 +96,24 @@ public class VanillaMachinesListener implements Listener { } } + @EventHandler(ignoreCancelled = true) + public void onCartographyTable(InventoryClickEvent e) { + // The Cartography Table was only ever added in MC 1.14 + if (!SlimefunPlugin.getMinecraftVersion().isAtLeast(MinecraftVersion.MINECRAFT_1_14)) { + return; + } + + if (e.getRawSlot() == 2 && e.getInventory().getType() == InventoryType.CARTOGRAPHY && e.getWhoClicked() instanceof Player) { + ItemStack item1 = e.getInventory().getContents()[0]; + ItemStack item2 = e.getInventory().getContents()[1]; + + if (checkForUnallowedItems(item1, item2)) { + e.setResult(Result.DENY); + SlimefunPlugin.getLocalization().sendMessage((Player) e.getWhoClicked(), "cartography_table.not-working", true); + } + } + } + @EventHandler(ignoreCancelled = true) public void onPreBrew(InventoryClickEvent e) { Inventory clickedInventory = e.getClickedInventory(); 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 b184181f1..4d6ebd3c5 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 @@ -104,7 +104,7 @@ public final class PostSetup { sender.sendMessage(ChatColor.GREEN + " - Wiki: https://github.com/Slimefun/Slimefun4/wiki"); sender.sendMessage(ChatColor.GREEN + " - Addons: https://github.com/Slimefun/Slimefun4/wiki/Addons"); sender.sendMessage(ChatColor.GREEN + " - Bug Reports: https://github.com/Slimefun/Slimefun4/issues"); - sender.sendMessage(ChatColor.GREEN + " - Discord: https://discord.gg/fsD4Bkh"); + sender.sendMessage(ChatColor.GREEN + " - Discord: https://discord.gg/slimefun"); } else { sender.sendMessage(ChatColor.GREEN + " - UNOFFICIALLY MODIFIED BUILD - NO OFFICIAL SUPPORT GIVEN"); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java index 5f0c583f6..bf4824ed5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/ResearchSetup.java @@ -275,7 +275,8 @@ public final class ResearchSetup { register("villager_rune", 264, "Reset Villager Trades", 26, SlimefunItems.VILLAGER_RUNE, SlimefunItems.STRANGE_NETHER_GOO); register("climbing_pick", 265, "Block Raider", 20, SlimefunItems.CLIMBING_PICK); register("even_higher_tier_capacitors", 266, "Tier 3 Capacitors", 40, SlimefunItems.ENERGIZED_CAPACITOR); - register("bee_armor", 267, "Bee Armor", 24, SlimefunItems.BEE_HELMET, SlimefunItems.BEE_WINGS, SlimefunItems.BEE_LEGGINGS, SlimefunItems.BEE_BOOTS); + register("caveman_talisman", 267, "Talisman of the Caveman", 20, SlimefunItems.TALISMAN_CAVEMAN); + register("bee_armor", 268, "Bee Armor", 24, SlimefunItems.BEE_HELMET, SlimefunItems.BEE_WINGS, SlimefunItems.BEE_LEGGINGS, SlimefunItems.BEE_BOOTS); } private static void register(String key, int id, String name, int defaultCost, ItemStack... items) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java index 5f8694041..eb27599ac 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunItemSetup.java @@ -872,6 +872,11 @@ public final class SlimefunItemSetup { "knight", 30, new PotionEffect(PotionEffectType.REGENERATION, 100, 3)) .register(plugin); + new Talisman(SlimefunItems.TALISMAN_CAVEMAN, + new ItemStack[] { SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, new ItemStack(Material.GOLDEN_PICKAXE), SlimefunItems.TALISMAN_MINER, SlimefunItems.EARTH_RUNE, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}, + false, false, "caveman", 50, new PotionEffect(PotionEffectType.FAST_DIGGING, 800, 2)) + .register(plugin); + new SlimefunItem(categories.resources, SlimefunItems.GILDED_IRON, RecipeType.SMELTERY, new ItemStack[] {SlimefunItems.GOLD_24K, SlimefunItems.IRON_DUST, null, null, null, null, null, null, null}) .register(plugin); @@ -1120,7 +1125,7 @@ public final class SlimefunItemSetup { new ItemStack[] {SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, SlimefunItems.COBALT_INGOT, null, SlimefunItems.NICKEL_INGOT, null, null, SlimefunItems.NICKEL_INGOT, null}) .register(plugin); - new SlimefunItem(categories.magicalResources, SlimefunItems.NECROTIC_SKULL, RecipeType.MAGIC_WORKBENCH, + new UnplaceableBlock(categories.magicalResources, SlimefunItems.NECROTIC_SKULL, RecipeType.MAGIC_WORKBENCH, new ItemStack[] {SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3, null, new ItemStack(Material.WITHER_SKELETON_SKULL), null, SlimefunItems.MAGIC_LUMP_3, null, SlimefunItems.MAGIC_LUMP_3}) .register(plugin); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java index b3615365c..a6fd8bdeb 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java @@ -27,7 +27,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientAltar; import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import io.github.thebusybiscuit.slimefun4.implementation.listeners.AncientAltarListener; -import me.mrCookieSlime.Slimefun.api.Slimefun; /** * The {@link AncientAltarTask} is responsible for the animation that happens when a ritual @@ -103,7 +102,7 @@ public class AncientAltarTask implements Runnable { } this.stage += 1; - Slimefun.runSync(this, speed); + SlimefunPlugin.runSync(this, speed); } private boolean checkLockedItems() { 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 1ece100a1..8b92ac872 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 @@ -112,7 +112,7 @@ public class ArmorTask implements Runnable { } if (item != null && armorpiece.getItem().isPresent()) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { SlimefunArmorPiece slimefunArmor = armorpiece.getItem().get(); if (Slimefun.hasUnlocked(p, slimefunArmor, true)) { @@ -172,7 +172,7 @@ public class ArmorTask implements Runnable { // If the item is enabled in the world, then make radioactivity do its job SlimefunPlugin.getLocalization().sendMessage(p, "messages.radiation"); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { p.addPotionEffects(radiationEffects); // if radiative fire is enabled 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 2fc7f82db..ba3856383 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 @@ -38,6 +38,9 @@ import me.mrCookieSlime.Slimefun.api.Slimefun; */ public class TickerTask implements Runnable { + // This Map holds all currently actively ticking locations + private final Map> activeTickers = new ConcurrentHashMap<>(); + // These are "Queues" of blocks that need to be removed or moved private final Map movingQueue = new ConcurrentHashMap<>(); private final Map deletionQueue = new ConcurrentHashMap<>(); @@ -90,8 +93,8 @@ public class TickerTask implements Runnable { } if (!halted) { - for (String chunk : BlockStorage.getTickingChunks()) { - tickChunk(tickers, chunk); + for (Map.Entry> entry : activeTickers.entrySet()) { + tickChunk(tickers, entry.getKey(), entry.getValue()); } } @@ -116,9 +119,9 @@ public class TickerTask implements Runnable { } } - private void tickChunk(@Nonnull Set tickers, @Nonnull String chunk) { + @ParametersAreNonnullByDefault + private void tickChunk(Set tickers, String chunk, Set locations) { try { - Set locations = BlockStorage.getTickingLocations(chunk); String[] components = PatternUtils.SEMICOLON.split(chunk); World world = Bukkit.getWorld(components[0]); @@ -147,7 +150,7 @@ public class TickerTask implements Runnable { item.getBlockTicker().update(); // We are inserting a new timestamp because synchronized // actions are always ran with a 50ms delay (1 game tick) - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { Block b = l.getBlock(); tickBlock(l, b, item, data, System.nanoTime()); }); @@ -223,13 +226,24 @@ public class TickerTask implements Runnable { deletionQueue.put(l, destroy); } + /** + * This returns the delay between ticks + * + * @return The tick delay + */ public int getTickRate() { return tickRate; } - @Override - public String toString() { - return "TickerTask {\n" + " HALTED = " + halted + "\n" + " move = " + movingQueue + "\n" + " delete = " + deletionQueue + "}"; + /** + * This method returns the {@link Map} of actively ticking locations according to + * their chunk id. + * + * @return The {@link Map} of active tickers + */ + @Nonnull + public Map> getActiveTickers() { + return activeTickers; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java index 82ff6cfee..f37c7db44 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java @@ -26,6 +26,9 @@ public final class ChestMenuUtils { private ChestMenuUtils() {} private static final ItemStack UI_BACKGROUND = new SlimefunItemStack("_UI_BACKGROUND", Material.GRAY_STAINED_GLASS_PANE, " "); + private static final ItemStack INPUT_SLOT = new SlimefunItemStack("_UI_INPUT_SLOT", Material.CYAN_STAINED_GLASS_PANE, " "); + private static final ItemStack OUTPUT_SLOT = new SlimefunItemStack("_UI_OUTPUT_SLOT", Material.ORANGE_STAINED_GLASS_PANE, " "); + private static final ItemStack BACK_BUTTON = new SlimefunItemStack("_UI_BACK", Material.ENCHANTED_BOOK, "&7\u21E6 Back", meta -> meta.addItemFlags(ItemFlag.HIDE_ENCHANTS)); private static final ItemStack MENU_BUTTON = new SlimefunItemStack("_UI_MENU", Material.COMPARATOR, "&eSettings / Info", "", "&7\u21E8 Click to see more"); private static final ItemStack SEARCH_BUTTON = new SlimefunItemStack("_UI_SEARCH", Material.NAME_TAG, "&bSearch"); @@ -43,6 +46,16 @@ public final class ChestMenuUtils { return UI_BACKGROUND; } + @Nonnull + public static ItemStack getInputSlotTexture() { + return INPUT_SLOT; + } + + @Nonnull + public static ItemStack getOutputSlotTexture() { + return OUTPUT_SLOT; + } + @Nonnull public static MenuClickHandler getEmptyClickHandler() { return CLICK_HANDLER; 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 98e5d28fa..d8ed4e0db 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -36,7 +36,6 @@ import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import me.mrCookieSlime.EmeraldEnchants.EmeraldEnchants; import me.mrCookieSlime.EmeraldEnchants.ItemEnchantment; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; /** @@ -351,7 +350,7 @@ public final class SlimefunUtils { Validate.notNull(l, "Cannot update a texture for null"); Validate.isTrue(capacity > 0, "Capacity must be greater than zero!"); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { Block b = l.getBlock(); if (b.getType() == Material.PLAYER_HEAD || b.getType() == Material.PLAYER_WALL_HEAD) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/ReactorHologram.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/ReactorHologram.java index 0060a0454..a0d56e4bf 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/ReactorHologram.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/ReactorHologram.java @@ -8,7 +8,7 @@ import org.bukkit.entity.ArmorStand; import org.bukkit.entity.Entity; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import me.mrCookieSlime.Slimefun.api.Slimefun; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; public final class ReactorHologram { @@ -35,7 +35,7 @@ public final class ReactorHologram { } public static void update(@Nonnull Location l, @Nonnull String name) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { ArmorStand hologram = getArmorStand(l, true); if (!hologram.isCustomNameVisible()) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/SimpleHologram.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/SimpleHologram.java index fc24ea0a8..05419dbf4 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/SimpleHologram.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/holograms/SimpleHologram.java @@ -10,7 +10,7 @@ import org.bukkit.entity.Entity; import org.bukkit.entity.EntityType; import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import me.mrCookieSlime.Slimefun.api.Slimefun; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; /** * This utility class provides a few static methods for modifying a simple Text-based Hologram. @@ -23,14 +23,14 @@ public final class SimpleHologram { private SimpleHologram() {} public static void update(@Nonnull Block b, @Nonnull String name) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { ArmorStand hologram = getArmorStand(b, true); hologram.setCustomName(ChatColors.color(name)); }); } public static void remove(@Nonnull Block b) { - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { ArmorStand hologram = getArmorStand(b, false); if (hologram != null) { diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java index 4dce26884..d663fa2f3 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AContainer.java @@ -5,7 +5,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.block.Block; @@ -16,6 +15,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.inventory.InvUtils; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; +import io.github.thebusybiscuit.slimefun4.api.events.AsyncMachineProcessCompleteEvent; import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent; import io.github.thebusybiscuit.slimefun4.core.networks.energy.EnergyNetComponentType; import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; @@ -77,11 +77,11 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock, } for (int i : BORDER_IN) { - preset.addItem(i, new CustomItem(Material.CYAN_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, ChestMenuUtils.getInputSlotTexture(), ChestMenuUtils.getEmptyClickHandler()); } for (int i : BORDER_OUT) { - preset.addItem(i, new CustomItem(Material.ORANGE_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler()); } preset.addItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); @@ -253,7 +253,7 @@ public abstract class AContainer extends SlimefunItem implements InventoryBlock, inv.pushItem(output.clone(), getOutputSlots()); } - Bukkit.getPluginManager().callEvent(new AsyncMachineProcessCompleteEvent(b, getProcessing(b))); + Bukkit.getPluginManager().callEvent(new AsyncMachineProcessCompleteEvent(b.getLocation(), AContainer.this, getProcessing(b))); progress.remove(b); processing.remove(b); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java index 41a20f16a..1bb305799 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AGenerator.java @@ -3,6 +3,7 @@ package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems; import java.util.HashMap; import java.util.Map; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; @@ -12,6 +13,7 @@ import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction; +import io.github.thebusybiscuit.slimefun4.api.events.AsyncGeneratorProcessCompleteEvent; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunItems; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.implementation.items.electric.AbstractEnergyProvider; @@ -86,11 +88,11 @@ public abstract class AGenerator extends AbstractEnergyProvider { } for (int i : border_in) { - preset.addItem(i, new CustomItem(new ItemStack(Material.CYAN_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, ChestMenuUtils.getInputSlotTexture(), ChestMenuUtils.getEmptyClickHandler()); } for (int i : border_out) { - preset.addItem(i, new CustomItem(new ItemStack(Material.ORANGE_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, ChestMenuUtils.getOutputSlotTexture(), ChestMenuUtils.getEmptyClickHandler()); } for (int i : getOutputSlots()) { @@ -163,6 +165,8 @@ public abstract class AGenerator extends AbstractEnergyProvider { inv.replaceExistingItem(22, new CustomItem(Material.BLACK_STAINED_GLASS_PANE, " ")); + Bukkit.getPluginManager().callEvent(new AsyncGeneratorProcessCompleteEvent(l, AGenerator.this, getProcessing(l))); + progress.remove(l); processing.remove(l); return 0; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java index b261a0b37..4f0ec5e90 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java @@ -15,6 +15,10 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Level; import java.util.logging.Logger; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; + import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -56,11 +60,11 @@ public class BlockStorage { private static int chunkChanges = 0; private int changes = 0; - public static BlockStorage getStorage(World world) { + public static BlockStorage getStorage(@Nonnull World world) { return SlimefunPlugin.getRegistry().getWorlds().get(world.getName()); } - public static BlockStorage getForcedStorage(World world) { + public static BlockStorage getForcedStorage(@Nonnull World world) { return isWorldRegistered(world.getName()) ? SlimefunPlugin.getRegistry().getWorlds().get(world.getName()) : new BlockStorage(world); } @@ -196,13 +200,9 @@ public class BlockStorage { storage.put(l, blockInfo); if (SlimefunPlugin.getRegistry().getTickerBlocks().contains(file.getName().replace(".sfb", ""))) { - Set locations = SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunkString, new HashSet<>()); + Map> tickers = SlimefunPlugin.getTickerTask().getActiveTickers(); + Set locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>()); locations.add(l); - SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations); - - if (!SlimefunPlugin.getRegistry().getActiveChunks().contains(chunkString)) { - SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString); - } } } } @@ -377,22 +377,22 @@ public class BlockStorage { /** * Retrieves the SlimefunItem's ItemStack from the specified Block. - * If the specified Block is registered in BlockStorage, its data will be erased from it, regardless of the returned - * value. + * If the specified Block is registered in BlockStorage, + * its data will be erased from it, regardless of the returned value. * * @param block * the block to retrieve the ItemStack from * * @return the SlimefunItem's ItemStack corresponding to the block if it has one, otherwise null - * - * @since 4.0 */ + @Nullable public static ItemStack retrieve(Block block) { if (!hasBlockInfo(block)) { return null; } else { - SlimefunItem item = SlimefunItem.getByID(getLocationInfo(block.getLocation(), "id")); + String id = getLocationInfo(block.getLocation(), "id"); + SlimefunItem item = SlimefunItem.getByID(id); clearBlockInfo(block); if (item == null) { @@ -404,6 +404,7 @@ public class BlockStorage { } } + @Nonnull public static Config getLocationInfo(Location l) { BlockStorage storage = getStorage(l.getWorld()); @@ -415,6 +416,7 @@ public class BlockStorage { return cfg == null ? emptyBlockData : cfg; } + @Nonnull private static Map parseJSON(String json) { Map map = new HashMap<>(); @@ -608,22 +610,20 @@ public class BlockStorage { } String chunkString = locationToChunkString(l); + Map> tickers = SlimefunPlugin.getTickerTask().getActiveTickers(); + Set locations = tickers.get(chunkString); - if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) { - Set locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString); + if (locations != null) { locations.remove(l); if (locations.isEmpty()) { - SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString); - SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString); - } - else { - SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations); + tickers.remove(chunkString); } } } } + @ParametersAreNonnullByDefault public static void moveBlockInfo(Location from, Location to) { SlimefunPlugin.getTickerTask().queueMove(from, to); } @@ -637,6 +637,7 @@ public class BlockStorage { * @param to * The destination {@link Location} */ + @ParametersAreNonnullByDefault public static void moveLocationInfoUnsafely(Location from, Location to) { if (!hasBlockInfo(from)) { return; @@ -657,17 +658,14 @@ public class BlockStorage { storage.storage.remove(from); String chunkString = locationToChunkString(from); + Map> tickers = SlimefunPlugin.getTickerTask().getActiveTickers(); + Set locations = tickers.get(chunkString); - if (SlimefunPlugin.getRegistry().getActiveTickers().containsKey(chunkString)) { - Set locations = SlimefunPlugin.getRegistry().getActiveTickers().get(chunkString); + if (locations != null) { locations.remove(from); if (locations.isEmpty()) { - SlimefunPlugin.getRegistry().getActiveTickers().remove(chunkString); - SlimefunPlugin.getRegistry().getActiveChunks().remove(chunkString); - } - else { - SlimefunPlugin.getRegistry().getActiveTickers().put(chunkString, locations); + tickers.remove(chunkString); } } } @@ -689,10 +687,9 @@ public class BlockStorage { String chunkString = locationToChunkString(l); if (value != null) { - Set locations = SlimefunPlugin.getRegistry().getActiveTickers().computeIfAbsent(chunkString, c -> new HashSet<>()); + Map> tickers = SlimefunPlugin.getTickerTask().getActiveTickers(); + Set locations = tickers.computeIfAbsent(chunkString, id -> new HashSet<>()); locations.add(l); - - SlimefunPlugin.getRegistry().getActiveChunks().add(chunkString); } } } @@ -754,14 +751,6 @@ public class BlockStorage { return SlimefunPlugin.getRegistry().getWorlds().containsKey(name); } - public static Set getTickingChunks() { - return SlimefunPlugin.getRegistry().getActiveChunks(); - } - - public static Set getTickingLocations(String chunk) { - return SlimefunPlugin.getRegistry().getActiveTickers().getOrDefault(chunk, new HashSet<>()); - } - public BlockMenu loadInventory(Location l, BlockMenuPreset preset) { if (preset == null) { return null; @@ -799,7 +788,7 @@ public class BlockStorage { for (HumanEntity human : new ArrayList<>(menu.toInventory().getViewers())) { // Prevents "java.lang.IllegalStateException: Asynchronous entity add!" // when closing the inventory while holding an item - Slimefun.runSync(human::closeInventory); + SlimefunPlugin.runSync(human::closeInventory); } inventories.get(l).delete(l); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java b/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java index b7d7af302..f13ba5bb0 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/Slimefun.java @@ -3,12 +3,11 @@ package me.mrCookieSlime.Slimefun.api; import java.util.Optional; import java.util.logging.Logger; -import org.bukkit.Bukkit; +import javax.annotation.Nonnull; + import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; -import org.bukkit.scheduler.BukkitTask; -import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; import io.github.thebusybiscuit.slimefun4.api.items.ItemState; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; @@ -26,6 +25,7 @@ public final class Slimefun { private Slimefun() {} + @Nonnull public static Logger getLogger() { return SlimefunPlugin.instance().getLogger(); } @@ -180,30 +180,4 @@ public final class Slimefun { } return true; } - - public static BukkitTask runSync(Runnable r) { - if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { - r.run(); - return null; - } - - if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) { - return null; - } - - return Bukkit.getScheduler().runTask(SlimefunPlugin.instance(), r); - } - - public static BukkitTask runSync(Runnable r, long delay) { - if (SlimefunPlugin.getMinecraftVersion() == MinecraftVersion.UNIT_TEST) { - r.run(); - return null; - } - - if (SlimefunPlugin.instance() == null || !SlimefunPlugin.instance().isEnabled()) { - return null; - } - - return Bukkit.getScheduler().runTaskLater(SlimefunPlugin.instance(), r, delay); - } } \ No newline at end of file diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java index feb7253df..8f78c8a11 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/SlimefunItemStack.java @@ -33,7 +33,7 @@ import io.github.thebusybiscuit.slimefun4.utils.HeadTexture; import io.github.thebusybiscuit.slimefun4.utils.PatternUtils; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class SlimefunItemStack extends CustomItem implements Cloneable { +public class SlimefunItemStack extends CustomItem { private String id; private ImmutableItemMeta immutableMeta; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java index 4cf2a02cf..be7877c56 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java @@ -3,17 +3,20 @@ package me.mrCookieSlime.Slimefun.api.inventory; import java.util.HashSet; import java.util.Set; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import org.apache.commons.lang.Validate; import org.bukkit.Location; import org.bukkit.block.Block; import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; import org.bukkit.inventory.InventoryView; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; public abstract class BlockMenuPreset extends ChestMenu { @@ -30,13 +33,15 @@ public abstract class BlockMenuPreset extends ChestMenu { private ItemManipulationEvent event; - public BlockMenuPreset(String id, String title) { + public BlockMenuPreset(@Nonnull String id, @Nonnull String title) { this(id, title, false); } - public BlockMenuPreset(String id, String title, boolean universal) { + public BlockMenuPreset(@Nonnull String id, @Nonnull String title, boolean universal) { super(title); + Validate.notNull(id, "You need to specify an id!"); + this.id = id; this.inventoryTitle = title; this.universal = universal; @@ -53,15 +58,57 @@ public abstract class BlockMenuPreset extends ChestMenu { public abstract void init(); - public abstract boolean canOpen(Block b, Player p); + /** + * This method returns whether a given {@link Player} is allowed to open the + * {@link BlockMenu} of that {@link Block}. + * Override this as necessary. + * + * @param b + * The {@link Block} trying to be opened + * @param p + * The {@link Player} who wants to open the {@link BlockMenu} + * + * @return Whether that {@link Player} is allowed + */ + public abstract boolean canOpen(@Nonnull Block b, @Nonnull Player p); public abstract int[] getSlotsAccessedByItemTransport(ItemTransportFlow flow); + /** + * This method is deprecated. + * + * @deprecated Override {@link #onItemStackChange(DirtyChestMenu, int, ItemStack, ItemStack)} instead + * + * @param event + * The event + */ + @Deprecated public void registerEvent(ItemManipulationEvent event) { this.event = event; } - public void newInstance(BlockMenu menu, Block b) { + /** + * This method is called whenever an {@link ItemStack} changes. + * You can override this as necessary if you need to listen to these events + * + * @param menu + * The {@link Inventory} affected by this + * @param slot + * The affected slot + * @param previous + * The {@link ItemStack} in that slot before the operation + * @param next + * The {@link ItemStack} that it changes to + * + * @return The new outcome of this operation + */ + @Nullable + protected ItemStack onItemStackChange(@Nonnull DirtyChestMenu menu, int slot, @Nullable ItemStack previous, @Nullable ItemStack next) { + // Override this as necessary + return next; + } + + public void newInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { // This method can optionally be overridden by implementations } @@ -76,7 +123,7 @@ public abstract class BlockMenuPreset extends ChestMenu { } @Override - public ChestMenu addItem(int slot, ItemStack item) { + public ChestMenu addItem(int slot, @Nullable ItemStack item) { checkIfLocked(); occupiedSlots.add(slot); @@ -89,6 +136,7 @@ public abstract class BlockMenuPreset extends ChestMenu { return super.addMenuClickHandler(slot, handler); } + @Nonnull public ChestMenu setSize(int size) { checkIfLocked(); @@ -134,10 +182,12 @@ public abstract class BlockMenuPreset extends ChestMenu { return universal; } + @Nonnull public Set getPresetSlots() { return occupiedSlots; } + @Nonnull public Set getInventorySlots() { Set emptySlots = new HashSet<>(); @@ -159,7 +209,7 @@ public abstract class BlockMenuPreset extends ChestMenu { return emptySlots; } - protected void clone(DirtyChestMenu menu) { + protected void clone(@Nonnull DirtyChestMenu menu) { menu.setPlayerInventoryClickable(true); for (int slot : occupiedSlots) { @@ -186,10 +236,10 @@ public abstract class BlockMenuPreset extends ChestMenu { menu.registerEvent(event); } - public void newInstance(BlockMenu menu, Location l) { + public void newInstance(@Nonnull BlockMenu menu, @Nonnull Location l) { Validate.notNull(l, "Cannot create a new BlockMenu without a Location"); - Slimefun.runSync(() -> { + SlimefunPlugin.runSync(() -> { locked = true; try { @@ -207,6 +257,8 @@ public abstract class BlockMenuPreset extends ChestMenu { * * @return Our identifier */ + + @Nonnull public String getID() { return id; } @@ -216,10 +268,13 @@ public abstract class BlockMenuPreset extends ChestMenu { * * @return The associated {@link SlimefunItem} */ + + @Nonnull public SlimefunItem getSlimefunItem() { return SlimefunItem.getByID(id); } + @Nullable public static BlockMenuPreset getPreset(String id) { return id == null ? null : SlimefunPlugin.getRegistry().getMenuPresets().get(id); } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java index f00223c45..20fda5505 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java @@ -2,6 +2,9 @@ package me.mrCookieSlime.Slimefun.api.inventory; import java.util.ArrayList; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.HumanEntity; @@ -21,7 +24,7 @@ public class DirtyChestMenu extends ChestMenu { protected ItemManipulationEvent event; protected int changes = 1; - public DirtyChestMenu(BlockMenuPreset preset) { + public DirtyChestMenu(@Nonnull BlockMenuPreset preset) { super(preset.getTitle()); this.preset = preset; @@ -49,6 +52,7 @@ public class DirtyChestMenu extends ChestMenu { return changes; } + @Nonnull public BlockMenuPreset getPreset() { return preset; } @@ -63,6 +67,15 @@ public class DirtyChestMenu extends ChestMenu { } } + /** + * This method has been deprecated. + * + * @deprecated The {@link ItemManipulationEvent} has been deprecated. + * + * @param event + * deprecated class + */ + @Deprecated public void registerEvent(ItemManipulationEvent event) { this.event = event; } @@ -77,15 +90,23 @@ public class DirtyChestMenu extends ChestMenu { } } - public boolean fits(ItemStack item, int... slots) { - return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots); + public boolean fits(@Nonnull ItemStack item, int... slots) { + if (getItemInSlot(slots[0]) == null) { + // Very small optimization + return true; + } + else { + return InvUtils.fits(toInventory(), new ItemStackWrapper(item), slots); + } } + @Nullable public ItemStack pushItem(ItemStack item, int... slots) { if (item == null || item.getType() == Material.AIR) { throw new IllegalArgumentException("Cannot push null or AIR"); } + ItemStackWrapper wrapper = null; int amount = item.getAmount(); for (int slot : slots) { @@ -99,9 +120,15 @@ public class DirtyChestMenu extends ChestMenu { replaceExistingItem(slot, item); return null; } - else if (stack.getAmount() < stack.getMaxStackSize() && ItemUtils.canStack(item, stack)) { - amount -= (stack.getMaxStackSize() - stack.getAmount()); - stack.setAmount(Math.min(stack.getAmount() + item.getAmount(), stack.getMaxStackSize())); + else if (stack.getAmount() < stack.getMaxStackSize()) { + if (wrapper == null) { + wrapper = new ItemStackWrapper(item); + } + + if (ItemUtils.canStack(wrapper, stack)) { + amount -= (stack.getMaxStackSize() - stack.getAmount()); + stack.setAmount(Math.min(stack.getAmount() + item.getAmount(), stack.getMaxStackSize())); + } } } @@ -132,9 +159,14 @@ public class DirtyChestMenu extends ChestMenu { } public void replaceExistingItem(int slot, ItemStack item, boolean event) { - if (event && this.event != null) { + if (event) { ItemStack previous = getItemInSlot(slot); - item = this.event.onEvent(slot, previous, item); + + if (this.event != null) { + item = this.event.onEvent(slot, previous, item); + } + + item = preset.onItemStackChange(this, slot, previous, item); } super.replaceExistingItem(slot, item); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java index 3a7899dbd..ce6591b0a 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/ItemManipulationEvent.java @@ -2,6 +2,13 @@ package me.mrCookieSlime.Slimefun.api.inventory; import org.bukkit.inventory.ItemStack; +/** + * @deprecated Please use {@link BlockMenuPreset#onItemStackChange(DirtyChestMenu, int, ItemStack, ItemStack)} instead. + * + * @author TheBusyBiscuit + * + */ +@Deprecated @FunctionalInterface public interface ItemManipulationEvent { diff --git a/src/main/resources/languages/messages_en.yml b/src/main/resources/languages/messages_en.yml index c292b1c82..ba59a468f 100644 --- a/src/main/resources/languages/messages_en.yml +++ b/src/main/resources/languages/messages_en.yml @@ -151,6 +151,7 @@ messages: knight: '&a&oYour Talisman gave you 5 Seconds of Regeneration' whirlwind: '&a&oYour Talisman reflected the Projectile' wizard: '&a&oYour Talisman has given you a better Fortune Level but maybe also lowered some other Enchantment Levels' + caveman: '&a&oYour Talisman gave you haste' soulbound-rune: fail: '&cYou can only bind one item to your soul at a time.' @@ -259,20 +260,23 @@ machines: finished: '&eYour Industrial Miner has finished! It obtained a total of %ores% ore(s)!' anvil: - not-working: '&4You cannot use Slimefun Items in an anvil!' + not-working: '&4You cannot use Slimefun items in an anvil!' brewing_stand: - not-working: '&4You cannot use Slimefun Items in a brewing stand!' + not-working: '&4You cannot use Slimefun items in a brewing stand!' + +cartography_table: + not-working: '&4You cannot use Slimefun items in a cartography table!' villagers: - no-trading: '&4You cannot trade Slimefun Items with Villagers!' + no-trading: '&4You cannot trade Slimefun items with Villagers!' backpack: already-open: '&cSorry, this Backpack is open somewhere else!' no-stack: '&cYou cannot stack Backpacks' workbench: - not-enhanced: '&4You cannot use Slimefun Items in a normal workbench' + not-enhanced: '&4You cannot use Slimefun items in a normal workbench' gps: deathpoint: '&4Deathpoint &7%date%' diff --git a/src/main/resources/languages/researches_en.yml b/src/main/resources/languages/researches_en.yml index b0ea41377..47f5243d0 100644 --- a/src/main/resources/languages/researches_en.yml +++ b/src/main/resources/languages/researches_en.yml @@ -61,6 +61,7 @@ slimefun: water_talisman: Talisman of the Water Breather angel_talisman: Talisman of the Angel fire_talisman: Talisman of the Firefighter + caveman_talisman: Talisman of the Caveman lava_crystal: Firey Situation magician_talisman: Talisman of the Magician traveller_talisman: Talisman of the Traveller diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/TestUtilities.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/TestUtilities.java index bd963339c..b6625ce90 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/TestUtilities.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/TestUtilities.java @@ -1,21 +1,5 @@ package io.github.thebusybiscuit.slimefun4.testing; -import static org.mockito.Mockito.when; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; - -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.OfflinePlayer; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.plugin.Plugin; -import org.junit.jupiter.api.Assertions; -import org.mockito.Mockito; - import be.seeseemelk.mockbukkit.ServerMock; import io.github.thebusybiscuit.cscorelib2.item.CustomItem; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; @@ -25,6 +9,21 @@ import io.github.thebusybiscuit.slimefun4.testing.mocks.MockSlimefunItem; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.Objects.Category; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.OfflinePlayer; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.plugin.Plugin; +import org.junit.jupiter.api.Assertions; +import org.mockito.Mockito; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; + +import static org.mockito.Mockito.when; public final class TestUtilities { @@ -73,18 +72,60 @@ public final class TestUtilities { public static void registerDefaultTags(ServerMock server) { // We really don't need these to be accurate, just fill them with some examples // that approximate the actual content - server.createMaterialTag(NamespacedKey.minecraft("logs"), Material.OAK_LOG, Material.STRIPPED_OAK_LOG, Material.OAK_WOOD, Material.STRIPPED_OAK_WOOD, Material.ACACIA_LOG, Material.STRIPPED_ACACIA_LOG, Material.ACACIA_WOOD, Material.STRIPPED_ACACIA_WOOD); - server.createMaterialTag(NamespacedKey.minecraft("wooden_trapdoors"), Material.OAK_TRAPDOOR, Material.BIRCH_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.JUNGLE_TRAPDOOR, Material.ACACIA_TRAPDOOR, Material.DARK_OAK_TRAPDOOR); - server.createMaterialTag(NamespacedKey.minecraft("wooden_slabs"), Material.OAK_SLAB, Material.BIRCH_SLAB, Material.JUNGLE_SLAB, Material.SPRUCE_SLAB, Material.ACACIA_SLAB, Material.DARK_OAK_SLAB); - server.createMaterialTag(NamespacedKey.minecraft("wooden_fences"), Material.OAK_FENCE, Material.BIRCH_FENCE, Material.JUNGLE_FENCE, Material.SPRUCE_FENCE, Material.ACACIA_FENCE, Material.DARK_OAK_FENCE); - server.createMaterialTag(NamespacedKey.minecraft("planks"), Material.OAK_PLANKS, Material.BIRCH_PLANKS, Material.SPRUCE_PLANKS, Material.JUNGLE_PLANKS, Material.ACACIA_PLANKS, Material.DARK_OAK_PLANKS); - server.createMaterialTag(NamespacedKey.minecraft("small_flowers"), Material.POPPY, Material.DANDELION, Material.AZURE_BLUET, Material.LILY_OF_THE_VALLEY); - server.createMaterialTag(NamespacedKey.minecraft("leaves"), Material.OAK_LEAVES, Material.BIRCH_LEAVES, Material.SPRUCE_LEAVES, Material.JUNGLE_LEAVES, Material.ACACIA_LEAVES, Material.DARK_OAK_LEAVES); - server.createMaterialTag(NamespacedKey.minecraft("saplings"), Material.OAK_SAPLING, Material.BIRCH_SAPLING, Material.SPRUCE_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING); - server.createMaterialTag(NamespacedKey.minecraft("coral_blocks"), Material.BRAIN_CORAL_BLOCK, Material.BUBBLE_CORAL_BLOCK, Material.FIRE_CORAL_BLOCK, Material.HORN_CORAL_BLOCK, Material.TUBE_CORAL_BLOCK); - server.createMaterialTag(NamespacedKey.minecraft("corals"), Material.BRAIN_CORAL, Material.BUBBLE_CORAL, Material.FIRE_CORAL, Material.HORN_CORAL, Material.TUBE_CORAL); - server.createMaterialTag(NamespacedKey.minecraft("ice"), Material.ICE, Material.PACKED_ICE, Material.FROSTED_ICE, Material.BLUE_ICE); + server.createMaterialTag(NamespacedKey.minecraft("logs"), Material.OAK_LOG, + Material.STRIPPED_OAK_LOG, Material.OAK_WOOD, Material.STRIPPED_OAK_WOOD, + Material.ACACIA_LOG, Material.STRIPPED_ACACIA_LOG, Material.ACACIA_WOOD, Material.STRIPPED_ACACIA_WOOD + ); + server.createMaterialTag(NamespacedKey.minecraft("wooden_trapdoors"), Material.OAK_TRAPDOOR, + Material.BIRCH_TRAPDOOR, Material.SPRUCE_TRAPDOOR, Material.JUNGLE_TRAPDOOR, + Material.ACACIA_TRAPDOOR, Material.DARK_OAK_TRAPDOOR + ); + server.createMaterialTag(NamespacedKey.minecraft("wooden_slabs"), Material.OAK_SLAB, Material.BIRCH_SLAB, + Material.JUNGLE_SLAB, Material.SPRUCE_SLAB, Material.ACACIA_SLAB, Material.DARK_OAK_SLAB + ); + server.createMaterialTag(NamespacedKey.minecraft("wooden_fences"), Material.OAK_FENCE, Material.BIRCH_FENCE, + Material.JUNGLE_FENCE, Material.SPRUCE_FENCE, Material.ACACIA_FENCE, Material.DARK_OAK_FENCE + ); + server.createMaterialTag(NamespacedKey.minecraft("planks"), Material.OAK_PLANKS, Material.BIRCH_PLANKS, + Material.SPRUCE_PLANKS, Material.JUNGLE_PLANKS, Material.ACACIA_PLANKS, Material.DARK_OAK_PLANKS + ); + server.createMaterialTag(NamespacedKey.minecraft("small_flowers"), Material.POPPY, Material.DANDELION, + Material.AZURE_BLUET, Material.LILY_OF_THE_VALLEY + ); + server.createMaterialTag(NamespacedKey.minecraft("leaves"), Material.OAK_LEAVES, Material.BIRCH_LEAVES, + Material.SPRUCE_LEAVES, Material.JUNGLE_LEAVES, Material.ACACIA_LEAVES, Material.DARK_OAK_LEAVES + ); + server.createMaterialTag(NamespacedKey.minecraft("saplings"), Material.OAK_SAPLING, Material.BIRCH_SAPLING, + Material.SPRUCE_SAPLING, Material.JUNGLE_SAPLING, Material.ACACIA_SAPLING, Material.DARK_OAK_SAPLING + ); + server.createMaterialTag(NamespacedKey.minecraft("coral_blocks"), Material.BRAIN_CORAL_BLOCK, + Material.BUBBLE_CORAL_BLOCK, Material.FIRE_CORAL_BLOCK, Material.HORN_CORAL_BLOCK, Material.TUBE_CORAL_BLOCK + ); + server.createMaterialTag(NamespacedKey.minecraft("corals"), Material.BRAIN_CORAL, Material.BUBBLE_CORAL, + Material.FIRE_CORAL, Material.HORN_CORAL, Material.TUBE_CORAL + ); + server.createMaterialTag(NamespacedKey.minecraft("ice"), Material.ICE, Material.PACKED_ICE, + Material.FROSTED_ICE, Material.BLUE_ICE + ); server.createMaterialTag(NamespacedKey.minecraft("fire"), Material.FIRE, Material.SOUL_FIRE); - } + + server.createMaterialTag(NamespacedKey.minecraft("boats"), Material.BIRCH_BOAT, Material.ACACIA_BOAT, + Material.DARK_OAK_BOAT, Material.JUNGLE_BOAT, Material.OAK_BOAT, Material.SPRUCE_BOAT + ); + server.createMaterialTag(NamespacedKey.minecraft("wooden_buttons"), Material.BIRCH_BUTTON, + Material.ACACIA_BUTTON, Material.SPRUCE_BUTTON, Material.DARK_OAK_BUTTON, + Material.JUNGLE_BOAT, Material.OAK_BUTTON + ); + server.createMaterialTag(NamespacedKey.minecraft("signs"), Material.SPRUCE_SIGN, Material.ACACIA_SIGN, + Material.OAK_SIGN, Material.JUNGLE_SIGN, Material.DARK_OAK_SIGN, Material.BIRCH_SIGN + ); + server.createMaterialTag(NamespacedKey.minecraft("wooden_doors"), Material.SPRUCE_DOOR, Material.ACACIA_DOOR, + Material.OAK_DOOR, Material.JUNGLE_DOOR, Material.DARK_OAK_DOOR, Material.BIRCH_DOOR + ); + server.createMaterialTag(NamespacedKey.minecraft("wooden_pressure_plates"), Material.SPRUCE_PRESSURE_PLATE, + Material.ACACIA_PRESSURE_PLATE, Material.OAK_PRESSURE_PLATE, Material.JUNGLE_PRESSURE_PLATE, + Material.DARK_OAK_PRESSURE_PLATE, Material.BIRCH_PRESSURE_PLATE + ); -} + } +} \ No newline at end of file diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/gps/TestWaypoints.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/gps/TestWaypoints.java index 6ae75c56c..f8d644f50 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/gps/TestWaypoints.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/gps/TestWaypoints.java @@ -4,6 +4,7 @@ import org.bukkit.entity.Player; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -15,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; -public class TestWaypoints { +class TestWaypoints { private static ServerMock server; @@ -31,7 +32,8 @@ public class TestWaypoints { } @Test - public void testAddWaypointToProfile() throws InterruptedException { + @DisplayName("Test Waypoints being added to the profile") + void testAddWaypointToProfile() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -48,7 +50,8 @@ public class TestWaypoints { } @Test - public void testRemoveWaypointFromProfile() throws InterruptedException { + @DisplayName("Test Waypoints being removed from the profile") + void testRemoveWaypointFromProfile() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -68,7 +71,8 @@ public class TestWaypoints { } @Test - public void testWaypointAlreadyExisting() throws InterruptedException { + @DisplayName("Verify that two waypoints cannot have the same name") + void testWaypointAlreadyExisting() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -81,7 +85,8 @@ public class TestWaypoints { } @Test - public void testTooManyWaypoints() throws InterruptedException { + @DisplayName("Verify that a maximum amount of waypoints is enforced") + void testTooManyWaypoints() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -95,7 +100,8 @@ public class TestWaypoints { } @Test - public void testWaypointEvent() throws InterruptedException { + @DisplayName("Verify that a WaypointCreateEvent is thrown") + void testWaypointEvent() throws InterruptedException { GPSNetwork network = new GPSNetwork(); Player player = server.addPlayer(); TestUtilities.awaitProfile(player); @@ -105,7 +111,8 @@ public class TestWaypoints { } @Test - public void testWaypointComparison() throws InterruptedException { + @DisplayName("Test equal Waypoints being equal") + void testWaypointComparison() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); @@ -121,7 +128,8 @@ public class TestWaypoints { } @Test - public void testIsDeathpoint() throws InterruptedException { + @DisplayName("Test Deathpoints being recognized as Deathpoints") + void testIsDeathpoint() throws InterruptedException { Player player = server.addPlayer(); PlayerProfile profile = TestUtilities.awaitProfile(player); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java index f7e9336e3..606c2acff 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestDietCookie.java @@ -7,6 +7,7 @@ import org.bukkit.potion.PotionEffectType; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -19,7 +20,7 @@ import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class TestDietCookie implements SlimefunItemTest { +class TestDietCookie implements SlimefunItemTest { private static ServerMock server; private static SlimefunPlugin plugin; @@ -44,7 +45,8 @@ public class TestDietCookie implements SlimefunItemTest { } @Test - public void testConsumptionBehaviour() { + @DisplayName("Test Diet Cookies giving Levitation Effect") + void testConsumptionBehaviour() { PlayerMock player = server.addPlayer(); DietCookie cookie = registerSlimefunItem(plugin, "TEST_DIET_COOKIE"); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMeatJerky.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMeatJerky.java index 9a84f1c2e..40aba208c 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMeatJerky.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMeatJerky.java @@ -5,6 +5,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -17,7 +18,7 @@ import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class TestMeatJerky implements SlimefunItemTest { +class TestMeatJerky implements SlimefunItemTest { private static ServerMock server; private static SlimefunPlugin plugin; @@ -42,7 +43,8 @@ public class TestMeatJerky implements SlimefunItemTest { } @Test - public void testConsumptionBehaviour() { + @DisplayName("Test Meat Jerky giving extra saturation") + void testConsumptionBehaviour() { PlayerMock player = server.addPlayer(); MeatJerky jerky = registerSlimefunItem(plugin, "TEST_MEAT_JERKY"); float saturation = player.getSaturation(); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java index 0002be40d..4b23f7d20 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/food/TestMonsterJerky.java @@ -6,6 +6,7 @@ import org.bukkit.potion.PotionEffectType; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -18,7 +19,7 @@ import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest; import me.mrCookieSlime.Slimefun.Lists.RecipeType; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -public class TestMonsterJerky implements SlimefunItemTest { +class TestMonsterJerky implements SlimefunItemTest { private static ServerMock server; private static SlimefunPlugin plugin; @@ -43,7 +44,8 @@ public class TestMonsterJerky implements SlimefunItemTest { } @Test - public void testConsumptionBehaviour() { + @DisplayName("Test Monster Jerky giving Saturation and removing Hunger") + void testConsumptionBehaviour() { PlayerMock player = server.addPlayer(); player.addPotionEffect(PotionEffectType.HUNGER.createEffect(20, 2)); MonsterJerky jerky = registerSlimefunItem(plugin, "TEST_MONSTER_JERKY"); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/tools/TestPortableDustbin.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/tools/TestPortableDustbin.java new file mode 100644 index 000000000..41ac7fe2c --- /dev/null +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/items/implementations/tools/TestPortableDustbin.java @@ -0,0 +1,59 @@ +package io.github.thebusybiscuit.slimefun4.testing.tests.items.implementations.tools; + +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; + +import be.seeseemelk.mockbukkit.MockBukkit; +import be.seeseemelk.mockbukkit.ServerMock; +import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; +import io.github.thebusybiscuit.slimefun4.implementation.items.tools.PortableDustbin; +import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; +import io.github.thebusybiscuit.slimefun4.testing.interfaces.SlimefunItemTest; +import me.mrCookieSlime.Slimefun.Lists.RecipeType; +import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; + +class TestPortableDustbin implements SlimefunItemTest { + + private static ServerMock server; + private static SlimefunPlugin plugin; + + @BeforeAll + public static void load() { + server = MockBukkit.mock(); + plugin = MockBukkit.load(SlimefunPlugin.class); + } + + @AfterAll + public static void unload() { + MockBukkit.unmock(); + } + + @Override + public PortableDustbin registerSlimefunItem(SlimefunPlugin plugin, String id) { + SlimefunItemStack item = new SlimefunItemStack(id, Material.BUCKET, "&4Test Dustbin"); + PortableDustbin dustbin = new PortableDustbin(TestUtilities.getCategory(plugin, "dustbin"), item, RecipeType.NULL, new ItemStack[9]); + dustbin.register(plugin); + return dustbin; + } + + @Test + @DisplayName("Test Dustbin opening an empty Inventory") + void testRightClickBehaviour() { + Player player = server.addPlayer(); + PortableDustbin dustbin = registerSlimefunItem(plugin, "TEST_PORTABLE_DUSTBIN"); + + simulateRightClick(player, dustbin); + + // We expect an empty Inventory to be open now + Inventory openInventory = player.getOpenInventory().getTopInventory(); + Assertions.assertTrue(openInventory.isEmpty()); + } + +} diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestIronGolemListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestIronGolemListener.java index 2f6be5615..020522d7e 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestIronGolemListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestIronGolemListener.java @@ -10,6 +10,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -22,7 +23,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.IronGolemList import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class TestIronGolemListener { +class TestIronGolemListener { private static SlimefunPlugin plugin; private static IronGolemListener listener; @@ -62,7 +63,8 @@ public class TestIronGolemListener { } @Test - public void testWithIron() { + @DisplayName("Test Iron Golem Healing not being disturbed") + void testWithIron() { // This should heal the Iron Golem ItemStack item = new ItemStack(Material.IRON_INGOT); @@ -74,7 +76,8 @@ public class TestIronGolemListener { } @Test - public void testWithSlimefunIron() { + @DisplayName("Test Iron Golem Healing with Slimefun Items being cancelled") + void testWithSlimefunIron() { SlimefunItem slimefunItem = TestUtilities.mockSlimefunItem(plugin, "SLIMEFUN_IRON", new CustomItem(Material.IRON_INGOT, "&cSlimefun Iron")); slimefunItem.register(plugin); @@ -87,7 +90,8 @@ public class TestIronGolemListener { } @Test - public void testWithVanillaIron() { + @DisplayName("Test Iron Golem Healing with vanilla items not being disturbed") + void testWithVanillaIron() { VanillaItem item = TestUtilities.mockVanillaItem(plugin, Material.IRON_INGOT, true); item.register(plugin); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestMultiblockListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestMultiblockListener.java index 4d7d96ef4..a56f3efe7 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestMultiblockListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestMultiblockListener.java @@ -12,6 +12,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -24,7 +25,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.listeners.MultiBlockLis import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class TestMultiblockListener { +class TestMultiblockListener { private static SlimefunPlugin plugin; private static MultiBlockListener listener; @@ -48,7 +49,8 @@ public class TestMultiblockListener { } @Test - public void testNoMultiblock() { + @DisplayName("Test MultiBlocks not messing up normal interactions") + void testNoMultiblock() { Player player = server.addPlayer(); World world = server.addSimpleWorld("Multiblock Test World"); Block b = world.getBlockAt(3456, 90, -100); @@ -62,7 +64,8 @@ public class TestMultiblockListener { } @Test - public void testMultiblock() { + @DisplayName("Test MultiBlocks being recognized on right click") + void testMultiblock() { Player player = server.addPlayer(); World world = server.addSimpleWorld("Multiblock Test World"); Block top = world.getBlockAt(1234, 92, -60); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java index 94cacd965..91cee4018 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestSlimefunGuideListener.java @@ -8,6 +8,7 @@ import org.bukkit.inventory.ItemStack; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; @@ -37,6 +38,7 @@ class TestSlimefunGuideListener { } @ParameterizedTest + @DisplayName("Test Slimefun Guides being given on first join") @MethodSource("cartesianBooleans") void testFirstJoin(boolean hasPlayedBefore, boolean giveSlimefunGuide) { SlimefunGuideListener listener = new SlimefunGuideListener(plugin, giveSlimefunGuide); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVanillaMachinesListener.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVanillaMachinesListener.java index a36b616f1..b87f39a25 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVanillaMachinesListener.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/listeners/TestVanillaMachinesListener.java @@ -76,6 +76,16 @@ public class TestVanillaMachinesListener { return event; } + private InventoryClickEvent mockCartographyTableEvent(ItemStack item) { + Player player = server.addPlayer(); + Inventory inv = TestUtilities.mockInventory(InventoryType.CARTOGRAPHY, new ItemStack(Material.FILLED_MAP), item, new ItemStack(Material.FILLED_MAP)); + InventoryView view = player.openInventory(inv); + InventoryClickEvent event = new InventoryClickEvent(view, SlotType.CONTAINER, 2, ClickType.LEFT, InventoryAction.PICKUP_ONE); + + listener.onCartographyTable(event); + return event; + } + private InventoryClickEvent mockBrewingEvent(ItemStack item) { Player player = server.addPlayer(); Inventory inv = TestUtilities.mockInventory(InventoryType.BREWING); @@ -242,6 +252,30 @@ public class TestVanillaMachinesListener { Assertions.assertEquals(Result.DEFAULT, event.getResult()); } + @Test + public void testCartographyTableWithoutSlimefunItems() { + InventoryClickEvent event = mockCartographyTableEvent(new ItemStack(Material.PAPER)); + Assertions.assertEquals(Result.DEFAULT, event.getResult()); + } + + @Test + public void testCartographyTableWithSlimefunItem() { + SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MOCKED_PAPER", new CustomItem(Material.PAPER, "&6Mock")); + item.register(plugin); + + InventoryClickEvent event = mockCartographyTableEvent(item.getItem()); + Assertions.assertEquals(Result.DENY, event.getResult()); + } + + @Test + public void testCartographyTableWithVanillaItem() { + VanillaItem item = TestUtilities.mockVanillaItem(plugin, Material.PAPER, true); + item.register(plugin); + + InventoryClickEvent event = mockCartographyTableEvent(item.getItem()); + Assertions.assertEquals(Result.DEFAULT, event.getResult()); + } + @Test public void testBrewingWithoutSlimefunItems() { InventoryClickEvent event = mockBrewingEvent(new ItemStack(Material.BLAZE_POWDER)); diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/multiblocks/TestMultiBlocks.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/multiblocks/TestMultiBlocks.java index 2579c9261..b226d5c0a 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/multiblocks/TestMultiBlocks.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/multiblocks/TestMultiBlocks.java @@ -5,6 +5,7 @@ import org.bukkit.block.BlockFace; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; @@ -15,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; import io.github.thebusybiscuit.slimefun4.testing.TestUtilities; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -public class TestMultiBlocks { +class TestMultiBlocks { private static SlimefunPlugin plugin; @@ -32,7 +33,8 @@ public class TestMultiBlocks { } @Test - public void testInvalidConstructors() { + @DisplayName("Test Exceptions for invalid MultiBlock constructors") + void testInvalidConstructors() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); Assertions.assertThrows(IllegalArgumentException.class, () -> new MultiBlock(null, null, null)); @@ -44,7 +46,8 @@ public class TestMultiBlocks { } @Test - public void testValidConstructor() { + @DisplayName("Test MultiBlock constructor") + void testValidConstructor() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); MultiBlock multiblock = new MultiBlock(item, new Material[9], BlockFace.DOWN); @@ -54,7 +57,8 @@ public class TestMultiBlocks { } @Test - public void testSymmetry() { + @DisplayName("Test symmetric MultiBlocks") + void testSymmetry() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); MultiBlock multiblock = new MultiBlock(item, new Material[] { null, null, null, Material.DIAMOND_BLOCK, null, Material.DIAMOND_BLOCK, null, Material.DISPENSER, null }, BlockFace.DOWN); @@ -65,28 +69,31 @@ public class TestMultiBlocks { } @Test - public void testEqual() { + @DisplayName("Test equal MultiBlocks being equal") + void testEqual() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); MultiBlock multiblock = new MultiBlock(item, new Material[] { Material.BIRCH_WOOD, Material.BIRCH_WOOD, Material.BIRCH_WOOD, null, Material.CRAFTING_TABLE, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.BIRCH_WOOD }, BlockFace.DOWN); MultiBlock multiblock2 = new MultiBlock(item, new Material[] { Material.BIRCH_WOOD, Material.BIRCH_WOOD, Material.BIRCH_WOOD, null, Material.CRAFTING_TABLE, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.BIRCH_WOOD }, BlockFace.DOWN); - Assertions.assertTrue(multiblock.equals(multiblock2)); + Assertions.assertEquals(multiblock, multiblock2); } @Test - public void testEqualWithTags() { + @DisplayName("Test equal MultiBlocks with Tags but different Materials being equal") + void testEqualWithTags() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); // The wooden fences are different but the structure should still match. MultiBlock multiblock = new MultiBlock(item, new Material[] { Material.OAK_FENCE, Material.OAK_FENCE, Material.OAK_FENCE, null, Material.CRAFTING_TABLE, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.BIRCH_WOOD }, BlockFace.DOWN); MultiBlock multiblock2 = new MultiBlock(item, new Material[] { Material.BIRCH_FENCE, Material.BIRCH_FENCE, Material.BIRCH_FENCE, null, Material.CRAFTING_TABLE, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.BIRCH_WOOD }, BlockFace.DOWN); - Assertions.assertTrue(multiblock.equals(multiblock2)); + Assertions.assertEquals(multiblock, multiblock2); } @Test - public void testEqualWithMovingPistons() { + @DisplayName("Test MultiBlocks with moving pistons still being equal") + void testEqualWithMovingPistons() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "PISTON_MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); // Some Pistons are moving but that should not interefere with the Multiblock @@ -94,12 +101,13 @@ public class TestMultiBlocks { MultiBlock multiblock2 = new MultiBlock(item, new Material[] { Material.MOVING_PISTON, Material.PISTON, Material.MOVING_PISTON, null, Material.CRAFTING_TABLE, null, Material.PISTON, Material.STONE, Material.PISTON }, BlockFace.DOWN); MultiBlock multiblock3 = new MultiBlock(item, new Material[] { Material.PISTON, Material.PISTON, Material.STICKY_PISTON, null, Material.CRAFTING_TABLE, null, Material.PISTON, Material.STONE, Material.PISTON }, BlockFace.DOWN); - Assertions.assertTrue(multiblock.equals(multiblock2)); - Assertions.assertFalse(multiblock.equals(multiblock3)); + Assertions.assertEquals(multiblock, multiblock2); + Assertions.assertNotEquals(multiblock, multiblock3); } @Test - public void testNotEqual() { + @DisplayName("Test different MultiBlocks not being equal") + void testNotEqual() { SlimefunItem item = TestUtilities.mockSlimefunItem(plugin, "MULTIBLOCK_TEST", new CustomItem(Material.BRICK, "&5Multiblock Test")); MultiBlock multiblock = new MultiBlock(item, new Material[] { Material.BIRCH_WOOD, Material.BIRCH_WOOD, Material.BIRCH_WOOD, null, Material.CRAFTING_TABLE, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.BIRCH_WOOD }, BlockFace.DOWN); @@ -107,10 +115,10 @@ public class TestMultiBlocks { MultiBlock multiblock3 = new MultiBlock(item, new Material[] { Material.DROPPER, Material.BIRCH_WOOD, Material.BIRCH_WOOD, null, Material.DIAMOND_BLOCK, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.TNT }, BlockFace.DOWN); MultiBlock multiblock4 = new MultiBlock(item, new Material[] { Material.BIRCH_WOOD, Material.BIRCH_WOOD, Material.BIRCH_WOOD, null, Material.CRAFTING_TABLE, null, Material.BIRCH_WOOD, Material.DISPENSER, Material.BIRCH_WOOD }, BlockFace.SELF); - Assertions.assertFalse(multiblock.equals(null)); - Assertions.assertFalse(multiblock.equals(multiblock2)); - Assertions.assertFalse(multiblock.equals(multiblock3)); - Assertions.assertFalse(multiblock.equals(multiblock4)); + Assertions.assertNotEquals(multiblock, null); + Assertions.assertNotEquals(multiblock, multiblock2); + Assertions.assertNotEquals(multiblock, multiblock3); + Assertions.assertNotEquals(multiblock, multiblock4); } } diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestItemDataService.java b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestItemDataService.java index 544deba6f..7a6d261c8 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestItemDataService.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/testing/tests/services/TestItemDataService.java @@ -9,13 +9,14 @@ import org.bukkit.inventory.meta.ItemMeta; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import be.seeseemelk.mockbukkit.MockBukkit; import io.github.thebusybiscuit.slimefun4.core.services.CustomItemDataService; import io.github.thebusybiscuit.slimefun4.implementation.SlimefunPlugin; -public class TestItemDataService { +class TestItemDataService { private static SlimefunPlugin plugin; @@ -31,13 +32,15 @@ public class TestItemDataService { } @Test - public void testInitialization() { + @DisplayName("Test CustomItemDataService constructor") + void testInitialization() { CustomItemDataService service = new CustomItemDataService(plugin, "test"); Assertions.assertEquals(new NamespacedKey(plugin, "test"), service.getKey()); } @Test - public void testSetDataItem() { + @DisplayName("Test setting item data for an ItemStack") + void testSetDataItem() { CustomItemDataService service = new CustomItemDataService(plugin, "test"); ItemStack item = new ItemStack(Material.EMERALD); @@ -49,7 +52,8 @@ public class TestItemDataService { } @Test - public void testSetDataItemMeta() { + @DisplayName("Test setting item data for an ItemMeta") + void testSetDataItemMeta() { CustomItemDataService service = new CustomItemDataService(plugin, "test"); ItemStack item = new ItemStack(Material.EMERALD); ItemMeta meta = item.getItemMeta();