diff --git a/README.md b/README.md index affc3ed96c..b5172a3612 100644 --- a/README.md +++ b/README.md @@ -1,165 +1,2 @@ -# Slimefun 4 -*Looking for the download link? [**Click here**](https://github.com/Slimefun/Slimefun4/blob/master/README.md#floppy_disk-download-slimefun-4)* +# This is our modification of Slimefun4 to be optimised for large servers. No support will be given by us or Slimefun for issues with this. -Slimefun is a plugin which aims to turn your Spigot Server into a modpack without ever installing a single mod. It offers everything you could possibly imagine. From Backpacks to Jetpacks! Slimefun lets every player decide on their own how much they want to dive into Magic or Tech.
-We got everything from magical wands to nuclear reactors.
-We feature a magical altar, an electric power grid and even item transport systems. - -This project originally started back **in 2013** and has grown ever since.
-From one single person working on this plugin back then, we grew to a community of thousands of players and hundreds of contributors to this project.
-It currently adds over **500 new items and recipes** to Minecraft ([Read more about the history of this project](https://github.com/Slimefun/Slimefun4/wiki/Slimefun-in-a-nutshell)). - -But it also comes with a lot of addons! Check out our [addons](https://github.com/Slimefun/Slimefun4/wiki/Addons), you may find exactly what you were looking for. - -### Quick navigation -* **[:floppy_disk: Download Slimefun4](#floppy_disk-download-slimefun-4)** -* **[:framed_picture: Screenshots](#framed_picture-screenshots)** -* **[:headphones: Discord Support Server](#headphones-discord)** -* **[:beetle: Bug Tracker](https://github.com/Slimefun/Slimefun4/issues)** -* **[:open_book: Wiki](https://github.com/Slimefun/Slimefun4/wiki)** -* **[:interrobang: FAQ](https://github.com/Slimefun/Slimefun4/wiki/FAQ)** -* **[:handshake: How to contribute](https://github.com/Slimefun/Slimefun4/blob/master/CONTRIBUTING.md)** - -## :floppy_disk: Download Slimefun 4 -Slimefun requires your Minecraft Server to be running on [Spigot](https://spigotmc.org/), [Paper](https://papermc.io/) or on any fork of these.
-(See also: [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun)) - -Slimefun 4 can be downloaded **for free** on our builds page.
-We currently provide two distinct versions of Slimefun, development builds and "stable" builds.
-Here is a full summary of the differences between the two different versions of Slimefun. - -| | development (latest) | "stable" | -| ------------------ | -------- | -------- | -| **Minecraft version(s)** | :video_game: **1.16.\* - 1.20.\*** | :video_game: **1.16.\* - 1.20.\*** | -| **Java version** | :computer: **Java 16 (or higher)** | :computer: **Java 16 (or higher)** | -| **automatic updates** | :heavy_check_mark: | :heavy_check_mark: | -| **frequent updates** | :heavy_check_mark: | :x: | -| **latest content** | :heavy_check_mark: | :x: | -| **Discord support** | :heavy_check_mark: | :x: | -| **Bug Reports** | :heavy_check_mark: | :x: | -| **testing before release** | :x: | :heavy_check_mark: | -| **change logs** | :x: | :memo: **[change log](https://github.com/Slimefun/Slimefun4/blob/master/CHANGELOG.md)** | -| **Download links** | :floppy_disk: **[download latest](https://blob.build/project/Slimefun4/Dev)** | :floppy_disk: **[download "stable"](https://blob.build/project/Slimefun4/RC)** | - -**:exclamation: We wholeheartedly recommend you to use _development builds_, they are the most recent version of Slimefun and also receive the most frequent updates! In fact, "stable" builds are so outdated that we won't accept bug reports from them at all.** -
- Here's why... - -"Stable" builds do not receive frequent updates or fast patches. As time goes on, bugs are fixed but it will take some time until these fixes make it into a "stable" build. We will also not accept or review any bug reports from "stable" builds. They are in fact just old development builds that seemed to run fine without any __major__ issues. - -**:question: Why use a "stable" build then?**
-While "stable" builds most definitely contain more bugs than development builds due to their very slow update schedule. you can be sure that they will not include __game-breaking__ issues, but rest assured that development builds almost never contain such issues either. If your server or business however heavily depends on a version of Slimefun that does not change/update a lot, you are forgiven if you choose the "stable" branch. But development builds will bring you the best experience, both in terms of features and bug fixes. - -**:question: What exactly are these "stable" builds then and why do you put them in quotes?**
-"Stable" builds are literally just outdated development builds that seemed to run fine without any __major__ issues. But they are far from bug-free hence why actually calling them stable would be hypocritical. However these builds can only really stay "stable" if there are enough people using development builds and report any bugs they come across. Otherwise potential issues may go unnoticed and slip into a "stable" build. Again, we really recommend you to choose the development builds. But since a few people really wanted "stable" builds, they are now an option too. - -
- -## :framed_picture: Screenshots -So what does Slimefun look like?
-Well, we asked some users on our [Discord server](#headphones-discord) to send us some screenshots, so see for yourself: -| Reactors and electricity | Awesome factories | Magic and Altars | -| :-------------------------------------------: | :--------------------------------------: | :----------------------------------------: | -| ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase1.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase6.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase5.png) | -| *Screenshot provided by HamtaBot#0001* | *Screenshot provided by Piͭxͪeͤl (mnb)#5049* | *Screenshot provided by Kilaruna#4981* | -| ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase4.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase3.png) | ![](https://raw.githubusercontent.com/Slimefun/Slimefun-Wiki/master/images/showcase2.png) | -| *Screenshot provided by GalaxyKat11#3816* | *Screenshot provided by TamThan#7987* | *Screenshot provided by Kilaruna#4981* | - -## :headphones: Discord -You can find Slimefun's community on Discord and connect with **over 7000** users of this plugin from all over the world.
-Click the badge down below to join the server for suggestions/questions or other discussions about this plugin.
-We are also hosting a community event every so often, join us to find out more.
-**Important: We don't accept bug reports on discord, please use our [Issue Tracker](https://github.com/Slimefun/Slimefun4/issues) to submit bug reports!** - -Due to the sheer size of this discord server, we need to enforce some [important rules](https://github.com/Slimefun/Slimefun4/wiki/Discord-Rules).
-Not following these rules can lead to a kick or even a ban from the server. - -

- - Discord Invite - -

- -## :open_book: Wiki -Slimefun has a (detailed and well-maintained - *cough*) Wiki for new players, maybe also consider -expanding the wiki to help grow our community and help out new users of this plugin. -https://github.com/Slimefun/Slimefun4/wiki - -#### :star: Highlighted Articles -* [What is Slimefun?](https://github.com/Slimefun/Slimefun4/wiki/Slimefun-in-a-nutshell) -* [How to install Slimefun](https://github.com/Slimefun/Slimefun4/wiki/Installing-Slimefun) -* [Addons for Slimefun 4](https://github.com/Slimefun/Slimefun4/wiki/Addons) -* [How to create an Addon for Slimefun 4](https://github.com/Slimefun/Slimefun4/wiki/Developer-Guide) -* [Getting Started](https://github.com/Slimefun/Slimefun4/wiki/Getting-Started) -* [Frequently Asked Questions](https://github.com/Slimefun/Slimefun4/wiki/FAQ) -* [Common issues](https://github.com/Slimefun/Slimefun4/wiki/Common-Issues) -* [Help us expand the Wiki!](https://github.com/Slimefun/Slimefun4/wiki/Expanding-the-Wiki) -* [Help us translate Slimefun!](https://github.com/Slimefun/Slimefun4/wiki/Translating-Slimefun) - -The wiki is entirely community-run, so if you find an article missing, feel free to write one and share it with others. - -## :handshake: Contributing to this project -Slimefun 4 is an Open-Source project and licensed under -[GNU GPLv3](https://github.com/Slimefun/Slimefun4/blob/master/LICENSE).
-**Over 200 people have already contributed to this amazing project. You guys are awesome! :heart:**
-Please consider helping us maintain this project too, your engagement keeps the project alive! - -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). - -## :exclamation: Disclaimers -Slimefun4 uses various systems that collect usage information or download automatic updates as well as the latest information about the project. -We do not collect any personal information from you but there are some services that may gather or download some form of data. - -You can opt-out of the Auto-Updater and stats collection at any time! - -
- Automatic updates - -Slimefun4 uses an Auto-Updater which connects to https://thebusybiscuit.github.io/builds/ to check for and download updates.
-This behaviour is enabled by default but can be turned off under `/plugins/Slimefun/config.yml`.
-We highly recommend you to keep this on at any time though, as you could be missing out on important patches. -
- -
- Metrics and Statistics - -Slimefun4 uses [bStats](https://bstats.org/plugin/bukkit/Slimefun/4574) to collect anonymous information about the usage of this plugin.
-This is solely for statistical purposes, as we are interested in how Servers/Players use this plugin.
-All available data is anonymous and aggregated, at no point can we see individual server or player information.
-All of the collected data is publicly accessible: https://bstats.org/plugin/bukkit/Slimefun/4574 - -You can also disable this behaviour under `/plugins/bStats/config.yml`.
-For more info see [bStats' Privacy Policy](https://bstats.org/privacy-policy) - -Our [bStats Module](https://github.com/Slimefun/MetricsModule) is downloaded automatically when installing this Plugin, this module will automatically update on server starts independently from the main plugin. This way we can automatically roll out updates to the bStats module, in cases of severe performance issues for example where live data and insight into what is impacting performance can be crucial. -These updates can of course be disabled under `/plugins/Slimefun/config.yml`. To disable metrics collection as a whole, see the paragraph above. - ---- - -Slimefun also uses its own analytics system to collect anonymous information about the performance of this plugin.
-This is solely for statistical purposes, as we are interested in how it's performing for all servers.
-All available data is anonymous and aggregated, at no point can we see individual server information.
- -You can also disable this behaviour under `/plugins/Slimefun/config.yml`.
- -
- -
- GitHub Integration - -Lastly, Slimefun4 connects to https://api.github.com/ to gather information about this open-source project.
-No information about you or your Minecraft Server is sent to GitHub. - -This information includes (but is not limited to) -* list of contributors, their username and profile link (from the repositories `Slimefun/Slimefun4`, `Slimefun/Slimefun-Wiki` and `Slimefun/Resourcepack`) -* amount of open issues in this repository -* amount of pending pull requests in this repository -* amount of stars in this repository -* amount of forks of this repository -* amount of code-bytes in this repository -* date of the last commit to this repository -
- -Additionally the plugin connects to [textures.minecraft.net](https://www.minecraft.net/en-us) to retrieve the Minecraft skins of our contributors (if possible).
- -*Note that Slimefun is not associated with `Mojang Studios` or `Minecraft`.* diff --git a/pom.xml b/pom.xml index 151afd0ccd..6ea210044f 100644 --- a/pom.xml +++ b/pom.xml @@ -9,7 +9,7 @@ - 4.9-UNOFFICIAL + 4.9-CYT 2013 jar diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/RadiationDamageEvent.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/RadiationDamageEvent.java new file mode 100644 index 0000000000..b3ef284e75 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/events/RadiationDamageEvent.java @@ -0,0 +1,69 @@ +package io.github.thebusybiscuit.slimefun4.api.events; + +import javax.annotation.Nonnull; + +import org.bukkit.entity.Player; +import org.bukkit.event.Cancellable; +import org.bukkit.event.Event; +import org.bukkit.event.HandlerList; + +/** + * The {@link RadiationDamageEvent} is called when a player takes radiation damage. + * + * @author HoosierTransfer + */ +public class RadiationDamageEvent extends Event implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + + private final Player player; + private final int exposure; + private boolean cancelled; + + /** + * This constructs a new {@link RadiationDamageEvent}. + * + * @param player The {@link Player} who took radiation damage + * @param exposure The amount of radiation exposure + */ + public RadiationDamageEvent(@Nonnull Player player, int exposure) { + this.player = player; + this.exposure = exposure; + } + + /** + * This returns the {@link Player} who took radiation damage. + * + * @return The {@link Player} who took radiation damage + */ + public @Nonnull Player getPlayer() { + return player; + } + + /** + * This returns the amount of radiation exposure. + * + * @return The amount of radiation exposure + */ + public int getExposure() { + return exposure; + } + + @Override + public boolean isCancelled() { + return cancelled; + } + + @Override + public void setCancelled(boolean cancelled) { + this.cancelled = cancelled; + } + + public static @Nonnull HandlerList getHandlerList() { + return handlers; + } + + @Override + public @Nonnull HandlerList getHandlers() { + return getHandlerList(); + } +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java index 4a49b89ec8..b47a71fff1 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/items/ItemSetting.java @@ -106,21 +106,8 @@ public void update(@Nonnull T newValue) { */ public @Nonnull T getValue() { if (value != null) { - /** - * If the value has been initialized, return it immediately. - */ return value; - } else if (Slimefun.instance().isUnitTest()) { - /* - * In Unit Tests, we want the test to fail. So we know there is - * something that needs to be fixed. - */ - throw new IllegalStateException("ItemSetting '" + key + "' was invoked but was not initialized yet."); } else { - /* - * In a normal environment, we can mitigate the issue - * easily and just print a warning instead. - */ item.warn("ItemSetting '" + key + "' was invoked but was not initialized yet."); return defaultValue; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java index 8dfc7414f8..d6b25537dc 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/player/PlayerProfile.java @@ -165,7 +165,6 @@ public void setResearched(@Nonnull Research research, boolean unlock) { * * @param research * The {@link Research} that is being queried - * * @return Whether this {@link Research} has been unlocked */ public boolean hasUnlocked(@Nullable Research research) { @@ -177,23 +176,6 @@ public boolean hasUnlocked(@Nullable Research research) { return !research.isEnabled() || data.getResearches().contains(research); } - /** - * This method returns whether this {@link Player} has unlocked all {@link Research Researches}. - * - * @return Whether they unlocked every {@link Research} - */ - public boolean hasUnlockedEverything() { - for (Research research : Slimefun.getRegistry().getResearches()) { - // If there is a single Research not unlocked: They haven't unlocked everything. - if (!hasUnlocked(research)) { - return false; - } - } - - // Player has everything unlocked - Hooray! - return true; - } - /** * This Method will return all Researches that this {@link Player} has unlocked * diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DistinctiveItem.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DistinctiveItem.java index 150bef8319..fc0c9da566 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DistinctiveItem.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/attributes/DistinctiveItem.java @@ -1,11 +1,10 @@ package io.github.thebusybiscuit.slimefun4.core.attributes; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import org.bukkit.inventory.meta.ItemMeta; -import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; - import javax.annotation.Nonnull; /** @@ -22,10 +21,8 @@ public interface DistinctiveItem extends ItemAttribute { * IDs match on a DistinctiveItem and should return if the two items can stack * with one another. * - * @param itemMetaOne - * The {@link ItemMeta} of the first stack being compared. - * @param itemMetaTwo - * The {@link ItemMeta} of the second stack being compared. + * @param itemMetaOne The {@link ItemMeta} of the first stack being compared. + * @param itemMetaTwo The {@link ItemMeta} of the second stack being compared. * * @return Whether the two {@link ItemMeta}s are stackable */ diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java index 2cce2bb796..79b211af0e 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/AbstractItemNetwork.java @@ -1,9 +1,17 @@ package io.github.thebusybiscuit.slimefun4.core.networks.cargo; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.Queue; +import java.util.Set; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -13,15 +21,29 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; +import org.bukkit.block.BlockState; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Directional; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import io.github.bakedlibs.dough.common.ChatColors; +import io.github.bakedlibs.dough.items.CustomItemStack; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.network.Network; import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; +import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; +import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; +import io.papermc.lib.PaperLib; +import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; +import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; /** @@ -33,6 +55,21 @@ */ abstract class AbstractItemNetwork extends Network { + private static final int[] slots = { 19, 20, 21, 28, 29, 30, 37, 38, 39 }; + private static final int[] TERMINAL_SLOTS = { 0, 1, 2, 3, 4, 5, 6, 9, 10, 11, 12, 13, 14, 15, 18, 19, 20, 21, 22, 23, 24, 27, 28, 29, 30, 31, 32, 33, 36, 37, 38, 39, 40, 41, 42 }; + private static final int TERMINAL_OUT_SLOT = 17; + + private final ItemStack terminalPlaceholderItem = new CustomItemStack(Material.BARRIER, "&4No Item cached"); + + protected final Set terminals = new HashSet<>(); + protected final Set imports = new HashSet<>(); + protected final Set exports = new HashSet<>(); + + /** + * This represents a {@link Queue} of requests to handle + */ + private final Queue itemRequests = new LinkedList<>(); + /** * This is a cache for the {@link BlockFace} a node is facing, so we don't need to * request the {@link BlockData} each time we visit a node @@ -44,11 +81,11 @@ abstract class AbstractItemNetwork extends Network { */ protected Map filterCache = new HashMap<>(); - protected AbstractItemNetwork(@Nonnull Location regulator) { + protected AbstractItemNetwork(Location regulator) { super(Slimefun.getNetworkManager(), regulator); } - protected Optional getAttachedBlock(@Nonnull Location l) { + protected Optional getAttachedBlock(Location l) { if (l.getWorld().isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)) { Block block = l.getBlock(); @@ -68,6 +105,235 @@ protected Optional getAttachedBlock(@Nonnull Location l) { return Optional.empty(); } + protected void handleItemRequests(Map inventories, Set providers, Set destinations) { + collectImportRequests(inventories); + collectExportRequests(inventories); + collectTerminalRequests(); + + Iterator iterator = itemRequests.iterator(); + while (iterator.hasNext()) { + ItemRequest request = iterator.next(); + BlockMenu menu = BlockStorage.getInventory(request.getTerminal()); + + if (menu != null) { + switch (request.getDirection()) { + case INSERT: + distributeInsertionRequest(inventories, request, menu, iterator, destinations); + break; + case WITHDRAW: + collectExtractionRequest(inventories, request, menu, iterator, providers); + break; + default: + break; + } + } + } + } + + private void distributeInsertionRequest(Map inventories, ItemRequest request, BlockMenu terminal, Iterator iterator, Set destinations) { + ItemStack item = request.getItem(); + + for (Location l : destinations) { + Optional target = getAttachedBlock(l); + + if (target.isPresent()) { + item = CargoUtils.insert(this, inventories, l.getBlock(), target.get(), false, item); + + if (item == null) { + terminal.replaceExistingItem(request.getSlot(), null); + break; + } + } + } + + if (item != null) { + terminal.replaceExistingItem(request.getSlot(), item); + } + + iterator.remove(); + } + + private void collectExtractionRequest(Map inventories, ItemRequest request, BlockMenu terminal, Iterator iterator, Set providers) { + int slot = request.getSlot(); + ItemStack prevStack = terminal.getItemInSlot(slot); + + if (!(prevStack == null || (prevStack.getAmount() + request.getItem().getAmount() <= prevStack.getMaxStackSize() && SlimefunUtils.isItemSimilar(prevStack, request.getItem(), true, false)))) { + iterator.remove(); + return; + } + + ItemStack stack = null; + ItemStack item = request.getItem(); + + for (Location l : providers) { + Optional target = getAttachedBlock(l); + + if (target.isPresent()) { + ItemStack is = CargoUtils.withdraw(this, inventories, l.getBlock(), target.get(), item); + + if (is != null) { + if (stack == null) { + stack = is; + } else { + stack = new CustomItemStack(stack, stack.getAmount() + is.getAmount()); + } + + if (is.getAmount() == item.getAmount()) { + break; + } else { + item = new CustomItemStack(item, item.getAmount() - is.getAmount()); + } + } + } + } + + if (stack != null) { + ItemStack prev = terminal.getItemInSlot(slot); + + if (prev == null) { + terminal.replaceExistingItem(slot, stack); + } else { + terminal.replaceExistingItem(slot, new CustomItemStack(stack, stack.getAmount() + prev.getAmount())); + } + } + + iterator.remove(); + } + + private void collectImportRequests(Map inventories) { + SlimefunItem item = SlimefunItem.getById("CT_IMPORT_BUS"); + + for (Location bus : imports) { + long timestamp = Slimefun.getProfiler().newEntry(); + BlockMenu menu = BlockStorage.getInventory(bus); + + if (menu.getItemInSlot(17) == null) { + Optional target = getAttachedBlock(bus); + + if (target.isPresent()) { + ItemStackAndInteger stack = CargoUtils.withdraw(this, inventories, bus.getBlock(), target.get()); + + if (stack != null) { + menu.replaceExistingItem(17, stack.getItem()); + } + } + } + + if (menu.getItemInSlot(17) != null) { + itemRequests.add(new ItemRequest(bus, 17, menu.getItemInSlot(17), ItemTransportFlow.INSERT)); + } + + Slimefun.getProfiler().closeEntry(bus, item, timestamp); + } + } + + private void collectExportRequests(Map inventories) { + SlimefunItem item = SlimefunItem.getById("CT_EXPORT_BUS"); + + for (Location bus : exports) { + long timestamp = Slimefun.getProfiler().newEntry(); + BlockMenu menu = BlockStorage.getInventory(bus); + + ItemStack itemSlot17 = menu.getItemInSlot(17); + if (itemSlot17 != null) { + Optional target = getAttachedBlock(bus); + target.ifPresent(block -> menu.replaceExistingItem(17, CargoUtils.insert(this, inventories, bus.getBlock(), block, false, itemSlot17))); + } + + if (menu.getItemInSlot(17) == null) { + List items = new ArrayList<>(); + + for (int slot : slots) { + ItemStack template = menu.getItemInSlot(slot); + + if (template != null) { + items.add(new CustomItemStack(template, 1)); + } + } + + if (!items.isEmpty()) { + int index = Integer.parseInt(BlockStorage.getLocationInfo(bus, "index")); + + index++; + if (index > (items.size() - 1)) { + index = 0; + } + + BlockStorage.addBlockInfo(bus, "index", String.valueOf(index)); + itemRequests.add(new ItemRequest(bus, 17, items.get(index), ItemTransportFlow.WITHDRAW)); + } + } + + Slimefun.getProfiler().closeEntry(bus, item, timestamp); + } + } + + private void collectTerminalRequests() { + for (Location terminal : terminals) { + BlockMenu menu = BlockStorage.getInventory(terminal); + ItemStack sendingItem = menu.getItemInSlot(TERMINAL_OUT_SLOT); + + if (sendingItem != null) { + itemRequests.add(new ItemRequest(terminal, TERMINAL_OUT_SLOT, sendingItem, ItemTransportFlow.INSERT)); + } + } + } + + /** + * This method updates every terminal on the network with {@link ItemStack ItemStacks} + * found in any provider of the network. + * + * @param providers + * A {@link Set} of providers to this {@link AbstractItemNetwork} + * + * @return The time it took to compute this operation + */ + protected long updateTerminals(@Nonnull Set providers) { + if (terminals.isEmpty()) { + // Performance improvement - We don't need to compute items for + // Cargo networks without any Chest Terminals + return 0; + } + + // Timings will be slightly inaccurate here but most often people are not + // gonna use no more than one terminal anyway, so this might be fine + long timestamp = System.nanoTime(); + Location firstTerminal = null; + SlimefunItem item = SlimefunItem.getById("CHEST_TERMINAL"); + List items = findAvailableItems(providers); + + try { + for (Location l : terminals) { + BlockMenu terminal = BlockStorage.getInventory(l); + String data = BlockStorage.getLocationInfo(l, "page"); + int page = data == null ? 1 : Integer.parseInt(data); + + if (!items.isEmpty() && items.size() < (page - 1) * TERMINAL_SLOTS.length + 1) { + page = 1; + BlockStorage.addBlockInfo(l, "page", String.valueOf(1)); + } + + for (int i = 0; i < TERMINAL_SLOTS.length; i++) { + int slot = TERMINAL_SLOTS[i]; + int index = i + (TERMINAL_SLOTS.length * (page - 1)); + updateTerminal(l, terminal, slot, index, items); + } + + if (firstTerminal == null) { + firstTerminal = l; + } + } + } catch (Exception | LinkageError x) { + item.error("An Exception was caused while trying to tick Chest terminals", x); + } + + if (firstTerminal != null) { + return Slimefun.getProfiler().closeEntry(firstTerminal, item, timestamp); + } else { + return System.nanoTime() - timestamp; + } + } + @Override public void markDirty(@Nonnull Location l) { markCargoNodeConfigurationDirty(l); @@ -91,6 +357,88 @@ public void markCargoNodeConfigurationDirty(@Nonnull Location node) { connectorCache.remove(node); } + @ParametersAreNonnullByDefault + private void updateTerminal(Location l, BlockMenu terminal, int slot, int index, List items) { + if (items.size() > index) { + ItemStackAndInteger item = items.get(index); + + ItemStack stack = item.getItem().clone(); + stack.setAmount(1); + ItemMeta im = stack.getItemMeta(); + List lore = new ArrayList<>(); + lore.add(""); + lore.add(ChatColors.color("&7Stored Items: &f" + NumberUtils.getCompactDouble(item.getInt()))); + + if (stack.getMaxStackSize() > 1) { + int amount = item.getInt() > stack.getMaxStackSize() ? stack.getMaxStackSize() : item.getInt(); + lore.add(ChatColors.color("&7")); + } else { + lore.add(ChatColors.color("&7")); + } + + lore.add(""); + + if (im.hasLore()) { + lore.addAll(im.getLore()); + } + + im.setLore(lore); + stack.setItemMeta(im); + terminal.replaceExistingItem(slot, stack); + terminal.addMenuClickHandler(slot, (p, sl, is, action) -> { + int amount = item.getInt() > item.getItem().getMaxStackSize() ? item.getItem().getMaxStackSize() : item.getInt(); + ItemStack requestedItem = new CustomItemStack(item.getItem(), action.isRightClicked() ? amount : 1); + itemRequests.add(new ItemRequest(l, 44, requestedItem, ItemTransportFlow.WITHDRAW)); + return false; + }); + + } else { + terminal.replaceExistingItem(slot, terminalPlaceholderItem); + terminal.addMenuClickHandler(slot, ChestMenuUtils.getEmptyClickHandler()); + } + } + + @Nonnull + private List findAvailableItems(@Nonnull Set providers) { + List items = new LinkedList<>(); + + for (Location l : providers) { + Optional block = getAttachedBlock(l); + + if (block.isPresent()) { + findAllItems(items, l, block.get()); + } + } + + Collections.sort(items, Comparator.comparingInt(item -> -item.getInt())); + return items; + } + + @ParametersAreNonnullByDefault + private void findAllItems(List items, Location l, Block target) { + UniversalBlockMenu menu = BlockStorage.getUniversalInventory(target); + + if (menu != null) { + for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.WITHDRAW, null)) { + ItemStack is = menu.getItemInSlot(slot); + filter(is, items, l); + } + } else if (BlockStorage.hasInventory(target)) { + BlockMenu blockMenu = BlockStorage.getInventory(target); + handleWithdraw(blockMenu, items, l); + } else if (CargoUtils.hasInventory(target)) { + BlockState state = PaperLib.getBlockState(target, false).getState(); + + if (state instanceof InventoryHolder) { + Inventory inv = ((InventoryHolder) state).getInventory(); + + for (ItemStack is : inv.getContents()) { + filter(is, items, l); + } + } + } + } + @ParametersAreNonnullByDefault private void handleWithdraw(DirtyChestMenu menu, List items, Location l) { for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.WITHDRAW, null)) { @@ -116,7 +464,8 @@ private void filter(@Nullable ItemStack stack, List items, } } - protected @Nonnull ItemFilter getItemFilter(@Nonnull Block node) { + @Nonnull + protected ItemFilter getItemFilter(@Nonnull Block node) { Location loc = node.getLocation(); ItemFilter filter = filterCache.get(loc); 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 35b5fe225f..87767bb748 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 @@ -175,8 +175,7 @@ private ItemStack distributeItem(ItemStack stack, Location inputNode, List target = network.getAttachedBlock(output); if (target.isPresent()) { - ItemStackWrapper wrapper = ItemStackWrapper.wrap(item); - item = CargoUtils.insert(network, inventories, output.getBlock(), target.get(), smartFill, item, wrapper); + item = CargoUtils.insert(network, inventories, output.getBlock(), target.get(), smartFill, item); if (item == null) { if (roundrobin) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java index ff8da96d0a..16283fa399 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/CargoUtils.java @@ -1,10 +1,12 @@ package io.github.thebusybiscuit.slimefun4.core.networks.cargo; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import java.util.Map; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.Tag; @@ -245,8 +247,8 @@ private static ItemStackAndInteger withdrawFromVanillaInventory(AbstractItemNetw } @Nullable - static ItemStack insert(AbstractItemNetwork network, Map inventories, Block node, Block target, boolean smartFill, ItemStack stack, ItemStackWrapper wrapper) { - Debug.log(TestCase.CARGO_INPUT_TESTING, "CargoUtils#insert"); + static ItemStack insert(AbstractItemNetwork network, Map inventories, Block node, Block target, boolean smartFill, ItemStack stack) { + // Debug.log(TestCase.CARGO_INPUT_TESTING, "CargoUtils#insert"); if (!matchesFilter(network, node, stack)) { return stack; } @@ -258,7 +260,7 @@ static ItemStack insert(AbstractItemNetwork network, Map in Inventory inventory = inventories.get(target.getLocation()); if (inventory != null) { - return insertIntoVanillaInventory(stack, wrapper, smartFill, inventory); + return insertIntoVanillaInventory(stack, smartFill, inventory); } BlockState state = PaperLib.getBlockState(target, false).getState(); @@ -266,14 +268,14 @@ static ItemStack insert(AbstractItemNetwork network, Map in if (state instanceof InventoryHolder inventoryHolder) { inventory = inventoryHolder.getInventory(); inventories.put(target.getLocation(), inventory); - return insertIntoVanillaInventory(stack, wrapper, smartFill, inventory); + return insertIntoVanillaInventory(stack, smartFill, inventory); } } return stack; } - for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.INSERT, wrapper)) { + for (int slot : menu.getPreset().getSlotsAccessedByItemTransport(menu, ItemTransportFlow.INSERT, stack)) { ItemStack itemInSlot = menu.getItemInSlot(slot); if (itemInSlot == null) { @@ -289,9 +291,10 @@ static ItemStack insert(AbstractItemNetwork network, Map in continue; } - if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false)) { + if ((SlimefunItem.getByItem(stack) != null || !stack.hasItemMeta() && !itemInSlot.hasItemMeta()) + && ItemFilter.altItemCompare(itemInSlot, stack)) { if (currentAmount < maxStackSize) { - int amount = currentAmount + stack.getAmount(); + int amount = currentAmount + stack.getAmount(); // get total amount itemInSlot.setAmount(Math.min(amount, maxStackSize)); if (amount > maxStackSize) { @@ -312,7 +315,7 @@ static ItemStack insert(AbstractItemNetwork network, Map in } @Nullable - private static ItemStack insertIntoVanillaInventory(@Nonnull ItemStack stack, @Nonnull ItemStackWrapper wrapper, boolean smartFill, @Nonnull Inventory inv) { + private static ItemStack insertIntoVanillaInventory(@Nonnull ItemStack stack, boolean smartFill, @Nonnull Inventory inv) { /* * If the Inventory does not accept this Item Type, bounce the item back. * Example: Shulker boxes within shulker boxes (fixes #2662) @@ -342,7 +345,8 @@ private static ItemStack insertIntoVanillaInventory(@Nonnull ItemStack stack, @N continue; } - if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false)) { + if ((SlimefunItem.getByItem(stack) != null || !stack.hasItemMeta() && !itemInSlot.hasItemMeta()) + && ItemFilter.altItemCompare(itemInSlot, stack)) { if (currentAmount < maxStackSize) { int amount = currentAmount + stack.getAmount(); @@ -381,6 +385,8 @@ static boolean matchesFilter(@Nonnull AbstractItemNetwork network, @Nonnull Bloc return network.getItemFilter(node).test(item); } + + /** * This method checks if a given {@link ItemStack} is smeltable or not. * The lazy-option is a performance-saver since actually calculating this can be quite expensive. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemFilter.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemFilter.java index 1de4b4a4a4..fc65f1da3d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemFilter.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemFilter.java @@ -1,12 +1,17 @@ package io.github.thebusybiscuit.slimefun4.core.networks.cargo; +import io.github.bakedlibs.dough.items.ItemMetaSnapshot; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.util.ArrayList; import java.util.List; import java.util.Objects; +import java.util.Optional; import java.util.function.Predicate; import javax.annotation.Nonnull; +import javax.annotation.Nullable; import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.inventory.ItemStack; @@ -21,6 +26,7 @@ import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; +import org.bukkit.inventory.meta.ItemMeta; /** * The {@link ItemFilter} is a performance-optimization for our {@link CargoNet}. @@ -59,6 +65,7 @@ class ItemFilter implements Predicate { * on the next tick. */ private boolean dirty = false; + private boolean checkCustomItems; /** * This creates a new {@link ItemFilter} for the given {@link Block}. @@ -69,6 +76,7 @@ class ItemFilter implements Predicate { */ public ItemFilter(@Nonnull Block b) { update(b); + checkCustomItems = Slimefun.getCfg().getBoolean("options.allow-custom-items-in-cargo-filters"); } /** @@ -161,7 +169,7 @@ public void markDirty() { @Override public boolean test(@Nonnull ItemStack item) { - Debug.log(TestCase.CARGO_INPUT_TESTING, "ItemFilter#test({})", item); + // Debug.log(TestCase.CARGO_INPUT_TESTING, "ItemFilter#test({})", item); /* * An empty Filter does not need to be iterated over. * We can just return our default value in this scenario. @@ -200,7 +208,8 @@ public boolean test(@Nonnull ItemStack item) { * and thus only perform .getItemMeta() once */ for (ItemStackWrapper stack : items) { - if (SlimefunUtils.isItemSimilar(subject, stack, checkLore, false)) { + if ((checkCustomItems && SlimefunUtils.isItemSimilar(subject, stack, checkLore, false) + || (!checkCustomItems && altItemCompare(subject, stack)))) { /* * The filter has found a match, we can return the opposite * of our default value. If we exclude items, this is where we @@ -215,4 +224,22 @@ public boolean test(@Nonnull ItemStack item) { } } + public static boolean altItemCompare(@Nullable ItemStack item, @Nullable ItemStack sfitem) { + if (item == null) { + return sfitem == null; + } else if (sfitem == null) { + return false; + } else if (item.getType() != sfitem.getType()) { + return false; + } else { + SlimefunItem sfitem1 = SlimefunItem.getByItem(item); + SlimefunItem sfitem2 = SlimefunItem.getByItem(sfitem); + if (sfitem1 != null && sfitem2 != null) { + return sfitem1.getId().equals(sfitem2.getId()); + } else if (sfitem1 == null && sfitem2 == null) { + return item.getType() == sfitem.getType(); + } + } + return false; + } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemRequest.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemRequest.java new file mode 100644 index 0000000000..2e015f5ba7 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/networks/cargo/ItemRequest.java @@ -0,0 +1,55 @@ +package io.github.thebusybiscuit.slimefun4.core.networks.cargo; + +import java.util.Objects; + +import org.bukkit.Location; +import org.bukkit.inventory.ItemStack; + +import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; + +class ItemRequest { + + private final ItemStack item; + private final ItemTransportFlow flow; + private final Location terminal; + private final int slot; + + ItemRequest(Location terminal, int slot, ItemStack item, ItemTransportFlow flow) { + this.terminal = terminal; + this.item = item; + this.slot = slot; + this.flow = flow; + } + + public Location getTerminal() { + return terminal; + } + + public ItemStack getItem() { + return item; + } + + public ItemTransportFlow getDirection() { + return flow; + } + + public int getSlot() { + return slot; + } + + @Override + public int hashCode() { + return Objects.hash(item, slot, flow, terminal); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof ItemRequest) { + ItemRequest request = (ItemRequest) obj; + return Objects.equals(item, request.item) && Objects.equals(terminal, request.terminal) && slot == request.slot && flow == request.flow; + } else { + return false; + } + } + +} diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java index 1be851ba17..3293e9db99 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/Slimefun.java @@ -1,35 +1,5 @@ package io.github.thebusybiscuit.slimefun4.implementation; -import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -import io.github.thebusybiscuit.slimefun4.storage.Storage; -import io.github.thebusybiscuit.slimefun4.storage.backend.legacy.LegacyStorage; - -import org.apache.commons.lang.Validate; -import org.bukkit.Bukkit; -import org.bukkit.Server; -import org.bukkit.World; -import org.bukkit.command.Command; -import org.bukkit.entity.Player; -import org.bukkit.event.Listener; -import org.bukkit.inventory.Recipe; -import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; -import org.bukkit.plugin.java.JavaPlugin; -import org.bukkit.scheduler.BukkitTask; - import io.github.bakedlibs.dough.config.Config; import io.github.bakedlibs.dough.protection.ProtectionManager; import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion; @@ -127,12 +97,41 @@ import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SlimefunArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.tasks.armor.SolarHelmetTask; import io.github.thebusybiscuit.slimefun4.integrations.IntegrationsManager; +import io.github.thebusybiscuit.slimefun4.storage.Storage; +import io.github.thebusybiscuit.slimefun4.storage.backend.legacy.LegacyStorage; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; import io.github.thebusybiscuit.slimefun4.utils.tags.SlimefunTag; import io.papermc.lib.PaperLib; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.MenuListener; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; +import org.apache.commons.lang.Validate; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.World; +import org.bukkit.command.Command; +import org.bukkit.entity.Player; +import org.bukkit.event.Listener; +import org.bukkit.inventory.Recipe; +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 javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Collectors; /** * This is the main class of Slimefun. @@ -215,6 +214,22 @@ public class Slimefun extends JavaPlugin implements SlimefunAddon { */ public Slimefun() { super(); + } + + /** + * This constructor is invoked in Unit Test environments only. + * + * @param loader Our {@link JavaPluginLoader} + * @param description A {@link PluginDescriptionFile} + * @param dataFolder The data folder + * @param file A {@link File} for this {@link Plugin} + */ + @ParametersAreNonnullByDefault + public Slimefun(JavaPluginLoader loader, PluginDescriptionFile description, File dataFolder, File file) { + super(loader, description, dataFolder, file); + + // This is only invoked during a Unit Test + minecraftVersion = MinecraftVersion.UNIT_TEST; // Check that we got loaded by MockBukkit rather than Bukkit's loader // TODO: This is very much a hack and we can hopefully move to a more native way in the future @@ -473,9 +488,8 @@ public void onDisable() { * Having this as a seperate method ensures the seperation between static and non-static fields. * It also makes sonarcloud happy :) * Only ever use it during {@link #onEnable()} or {@link #onDisable()}. - * - * @param pluginInstance - * Our instance of {@link Slimefun} or null + * + * @param pluginInstance Our instance of {@link Slimefun} or null */ private static void setInstance(@Nullable Slimefun pluginInstance) { instance = pluginInstance; @@ -483,10 +497,9 @@ private static void setInstance(@Nullable Slimefun pluginInstance) { /** * This returns the time it took to load Slimefun (given a starting point). - * - * @param timestamp - * The time at which we started to load Slimefun. - * + * + * @param timestamp The time at which we started to load Slimefun. + * * @return The total time it took to load Slimefun (in ms or s) */ private @Nonnull String getStartupTime(long timestamp) { @@ -502,7 +515,7 @@ private static void setInstance(@Nullable Slimefun pluginInstance) { /** * This method checks if this is currently running in a unit test * environment. - * + * * @return Whether we are inside a unit test */ public boolean isUnitTest() { @@ -563,11 +576,11 @@ private boolean isVersionUnsupported() { * that Slimefun is compatible with (as a {@link String} representation). *

* Example: - * + * *

      * { 1.14.x, 1.15.x, 1.16.x }
      * 
- * + * * @return A {@link Collection} of all compatible minecraft versions as strings */ static @Nonnull Collection getSupportedVersions() { @@ -737,7 +750,7 @@ private static void validateInstance() { * This returns the {@link Logger} instance that Slimefun uses. *

* Any {@link SlimefunAddon} should use their own {@link Logger} instance! - * + * * @return Our {@link Logger} instance */ public static @Nonnull Logger logger() { @@ -774,7 +787,7 @@ private static void validateInstance() { * This returns our {@link GPSNetwork} instance. * The {@link GPSNetwork} is responsible for handling any GPS-related * operations and for managing any {@link GEOResource}. - * + * * @return Our {@link GPSNetwork} instance */ public static @Nonnull GPSNetwork getGPSNetwork() { @@ -801,7 +814,7 @@ private static void validateInstance() { * This method returns out {@link MinecraftRecipeService} for Slimefun. * This service is responsible for finding/identifying {@link Recipe Recipes} * from vanilla Minecraft. - * + * * @return Slimefun's {@link MinecraftRecipeService} instance */ public static @Nonnull MinecraftRecipeService getMinecraftRecipeService() { @@ -834,7 +847,7 @@ private static void validateInstance() { * That service is responsible for managing item settings per * {@link World}, such as disabling a {@link SlimefunItem} in a * specific {@link World}. - * + * * @return Our instance of {@link PerWorldSettingsService} */ public static @Nonnull PerWorldSettingsService getWorldSettingsService() { @@ -845,7 +858,7 @@ private static void validateInstance() { /** * This returns our {@link HologramsService} which handles the creation and * cleanup of any holograms. - * + * * @return Our instance of {@link HologramsService} */ public static @Nonnull HologramsService getHologramsService() { @@ -867,7 +880,7 @@ public static SoundService getSoundService() { /** * This returns our instance of {@link IntegrationsManager}. * This is responsible for managing any integrations with third party {@link Plugin plugins}. - * + * * @return Our instance of {@link IntegrationsManager} */ public static @Nonnull IntegrationsManager getIntegrations() { @@ -878,7 +891,7 @@ public static SoundService getSoundService() { /** * This returns out instance of the {@link ProtectionManager}. * This bridge is used to hook into any third-party protection {@link Plugin}. - * + * * @return Our instanceof of the {@link ProtectionManager} */ public static @Nonnull ProtectionManager getProtectionManager() { @@ -932,7 +945,7 @@ public static SoundService getSoundService() { /** * This returns our {@link NetworkManager} which is responsible * for handling the Cargo and Energy networks. - * + * * @return Our {@link NetworkManager} instance */ @@ -1026,15 +1039,13 @@ public static boolean isNewlyInstalled() { /** * 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 - * + * + * @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 */ public static @Nullable BukkitTask runSync(@Nonnull Runnable runnable, long delay) { @@ -1057,13 +1068,12 @@ public static boolean isNewlyInstalled() { /** * 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 - * + * + * @param runnable The {@link Runnable} to run + * * @return The resulting {@link BukkitTask} or null if Slimefun was disabled */ public static @Nullable BukkitTask runSync(@Nonnull Runnable runnable) { 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 471551575b..8db9826bc7 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 @@ -25,7 +25,6 @@ import org.bukkit.entity.Player; import org.bukkit.event.block.BlockBreakEvent; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.ItemMeta; @@ -55,8 +54,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineFuel; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; @@ -847,18 +844,7 @@ private void constructMenu(@Nonnull BlockMenuPreset preset) { preset.drawBackground(ChestMenuUtils.getOutputSlotTexture(), OUTPUT_BORDER); for (int i : getOutputSlots()) { - preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() { - - @Override - public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { - return false; - } - - @Override - public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { - return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; - } - }); + preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler()); } preset.addItem(34, getFuelSource().getItem(), ChestMenuUtils.getEmptyClickHandler()); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java index d3197270bf..9101f02ffd 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/cargo/AbstractFilterNode.java @@ -1,13 +1,20 @@ package io.github.thebusybiscuit.slimefun4.implementation.items.cargo; +import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import javax.annotation.Nonnull; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; +import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; +import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; +import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.items.CustomItemStack; @@ -37,11 +44,13 @@ abstract class AbstractFilterNode extends AbstractCargoNode { protected static final int[] SLOTS = { 19, 20, 21, 28, 29, 30, 37, 38, 39 }; private static final String FILTER_TYPE = "filter-type"; private static final String FILTER_LORE = "filter-lore"; + private final boolean allowCustomItems; @ParametersAreNonnullByDefault protected AbstractFilterNode(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe, @Nullable ItemStack recipeOutput) { super(itemGroup, item, recipeType, recipe, recipeOutput); + allowCustomItems = Slimefun.getCfg().getBoolean("options.allow-custom-items-in-cargo-filters"); addItemHandler(onBreak()); } @@ -125,6 +134,31 @@ protected void updateBlockMenu(BlockMenu menu, Block b) { }); } + if (!allowCustomItems) { + for (int filterSlot : SLOTS) { + menu.addMenuClickHandler(filterSlot, new AdvancedMenuClickHandler() { + @Override + public boolean onClick(Player p, int slot, ItemStack item, ClickAction action) { + return false; + } + + @Override + public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { + if (cursor != null) { + SlimefunItem sfItem = SlimefunItem.getByItem(cursor); + if (sfItem == null && !(SlimefunUtils.isItemSimilar(cursor, + new ItemStack(cursor.getType()), true, false)) + ) { + Slimefun.getLocalization().sendMessage(p, "machines.CARGO_NODES.no-custom-items", true); + return false; + } + } + return true; + } + }); + } + } + addChannelSelector(b, menu, 41, 42, 43); markDirty(loc); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java index 24e0e0c33e..2218339998 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/ElectricSmeltery.java @@ -11,7 +11,6 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.items.CustomItemStack; @@ -25,8 +24,6 @@ import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.DirtyChestMenu; @@ -126,18 +123,7 @@ protected void constructMenu(BlockMenuPreset preset) { preset.addItem(22, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); for (int i : getOutputSlots()) { - preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() { - - @Override - public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { - return false; - } - - @Override - public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { - return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; - } - }); + preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java index d5607d1736..13b66afc08 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/FluidPump.java @@ -14,8 +14,6 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.BlockData; import org.bukkit.block.data.Levelled; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.blocks.Vein; @@ -33,8 +31,6 @@ import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -101,18 +97,7 @@ private void constructMenu(@Nonnull BlockMenuPreset preset) { } for (int i : getOutputSlots()) { - preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() { - - @Override - public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { - return false; - } - - @Override - public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { - return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; - } - }); + preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler()); } } @@ -158,7 +143,7 @@ protected void tick(@Nonnull Block b) { removeCharge(b.getLocation(), ENERGY_CONSUMPTION); menu.consumeItem(slot); menu.pushItem(bucket, getOutputSlots()); - nextFluid.setType(Material.AIR); + // nextFluid.setType(Material.AIR); } return; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/Freezer.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/Freezer.java index c2ad401d80..cd39441c9f 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/Freezer.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/Freezer.java @@ -3,13 +3,10 @@ import java.util.ArrayList; import java.util.List; -import javax.annotation.ParametersAreNonnullByDefault; - import org.bukkit.Material; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.items.ItemGroup; -import io.github.thebusybiscuit.slimefun4.api.items.ItemSetting; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItemStack; import io.github.thebusybiscuit.slimefun4.api.recipes.RecipeType; import io.github.thebusybiscuit.slimefun4.core.attributes.RecipeDisplayItem; @@ -18,36 +15,18 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.MachineRecipe; -/** - * The {@link Freezer} can freeze items into its frozen state, e.g. water to ice. - * - * @author TheBusyBiscuit - * @author svr333 - * @author J3fftw1 - */ public class Freezer extends AContainer implements RecipeDisplayItem { - private final ItemSetting useVanillaRatios = new ItemSetting<>(this, "use-vanilla-ratios", false); - - @ParametersAreNonnullByDefault public Freezer(ItemGroup itemGroup, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) { super(itemGroup, item, recipeType, recipe); - addItemSetting(useVanillaRatios); } @Override protected void registerDefaultRecipes() { - // This if statement makes the transformation follow Minecraft logic - if (useVanillaRatios.getValue()) { - registerRecipe(4, new ItemStack[] { new ItemStack(Material.ICE, 9) }, new ItemStack[] { new ItemStack(Material.PACKED_ICE) }); - registerRecipe(6, new ItemStack[] { new ItemStack(Material.PACKED_ICE, 9) }, new ItemStack[] { new ItemStack(Material.BLUE_ICE) }); - } else { - registerRecipe(4, new ItemStack[] { new ItemStack(Material.ICE) }, new ItemStack[] { new ItemStack(Material.PACKED_ICE) }); - registerRecipe(6, new ItemStack[] { new ItemStack(Material.PACKED_ICE) }, new ItemStack[] { new ItemStack(Material.BLUE_ICE) }); - } - registerRecipe(2, new ItemStack[] { new ItemStack(Material.WATER_BUCKET) }, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.ICE) }); registerRecipe(8, new ItemStack[] { new ItemStack(Material.LAVA_BUCKET) }, new ItemStack[] { new ItemStack(Material.BUCKET), new ItemStack(Material.OBSIDIAN) }); + registerRecipe(4, new ItemStack[] { new ItemStack(Material.ICE) }, new ItemStack[] { new ItemStack(Material.PACKED_ICE) }); + registerRecipe(6, new ItemStack[] { new ItemStack(Material.PACKED_ICE) }, new ItemStack[] { new ItemStack(Material.BLUE_ICE) }); registerRecipe(8, new ItemStack[] { new ItemStack(Material.BLUE_ICE) }, new ItemStack[] { SlimefunItems.REACTOR_COOLANT_CELL }); registerRecipe(6, new ItemStack[] { new ItemStack(Material.SNOW_BLOCK, 2) }, new ItemStack[] { new ItemStack(Material.ICE) }); registerRecipe(6, new ItemStack[] { new ItemStack(Material.MAGMA_CREAM) }, new ItemStack[] { new ItemStack(Material.SLIME_BALL) }); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/WitherAssembler.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/WitherAssembler.java index cc2c336672..c77dc06de9 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/WitherAssembler.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/electric/machines/entities/WitherAssembler.java @@ -2,6 +2,7 @@ import javax.annotation.ParametersAreNonnullByDefault; +import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.entity.Wither; @@ -14,6 +15,8 @@ import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.metadata.MetadataValue; /** * The {@link WitherAssembler} is an electrical machine that can automatically spawn @@ -70,7 +73,14 @@ protected void constructMenu(BlockMenuPreset preset) { @Override public Wither spawnEntity(Location l) { - return l.getWorld().spawn(l, Wither.class); + Wither w; + w = l.getWorld().spawn(l, Wither.class); + w.setAI(false); + if (Slimefun.instance() != null) { + // System.out.println("Wither assembled spawning wither, setting metadata"); + w.setMetadata("wither-assembler", new FixedMetadataValue(Slimefun.instance(), true)); + } + return w; } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java index be9245e51a..8012a00056 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/elevator/ElevatorFloor.java @@ -14,7 +14,7 @@ * @author TheBusyBiscuit * */ -class ElevatorFloor { +public class ElevatorFloor { /** * The name of this floor. diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java index cc09eb0ac6..d21815533b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/items/geo/GEOMiner.java @@ -11,9 +11,7 @@ import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.entity.Player; import org.bukkit.event.block.BlockPlaceEvent; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.items.CustomItemStack; @@ -38,8 +36,6 @@ import io.github.thebusybiscuit.slimefun4.utils.ChestMenuUtils; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -265,18 +261,7 @@ protected void constructMenu(@Nonnull BlockMenuPreset preset) { preset.addItem(4, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); for (int i : OUTPUT_SLOTS) { - preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() { - - @Override - public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { - return false; - } - - @Override - public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { - return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; - } - }); + preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler()); } } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java index a0d1e59a6b..40b976e345 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/BlockListener.java @@ -71,18 +71,18 @@ public void onBlockPlaceExisting(BlockPlaceEvent e) { Block block = e.getBlock(); // Fixes #2636 - This will solve the "ghost blocks" issue - if (e.getBlockReplacedState().getType().isAir()) { + if (e.getBlockReplacedState().getType().isAir() && BlockStorage.hasBlockInfo(block) && !Slimefun.getTickerTask().isDeletedSoon(block.getLocation())) { SlimefunItem sfItem = BlockStorage.check(block); - if (sfItem != null && !Slimefun.getTickerTask().isDeletedSoon(block.getLocation())) { + if (sfItem != null) { for (ItemStack item : sfItem.getDrops()) { if (item != null && !item.getType().isAir()) { block.getWorld().dropItemNaturally(block.getLocation(), item); } } - - BlockStorage.clearBlockInfo(block); } + + BlockStorage.clearBlockInfo(block); } else if (BlockStorage.hasBlockInfo(e.getBlock())) { // If there is no air (e.g. grass) then don't let the block be placed e.setCancelled(true); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CargoNodeListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CargoNodeListener.java index 0cb86a6d9b..7b2ff99dba 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CargoNodeListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/CargoNodeListener.java @@ -1,11 +1,15 @@ package io.github.thebusybiscuit.slimefun4.implementation.listeners; +import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils; import javax.annotation.Nonnull; import org.bukkit.block.Block; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryMoveItemEvent; import org.bukkit.inventory.ItemStack; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; @@ -35,6 +39,32 @@ public void onCargoNodePlace(BlockPlaceEvent e) { } } + @EventHandler(ignoreCancelled = true) + public void onFilterMove(InventoryClickEvent e) { + String invName = e.getWhoClicked().getOpenInventory().getTitle(); + if ((invName.equals("Cargo Node (Input)") || invName.equals("Advanced Cargo Node (Output)"))) { + if (Slimefun.getCfg().getBoolean("options.allow-custom-items-in-cargo-filters")) { + return; + } + + if (e.getClick() == ClickType.NUMBER_KEY) { + e.setCancelled(true); + return; + } + + ItemStack item = e.getCurrentItem(); + if (item == null) { + return; + } + + SlimefunItem sfItem = SlimefunItem.getByItem(item); + if (sfItem == null && !SlimefunUtils.isItemSimilar(item, new ItemStack(item.getType()), true, false)) { + Slimefun.getLocalization().sendMessage(e.getWhoClicked(), "machines.CARGO_NODES.no-custom-items", true); + e.setCancelled(true); + } + } + } + private boolean isCargoNode(@Nonnull ItemStack item) { return SlimefunItem.getByItem(item) instanceof CargoNode; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/MobDropListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/MobDropListener.java index 7d69ffc900..965c96eeb6 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/MobDropListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/entity/MobDropListener.java @@ -6,6 +6,7 @@ import javax.annotation.Nonnull; import org.bukkit.Material; +import org.bukkit.entity.EntityType; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -59,6 +60,13 @@ public void onEntityKill(EntityDeathEvent e) { } } } + + if (e.getEntityType().equals(EntityType.WITHER)) { + if (e.getEntity().hasMetadata("wither-assembler")) { + // System.out.println("Wither assembled wither found, removing drops."); + e.getDrops().clear(); + } + } } private boolean canDrop(@Nonnull Player p, @Nonnull ItemStack item) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java index 6899bdf0d1..85e4c4bfe8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/armor/RadiationTask.java @@ -1,6 +1,7 @@ package io.github.thebusybiscuit.slimefun4.implementation.tasks.armor; import io.github.bakedlibs.dough.common.ChatColors; +import io.github.thebusybiscuit.slimefun4.api.events.RadiationDamageEvent; import io.github.thebusybiscuit.slimefun4.api.items.SlimefunItem; import io.github.thebusybiscuit.slimefun4.api.player.PlayerProfile; import io.github.thebusybiscuit.slimefun4.core.attributes.ProtectionType; @@ -12,6 +13,8 @@ import net.md_5.bungee.api.ChatMessageType; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.api.chat.ComponentBuilder; + +import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; @@ -71,6 +74,13 @@ protected void onPlayerTick(Player p, PlayerProfile profile) { int exposureLevelAfter = RadiationUtils.getExposure(p); Slimefun.runSync(() -> { + RadiationDamageEvent event = new RadiationDamageEvent(p, exposureLevelAfter); + Bukkit.getPluginManager().callEvent(event); + + if (event.isCancelled()) { + return; + } + for (RadiationSymptom symptom : symptoms) { if (symptom.shouldApply(exposureLevelAfter)) { symptom.apply(p); 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 3df992835b..928233eb5d 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java @@ -5,9 +5,11 @@ import javax.annotation.Nonnull; +import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; @@ -43,6 +45,19 @@ private ChestMenuUtils() {} private static final ItemStack PREV_BUTTON_INACTIVE = new SlimefunItemStack("_UI_PREVIOUS_INACTIVE", Material.BLACK_STAINED_GLASS_PANE, "&8\u21E6 Previous Page"); private static final ItemStack NEXT_BUTTON_INACTIVE = new SlimefunItemStack("_UI_NEXT_INACTIVE", Material.BLACK_STAINED_GLASS_PANE, "&8Next Page \u21E8"); + private static final ChestMenu.AdvancedMenuClickHandler OUTPUT_HANDLER = new ChestMenu.AdvancedMenuClickHandler() { + + @Override + public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { + return false; + } + + @Override + public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { + return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; + } + }; + private static final MenuClickHandler CLICK_HANDLER = (p, s, i, a) -> false; public static @Nonnull ItemStack getBackground() { @@ -69,6 +84,10 @@ private ChestMenuUtils() {} return CLICK_HANDLER; } + public static @Nonnull ChestMenu.AdvancedMenuClickHandler getDefaultOutputHandler() { + return OUTPUT_HANDLER; + } + public static @Nonnull ItemStack getBackButton(@Nonnull Player p, String... lore) { return new CustomItemStack(BACK_BUTTON, "&7\u21E6 " + Slimefun.getLocalization().getMessage(p, "guide.back.title"), lore); } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java index 0b85e6e68d..1b1bf24fc8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/NumberUtils.java @@ -224,7 +224,7 @@ public static int getInt(@Nonnull String str, int defaultValue) { } public static double reparseDouble(double number) { - return Double.valueOf(roundDecimalNumber(number)); + return Double.parseDouble(roundDecimalNumber(number)); } public static long getLong(@Nullable Long value, long defaultValue) { 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 b2fd0ac052..9bc8a128f7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/SlimefunUtils.java @@ -1,32 +1,5 @@ package io.github.thebusybiscuit.slimefun4.utils; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; -import java.util.Optional; -import java.util.OptionalInt; - -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -import org.apache.commons.lang.Validate; -import org.bukkit.ChatColor; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.NamespacedKey; -import org.bukkit.World; -import org.bukkit.entity.Item; -import org.bukkit.entity.Player; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.bukkit.inventory.meta.PotionMeta; -import org.bukkit.metadata.FixedMetadataValue; -import org.bukkit.persistence.PersistentDataContainer; -import org.bukkit.persistence.PersistentDataType; - import io.github.bakedlibs.dough.common.CommonPatterns; import io.github.bakedlibs.dough.items.ItemMetaSnapshot; import io.github.bakedlibs.dough.skins.PlayerHead; @@ -47,6 +20,31 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.altar.AncientPedestal; import io.github.thebusybiscuit.slimefun4.implementation.tasks.CapacitorTextureUpdateTask; import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; +import org.apache.commons.lang.Validate; +import org.bukkit.ChatColor; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.NamespacedKey; +import org.bukkit.World; +import org.bukkit.entity.Item; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.PotionMeta; +import org.bukkit.metadata.FixedMetadataValue; +import org.bukkit.persistence.PersistentDataContainer; +import org.bukkit.persistence.PersistentDataType; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.Optional; +import java.util.OptionalInt; /** * This utility class holds method that are directly linked to Slimefun. @@ -62,14 +60,15 @@ public final class SlimefunUtils { private static final String NO_PICKUP_METADATA = "no_pickup"; private static final String SOULBOUND_LORE = ChatColor.GRAY + "Soulbound"; - private SlimefunUtils() {} + private SlimefunUtils() { + } /** * This method quickly returns whether an {@link Item} was marked as "no_pickup" by * a Slimefun device. * - * @param item - * The {@link Item} to query + * @param item The {@link Item} to query + * * @return Whether the {@link Item} is excluded from being picked up */ public static boolean hasNoPickupFlag(@Nonnull Item item) { @@ -80,10 +79,8 @@ public static boolean hasNoPickupFlag(@Nonnull Item item) { * This will prevent the given {@link Item} from being picked up. * This is useful for display items which the {@link AncientPedestal} uses. * - * @param item - * The {@link Item} to prevent from being picked up - * @param context - * The context in which this {@link Item} was flagged + * @param item The {@link Item} to prevent from being picked up + * @param context The context in which this {@link Item} was flagged */ public static void markAsNoPickup(@Nonnull Item item, @Nonnull String context) { item.setMetadata(NO_PICKUP_METADATA, new FixedMetadataValue(Slimefun.instance(), context)); @@ -98,8 +95,8 @@ public static void markAsNoPickup(@Nonnull Item item, @Nonnull String context) { /** * This method checks whether the given {@link ItemStack} is considered {@link Soulbound}. * - * @param item - * The {@link ItemStack} to check for + * @param item The {@link ItemStack} to check for + * * @return Whether the given item is soulbound */ public static boolean isSoulbound(@Nullable ItemStack item) { @@ -113,11 +110,10 @@ public static boolean isSoulbound(@Nullable ItemStack item) { * If the provided item is {@link Soulbound} through the {@link SlimefunItems#SOULBOUND_RUNE}, then this * method will also check that the {@link SlimefunItems#SOULBOUND_RUNE} is enabled in the provided {@link World} * - * @param item - * The {@link ItemStack} to check for - * @param world - * The {@link World} to check if the {@link SlimefunItem} is enabled in if applicable. - * If {@code null} then this will not do a world check. + * @param item The {@link ItemStack} to check for + * @param world The {@link World} to check if the {@link SlimefunItem} is enabled in if applicable. + * If {@code null} then this will not do a world check. + * * @return Whether the given item is soulbound */ public static boolean isSoulbound(@Nullable ItemStack item, @Nullable World world) { @@ -163,10 +159,8 @@ private static boolean hasSoulboundFlag(@Nullable ItemMeta meta) { * by {@link #isSoulbound(ItemStack)}.
* If false is passed, this property will be removed. * - * @param item - * The {@link ItemStack} you want to add/remove Soulbound from. - * @param makeSoulbound - * If the item should be soulbound. + * @param item The {@link ItemStack} you want to add/remove Soulbound from. + * @param makeSoulbound If the item should be soulbound. * * @see #isSoulbound(ItemStack) */ @@ -206,8 +200,7 @@ public static void setSoulbound(@Nullable ItemStack item, boolean makeSoulbound) /** * This method checks whether the given {@link ItemStack} is radioactive. * - * @param item - * The {@link ItemStack} to check + * @param item The {@link ItemStack} to check * * @return Whether this {@link ItemStack} is radioactive or not */ @@ -219,8 +212,7 @@ public static boolean isRadioactive(@Nullable ItemStack item) { * This method returns an {@link ItemStack} for the given texture. * The result will be a Player Head with this texture. * - * @param texture - * The texture for this head (base64 or hash) + * @param texture The texture for this head (base64 or hash) * * @return An {@link ItemStack} with this Head texture */ @@ -275,16 +267,14 @@ public static boolean containsSimilarItem(Inventory inventory, ItemStack item, b * for performance. * Will check for distintion of items by default and will also confirm the amount * is the same. - * @see DistinctiveItem * - * @param item - * The {@link ItemStack} being tested. - * @param sfitem - * The {@link ItemStack} that {@param item} is being compared against. - * @param checkLore - * Whether to include the current lore of either item in the comparison + * @param item The {@link ItemStack} being tested. + * @param sfitem The {@link ItemStack} that {@param item} is being compared against. + * @param checkLore Whether to include the current lore of either item in the comparison * * @return True if the given {@link ItemStack}s are similar under the given constraints + * + * @see DistinctiveItem */ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStack sfitem, boolean checkLore) { return isItemSimilar(item, sfitem, checkLore, true, true); @@ -295,18 +285,15 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac * Takes into account some shortcut checks specific to {@link SlimefunItem}s * for performance. * Will check for distintion of items by default - * @see DistinctiveItem * - * @param item - * The {@link ItemStack} being tested. - * @param sfitem - * The {@link ItemStack} that {@param item} is being compared against. - * @param checkLore - * Whether to include the current lore of either item in the comparison - * @param checkAmount - * Whether to include the item's amount(s) in the comparison + * @param item The {@link ItemStack} being tested. + * @param sfitem The {@link ItemStack} that {@param item} is being compared against. + * @param checkLore Whether to include the current lore of either item in the comparison + * @param checkAmount Whether to include the item's amount(s) in the comparison * * @return True if the given {@link ItemStack}s are similar under the given constraints + * + * @see DistinctiveItem */ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStack sfitem, boolean checkLore, boolean checkAmount) { return isItemSimilar(item, sfitem, checkLore, checkAmount, true); @@ -317,19 +304,15 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac * Takes into account some shortcut checks specific to {@link SlimefunItem}s * for performance. * - * @param item - * The {@link ItemStack} being tested. - * @param sfitem - * The {@link ItemStack} that {@param item} is being compared against. - * @param checkLore - * Whether to include the current lore of either item in the comparison - * @param checkAmount - * Whether to include the item's amount(s) in the comparison - * @param checkDistinction - * Whether to check for special distinctive properties of the items. - * @see DistinctiveItem + * @param item The {@link ItemStack} being tested. + * @param sfitem The {@link ItemStack} that {@param item} is being compared against. + * @param checkLore Whether to include the current lore of either item in the comparison + * @param checkAmount Whether to include the item's amount(s) in the comparison + * @param checkDistinction Whether to check for special distinctive properties of the items. * * @return True if the given {@link ItemStack}s are similar under the given constraints + * + * @see DistinctiveItem */ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStack sfitem, boolean checkLore, boolean checkAmount, boolean checkDistinction) { if (item == null) { @@ -345,7 +328,10 @@ public static boolean isItemSimilar(@Nullable ItemStack item, @Nullable ItemStac /* * PR #3417 * - * Some items can't rely on just IDs matching and will implement {@link DistinctiveItem} + * Some items can't rely on just IDs matching and will implement Distinctive Item + * in which case we want to use the method provided to compare + * + * Some items can 't rely on just IDs matching and will implement {@link DistinctiveItem} * in which case we want to use the method provided to compare */ if (checkDistinction && stackOne instanceof DistinctiveItem distinctive && stackTwo instanceof DistinctiveItem) { @@ -509,10 +495,8 @@ private static boolean equalsItemMeta(@Nonnull ItemMeta itemMeta, @Nonnull ItemM * This checks if the two provided lores are equal. * This method will ignore any lines such as the soulbound one. * - * @param lore1 - * The first lore - * @param lore2 - * The second lore + * @param lore1 The first lore + * @param lore2 The second lore * * @return Whether the two lores are equal */ @@ -568,12 +552,9 @@ public static void updateCapacitorTexture(@Nonnull Location l, int charge, int c *

* If you already have an instance of {@link SlimefunItem}, please use {@link SlimefunItem#canUse(Player, boolean)}. * - * @param p - * The {@link Player} - * @param item - * The {@link ItemStack} to check - * @param sendMessage - * Whether to send a message response to the {@link Player} + * @param p The {@link Player} + * @param item The {@link ItemStack} to check + * @param sendMessage Whether to send a message response to the {@link Player} * * @return Whether the {@link Player} is able to use that item. */ @@ -594,16 +575,11 @@ public static boolean canPlayerUseItem(@Nonnull Player p, @Nullable ItemStack it * This method automatically calls a {@link SlimefunItemSpawnEvent} to allow * other plugins to catch the item being dropped. * - * @param loc - * The {@link Location} where to drop the item - * @param item - * The {@link ItemStack} to drop - * @param reason - * The {@link ItemSpawnReason} why the item is being dropped - * @param addRandomOffset - * Whether a random offset should be added (see {@link World#dropItemNaturally(Location, ItemStack)}) - * @param player - * The player that caused this {@link SlimefunItemSpawnEvent} + * @param loc The {@link Location} where to drop the item + * @param item The {@link ItemStack} to drop + * @param reason The {@link ItemSpawnReason} why the item is being dropped + * @param addRandomOffset Whether a random offset should be added (see {@link World#dropItemNaturally(Location, ItemStack)}) + * @param player The player that caused this {@link SlimefunItemSpawnEvent} * * @return The dropped {@link Item} (or null if the {@link SlimefunItemSpawnEvent} was cancelled) */ @@ -630,14 +606,10 @@ public static boolean canPlayerUseItem(@Nonnull Player p, @Nullable ItemStack it * This method automatically calls a {@link SlimefunItemSpawnEvent} to allow * other plugins to catch the item being dropped. * - * @param loc - * The {@link Location} where to drop the item - * @param item - * The {@link ItemStack} to drop - * @param reason - * The {@link ItemSpawnReason} why the item is being dropped - * @param addRandomOffset - * Whether a random offset should be added (see {@link World#dropItemNaturally(Location, ItemStack)}) + * @param loc The {@link Location} where to drop the item + * @param item The {@link ItemStack} to drop + * @param reason The {@link ItemSpawnReason} why the item is being dropped + * @param addRandomOffset Whether a random offset should be added (see {@link World#dropItemNaturally(Location, ItemStack)}) * * @return The dropped {@link Item} (or null if the {@link SlimefunItemSpawnEvent} was cancelled) */ @@ -651,12 +623,9 @@ public static boolean canPlayerUseItem(@Nonnull Player p, @Nullable ItemStack it * This method automatically calls a {@link SlimefunItemSpawnEvent} to allow * other plugins to catch the item being dropped. * - * @param loc - * The {@link Location} where to drop the item - * @param item - * The {@link ItemStack} to drop - * @param reason - * The {@link ItemSpawnReason} why the item is being dropped + * @param loc The {@link Location} where to drop the item + * @param item The {@link ItemStack} to drop + * @param reason The {@link ItemSpawnReason} why the item is being dropped * * @return The dropped {@link Item} (or null if the {@link SlimefunItemSpawnEvent} was cancelled) */ @@ -670,8 +639,7 @@ public static boolean canPlayerUseItem(@Nonnull Player p, @Nullable ItemStack it * If the MC version is 1.16 or above * this will call {@link Inventory#isEmpty()} (Which calls MC code resulting in a faster method). * - * @param inventory - * The {@link Inventory} to check. + * @param inventory The {@link Inventory} to check. * * @return True if the inventory is empty and false otherwise */ diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java index 872972c687..e257f40647 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMap.java @@ -1,5 +1,17 @@ package io.github.thebusybiscuit.slimefun4.utils.biomes; +import com.google.gson.JsonElement; +import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; +import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; +import org.apache.commons.lang.Validate; +import org.bukkit.Keyed; +import org.bukkit.NamespacedKey; +import org.bukkit.block.Biome; +import org.bukkit.plugin.java.JavaPlugin; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import javax.annotation.ParametersAreNonnullByDefault; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; @@ -8,21 +20,6 @@ import java.util.Map; import java.util.stream.Collectors; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import javax.annotation.ParametersAreNonnullByDefault; - -import org.apache.commons.lang.Validate; -import org.bukkit.Keyed; -import org.bukkit.NamespacedKey; -import org.bukkit.block.Biome; - -import com.google.gson.JsonElement; - -import io.github.thebusybiscuit.slimefun4.api.exceptions.BiomeMapException; -import io.github.thebusybiscuit.slimefun4.api.geo.GEOResource; -import org.bukkit.plugin.java.JavaPlugin; - /** * {@link BiomeMap}s are used to map data values to {@link Biome} constants. *

@@ -34,11 +31,10 @@ * The most common type is {@link Integer}, if you are using complex objects and try to read * your {@link BiomeMap} from a {@link JsonElement}, make sure to provide an adequate * {@link BiomeDataConverter} to convert the raw json data. - * - * @author TheBusyBiscuit * - * @param - * The stored data type + * @param The stored data type + * + * @author TheBusyBiscuit */ public class BiomeMap implements Keyed { @@ -54,9 +50,8 @@ public class BiomeMap implements Keyed { /** * This constructs a new {@link BiomeMap} with the given {@link NamespacedKey}. - * - * @param namespacedKey - * The {@link NamespacedKey} for this {@link BiomeMap} + * + * @param namespacedKey The {@link NamespacedKey} for this {@link BiomeMap} */ @ParametersAreNonnullByDefault public BiomeMap(NamespacedKey namespacedKey) { @@ -92,7 +87,7 @@ public boolean containsValue(@Nonnull T value) { /** * This returns whether this {@link BiomeMap} is empty. * An empty {@link BiomeMap} contains no biomes or values. - * + * * @return Whether this {@link BiomeMap} is empty. */ public boolean isEmpty() { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java index 62d345acf8..56bf92979b 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/biomes/BiomeMapParser.java @@ -61,7 +61,7 @@ public class BiomeMapParser { * A function to convert {@link JsonElement}s into your desired data type */ @ParametersAreNonnullByDefault - public BiomeMapParser(NamespacedKey key, BiomeDataConverter valueConverter) { + BiomeMapParser(NamespacedKey key, BiomeDataConverter valueConverter) { Validate.notNull(key, "The key shall not be null."); Validate.notNull(valueConverter, "You must provide a Function to convert raw json values to your desired data type."); @@ -79,7 +79,7 @@ public BiomeMapParser(NamespacedKey key, BiomeDataConverter valueConverter) { * @param isLenient * Whether this parser should be lenient or not. */ - public void setLenient(boolean isLenient) { + void setLenient(boolean isLenient) { this.isLenient = isLenient; } @@ -92,13 +92,13 @@ public void setLenient(boolean isLenient) { * * @return Whether this parser is lenient or not. */ - public boolean isLenient() { + boolean isLenient() { return isLenient; } - public void read(@Nonnull String json) throws BiomeMapException { + void read(@Nonnull String json) throws BiomeMapException { Validate.notNull(json, "The JSON string should not be null!"); - JsonArray root = null; + JsonArray root; try { root = JsonUtils.parseString(json).getAsJsonArray(); @@ -113,14 +113,14 @@ public void read(@Nonnull String json) throws BiomeMapException { read(root); } - public void read(@Nonnull JsonArray json) throws BiomeMapException { + void read(@Nonnull JsonArray json) throws BiomeMapException { Validate.notNull(json, "The JSON Array should not be null!"); for (JsonElement element : json) { if (element instanceof JsonObject) { readEntry(element.getAsJsonObject()); } else { - throw new BiomeMapException(key, "Unexpected array element: " + element.getClass().getSimpleName() + " - " + element.toString()); + throw new BiomeMapException(key, "Unexpected array element: " + element.getClass().getSimpleName() + " - " + element); } } } @@ -184,7 +184,7 @@ private void readEntry(@Nonnull JsonObject entry) throws BiomeMapException { throw new BiomeMapException(key, "Could not recognize value '" + value + "'"); } } else { - throw new BiomeMapException(key, "Unexpected array element: " + element.getClass().getSimpleName() + " - " + element.toString()); + throw new BiomeMapException(key, "Unexpected array element: " + element.getClass().getSimpleName() + " - " + element); } } @@ -200,7 +200,7 @@ private void readEntry(@Nonnull JsonObject entry) throws BiomeMapException { * @return The resulting {@link BiomeMap} */ @Nonnull - public BiomeMap buildBiomeMap() { + BiomeMap buildBiomeMap() { BiomeMap biomeMap = new BiomeMap<>(key); biomeMap.putAll(map); return biomeMap; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java index 063d91f8d1..3aeb682333 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/itemstack/ColoredFireworkStar.java @@ -28,9 +28,7 @@ public class ColoredFireworkStar extends CustomItemStack { @ParametersAreNonnullByDefault public ColoredFireworkStar(Color color, String name, String... lore) { super(Material.FIREWORK_STAR, im -> { - if (name != null) { - im.setDisplayName(ChatColors.color(name)); - } + im.setDisplayName(ChatColors.color(name)); ((FireworkEffectMeta) im).setEffect(FireworkEffect.builder().with(Type.BURST).withColor(color).build()); 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 be71fbe598..cf68ec145d 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 @@ -12,8 +12,6 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.block.Block; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.Inventory; import org.bukkit.inventory.ItemStack; @@ -37,8 +35,6 @@ import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.interfaces.InventoryBlock; import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; import me.mrCookieSlime.Slimefun.api.BlockStorage; @@ -115,18 +111,7 @@ protected void constructMenu(BlockMenuPreset preset) { preset.addItem(22, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); for (int i : getOutputSlots()) { - preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() { - - @Override - public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { - return false; - } - - @Override - public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { - return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; - } - }); + preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler()); } } @@ -255,12 +240,11 @@ public void register(@Nonnull SlimefunAddon addon) { warn("Make sure to call '" + getClass().getSimpleName() + "#setProcessingSpeed(...)' before registering!"); } + registerDefaultRecipes(); + if (getCapacity() > 0 && getEnergyConsumption() > 0 && getSpeed() > 0) { super.register(addon); } - - // Fixes #3429 - Initialize Item Settings before recipes - registerDefaultRecipes(); } /** 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 0bc27e5d17..db5555f6c9 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 @@ -12,7 +12,6 @@ import org.bukkit.Material; import org.bukkit.block.Block; import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.inventory.ItemStack; import io.github.bakedlibs.dough.items.CustomItemStack; @@ -35,8 +34,6 @@ import io.github.thebusybiscuit.slimefun4.utils.itemstack.ItemStackWrapper; import me.mrCookieSlime.CSCoreLibPlugin.Configuration.Config; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.AdvancedMenuClickHandler; -import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ClickAction; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; @@ -122,18 +119,7 @@ private void constructMenu(BlockMenuPreset preset) { } for (int i : getOutputSlots()) { - preset.addMenuClickHandler(i, new AdvancedMenuClickHandler() { - - @Override - public boolean onClick(Player p, int slot, ItemStack cursor, ClickAction action) { - return false; - } - - @Override - public boolean onClick(InventoryClickEvent e, Player p, int slot, ItemStack cursor, ClickAction action) { - return cursor == null || cursor.getType() == null || cursor.getType() == Material.AIR; - } - }); + preset.addMenuClickHandler(i, ChestMenuUtils.getDefaultOutputHandler()); } preset.addItem(22, new CustomItemStack(Material.BLACK_STAINED_GLASS_PANE, " "), ChestMenuUtils.getEmptyClickHandler()); @@ -282,7 +268,7 @@ public void register(@Nonnull SlimefunAddon addon) { if (getCapacity() < 0) { warn("The capacity has not been configured correctly. The Item was disabled."); - warn("Make sure to call '" + getClass().getSimpleName() + "#setEnergyCapacity(...)' before registering!"); + warn("Make sure to call '" + getClass().getSimpleName() + "#setCapacity(...)' before registering!"); } if (getEnergyProduction() <= 0) { diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 5e36b700b7..598eb87870 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -16,6 +16,7 @@ options: legacy-ore-washer: false legacy-dust-washer: false legacy-ore-grinder: true + allow-custom-items-in-cargo-filters: true language: en enable-translations: true log-duplicate-block-entries: true diff --git a/src/main/resources/languages/en/messages.yml b/src/main/resources/languages/en/messages.yml index 81d5115c30..10bd742d3d 100644 --- a/src/main/resources/languages/en/messages.yml +++ b/src/main/resources/languages/en/messages.yml @@ -323,6 +323,7 @@ machines: CARGO_NODES: must-be-placed: '&4Must be placed onto a chest or machine!' + no-custom-items: '&cCustom Items are not allowed in filters!' connected: '&2Connected!' not-connected: '&4Not connected!' diff --git a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java index 0e9fe8e3f6..edc8ff7400 100644 --- a/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java +++ b/src/test/java/io/github/thebusybiscuit/slimefun4/utils/tags/TestSlimefunTags.java @@ -131,8 +131,8 @@ private void assertNotCyclic(@Nonnull SlimefunTag tag) { Set visited = new HashSet<>(); if (isCyclic(visiting, visited, tag)) { - System.out.println("Currently visiting: " + visiting); - System.out.println("Previously visited" + visiting); + // System.out.println("Currently visiting: " + visiting); + // System.out.println("Previously visited" + visiting); Assertions.fail("Tag '" + tag.getKey() + "' is cyclic!"); } }