From 22fe2822981aa79cf4e5785091bf65887b7f116e Mon Sep 17 00:00:00 2001 From: Alexander Date: Fri, 5 Apr 2024 00:06:57 +0100 Subject: [PATCH] Yeet canvas --- plugins/civmodcore-paper/build.gradle.kts | 1 - .../org/ipvp/canvas/type/AbstractCivMenu.java | 317 ------------------ .../org/ipvp/canvas/type/CivChestMenu.java | 91 ----- .../org/ipvp/canvas/type/OpenHandler.java | 16 - .../org/ipvp/canvas/type/UpdateHandler.java | 17 - .../mc/civmodcore/CivModCorePlugin.java | 2 - .../inventory/gui/canvas/MenuPagination.java | 241 ------------- .../inventory/gui/canvas/MenuUtils.java | 102 ------ .../inventory/gui/canvas/MultiPageCanvas.java | 180 ---------- 9 files changed, 967 deletions(-) delete mode 100644 plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/AbstractCivMenu.java delete mode 100644 plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/CivChestMenu.java delete mode 100644 plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/OpenHandler.java delete mode 100644 plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/UpdateHandler.java delete mode 100644 plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuPagination.java delete mode 100644 plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuUtils.java delete mode 100644 plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MultiPageCanvas.java diff --git a/plugins/civmodcore-paper/build.gradle.kts b/plugins/civmodcore-paper/build.gradle.kts index 113eabedf..09bc946ca 100644 --- a/plugins/civmodcore-paper/build.gradle.kts +++ b/plugins/civmodcore-paper/build.gradle.kts @@ -15,7 +15,6 @@ dependencies { api("com.mojang:datafixerupper:1.0.20") api("com.zaxxer:HikariCP:5.0.1") api("co.aikar:taskchain-bukkit:3.7.2") - api("com.github.IPVP-MC:canvas:91ec97f076") api("org.apache.commons:commons-lang3:3.12.0") api("org.apache.commons:commons-collections4:4.4") api("com.google.code.findbugs:jsr305:3.0.2") diff --git a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/AbstractCivMenu.java b/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/AbstractCivMenu.java deleted file mode 100644 index df5443107..000000000 --- a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/AbstractCivMenu.java +++ /dev/null @@ -1,317 +0,0 @@ -package org.ipvp.canvas.type; - -import java.lang.reflect.Field; -import java.lang.reflect.InvocationTargetException; -import java.lang.reflect.Method; -import java.util.Objects; -import java.util.Optional; -import java.util.Set; -import net.kyori.adventure.text.Component; -import org.apache.commons.lang3.reflect.FieldUtils; -import org.apache.commons.lang3.reflect.MethodUtils; -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.InventoryType; -import org.bukkit.inventory.Inventory; -import org.bukkit.inventory.InventoryHolder; -import org.ipvp.canvas.Menu; -import org.ipvp.canvas.slot.DefaultSlot; -import org.ipvp.canvas.slot.Slot; -import vg.civcraft.mc.civmodcore.chat.ChatUtils; -import vg.civcraft.mc.civmodcore.inventory.InventoryUtils; -import vg.civcraft.mc.civmodcore.inventory.gui.canvas.MenuUtils; -import vg.civcraft.mc.civmodcore.utilities.NullUtils; - -public abstract class AbstractCivMenu extends AbstractMenu { - - private static final Field VIEWERS_FIELD; - private static final Field SLOTS_FIELD; - private static final Method UPDATE_INV_CONTENTS_METHOD; - - static { - VIEWERS_FIELD = FieldUtils.getDeclaredField(AbstractMenu.class, "viewers", true); - SLOTS_FIELD = FieldUtils.getDeclaredField(AbstractMenu.class, "slots", true); - UPDATE_INV_CONTENTS_METHOD = MethodUtils.getMatchingMethod(AbstractMenu.class, - "updateInventoryContents", Player.class, Inventory.class); - UPDATE_INV_CONTENTS_METHOD.setAccessible(true); - } - - private final Component title; - private OpenHandler openHandler; - private UpdateHandler updateHandler; - protected boolean callCloseHandlerRegardless; - - protected AbstractCivMenu(final Component title, - final int slots, - final Menu parent, - final boolean redraw) { - super(null, slots, parent, redraw); - if (!InventoryUtils.isValidChestSize(slots)) { - throw new IllegalArgumentException("Not a valid chest size."); - } - this.title = ChatUtils.isNullOrEmpty(title) ? InventoryType.CHEST.defaultTitle() : title; - } - - protected AbstractCivMenu(final Component title, - final InventoryType type, - final Menu parent, - final boolean redraw) { - super(null, type, parent, redraw); - this.title = ChatUtils.isNullOrEmpty(title) ? type.defaultTitle() : title; - this.inventorySlots = type.getDefaultSize(); - } - - /** - * @return Returns a clone of this menu's title. - */ - protected Component getTitle() { - return this.title; - } - - /** - * @return Retrieves this menu's open event handler. - */ - public Optional getOpenHandler() { - return Optional.ofNullable(this.openHandler); - } - - /** - * Sets the open event handler for this menu. Use - * {@link MenuUtils#overrideOpenHandler(AbstractCivMenu, OpenHandler, boolean)} instead if you'd prefer to - * override the event handler rather than replace it. - * - * @param openHandler The open event handler to set for this menu. - */ - public void setOpenHandler(final OpenHandler openHandler) { - this.openHandler = openHandler; - } - - /** - * @return Retrieves this menu's update event handler. - */ - public Optional getUpdateHandler() { - return Optional.ofNullable(this.updateHandler); - } - - /** - * Sets the update event handler for this menu. Use - * {@link MenuUtils#overrideUpdateHandler(AbstractCivMenu, UpdateHandler, boolean)} instead if you'd prefer to - * override the event handler rather than replace it. - * - * @param updateHandler The update event handler to set for this menu. - */ - public void setUpdateHandler(final UpdateHandler updateHandler) { - this.updateHandler = updateHandler; - } - - /** - * Sets the close event handler for this menu. Use - * {@link MenuUtils#overrideCloseHandler(AbstractCivMenu, CloseHandler, boolean)} instead if you'd prefer to - * override the event handler rather than replace it. - * - * @param closeHandler The close event handler to set for this menu. - */ - @Override - public void setCloseHandler(final CloseHandler closeHandler) { - super.setCloseHandler(closeHandler); - } - - /** - * @return Returns whether or not this menu will invoke its close event handler regardless of whether - * {@link #closedByPlayer(Player, boolean)}'s second parameter, "triggerCloseHandler", is false. - */ - public boolean isCallingCloseHandlerRegardless() { - return this.callCloseHandlerRegardless; - } - - /** - * @param callCloseHandlerRegardless Set this to true if you want this menu to invoke its close event handler - * regardless of whether {@link #closedByPlayer(Player, boolean)}'s second - * parameter, "triggerCloseHandler", is false. - */ - public void setCallCloseHandlerRegardless(final boolean callCloseHandlerRegardless) { - this.callCloseHandlerRegardless = callCloseHandlerRegardless; - } - - /** - * @return Returns the total slot count for this menu. - */ - protected int getSlotCount() { - return this.inventorySlots; - } - - /** - * @return Returns the underlying viewers via reflection. - */ - @SuppressWarnings("unchecked") - protected final Set getRawViewers() { - try { - return (Set) FieldUtils.readField(VIEWERS_FIELD, this); - } - catch (final IllegalAccessException exception) { - throw new RuntimeException(exception); - } - } - - /** - * @return Returns the underlying slots via reflection. - */ - protected final DefaultSlot[] getRawSlots() { - try { - return (DefaultSlot[]) FieldUtils.readField(SLOTS_FIELD, this); - } - catch (final IllegalAccessException exception) { - throw new RuntimeException(exception); - } - } - - /** - * Switches from this menu to a given menu. - * - * @param viewer The viewer to switch. - * @param otherMenu The other menu to switch to. - */ - public void openOtherMenu(final Player viewer, final AbstractCivMenu otherMenu) { - if (otherMenu == null) { - viewer.closeInventory(); - return; - } - otherMenu.open(viewer); - } - - /** - * Opens this menu's parent, or closes if it doesn't exist. - * - * @param viewer The viewer to navigate. - */ - public void openParent(final Player viewer) { - final var parent = getParent().orElse(null); - if (parent == null) { - viewer.closeInventory(); - return; - } - if (parent instanceof AbstractCivMenu) { - ((AbstractCivMenu) parent).openOtherMenu(viewer, this); - return; - } - parent.open(viewer); - } - - /** - * Basically a carbon copy of {@link AbstractMenu#closedByPlayer(Player, boolean)}, except - * for the additional logic of {@link #callCloseHandlerRegardless} to force the menu to call - * the close handler even if {@code triggerCloseHandler} is false. - * - * @param viewer The closing viewer. - * @param triggerCloseHandler Whether to call the close handler, which defers to - * {@link #callCloseHandlerRegardless}. - */ - @Override - public void closedByPlayer(final Player viewer, final boolean triggerCloseHandler) { - final var currentInventory = viewer.getOpenInventory().getTopInventory().getHolder(); - final var viewers = getRawViewers(); - if (!(currentInventory instanceof MenuHolder) - || !viewers.contains(currentInventory)) { - return; - } - if (triggerCloseHandler || this.callCloseHandlerRegardless) { - getCloseHandler().ifPresent(handler -> handler.close(viewer, this)); - } - viewers.remove((MenuHolder) currentInventory); - } - - /** - * @param viewer The viewer to update this menu for. - */ - @Override - public void update(final Player viewer) throws IllegalStateException { - if (!isOpen(viewer)) { - return; - } - - final var currentHolder = viewer.getOpenInventory().getTopInventory().getHolder(); - final var currentInventory = NullUtils.isNotNull(currentHolder).getInventory(); - - for (final Slot slot : getRawSlots()) { - currentInventory.setItem(slot.getIndex(), slot.getItem(viewer)); - } - - getUpdateHandler().ifPresent(handler -> handler.handle(viewer, this)); - viewer.updateInventory(); - } - - /** - * Basically a carbon copy of {@link AbstractMenu#open(Player)}, which is needed to override the - * {@code createInventory()} method, but it's private so the entire function needs to be copied, - * alongside its other dependent private methods. - */ - @Override - public void open(final Player viewer) { - final var currentHolder = viewer.getOpenInventory().getTopInventory().getHolder(); - final MenuHolder holder; - if (currentHolder instanceof MenuHolder) { - holder = (MenuHolder) currentHolder; - final var currentMenu = holder.getMenu(); - - if (currentMenu == this) { - return; - } - - Inventory inventory; - if (isRedraw() && Objects.equals(getDimensions(), currentMenu.getDimensions())) { - inventory = holder.getInventory(); - if (currentMenu instanceof AbstractMenu) { - ((AbstractMenu) currentMenu).closedByPlayer(viewer, false); - } - } - else { - currentMenu.close(viewer); - inventory = createInventory(holder); - holder.setInventory(inventory); - viewer.openInventory(inventory); - } - - updateInventoryContents(viewer, inventory); - holder.setMenu(this); - } - else { - // Create new MenuHolder for the player - holder = new MenuHolder(viewer, this); - final var inventory = createInventory(holder); - updateInventoryContents(viewer, inventory); - holder.setInventory(inventory); - viewer.openInventory(inventory); - } - getRawViewers().add(holder); - getOpenHandler().ifPresent(handler -> handler.handle(viewer, this)); - } - - /** - * Basically a carbon copy of {@link AbstractMenu}'s version, but uses a component title instead. - * - * @param holder The menu's inventory holder. - * @return Returns the new inventory. - */ - protected Inventory createInventory(final InventoryHolder holder) { - if (this.inventoryType == null) { - return Bukkit.createInventory(holder, this.inventorySlots, this.title); - } - return Bukkit.createInventory(holder, this.inventoryType, this.title); - } - - /** - * Invokes {@link AbstractMenu}'s version via reflection. - * - * @param viewer The viewer to update. - * @param inventory The inventory to update. - */ - protected void updateInventoryContents(final Player viewer, final Inventory inventory) { - try { - UPDATE_INV_CONTENTS_METHOD.invoke(this, viewer, inventory); - } - catch (final InvocationTargetException | IllegalAccessException exception) { - throw new RuntimeException(exception); - } - } - -} diff --git a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/CivChestMenu.java b/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/CivChestMenu.java deleted file mode 100644 index 95252097a..000000000 --- a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/CivChestMenu.java +++ /dev/null @@ -1,91 +0,0 @@ -package org.ipvp.canvas.type; - -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer; -import org.apache.commons.lang3.StringUtils; -import org.ipvp.canvas.Menu; -import vg.civcraft.mc.civmodcore.chat.ChatUtils; - -public class CivChestMenu extends AbstractCivMenu { - - private Dimension dimension; - - public CivChestMenu(final Component title, final int rows) { - this(title, rows, true); - } - - public CivChestMenu(final Component title, final int rows, final boolean redraw) { - this(title, rows, null, redraw); - } - - public CivChestMenu(final Component title, final int rows, final Menu parent, final boolean redraw) { - super(title, rows * 9, parent, redraw); - } - - /** - * @return Return this chest menu's row and column counts. - */ - @Override - public Dimension getDimensions() { - if (this.dimension == null) { - this.dimension = new Dimension(getSlotCount() / 9, 9); - } - return this.dimension; - } - - /** - * Returns a new builder. - * - * @param rows The amount of rows for the inventory to contain - * @throws IllegalArgumentException if rows is not between 1 and 6 inclusive - */ - public static Builder builder(final int rows) { - if (rows < 1 || rows > 6) { - throw new IllegalArgumentException("rows must be a value from 1 to 6"); - } - return new Builder(rows); - } - - /** - * A builder for creating a CustomChestMenu instance. - */ - public static class Builder extends AbstractMenu.Builder { - - private Component title; - - Builder(final int rows) { - super(new Dimension(rows, 9)); - } - - @Deprecated - @Override - public Builder title(final String title) { - if (StringUtils.isBlank(title)) { - this.title = null; - return this; - } - this.title = LegacyComponentSerializer.legacyAmpersand().deserialize(title); - if (ChatUtils.isNullOrEmpty(this.title)) { - this.title = null; - } - return this; - } - - public Builder title(final Component title) { - this.title = title; - return this; - } - - public Component getComponentTitle() { - return this.title; - } - - @Override - public CivChestMenu build() { - return new CivChestMenu(getComponentTitle(), - getDimensions().getArea(), getParent(), isRedraw()); - } - - } - -} diff --git a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/OpenHandler.java b/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/OpenHandler.java deleted file mode 100644 index a845cb524..000000000 --- a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/OpenHandler.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.ipvp.canvas.type; - -import org.bukkit.entity.Player; - -@FunctionalInterface -public interface OpenHandler { - - /** - * Is called by {@link AbstractCivMenu} when one of its menus are opened by a viewer. - * - * @param viewer The viewer of the opened menu. - * @param menu The menu being opened. - */ - void handle(Player viewer, AbstractCivMenu menu); - -} diff --git a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/UpdateHandler.java b/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/UpdateHandler.java deleted file mode 100644 index e145b9758..000000000 --- a/plugins/civmodcore-paper/src/main/java/org/ipvp/canvas/type/UpdateHandler.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.ipvp.canvas.type; - -import org.bukkit.entity.Player; - -@FunctionalInterface -public interface UpdateHandler { - - /** - * Is called by {@link AbstractCivMenu} when one of its menus are updated. This is called after the menu has been - * updated but before the update packets have been sent to the player. - * - * @param viewer The viewer of the updating menu. - * @param menu The menu being updated. - */ - void handle(Player viewer, AbstractCivMenu menu); - -} diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java index ab877bbaf..a003e37bb 100644 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java +++ b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/CivModCorePlugin.java @@ -7,7 +7,6 @@ import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.entity.HumanEntity; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.plugin.java.JavaPluginLoader; -import org.ipvp.canvas.MenuFunctionListener; import vg.civcraft.mc.civmodcore.chat.dialog.DialogManager; import vg.civcraft.mc.civmodcore.commands.ChunkMetaCommand; import vg.civcraft.mc.civmodcore.commands.CommandManager; @@ -85,7 +84,6 @@ public class CivModCorePlugin extends ACivMod { } ScoreBoardAPI.setDefaultHeader(this.config.getScoreboardHeader()); // Register listeners - registerListener(new MenuFunctionListener()); registerListener(new ClickableInventoryListener()); registerListener(DialogManager.INSTANCE); registerListener(new ScoreBoardListener()); diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuPagination.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuPagination.java deleted file mode 100644 index 78e04292e..000000000 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuPagination.java +++ /dev/null @@ -1,241 +0,0 @@ -package vg.civcraft.mc.civmodcore.inventory.gui.canvas; - -import it.unimi.dsi.fastutil.objects.Object2ObjectAVLTreeMap; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.UUID; -import org.apache.commons.collections4.CollectionUtils; -import org.bukkit.entity.Player; -import org.ipvp.canvas.slot.SlotSettings; -import org.ipvp.canvas.type.AbstractCivMenu; - -/** - * Better version of {@link org.ipvp.canvas.paginate.PaginatedMenuBuilder} as it allows you to apply pagination to an - * already existing menu, rather than using a builder to spawn a bunch of new menu instances that'll just be used by a - * single player before promptly discarded. - */ -public final class MenuPagination { - - private final AbstractCivMenu menu; - private final Map playerPages; - private final List menuBar; - private final ElementSupplier supplier; - private final int buttonSlots; - - private MenuPagination(final AbstractCivMenu menu, - final ElementSupplier supplier, - final List menuBar) { - this.menu = Objects.requireNonNull(menu, "Menu cannot be null"); - final int rows = menu.getDimensions().getRows(); - if (rows < 2 || rows > 5) { - throw new IllegalArgumentException("Row count must be between 2 and 5 inclusively"); - } - this.playerPages = new Object2ObjectAVLTreeMap<>(); - this.menuBar = List.copyOf(menuBar); - if (menuBar.size() > 9) { - throw new IllegalArgumentException("Bar cannot contain more than 9 buttons"); - } - this.supplier = Objects.requireNonNull(supplier, "Element supplier cannot be null"); - this.buttonSlots = (rows * 9) - 9; - - MenuUtils.overrideOpenHandler(menu, (viewer, opened) -> { - final var pager = INTERNAL_getPlayerPager(viewer); - pager.pageNumber = 0; - pager.elements = this.supplier.generate(viewer, opened); - INTERNAL_applyPlayerPage(viewer, opened, INTERNAL_getPlayerPager(viewer)); - }, true); - - MenuUtils.overrideUpdateHandler(menu, (viewer, updated) -> { - INTERNAL_applyPlayerPage(viewer, updated, INTERNAL_getPlayerPager(viewer)); - }, true); - - menu.setCallCloseHandlerRegardless(true); - MenuUtils.overrideCloseHandler(menu, (viewer, ignored) -> { - this.playerPages.remove(viewer.getUniqueId()); - }, true); - - for (int i = 0; i < this.buttonSlots; i++) { - menu.getSlot(i).setClickHandler((viewer, click) -> { - final var pager = INTERNAL_getPlayerPager(viewer); - final int buttonIndex = INTERNAL_calculateElementIndex(pager, click.getClickedSlot().getIndex()); - if (buttonIndex >= pager.elements.size()) { - return; - } - final var handler = pager.elements.get(buttonIndex).getClickHandler(); - if (handler == null) { - return; - } - handler.click(viewer, click); - }); - } - - for (int i = 0; i < 9; i++) { - final var slotIndex = INTERNAL_calculateBarIndex(i); - if (i >= this.menuBar.size()) { - menu.getSlot(slotIndex).setSettings(MenuUtils.createEmptySlot()); - break; - } - final var barElement = this.menuBar.get(i); - if (barElement == null) { - menu.getSlot(slotIndex).setSettings(MenuUtils.createEmptySlot()); - continue; - } - menu.getSlot(slotIndex).setSettings(barElement); - } - } - - /** - * @param viewer The viewer to send to the next page. - */ - public void nextPage(final Player viewer) { - final var pager = INTERNAL_getPlayerPager(viewer); - pager.pageNumber++; - this.menu.update(viewer); - } - - /** - * @param viewer The viewer to send to the previous page. - */ - public void previousPage(final Player viewer) { - final var pager = INTERNAL_getPlayerPager(viewer); - pager.pageNumber--; - this.menu.update(viewer); - } - - /** - * @param viewer The viewer to check if they have a next page. - * @return Returns whether the viewer has a next page. - */ - public boolean hasNextPage(final Player viewer) { - final var pager = INTERNAL_getPlayerPager(viewer); - final int elementsSize = CollectionUtils.size(pager.elements); - final int totalPages = elementsSize / this.buttonSlots; - if (totalPages == 0) { - return false; - } - return pager.pageNumber >= totalPages; - } - - /** - * @param viewer The viewer to check if they have a previous page. - * @return Returns whether the viewer has a previous page. - */ - public boolean hasPreviousPage(final Player viewer) { - final var pager = INTERNAL_getPlayerPager(viewer); - final int elementsSize = CollectionUtils.size(pager.elements); - final int totalPages = elementsSize / this.buttonSlots; - if (totalPages == 0) { - return false; - } - return pager.pageNumber < totalPages; - } - - protected void INTERNAL_applyPlayerPage(final Player viewer, - final AbstractCivMenu menu, - final INTERNAL_PlayerPager pager) { - pager.pageNumber = Math.max(pager.pageNumber, 0); - pager.pageNumber = Math.min(pager.pageNumber, pager.elements.size() / this.buttonSlots); - for (int i = 0; i < this.buttonSlots; i++) { - final int buttonIndex = INTERNAL_calculateElementIndex(pager, i); - if (buttonIndex >= pager.elements.size()) { - menu.getSlot(i).setRawItem(viewer, null); - continue; - } - final var template = pager.elements.get(buttonIndex).getItemTemplate(); - if (template == null) { - menu.getSlot(i).setRawItem(viewer, null); - continue; - } - menu.getSlot(i).setRawItem(viewer, template.getItem(viewer)); - } - } - - protected INTERNAL_PlayerPager INTERNAL_getPlayerPager(final Player viewer) { - return this.playerPages.computeIfAbsent(viewer.getUniqueId(), (uuid) -> new INTERNAL_PlayerPager()); - } - - protected int INTERNAL_calculateElementIndex(final INTERNAL_PlayerPager pager, final int slot) { - return (pager.pageNumber * this.buttonSlots) + slot; - } - - protected int INTERNAL_calculateBarIndex(final int slot) { - return this.buttonSlots + slot; - } - - protected static class INTERNAL_PlayerPager { - private int pageNumber; - private List elements; - } - - @FunctionalInterface - public interface ElementSupplier { - List generate(Player viewer, AbstractCivMenu menu); - } - - /** - * @return Returns a new pagination builder. - */ - public static Builder builder() { - return new Builder(); - } - - public static class Builder { - - private AbstractCivMenu menu; - private ElementSupplier supplier; - private final SlotSettings[] menuBar; - - Builder() { - this.menuBar = new SlotSettings[] { - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot(), - MenuUtils.createEmptySlot() - }; - } - - /** - * @param menu The menu to paginate. - * @return Returns this builder. - */ - public Builder setMenu(final AbstractCivMenu menu) { - this.menu = menu; - return this; - } - - /** - * @param supplier Supplier method to return all the elements to be paginated. - * @return Returns this builder. - */ - public Builder setElementSupplier(final ElementSupplier supplier) { - this.supplier = supplier; - return this; - } - - /** - * @param index The index of the menu bar element from 0-8 inclusively. - * @param element The menu bar element to add. - * @return Returns this builder. - */ - public Builder setMenuBarElement(final int index, final SlotSettings element) { - this.menuBar[index] = element == null ? MenuUtils.createEmptySlot() : element; - return this; - } - - /** - * @return Returns a constructed menu pagination based on this builder. - */ - public MenuPagination build() { - return new MenuPagination(this.menu, this.supplier, Arrays.asList(this.menuBar)); - } - - } - -} diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuUtils.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuUtils.java deleted file mode 100644 index 6d7b57cbf..000000000 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MenuUtils.java +++ /dev/null @@ -1,102 +0,0 @@ -package vg.civcraft.mc.civmodcore.inventory.gui.canvas; - -import org.ipvp.canvas.Menu; -import org.ipvp.canvas.slot.SlotSettings; -import org.ipvp.canvas.type.AbstractCivMenu; -import org.ipvp.canvas.type.OpenHandler; -import org.ipvp.canvas.type.UpdateHandler; - -public final class MenuUtils { - - /** - * @return Returns an empty, unmodifiable slot. - */ - public static SlotSettings createEmptySlot() { - return SlotSettings.builder().build(); - } - - /** - * Overrides a given menu's open event handler, in lieu of just replacing it, meaning that you can add handlers to - * a menu without fear of removing any previously added functionality. - * - * @param menu The menu to add the handler for. - * @param handler The handler to add. - * @param callSuperBefore Whether or not to call the existing handler before or after the given handler. - */ - public static void overrideOpenHandler(final AbstractCivMenu menu, - final OpenHandler handler, - final boolean callSuperBefore) { - final var findExisting = menu.getOpenHandler(); - if (findExisting.isEmpty()) { - menu.setOpenHandler(handler); - return; - } - final var existing = findExisting.get(); - menu.setOpenHandler((viewer, openedMenu) -> { - if (callSuperBefore) { - existing.handle(viewer, openedMenu); - } - handler.handle(viewer, openedMenu); - if (!callSuperBefore) { - existing.handle(viewer, openedMenu); - } - }); - } - - /** - * Overrides a given menu's update event handler, in lieu of just replacing it, meaning that you can add handlers - * to a menu without fear of removing any previously added functionality. - * - * @param menu The menu to add the handler for. - * @param handler The handler to add. - * @param callSuperBefore Whether or not to call the existing handler before or after the given handler. - */ - public static void overrideUpdateHandler(final AbstractCivMenu menu, - final UpdateHandler handler, - final boolean callSuperBefore) { - final var findExisting = menu.getUpdateHandler(); - if (findExisting.isEmpty()) { - menu.setUpdateHandler(handler); - return; - } - final var existing = findExisting.get(); - menu.setUpdateHandler((viewer, openedMenu) -> { - if (callSuperBefore) { - existing.handle(viewer, openedMenu); - } - handler.handle(viewer, openedMenu); - if (!callSuperBefore) { - existing.handle(viewer, openedMenu); - } - }); - } - - /** - * Overrides a given menu's close event handler, in lieu of just replacing it, meaning that you can add handlers to - * a menu without fear of removing any previously added functionality. - * - * @param menu The menu to add the handler for. - * @param handler The handler to add. - * @param callSuperBefore Whether or not to call the existing handler before or after the given handler. - */ - public static void overrideCloseHandler(final AbstractCivMenu menu, - final Menu.CloseHandler handler, - final boolean callSuperBefore) { - final var findExisting = menu.getCloseHandler(); - if (findExisting.isEmpty()) { - menu.setCloseHandler(handler); - return; - } - final var existing = findExisting.get(); - menu.setCloseHandler((viewer, openedMenu) -> { - if (callSuperBefore) { - existing.close(viewer, openedMenu); - } - handler.close(viewer, openedMenu); - if (!callSuperBefore) { - existing.close(viewer, openedMenu); - } - }); - } - -} diff --git a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MultiPageCanvas.java b/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MultiPageCanvas.java deleted file mode 100644 index 0b3375dbe..000000000 --- a/plugins/civmodcore-paper/src/main/java/vg/civcraft/mc/civmodcore/inventory/gui/canvas/MultiPageCanvas.java +++ /dev/null @@ -1,180 +0,0 @@ -package vg.civcraft.mc.civmodcore.inventory.gui.canvas; - -import java.util.List; -import java.util.Objects; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import net.kyori.adventure.text.Component; -import net.kyori.adventure.text.format.NamedTextColor; -import org.bukkit.Material; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; -import org.ipvp.canvas.slot.SlotSettings; -import org.ipvp.canvas.type.AbstractCivMenu; -import org.ipvp.canvas.type.CivChestMenu; -import vg.civcraft.mc.civmodcore.inventory.InventoryUtils; -import vg.civcraft.mc.civmodcore.inventory.items.ItemUtils; - -/** - * Utility to automate creating views, which have multiple pages and automatically adjust their size - * - */ -public class MultiPageCanvas { - - private final Player viewer; - private final Component title; - private final List slots; - private final boolean adjustSize; - private final SlotSettings[] extraMenuItems; - - private AbstractCivMenu window; - private int currentPage; - - public MultiPageCanvas(@Nonnull final Player viewer, - @Nullable final Component title, - @Nonnull final List slots, - final boolean adjustSize) { - this.viewer = Objects.requireNonNull(viewer); - this.title = title; - this.slots = List.copyOf(slots); - this.adjustSize = adjustSize; - this.extraMenuItems = new SlotSettings[7]; - this.currentPage = 0; - } - - private void INTERNAL_constructInventory() { - // Clamp the total page within the valid range - if (this.currentPage < 0) { - this.currentPage = 0; - } - final int totalPages = INTERNAL_calculateTotalPages(); - if (this.currentPage >= totalPages) { - this.currentPage = totalPages - 1; - } - // Update the window instance if necessary - final int totalRows = INTERNAL_calculateTotalRows(); - if (this.window == null) { - this.window = new CivChestMenu(this.title, totalRows); - } - else { - this.window.clear(); - if (this.adjustSize && totalRows != this.window.getDimensions().getRows()) { - this.window = new CivChestMenu(this.title, totalRows); - } - } - // Add all content slots - final int contentOffset = this.currentPage * InventoryUtils.CHEST_5_ROWS; - final int contentLength = Math.min(this.slots.size() - contentOffset, InventoryUtils.CHEST_5_ROWS); - for (int i = 0; i < contentLength; i++) { - this.window.getSlot(i).setSettings(this.slots.get(contentOffset + i)); - } - final int totalSlots = this.window.getDimensions().getArea(); - // Back button - if (this.currentPage > 0) { - this.window.getSlot(totalSlots - 10).setSettings(SlotSettings.builder() - .itemTemplate((ignored) -> { - final var item = new ItemStack(Material.ARROW); - ItemUtils.handleItemMeta(item, (ItemMeta meta) -> { - meta.displayName(Component.text() - .color(NamedTextColor.GOLD) - .content("Go to previous page") - .build()); - return true; - }); - return item; - }) - .clickHandler((clicker, click) -> { - if (MultiPageCanvas.this.currentPage > 0) { - MultiPageCanvas.this.currentPage--; - } - showScreen(); - }) - .build()); - } - // Next button - if (this.currentPage < totalPages) { - this.window.getSlot(totalSlots - 1).setSettings(SlotSettings.builder() - .itemTemplate((ignored) -> { - final var item = new ItemStack(Material.ARROW); - ItemUtils.handleItemMeta(item, (ItemMeta meta) -> { - meta.displayName(Component.text() - .color(NamedTextColor.GOLD) - .content("Go to next page") - .build()); - return true; - }); - return item; - }) - .clickHandler((clicker, click) -> { - if (MultiPageCanvas.this.currentPage < totalPages) { - MultiPageCanvas.this.currentPage++; - } - showScreen(); - }) - .build()); - } - // Other menu items - for (int i = 0; i < this.extraMenuItems.length; i++) { - final SlotSettings slot = this.extraMenuItems[i]; - if (slot == null) { - continue; - } - this.window.getSlot(totalSlots - 9 + i).setSettings(slot); - } - } - - protected int INTERNAL_calculateTotalPages() { - final int size = this.slots.size(); - int pages = size / InventoryUtils.CHEST_5_ROWS; - if ((size % InventoryUtils.CHEST_5_ROWS) > 0) { - pages++; - } - return Math.max(pages, 0); - } - - private int INTERNAL_calculateTotalRows() { - if (!this.adjustSize) { - return 6; - } - final int clicks = this.slots.size(); - if (clicks >= InventoryUtils.CHEST_5_ROWS) { - return 6; - } - final int rows = (clicks / 9) + ((clicks % 9) > 0 ? 1 : 0); - return Math.max(rows, 2); // Always have at least 2 rows - } - - /** - * Shows the current page - */ - public void showScreen() { - INTERNAL_constructInventory(); - this.window.open(this.viewer); - } - - /** - * Allows setting a menu slot at the bottom of the GUI. Will not update the inventory, you'll need to do that - * manually with {@link #showScreen()}. - * - * @param slot The slot to set. - * @param index The index of the slot. Must be between 0 and 6 inclusively. - */ - public void setMenuSlot(@Nullable final SlotSettings slot, final int index) { - if (index < 0 || index > 6) { - throw new IllegalArgumentException("Index for MultiPageView menu must be between 0 and 6"); - } - this.extraMenuItems[index] = slot; - } - - /** - * Forcibly changes the page of this view. Will not update the inventory, you'll need to do that manually with - * {@link #showScreen()}. - * - * @param page The page to set. - */ - public void setPage(final int page) { - this.currentPage = page; - } - -}