Initial commit

This commit is contained in:
Kristian Knarvik 2023-01-18 16:15:51 +01:00
commit ead39f6fd1
7 changed files with 415 additions and 0 deletions

88
pom.xml Normal file
View File

@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.knarcraft</groupId>
<artifactId>KnarGUI</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>KnarGUI</name>
<properties>
<java.version>16</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>spigotmc-repo</id>
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
</repository>
<repository>
<id>sonatype</id>
<url>https://oss.sonatype.org/content/groups/public/</url>
</repository>
<repository>
<id>knarcraft-repo</id>
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
</repository>
</repositories>
<distributionManagement>
<repository>
<id>knarcraft-repo</id>
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
</repository>
<snapshotRepository>
<id>knarcraft-repo</id>
<url>https://git.knarcraft.net/api/packages/EpicKnarvik97/maven</url>
</snapshotRepository>
</distributionManagement>
<dependencies>
<dependency>
<groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId>
<version>1.19.3-R0.1-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>

View File

@ -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<Integer, Map<ClickType, GUIAction>> actions;
/**
* Instantiates a new abstract GUI
*
* @param inventorySize <p>The size of the inventory (ignored if inventory type is set)</p>
* @param inventoryName <p>The name of the inventory</p>
* @param inventoryType <p>The type of inventory to use for the GUI, or null for a variable chest GUI</p>
*/
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 <p>This inventory's unique id</p>
*/
public UUID getUuid() {
return this.uuid;
}
/**
* Gets the inventory used for this GUI
*
* @return <p>The inventory used for this GUI</p>
*/
public Inventory getInventory() {
return this.inventory;
}
/**
* Sets the item in the given inventory slot
*
* @param inventorySlot <p>The inventory slot to set the item for</p>
* @param itemStack <p>The item to display in the slot</p>
* @return <p>This GUI. Used for chaining commands</p>
*/
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 <p>The inventory slot to set the action for</p>
* @param clickType <p>The type of click to set an action for</p>
* @param action <p>The action triggered when a click occurs</p>
* @return <p>This GUI. Used for chaining commands</p>
*/
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 <p>The player to open this inventory for</p>
*/
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 <p>The inventory slot to get the action for</p>
* @param clickType <p>The click type to get the action for</p>
* @return <p>The action to run, or null if not set</p>
*/
public GUIAction getAction(int inventorySlot, ClickType clickType) {
Map<ClickType, GUIAction> storedActions = this.actions.get(inventorySlot);
if (storedActions == null) {
return null;
} else {
return storedActions.get(clickType);
}
}
}

View File

@ -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<String, Player> action;
public AnvilGUI(String inventoryName) {
super(0, inventoryName, InventoryType.ANVIL);
}
/**
* Gets the text the user has written in the renaming field
*
* @return <p>The text in the renaming field</p>
*/
public String getText() {
AnvilInventory anvilInventory = (AnvilInventory) this.getInventory();
return anvilInventory.getRenameText();
}
/**
* Sets an action to be run if this GUI is closed
*
* <p>The action will be passed the current value of the anvil text</p>
*
* @param action <p>The action to be run</p>
*/
public void setCloseAction(BiConsumer<String, Player> action) {
this.action = action;
}
/**
* Runs the action this GUI should run when closing
*
* @param player <p>The player that closed this GUI</p>
*/
public void runCloseAction(Player player) {
if (action != null) {
this.action.accept(getText(), player);
}
}
}

View File

@ -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 <p>The player that triggered this action</p>
*/
void run(Player player);
}

View File

@ -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());
}
}

View File

@ -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<UUID, AbstractGUI> registeredGUIs = new HashMap<>();
private static final Map<UUID, UUID> openGUIs = new HashMap<>();
/**
* Registers a GUI being opened
*
* @param player <p>The player the GUI is open for</p>
* @param guiId <p>The unique identifier for the opened GUI</p>
*/
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 <p>The GUI to register</p>
*/
public static void registerGUI(AbstractGUI newGUI) {
registeredGUIs.put(newGUI.getUuid(), newGUI);
}
/**
* Gets the given player's currently open GUI
*
* @param player <p>The player to get the GUI for</p>
* @return <p>The player's open GUI, or null if no GUI is open</p>
*/
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 <p>The player that closed a GUI</p>
*/
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 <p>The id of the GUI to delete</p>
*/
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);
}
}

View File

@ -0,0 +1,10 @@
package net.knarcraft.knargui;
@SuppressWarnings("unused")
public final class KnarGUI {
private KnarGUI() {
}
}