diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java index 8a1e917c6..9042e71b1 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/inject/BukkitModule.java @@ -28,6 +28,7 @@ package com.plotsquared.bukkit.inject; import com.google.inject.AbstractModule; import com.google.inject.Provides; import com.google.inject.Singleton; +import com.google.inject.TypeLiteral; import com.google.inject.assistedinject.FactoryModuleBuilder; import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.listener.SingleWorldListener; @@ -43,6 +44,8 @@ import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.fawe.FaweRegionManager; import com.plotsquared.bukkit.util.fawe.FaweSchematicHandler; +import com.plotsquared.bukkit.util.gui.BukkitPlotInventory; +import com.plotsquared.bukkit.util.gui.BukkitPlotInventoryProvider; import com.plotsquared.core.PlotPlatform; import com.plotsquared.core.PlotSquared; import com.plotsquared.core.configuration.Settings; @@ -70,6 +73,7 @@ import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.WorldUtil; +import com.plotsquared.core.util.gui.PlotInventoryProvider; import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.extension.platform.Actor; import org.apache.logging.log4j.LogManager; @@ -103,6 +107,7 @@ public class BukkitModule extends AbstractModule { bind(InventoryUtil.class).to(BukkitInventoryUtil.class); bind(SetupUtils.class).to(BukkitSetupUtils.class); bind(WorldUtil.class).to(BukkitUtil.class); + bind(new TypeLiteral>(){}).to(BukkitPlotInventoryProvider.class); install(new FactoryModuleBuilder() .implement(ProgressSubscriber.class, DefaultProgressSubscriber.class) .build(ProgressSubscriberFactory.class)); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/player/BukkitPlayer.java b/Bukkit/src/main/java/com/plotsquared/bukkit/player/BukkitPlayer.java index aae86f930..a48c79f93 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/player/BukkitPlayer.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/player/BukkitPlayer.java @@ -364,6 +364,11 @@ public class BukkitPlayer extends PlotPlayer { } } + @Override + public void closeInventory() { + this.player.closeInventory(); + } + /** * Convert from PlotSquared's {@link TeleportCause} to Bukkit's {@link PlayerTeleportEvent.TeleportCause} * diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/gui/BukkitPlotInventory.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/gui/BukkitPlotInventory.java new file mode 100644 index 000000000..471e3f41e --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/gui/BukkitPlotInventory.java @@ -0,0 +1,224 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2014 - 2022 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.bukkit.util.gui; + +import com.google.common.base.Preconditions; +import com.plotsquared.bukkit.BukkitPlatform; +import com.plotsquared.bukkit.util.BukkitUtil; +import com.plotsquared.core.PlotSquared; +import com.plotsquared.core.configuration.caption.Caption; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.PlotItemStack; +import com.plotsquared.core.util.gui.PlotInventory; +import com.plotsquared.core.util.gui.PlotInventoryClickHandler; +import com.sk89q.worldedit.bukkit.BukkitAdapter; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.UUID; +import java.util.WeakHashMap; + +/** + * Implementation of the {@link PlotInventory} for the bukkit platform. + */ +public class BukkitPlotInventory extends PlotInventory { + + private static Listener INVENTORY_LISTENER; + private final ItemStack[] items; + private final PlotInventoryClickHandler[] clickHandlers; + private final Map viewers = new WeakHashMap<>(); + private static final Map INVENTORIES = new WeakHashMap<>(); + + /** + * {@inheritDoc} + */ + protected BukkitPlotInventory(final int size, final Caption titleCaption, final TagResolver... titleResolvers) { + super(size, titleCaption, titleResolvers); + this.items = new ItemStack[size]; + this.clickHandlers = new PlotInventoryClickHandler[size]; + + if (INVENTORY_LISTENER != null) { + return; + } + INVENTORY_LISTENER = new Listener() { + @EventHandler + public void onInventoryClick(final org.bukkit.event.inventory.InventoryClickEvent event) { + final PlotPlayer player = BukkitUtil.adapt((Player) event.getWhoClicked()); + + BukkitPlotInventory currentInventory = INVENTORIES.get(player.getUUID()); + if (currentInventory == null) { + return; + } + if (!Objects.equals(event.getClickedInventory(), currentInventory.viewers.get(player.getUUID()))) { + return; + } + + final int slot = event.getRawSlot(); + if (slot < 0 || slot >= currentInventory.size()) { + return; + } + final PlotInventoryClickHandler clickHandler = currentInventory.clickHandlers[slot]; + if (clickHandler == null) { + return; + } + event.setCancelled(true); + final ItemStack item = event.getCurrentItem(); + if (item == null) { + clickHandler.handle(null, player); + return; + } + clickHandler.handle(new PlotItemStack( + BukkitAdapter.asItemType(item.getType()), + item.getAmount(), + item.getItemMeta().getDisplayName(), + item.getItemMeta().hasLore() ? item.getItemMeta().getLore().toArray(String[]::new) : new String[0] + ), player); + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + final PlotPlayer player = BukkitUtil.adapt((Player) event.getPlayer()); + BukkitPlotInventory currentInventory = INVENTORIES.get(player.getUUID()); + if (currentInventory == null) { + return; + } + currentInventory.viewers.remove(player.getUUID()); + INVENTORIES.remove(player.getUUID()); + } + + }; + BukkitPlatform bukkitPlatform = ((BukkitPlatform) PlotSquared.platform()); + bukkitPlatform.getServer().getPluginManager().registerEvents(INVENTORY_LISTENER, bukkitPlatform); + } + + @Override + public void setItem(final int slot, final PlotItemStack item, final PlotInventoryClickHandler onClick) { + Preconditions.checkElementIndex(slot, size(), "Slot must be in range (0, " + size() + ")"); + this.items[slot] = toPlatformItem(item); + this.clickHandlers[slot] = onClick; + for (final Inventory value : viewers.values()) { + value.setItem(slot, this.items[slot]); + } + } + + @Override + public void addItem(final PlotItemStack item, final PlotInventoryClickHandler onClick) { + // TODO: probably needs more love (who doesn't) + int slot = -1; + // try to fill stacks + for (int i = 0; i < items.length; i++) { + if (Objects.equals(items[i], toPlatformItem(item))) { + slot = i; + break; + } + } + // search for empty slots + if (slot == -1) { + for (int i = 0; i < items.length; i++) { + if (items[i] == null || items[i].getType() == Material.AIR) { + slot = i; + break; + } + } + } + Preconditions.checkElementIndex(slot, size()); + this.items[slot] = toPlatformItem(item); + this.clickHandlers[slot] = onClick; + for (final Inventory value : viewers.values()) { + value.setItem(slot, this.items[slot]); + } + } + + @Override + protected void openPlatformPlayer(final PlotPlayer player) { + Component title = MiniMessage.miniMessage().deserialize( + titleCaption().getComponent(player), titleResolvers() + ); + Inventory inventory = Bukkit.createInventory(player.getPlatformPlayer(), size(), + BukkitUtil.LEGACY_COMPONENT_SERIALIZER.serialize(title) + ); + for (int i = 0; i < items.length; i++) { + inventory.setItem(i, items[i]); + } + INVENTORIES.put(player.getUUID(), this); + viewers.put(player.getUUID(), inventory); + player.getPlatformPlayer().openInventory(inventory); + } + + @Override + protected void closePlatformPlayer(final PlotPlayer player) { + if (player.getPlatformPlayer().getOpenInventory().getTopInventory().equals(INVENTORIES.get(player.getUUID()))) { + player.getPlatformPlayer().closeInventory(); + } + } + + @Override + public ItemStack toPlatformItem(final PlotItemStack item) { + if (item == null) { + return null; + } + Material material = BukkitAdapter.adapt(item.getType()); + if (material == null) { + return null; + } + ItemStack stack = new ItemStack(material, item.getAmount()); + ItemMeta meta = null; + if (item.getName() != null) { + meta = stack.getItemMeta(); + Component nameComponent = BukkitUtil.MINI_MESSAGE.deserialize(item.getName()); + meta.setDisplayName(BukkitUtil.LEGACY_COMPONENT_SERIALIZER.serialize(nameComponent)); + } + if (item.getLore() != null) { + if (meta == null) { + meta = stack.getItemMeta(); + } + List lore = new ArrayList<>(); + for (String entry : item.getLore()) { + lore.add(BukkitUtil.LEGACY_COMPONENT_SERIALIZER.serialize(BukkitUtil.MINI_MESSAGE.deserialize(entry))); + } + meta.setLore(lore); + } + if (meta != null) { + stack.setItemMeta(meta); + } + return stack; + } + +} diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/gui/BukkitPlotInventoryProvider.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/gui/BukkitPlotInventoryProvider.java new file mode 100644 index 000000000..bfe712ad2 --- /dev/null +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/gui/BukkitPlotInventoryProvider.java @@ -0,0 +1,46 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2014 - 2022 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.bukkit.util.gui; + +import com.plotsquared.core.configuration.caption.Caption; +import com.plotsquared.core.util.gui.PlotInventory; +import com.plotsquared.core.util.gui.PlotInventoryProvider; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; + +public class BukkitPlotInventoryProvider implements PlotInventoryProvider { + + @Override + public PlotInventory createInventory( + final int size, + final Caption titleCaption, + final TagResolver... titleResolvers + ) { + return new BukkitPlotInventory(size, titleCaption, titleResolvers); + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/command/Music.java b/Core/src/main/java/com/plotsquared/core/command/Music.java index cdb2a58d6..fb160705d 100644 --- a/Core/src/main/java/com/plotsquared/core/command/Music.java +++ b/Core/src/main/java/com/plotsquared/core/command/Music.java @@ -34,24 +34,21 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.plot.Plot; -import com.plotsquared.core.plot.PlotInventory; import com.plotsquared.core.plot.PlotItemStack; import com.plotsquared.core.plot.flag.PlotFlag; import com.plotsquared.core.plot.flag.implementations.MusicFlag; import com.plotsquared.core.util.EventDispatcher; -import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.Permissions; -import com.sk89q.worldedit.world.item.ItemType; +import com.plotsquared.core.util.gui.PlotInventory; +import com.plotsquared.core.util.gui.PlotInventoryProvider; import com.sk89q.worldedit.world.item.ItemTypes; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.checkerframework.checker.nullness.qual.NonNull; -import javax.annotation.Nullable; -import java.util.Arrays; -import java.util.Collection; -import java.util.Locale; +import java.util.List; +import java.util.stream.Stream; @CommandDeclaration(command = "music", permission = "plots.music", @@ -60,20 +57,33 @@ import java.util.Locale; requiredType = RequiredType.PLAYER) public class Music extends SubCommand { - private static final Collection DISCS = Arrays - .asList("music_disc_13", "music_disc_cat", "music_disc_blocks", "music_disc_chirp", - "music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal", - "music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait", "music_disc_otherside", - "music_disc_pigstep" - ); + private static final List DISCS = Stream.of( + "music_disc_13", + "music_disc_cat", + "music_disc_blocks", + "music_disc_chirp", + "music_disc_far", + "music_disc_mall", + "music_disc_mellohi", + "music_disc_stal", + "music_disc_strad", + "music_disc_ward", + "music_disc_11", + "music_disc_wait", + "music_disc_otherside", + "music_disc_pigstep" + ).filter(s -> ItemTypes.get(s) != null).toList(); - private final InventoryUtil inventoryUtil; private final EventDispatcher eventDispatcher; + private final PlotInventoryProvider inventoryProvider; @Inject - public Music(final @Nullable InventoryUtil inventoryUtil, final @NonNull EventDispatcher eventDispatcher) { - this.inventoryUtil = inventoryUtil; + public Music( + final @NonNull EventDispatcher eventDispatcher, final + PlotInventoryProvider inventoryProvider + ) { this.eventDispatcher = eventDispatcher; + this.inventoryProvider = inventoryProvider; } @Override @@ -99,85 +109,67 @@ public class Music extends SubCommand { ); return true; } - PlotInventory inv = new PlotInventory( - this.inventoryUtil, - player, - 2, - TranslatableCaption.of("plotjukebox.jukebox_header").getComponent(player) - ) { - @Override - public boolean onClick(int index) { - PlotItemStack item = getItem(index); - if (item == null) { - return true; - } - if (item.getType() == ItemTypes.BEDROCK) { - PlotFlag plotFlag = plot.getFlagContainer().getFlag(MusicFlag.class) - .createFlagInstance(item.getType()); - PlotFlagRemoveEvent event = eventDispatcher.callFlagRemove(plotFlag, plot); - if (event.getEventResult() == Result.DENY) { - getPlayer().sendMessage( - TranslatableCaption.of("events.event_denied"), - TagResolver.resolver("value", Tag.inserting(Component.text("Music removal"))) - ); - return true; - } - plot.removeFlag(event.getFlag()); - getPlayer().sendMessage( - TranslatableCaption.of("flag.flag_removed"), - TagResolver.builder() - .tag("flag", Tag.inserting(Component.text("music"))) - .tag("value", Tag.inserting(Component.text("music_disc"))) - .build() - ); - } else if (item.getName().toLowerCase(Locale.ENGLISH).contains("disc")) { - PlotFlag plotFlag = plot.getFlagContainer().getFlag(MusicFlag.class) - .createFlagInstance(item.getType()); - PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot); - if (event.getEventResult() == Result.DENY) { - getPlayer().sendMessage( - TranslatableCaption.of("events.event_denied"), - TagResolver.resolver("value", Tag.inserting(Component.text("Music addition"))) - ); - return true; - } - plot.setFlag(event.getFlag()); - getPlayer().sendMessage( - TranslatableCaption.of("flag.flag_added"), - TagResolver.builder() - .tag("flag", Tag.inserting(Component.text("music"))) - .tag("value", Tag.inserting(Component.text(event.getFlag().getValue().toString()))) - .build() - ); - } else { - getPlayer().sendMessage(TranslatableCaption.of("flag.flag_not_added")); - } - return false; - } - }; - int index = 0; + + final PlotInventory inventory = inventoryProvider.createInventory( + 9 * 2, + TranslatableCaption.of("plotjukebox.jukebox_header") + ); for (final String disc : DISCS) { - final String name = String.format("%s", disc); - final String[] lore = {TranslatableCaption.of("plotjukebox.click_to_play").getComponent(player)}; - ItemType type = ItemTypes.get(disc); - if (type == null) { - continue; - } - final PlotItemStack item = new PlotItemStack(type, 1, name, lore); - if (inv.setItemChecked(index, item)) { - index++; - } + PlotItemStack itemStack = new PlotItemStack( + disc, 1, String.format("%s", disc), + TranslatableCaption.of("plotjukebox.click_to_play").getComponent(player) + ); + inventory.addItem(itemStack, (item, clicker) -> { + clicker.closeInventory(); + PlotFlag plotFlag = plot.getFlagContainer().getFlag(MusicFlag.class) + .createFlagInstance(item.getType()); + PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot); + if (event.getEventResult() == Result.DENY) { + clicker.sendMessage( + TranslatableCaption.of("events.event_denied"), + TagResolver.resolver("value", Tag.inserting(Component.text("Music addition"))) + ); + return; + } + plot.setFlag(event.getFlag()); + clicker.sendMessage( + TranslatableCaption.of("flag.flag_added"), + TagResolver.builder() + .tag("flag", Tag.inserting(Component.text("music"))) + .tag("value", Tag.inserting(Component.text(event.getFlag().getValue().toString()))) + .build() + ); + }); } - // Always add the cancel button - // if (player.getMeta("music") != null) { - String name = TranslatableCaption.of("plotjukebox.cancel_music").getComponent(player); - String[] lore = {TranslatableCaption.of("plotjukebox.reset_music").getComponent(player)}; - inv.setItem(index, new PlotItemStack("bedrock", 1, name, lore)); - // } - - inv.openInventory(); + PlotItemStack cancelItem = new PlotItemStack( + ItemTypes.BEDROCK, 1, + TranslatableCaption.of("plotjukebox.cancel_music").getComponent(player), + TranslatableCaption.of("plotjukebox.reset_music").getComponent(player) + ); + inventory.setItem(inventory.size() - 1, cancelItem, (item, clicker) -> { + clicker.closeInventory(); + PlotFlag plotFlag = plot.getFlagContainer().getFlag(MusicFlag.class) + .createFlagInstance(item.getType()); + PlotFlagRemoveEvent event = eventDispatcher.callFlagRemove(plotFlag, plot); + if (event.getEventResult() == Result.DENY) { + clicker.sendMessage( + TranslatableCaption.of("events.event_denied"), + TagResolver.resolver("value", Tag.inserting(Component.text("Music removal"))) + ); + return; + } + plot.removeFlag(event.getFlag()); + clicker.sendMessage( + TranslatableCaption.of("flag.flag_removed"), + TagResolver.builder() + .tag("flag", Tag.inserting(Component.text("music"))) + .tag("value", Tag.inserting(Component.text("music_disc"))) + .build() + ); + }); + inventory.open(player); return true; } diff --git a/Core/src/main/java/com/plotsquared/core/player/ConsolePlayer.java b/Core/src/main/java/com/plotsquared/core/player/ConsolePlayer.java index 55e1ef95a..dfa74efc7 100644 --- a/Core/src/main/java/com/plotsquared/core/player/ConsolePlayer.java +++ b/Core/src/main/java/com/plotsquared/core/player/ConsolePlayer.java @@ -258,4 +258,8 @@ public class ConsolePlayer extends PlotPlayer { return true; } + @Override + public void closeInventory() { + } + } diff --git a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java index 9da715c8e..c45fbd97e 100644 --- a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java +++ b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java @@ -1015,6 +1015,12 @@ public abstract class PlotPlayer

implements CommandCaller, OfflinePlotPlayer, public @NonNull abstract Audience getAudience(); + /** + * Closes the current open inventory, if present + * @since TODO + */ + public abstract void closeInventory(); + /** * Get this player's {@link LockRepository} * diff --git a/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventory.java b/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventory.java new file mode 100644 index 000000000..7b73e6f6d --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventory.java @@ -0,0 +1,145 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2014 - 2022 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.gui; + +import com.plotsquared.core.configuration.caption.Caption; +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.PlotItemStack; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +/** + * @param

The platform player + * @param The platform item object + * @since TODO + */ +public abstract class PlotInventory { + + private final PlotInventoryClickHandler

NOOP_CLICK_HANDLER = (x, y) -> { + }; + + private final int size; + private final Caption titleCaption; + private final TagResolver[] titleResolvers; + + /** + * Instantiates a new Plot inventory. + * + * @param size The size of the inventory - must be a multiple of 9 + * @param titleCaption The caption to use for the title + * @param titleResolvers The tag resolvers to use for the title + * @since 7.0.0 + */ + protected PlotInventory(int size, Caption titleCaption, TagResolver... titleResolvers) { + this.size = size; + this.titleCaption = titleCaption; + this.titleResolvers = titleResolvers; + } + + /** + * Set an item in this inventory at a specific slot / index. + * Overrides existing items and click handler. + * + * @param slot The slot / index where to place the item + * @param item The item to add to this inventory + * @param onClick The handler to call when clicking this item + * @since TODO + */ + public abstract void setItem(int slot, PlotItemStack item, PlotInventoryClickHandler

onClick); + + /** + * Set an item in this inventory at a specific slot / index. + * Overrides existing items and click handler. + * + * @param slot The slot / index where to place the item + * @param item The item to add to this inventory + * @since TODO + */ + public void setItem(int slot, PlotItemStack item) { + setItem(slot, item, NOOP_CLICK_HANDLER); + } + + /** + * Add an item to this inventory, at the first slot possible (first empty slot, or first slot with the exact same item) + * + * @param item The item to add to this inventory + * @param onClick The handler to call when clicking this item + * @since TODO + */ + public abstract void addItem(PlotItemStack item, PlotInventoryClickHandler

onClick); + + /** + * Add an item to this inventory, at the first slot possible (first empty slot, or first slot with the exact same item) + * + * @param item The item to add to this inventory + * @since TODO + */ + public void addItem(PlotItemStack item) { + addItem(item, NOOP_CLICK_HANDLER); + } + + /** + * Opens this inventory for a specific {@link PlotPlayer} + * + * @param player The player to open this inventory for + * @since TODO + */ + public void open(PlotPlayer player) { + this.openPlatformPlayer((PlotPlayer

) player); + } + + protected abstract void openPlatformPlayer(PlotPlayer

player); + + /** + * Close this inventory for a specific {@link PlotPlayer} + * + * @param player The player to close this inventory for + * @since TODO + */ + public void close(PlotPlayer player) { + this.closePlatformPlayer((PlotPlayer

) player); + } + + protected abstract void closePlatformPlayer(PlotPlayer

player); + + public abstract I toPlatformItem(PlotItemStack item); + + /** + * @return the size of this inventory (must be a multiple of 9) + * @since TODO + */ + public int size() { + return size; + } + + protected Caption titleCaption() { + return titleCaption; + } + + protected TagResolver[] titleResolvers() { + return titleResolvers; + } + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventoryClickHandler.java b/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventoryClickHandler.java new file mode 100644 index 000000000..0f08d24c0 --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventoryClickHandler.java @@ -0,0 +1,35 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2014 - 2022 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.gui; + +import com.plotsquared.core.player.PlotPlayer; +import com.plotsquared.core.plot.PlotItemStack; + +public interface PlotInventoryClickHandler

{ + + void handle(PlotItemStack itemStack, PlotPlayer

plotPlayer); + +} diff --git a/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventoryProvider.java b/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventoryProvider.java new file mode 100644 index 000000000..ede28bf1a --- /dev/null +++ b/Core/src/main/java/com/plotsquared/core/util/gui/PlotInventoryProvider.java @@ -0,0 +1,49 @@ +/* + * _____ _ _ _____ _ + * | __ \| | | | / ____| | | + * | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| | + * | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | + * | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| | + * |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_| + * | | + * |_| + * PlotSquared plot management system for Minecraft + * Copyright (C) 2014 - 2022 IntellectualSites + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package com.plotsquared.core.util.gui; + +import com.plotsquared.core.configuration.caption.Caption; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +/** + * Provider for creating a {@link PlotInventory} + * + * @param

The platform player + * @param The platform item + */ +public interface PlotInventoryProvider { + + /** + * Creates a new {@link PlotInventory} based on the passed data for the current platform. + * + * @param size The size of the inventory (must be a multiple of 9) + * @param titleCaption The title for the inventory + * @param titleResolvers The (optional) placeholder resolvers for the inventory + * @return The platform inventory + */ + PlotInventory createInventory(int size, Caption titleCaption, TagResolver... titleResolvers); + +}