commit ead39f6fd10f97944343be77bb6375b117da88f4 Author: EpicKnarvik97 Date: Wed Jan 18 16:15:51 2023 +0100 Initial commit diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..6011849 --- /dev/null +++ b/pom.xml @@ -0,0 +1,88 @@ + + + 4.0.0 + + net.knarcraft + KnarGUI + 1.0-SNAPSHOT + jar + + KnarGUI + + + 16 + UTF-8 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + ${java.version} + ${java.version} + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.4 + + + package + + shade + + + false + + + + + + + + src/main/resources + true + + + + + + + spigotmc-repo + https://hub.spigotmc.org/nexus/content/repositories/snapshots/ + + + sonatype + https://oss.sonatype.org/content/groups/public/ + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + + knarcraft-repo + https://git.knarcraft.net/api/packages/EpicKnarvik97/maven + + + + + + org.spigotmc + spigot-api + 1.19.3-R0.1-SNAPSHOT + provided + + + diff --git a/src/net/knarcraft/knargui/AbstractGUI.java b/src/net/knarcraft/knargui/AbstractGUI.java new file mode 100644 index 0000000..3fb8988 --- /dev/null +++ b/src/net/knarcraft/knargui/AbstractGUI.java @@ -0,0 +1,110 @@ +package net.knarcraft.knargui; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public abstract class AbstractGUI { + + private final UUID uuid; + private final Inventory inventory; + private final Map> actions; + + /** + * Instantiates a new abstract GUI + * + * @param inventorySize

The size of the inventory (ignored if inventory type is set)

+ * @param inventoryName

The name of the inventory

+ * @param inventoryType

The type of inventory to use for the GUI, or null for a variable chest GUI

+ */ + public AbstractGUI(int inventorySize, String inventoryName, InventoryType inventoryType) { + this.uuid = UUID.randomUUID(); + if (inventoryType == null) { + this.inventory = Bukkit.createInventory(null, inventorySize, inventoryName); + } else { + this.inventory = Bukkit.createInventory(null, inventoryType, inventoryName); + } + this.actions = new HashMap<>(); + GUIRegistry.registerGUI(this); + } + + /** + * Gets this inventory's unique id + * + * @return

This inventory's unique id

+ */ + public UUID getUuid() { + return this.uuid; + } + + /** + * Gets the inventory used for this GUI + * + * @return

The inventory used for this GUI

+ */ + public Inventory getInventory() { + return this.inventory; + } + + /** + * Sets the item in the given inventory slot + * + * @param inventorySlot

The inventory slot to set the item for

+ * @param itemStack

The item to display in the slot

+ * @return

This GUI. Used for chaining commands

+ */ + public AbstractGUI setItem(int inventorySlot, ItemStack itemStack) { + this.inventory.setItem(inventorySlot, itemStack); + return this; + } + + /** + * Sets the action for clicking the given item slot + * + * @param inventorySlot

The inventory slot to set the action for

+ * @param clickType

The type of click to set an action for

+ * @param action

The action triggered when a click occurs

+ * @return

This GUI. Used for chaining commands

+ */ + public AbstractGUI setClickAction(int inventorySlot, ClickType clickType, GUIAction action) { + if (!this.actions.containsKey(inventorySlot)) { + this.actions.put(inventorySlot, new HashMap<>()); + } + this.actions.get(inventorySlot).put(clickType, action); + return this; + } + + /** + * Opens this inventory for the given player + * + * @param player

The player to open this inventory for

+ */ + public void openFor(Player player) { + player.openInventory(this.inventory); + GUIRegistry.registerOpenGUI(player, getUuid()); + } + + /** + * Gets the action to trigger for the given inventory slot, and the given click type + * + * @param inventorySlot

The inventory slot to get the action for

+ * @param clickType

The click type to get the action for

+ * @return

The action to run, or null if not set

+ */ + public GUIAction getAction(int inventorySlot, ClickType clickType) { + Map storedActions = this.actions.get(inventorySlot); + if (storedActions == null) { + return null; + } else { + return storedActions.get(clickType); + } + } + +} diff --git a/src/net/knarcraft/knargui/AnvilGUI.java b/src/net/knarcraft/knargui/AnvilGUI.java new file mode 100644 index 0000000..1c111ed --- /dev/null +++ b/src/net/knarcraft/knargui/AnvilGUI.java @@ -0,0 +1,52 @@ +package net.knarcraft.knargui; + +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.inventory.AnvilInventory; + +import java.util.function.BiConsumer; + +/** + * A user-interface using an anvil GUI + */ +public abstract class AnvilGUI extends AbstractGUI { + + private BiConsumer action; + + public AnvilGUI(String inventoryName) { + super(0, inventoryName, InventoryType.ANVIL); + } + + /** + * Gets the text the user has written in the renaming field + * + * @return

The text in the renaming field

+ */ + public String getText() { + AnvilInventory anvilInventory = (AnvilInventory) this.getInventory(); + return anvilInventory.getRenameText(); + } + + /** + * Sets an action to be run if this GUI is closed + * + *

The action will be passed the current value of the anvil text

+ * + * @param action

The action to be run

+ */ + public void setCloseAction(BiConsumer action) { + this.action = action; + } + + /** + * Runs the action this GUI should run when closing + * + * @param player

The player that closed this GUI

+ */ + public void runCloseAction(Player player) { + if (action != null) { + this.action.accept(getText(), player); + } + } + +} diff --git a/src/net/knarcraft/knargui/GUIAction.java b/src/net/knarcraft/knargui/GUIAction.java new file mode 100644 index 0000000..b0ef768 --- /dev/null +++ b/src/net/knarcraft/knargui/GUIAction.java @@ -0,0 +1,17 @@ +package net.knarcraft.knargui; + +import org.bukkit.entity.Player; + +/** + * An action which can be triggered on GUI interaction + */ +public interface GUIAction { + + /** + * Runs this action for the given player + * + * @param player

The player that triggered this action

+ */ + void run(Player player); + +} diff --git a/src/net/knarcraft/knargui/GUIListener.java b/src/net/knarcraft/knargui/GUIListener.java new file mode 100644 index 0000000..d05c604 --- /dev/null +++ b/src/net/knarcraft/knargui/GUIListener.java @@ -0,0 +1,52 @@ +package net.knarcraft.knargui; + +import org.bukkit.entity.HumanEntity; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.inventory.InventoryCloseEvent; +import org.bukkit.event.player.PlayerQuitEvent; + +/** + * A listener for tracking GUI interaction + */ +public class GUIListener implements Listener { + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + HumanEntity clicker = event.getWhoClicked(); + //We're not interested in NPCs + if (!(clicker instanceof Player player)) { + return; + } + + AbstractGUI gui = GUIRegistry.getOpenGUI(player); + + //Not our GUI + if (gui == null) { + return; + } + + //Cancel the event to prevent the player from moving or taking items + event.setCancelled(true); + GUIAction action = gui.getAction(event.getSlot(), event.getClick()); + if (action != null) { + action.run(player); + } + } + + @EventHandler + public void onInventoryClose(InventoryCloseEvent event) { + if (!(event.getPlayer() instanceof Player player)) { + return; + } + GUIRegistry.closeGUI(player); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + GUIRegistry.closeGUI(event.getPlayer()); + } + +} diff --git a/src/net/knarcraft/knargui/GUIRegistry.java b/src/net/knarcraft/knargui/GUIRegistry.java new file mode 100644 index 0000000..0a6c738 --- /dev/null +++ b/src/net/knarcraft/knargui/GUIRegistry.java @@ -0,0 +1,86 @@ +package net.knarcraft.knargui; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +/** + * A registry that keeps track of every GUI + */ +public class GUIRegistry { + + private static final Map registeredGUIs = new HashMap<>(); + private static final Map openGUIs = new HashMap<>(); + + /** + * Registers a GUI being opened + * + * @param player

The player the GUI is open for

+ * @param guiId

The unique identifier for the opened GUI

+ */ + public static void registerOpenGUI(Player player, UUID guiId) { + if (!registeredGUIs.containsKey(guiId)) { + throw new IllegalArgumentException("Tried to register GUI being opened for unknown GUI"); + } + openGUIs.put(player.getUniqueId(), guiId); + } + + /** + * Registers the given GUI as a tracked GUI + * + * @param newGUI

The GUI to register

+ */ + public static void registerGUI(AbstractGUI newGUI) { + registeredGUIs.put(newGUI.getUuid(), newGUI); + } + + /** + * Gets the given player's currently open GUI + * + * @param player

The player to get the GUI for

+ * @return

The player's open GUI, or null if no GUI is open

+ */ + public static AbstractGUI getOpenGUI(Player player) { + UUID guiId = openGUIs.get(player.getUniqueId()); + if (guiId == null) { + return null; + } + + return registeredGUIs.get(guiId); + } + + /** + * Registers a GUI as being closed for the given player + * + * @param player

The player that closed a GUI

+ */ + public static void closeGUI(Player player) { + //Run the close action if an anvil GUI is used + AbstractGUI gui = getOpenGUI(player); + if (gui instanceof AnvilGUI anvilGUI) { + anvilGUI.runCloseAction(player); + } + //Un-register the player's open GUI + openGUIs.remove(player.getUniqueId()); + } + + /** + * Deletes the given GUI + * + * @param guiId

The id of the GUI to delete

+ */ + public static void deleteGUI(UUID guiId) { + for (Player player : Bukkit.getOnlinePlayers()) { + AbstractGUI gui = getOpenGUI(player); + //Close the deleted GUI for every player that has it open. The listener should take care of the rest. + if (gui != null && gui.getUuid().equals(guiId)) { + player.closeInventory(); + } + } + registeredGUIs.remove(guiId); + } + +} diff --git a/src/net/knarcraft/knargui/KnarGUI.java b/src/net/knarcraft/knargui/KnarGUI.java new file mode 100644 index 0000000..9e66306 --- /dev/null +++ b/src/net/knarcraft/knargui/KnarGUI.java @@ -0,0 +1,10 @@ +package net.knarcraft.knargui; + +@SuppressWarnings("unused") +public final class KnarGUI { + + private KnarGUI() { + + } + +}