diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java index 2e32e9be91..31cb89a4cb 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/controller/BlockDataController.java @@ -585,12 +585,12 @@ public void removeAllDataInWorldAsync(World world, Runnable onFinishedCallback) }); } - public UniversalChestMenu createUniversalInventory() { + public UniversalChestMenu createUniversalInventory(@Nonnull UUID uuid) { // TODO: Fill code return null; } - @Nullable public UniversalChestMenu getUniversalInventory(@Nonnull UUID universalID) { + @Nullable public UniversalChestMenu getUniversalInventory(@Nonnull UUID uuid) { // TODO: Fill code return null; } diff --git a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java index f5fc4a6e8f..1632bc8399 100644 --- a/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java +++ b/src/main/java/com/xzavier0722/mc/plugin/slimefun4/storage/util/StorageCacheUtils.java @@ -7,9 +7,11 @@ import io.github.thebusybiscuit.slimefun4.implementation.Slimefun; import java.util.HashSet; import java.util.Set; +import java.util.UUID; import javax.annotation.Nullable; import javax.annotation.ParametersAreNonnullByDefault; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; +import me.mrCookieSlime.Slimefun.api.inventory.UniversalChestMenu; import org.bukkit.Location; /** @@ -77,6 +79,11 @@ public static void removeData(Location loc, String key) { return blockData.getBlockMenu(); } + @ParametersAreNonnullByDefault + @Nullable public static UniversalChestMenu getUniversalMenu(UUID uuid) { + return Slimefun.getDatabaseManager().getBlockDataController().getUniversalInventory(uuid); + } + public static void requestLoad(SlimefunBlockData blockData) { if (blockData.isDataLoaded()) { return; 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 0e75b04434..53e3a135f4 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 @@ -45,6 +45,7 @@ import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; import me.mrCookieSlime.Slimefun.api.inventory.BlockMenuPreset; import me.mrCookieSlime.Slimefun.api.inventory.UniversalChestMenu; +import me.mrCookieSlime.Slimefun.api.inventory.UniversalMenuPreset; import me.mrCookieSlime.Slimefun.api.item_transport.ItemTransportFlow; import org.apache.commons.lang.Validate; import org.bukkit.Bukkit; @@ -101,7 +102,7 @@ public ProgrammableAndroid( texture = item.getSkullTexture().orElse(null); registerDefaultFuelTypes(); - new BlockMenuPreset(getId(), "可编程式机器人") { + new UniversalMenuPreset(getId(), "可编程式机器人") { @Override public void init() { @@ -188,7 +189,7 @@ public void onPlayerPlace(BlockPlaceEvent e) { Block b = e.getBlock(); UUID uuid = UUID.randomUUID(); - // FIXME: create universal inv + Slimefun.getDatabaseManager().getBlockDataController().createUniversalInventory(uuid); PDCUtil.setValue(b, PDCUtil.uuid, OWNER_KEY, p.getUniqueId()); PDCUtil.setValue(b, PDCUtil.uuid, UUID_KEY, uuid); @@ -218,18 +219,17 @@ private BlockBreakHandler onBreak() { @Override public void onPlayerBreak(BlockBreakEvent e, ItemStack item, List drops) { Block b = e.getBlock(); - var blockData = StorageCacheUtils.getBlock(b.getLocation()); - String owner = blockData.getData("owner"); + UUID owner = PDCUtil.getValue(b, PDCUtil.uuid, OWNER_KEY); + UUID uuid = PDCUtil.getValue(b, PDCUtil.uuid, UUID_KEY); if (!e.getPlayer().hasPermission("slimefun.android.bypass") - && !e.getPlayer().getUniqueId().toString().equals(owner)) { + && !e.getPlayer().getUniqueId().equals(owner)) { // The Player is not allowed to break this android e.setCancelled(true); return; } - // FIXME: use universal inv - BlockMenu inv = blockData.getBlockMenu(); + UniversalChestMenu inv = Slimefun.getDatabaseManager().getBlockDataController().getUniversalInventory(uuid); if (inv != null) { inv.dropItems(b.getLocation(), 43); @@ -289,6 +289,7 @@ public void openScript(Player p, Block b, String sourceCode) { ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + Slimefun.getLocalization().getMessage(p, "android.scripts.editor")); menu.setEmptySlotsClickable(false); + UUID uuid = PDCUtil.getValue(b, PDCUtil.uuid, UUID_KEY); menu.addItem( 0, @@ -298,7 +299,7 @@ public void openScript(Player p, Block b, String sourceCode) { "", "&7\u21E8 &e左键 &7返回机器人的控制面板")); menu.addMenuClickHandler(0, (pl, slot, item, action) -> { - BlockMenu inv = StorageCacheUtils.getMenu(b.getLocation()); + UniversalChestMenu inv = StorageCacheUtils.getUniversalMenu(uuid); // Fixes #2937 if (inv != null) { inv.open(pl); @@ -333,7 +334,7 @@ public void openScript(Player p, Block b, String sourceCode) { "", "&7\u21E8 &e左键 &7返回机器人的控制面板")); menu.addMenuClickHandler(slot, (pl, s, item, action) -> { - BlockMenu inv = StorageCacheUtils.getMenu(b.getLocation()); + UniversalChestMenu inv = StorageCacheUtils.getUniversalMenu(uuid); // Fixes #2937 if (inv != null) { inv.open(pl); @@ -579,6 +580,8 @@ public void openScriptEditor(Player p, Block b) { new ChestMenu(ChatColor.DARK_AQUA + Slimefun.getLocalization().getMessage(p, "android.scripts.editor")); menu.setEmptySlotsClickable(false); + UUID uuid = PDCUtil.getValue(b, PDCUtil.uuid, UUID_KEY); + menu.addItem(1, new CustomItemStack(HeadTexture.SCRIPT_FORWARD.getAsItemStack(), "&2> 编辑脚本", "", "&a修改你现有的脚本")); menu.addMenuClickHandler(1, (pl, slot, item, action) -> { String script = StorageCacheUtils.getData(b.getLocation(), "script"); @@ -620,7 +623,7 @@ public void openScriptEditor(Player p, Block b) { menu.addItem(8, new CustomItemStack(HeadTexture.SCRIPT_LEFT.getAsItemStack(), "&6> 返回", "", "&7返回机器人控制面板")); menu.addMenuClickHandler(8, (pl, slot, item, action) -> { - BlockMenu inv = StorageCacheUtils.getMenu(b.getLocation()); + UniversalChestMenu inv = StorageCacheUtils.getUniversalMenu(uuid); // Fixes #2937 if (inv != null) { inv.open(pl); @@ -995,7 +998,8 @@ public boolean onClick( public void addItems(Block b, ItemStack... items) { Validate.notNull(b, "The Block cannot be null."); - BlockMenu inv = StorageCacheUtils.getMenu(b.getLocation()); + UUID uuid = PDCUtil.getValue(b, PDCUtil.uuid, UUID_KEY); + UniversalChestMenu inv = StorageCacheUtils.getUniversalMenu(uuid); if (inv != null) { for (ItemStack item : items) { diff --git a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java index 760d2efc3d..8df34f1568 100644 --- a/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java +++ b/src/main/java/me/mrCookieSlime/CSCoreLibPlugin/general/Inventory/ChestMenu.java @@ -9,6 +9,7 @@ import java.util.UUID; import java.util.concurrent.CopyOnWriteArraySet; import javax.annotation.Nonnull; +import lombok.Getter; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.entity.Player; @@ -26,6 +27,7 @@ public class ChestMenu extends SlimefunInventoryHolder { private boolean clickable; private boolean emptyClickable; + @Getter private String title; private List items; private Map handlers; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java index 742c0e7122..9454918817 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java @@ -20,12 +20,12 @@ // This class will be deprecated, relocated and rewritten in a future version. public abstract class BlockMenuPreset extends ChestMenu { - private final Set occupiedSlots = new HashSet<>(); + final Set occupiedSlots = new HashSet<>(); private final String inventoryTitle; private final String id; // -1 means "automatically update according to the contents" - private int size = -1; + int size = -1; private boolean locked; @@ -91,10 +91,6 @@ public void newInstance(@Nonnull BlockMenu menu, @Nonnull Block b) { // This method can optionally be overridden by implementations } - public void newInstance(@Nonnull UniversalChestMenu menu, @Nonnull Block b) { - // This method can optionally be overridden by implementations - } - public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) { // This method will default to that method, it can be overridden by subclasses though return getSlotsAccessedByItemTransport(flow); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java index 5cf98e3c93..24ecf9b111 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/DirtyChestMenu.java @@ -80,12 +80,6 @@ public void close() { } public boolean fits(@Nonnull ItemStack item, int... slots) { - Debug.log( - TestCase.UTILS, - "DirtyChestMenu#fits - start check fits | item {} | slots {}", - StringUtil.itemStackToString(item), - Arrays.stream(slots).mapToObj(String::valueOf).collect(Collectors.joining(","))); - var isSfItem = SlimefunItem.getByItem(item) != null; var wrapper = ItemStackWrapper.wrap(item); var remain = item.getAmount(); @@ -97,15 +91,7 @@ public boolean fits(@Nonnull ItemStack item, int... slots) { return true; } - Debug.log( - TestCase.UTILS, - "DirtyChestMenu#fits - Now checking item | Slot {} | Item {}", - slot, - StringUtil.itemStackToString(slotItem)); - if (isSfItem) { - Debug.log(TestCase.UTILS, "DirtyChestMenu#fits - Check slimefun item fits"); - if (!slotItem.hasItemMeta() || item.getType() != slotItem.getType() || !SlimefunUtils.isItemSimilar(slotItem, wrapper, true, false)) { @@ -114,14 +100,9 @@ public boolean fits(@Nonnull ItemStack item, int... slots) { var slotRemain = slotItem.getMaxStackSize() - slotItem.getAmount(); - Debug.log(TestCase.UTILS, "DirtyChestMenu#fits - current slot remain: {}", slotRemain); - remain -= slotRemain; - Debug.log(TestCase.UTILS, "DirtyChestMenu#fits - remaining amount: {}", remain); - if (remain <= 0) { - Debug.log(TestCase.UTILS, "DirtyChestMenu#fits - check fits result (no remain): false"); return true; } } @@ -133,8 +114,6 @@ public boolean fits(@Nonnull ItemStack item, int... slots) { result = InvUtils.fits(toInventory(), wrapper, slots); } - Debug.log(TestCase.UTILS, "DirtyChestMenu#fits - check fits result: {}", result); - return result; } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalChestMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalChestMenu.java index 1ce2c684bc..e89e4cda80 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalChestMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalChestMenu.java @@ -2,6 +2,8 @@ import java.util.UUID; import javax.annotation.Nonnull; +import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; +import org.bukkit.Location; import org.bukkit.inventory.ItemStack; /** @@ -11,13 +13,12 @@ public class UniversalChestMenu extends DirtyChestMenu { private final UUID uuid; - public UniversalChestMenu(@Nonnull BlockMenuPreset preset, @Nonnull UUID uuid) { + public UniversalChestMenu(@Nonnull UniversalMenuPreset preset, @Nonnull UUID uuid) { super(preset); - this.uuid = uuid; } - public UniversalChestMenu(BlockMenuPreset preset, @Nonnull UUID uuid, ItemStack[] contents) { + public UniversalChestMenu(@Nonnull UniversalMenuPreset preset, @Nonnull UUID uuid, ItemStack[] contents) { super(preset); this.uuid = uuid; @@ -30,6 +31,25 @@ public UniversalChestMenu(BlockMenuPreset preset, @Nonnull UUID uuid, ItemStack[ } preset.clone(this); - this.getContents(); + } + + /** + * This method drops the contents of this {@link BlockMenu} on the ground at the given + * {@link Location}. + * + * @param l + * Where to drop these items + * @param slots + * The slots of items that should be dropped + */ + public void dropItems(Location l, int... slots) { + for (int slot : slots) { + ItemStack item = getItemInSlot(slot); + + if (item != null) { + l.getWorld().dropItemNaturally(l, item); + replaceExistingItem(slot, null); + } + } } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalMenuPreset.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalMenuPreset.java new file mode 100644 index 0000000000..1ae031b049 --- /dev/null +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/UniversalMenuPreset.java @@ -0,0 +1,45 @@ +package me.mrCookieSlime.Slimefun.api.inventory; + +import javax.annotation.Nonnull; +import org.bukkit.block.Block; + +public abstract class UniversalMenuPreset extends BlockMenuPreset { + /** + * Creates a new ChestMenu with the specified + * Title + * + * @param title The title of the Menu + */ + public UniversalMenuPreset(@Nonnull String id, @Nonnull String title) { + super(id, title); + } + + public void newInstance(@Nonnull UniversalChestMenu menu, @Nonnull Block b) { + // This method can optionally be overridden by implementations + } + + protected void clone(@Nonnull DirtyChestMenu menu, @Nonnull Block block) { + menu.setPlayerInventoryClickable(true); + + for (int slot : occupiedSlots) { + menu.addItem(slot, getItemInSlot(slot)); + } + + if (size > -1) { + menu.addItem(size - 1, null); + } + + if (menu instanceof UniversalChestMenu universalChestMenu) { + newInstance(universalChestMenu, block); + } + + for (int slot = 0; slot < 54; slot++) { + if (getMenuClickHandler(slot) != null) { + menu.addMenuClickHandler(slot, getMenuClickHandler(slot)); + } + } + + menu.addMenuOpeningHandler(getMenuOpeningHandler()); + menu.addMenuCloseHandler(getMenuCloseHandler()); + } +}