mirror of
https://github.com/HibiscusMC/HMCCosmetics.git
synced 2025-12-30 12:29:16 +00:00
feat: backend recode of the menu system, add refresh rate to auto-update gui
This commit is contained in:
@@ -14,6 +14,7 @@ import dev.triumphteam.gui.guis.Gui;
|
||||
import dev.triumphteam.gui.guis.GuiItem;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@@ -23,7 +24,9 @@ import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class Menu {
|
||||
|
||||
@@ -32,6 +35,8 @@ public class Menu {
|
||||
private final int rows;
|
||||
private final ConfigurationNode config;
|
||||
private final String permissionNode;
|
||||
private final ArrayList<MenuItem> items;
|
||||
private final int refreshRate;
|
||||
|
||||
public Menu(String id, @NotNull ConfigurationNode config) {
|
||||
this.id = id;
|
||||
@@ -40,64 +45,15 @@ public class Menu {
|
||||
title = config.node("title").getString("chest");
|
||||
rows = config.node("rows").getInt(1);
|
||||
permissionNode = config.node("permission").getString("");
|
||||
refreshRate = config.node("refresh-rate").getInt(-1);
|
||||
|
||||
items = new ArrayList<>();
|
||||
setupItems();
|
||||
|
||||
Menus.addMenu(this);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public int getRows() {
|
||||
return this.getRows();
|
||||
}
|
||||
|
||||
public void openMenu(CosmeticUser user) {
|
||||
openMenu(user, false);
|
||||
}
|
||||
|
||||
public void openMenu(@NotNull CosmeticUser user, boolean ignorePermission) {
|
||||
Player player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
if (!ignorePermission && !permissionNode.isEmpty()) {
|
||||
if (!player.hasPermission(permissionNode) && !player.isOp()) {
|
||||
MessagesUtil.sendMessage(player, "no-permission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Component component = Adventure.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(player, this.title));
|
||||
Gui gui = Gui.gui().
|
||||
title(component).
|
||||
rows(this.rows).
|
||||
create();
|
||||
|
||||
gui.setDefaultClickAction(event -> event.setCancelled(true));
|
||||
|
||||
// TODO: Redo this whole gui creation process to allow for all items, possibly implement caching
|
||||
gui = getItems(user, gui);
|
||||
final Gui finalGui = gui; // Need to make it final for the runtask
|
||||
|
||||
// API
|
||||
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
});
|
||||
if (event.isCancelled()) return;
|
||||
// Internal
|
||||
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
finalGui.open(player);
|
||||
});
|
||||
}
|
||||
|
||||
@Contract("_, _ -> param2")
|
||||
private Gui getItems(@NotNull CosmeticUser user, Gui gui) {
|
||||
Player player = user.getPlayer();
|
||||
|
||||
private void setupItems() {
|
||||
for (ConfigurationNode config : config.node("items").childrenMap().values()) {
|
||||
|
||||
List<String> slotString;
|
||||
@@ -137,27 +93,97 @@ public class Menu {
|
||||
if (Types.isType(typeId)) type = Types.getType(typeId);
|
||||
}
|
||||
|
||||
for (int slot : slots) {
|
||||
ItemStack modifiedItem = getMenuItem(user, type, config, item.clone(), slot).clone();
|
||||
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
|
||||
items.add(new MenuItem(slots, item, type, config));
|
||||
}
|
||||
}
|
||||
|
||||
Type finalType = type;
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return this.title;
|
||||
}
|
||||
|
||||
public int getRows() {
|
||||
return this.getRows();
|
||||
}
|
||||
|
||||
public void openMenu(CosmeticUser user) {
|
||||
openMenu(user, false);
|
||||
}
|
||||
|
||||
public void openMenu(@NotNull CosmeticUser user, boolean ignorePermission) {
|
||||
Player player = user.getPlayer();
|
||||
if (player == null) return;
|
||||
if (!ignorePermission && !permissionNode.isEmpty()) {
|
||||
if (!player.hasPermission(permissionNode) && !player.isOp()) {
|
||||
MessagesUtil.sendMessage(player, "no-permission");
|
||||
return;
|
||||
}
|
||||
}
|
||||
final Component component = Adventure.MINI_MESSAGE.deserialize(Hooks.processPlaceholders(player, this.title));
|
||||
Gui gui = Gui.gui().
|
||||
title(component).
|
||||
rows(this.rows).
|
||||
create();
|
||||
|
||||
gui.setDefaultClickAction(event -> event.setCancelled(true));
|
||||
|
||||
AtomicInteger taskid = new AtomicInteger(-1);
|
||||
gui.setOpenGuiAction(event -> {
|
||||
Runnable run = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (gui.getInventory().getViewers().size() == 0 && taskid.get() != -1) {
|
||||
Bukkit.getScheduler().cancelTask(taskid.get());
|
||||
}
|
||||
|
||||
updateMenu(user, gui);
|
||||
}
|
||||
};
|
||||
|
||||
if (refreshRate != -1) {
|
||||
taskid.set(Bukkit.getScheduler().scheduleSyncRepeatingTask(HMCCosmeticsPlugin.getInstance(), run, 0, refreshRate));
|
||||
} else {
|
||||
run.run();
|
||||
}
|
||||
});
|
||||
|
||||
gui.setCloseGuiAction(event -> {
|
||||
if (taskid.get() != -1) Bukkit.getScheduler().cancelTask(taskid.get());
|
||||
});
|
||||
|
||||
// API
|
||||
PlayerMenuOpenEvent event = new PlayerMenuOpenEvent(user, this);
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
Bukkit.getPluginManager().callEvent(event);
|
||||
});
|
||||
if (event.isCancelled()) return;
|
||||
// Internal
|
||||
|
||||
Bukkit.getScheduler().runTask(HMCCosmeticsPlugin.getInstance(), () -> {
|
||||
gui.open(player);
|
||||
});
|
||||
}
|
||||
|
||||
private void updateMenu(CosmeticUser user, Gui gui) {
|
||||
for (MenuItem item : items) {
|
||||
Type type = item.getType();
|
||||
for (int slot : item.getSlots()) {
|
||||
ItemStack modifiedItem = getMenuItem(user, type, item.getItemConfig(), item.getItem().clone(), slot);
|
||||
GuiItem guiItem = ItemBuilder.from(modifiedItem).asGuiItem();
|
||||
guiItem.setAction(event -> {
|
||||
MessagesUtil.sendDebugMessages("Selected slot " + slot);
|
||||
final ClickType clickType = event.getClick();
|
||||
if (finalType != null) finalType.run(user, config, clickType);
|
||||
// Need to delay the update by a tick so it will actually update with new values
|
||||
for (int guiSlot : slots) {
|
||||
gui.updateItem(guiSlot, getMenuItem(user, finalType, config, item.clone(), guiSlot));
|
||||
}
|
||||
MessagesUtil.sendDebugMessages("Updated slot " + slot);
|
||||
if (type != null) type.run(user, item.getItemConfig(), clickType);
|
||||
updateMenu(user, gui);
|
||||
});
|
||||
|
||||
MessagesUtil.sendDebugMessages("Added " + slots + " as " + guiItem + " in the menu");
|
||||
gui.setItem(slot, guiItem);
|
||||
MessagesUtil.sendDebugMessages("Added " + slot + " as " + guiItem + " in the menu");
|
||||
gui.updateItem(slot, guiItem);
|
||||
}
|
||||
}
|
||||
return gui;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.hibiscusmc.hmccosmetics.gui;
|
||||
|
||||
import com.hibiscusmc.hmccosmetics.gui.type.Type;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MenuItem {
|
||||
|
||||
private List<Integer> slots;
|
||||
private ItemStack item;
|
||||
private Type type;
|
||||
private ConfigurationNode itemConfig;
|
||||
|
||||
public MenuItem(List<Integer> slots, ItemStack item, Type type, ConfigurationNode itemConfig) {
|
||||
this.slots = slots;
|
||||
this.item = item;
|
||||
this.type = type;
|
||||
this.itemConfig = itemConfig;
|
||||
}
|
||||
|
||||
public List<Integer> getSlots() {
|
||||
return slots;
|
||||
}
|
||||
|
||||
public ItemStack getItem() {
|
||||
return item;
|
||||
}
|
||||
|
||||
public Type getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public ConfigurationNode getItemConfig() {
|
||||
return itemConfig;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,16 +33,22 @@ public class TypeCosmetic extends Type {
|
||||
|
||||
@Override
|
||||
public void run(CosmeticUser user, @NotNull ConfigurationNode config, ClickType clickType) {
|
||||
if (config.node("cosmetic").virtual()) return;
|
||||
MessagesUtil.sendDebugMessages("Running Cosmetic Click Type");
|
||||
if (config.node("cosmetic").virtual()) {
|
||||
MessagesUtil.sendDebugMessages("Cosmetic Config Field Virtual");
|
||||
return;
|
||||
}
|
||||
String cosmeticName = config.node("cosmetic").getString();
|
||||
Cosmetic cosmetic = Cosmetics.getCosmetic(cosmeticName);
|
||||
Player player = user.getPlayer();
|
||||
if (cosmetic == null) {
|
||||
MessagesUtil.sendDebugMessages("No Cosmetic Found");
|
||||
MessagesUtil.sendMessage(player, "invalid-cosmetic");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.canEquipCosmetic(cosmetic)) {
|
||||
MessagesUtil.sendDebugMessages("No Cosmetic Permission");
|
||||
MessagesUtil.sendMessage(player, "no-cosmetic-permission");
|
||||
return;
|
||||
}
|
||||
@@ -50,6 +56,8 @@ public class TypeCosmetic extends Type {
|
||||
List<String> actionStrings = new ArrayList<>();
|
||||
ConfigurationNode actionConfig = config.node("actions");
|
||||
|
||||
MessagesUtil.sendDebugMessages("Running Actions");
|
||||
|
||||
try {
|
||||
if (!actionConfig.node("any").virtual()) actionStrings.addAll(actionConfig.node("any").getList(String.class));
|
||||
|
||||
@@ -80,7 +88,7 @@ public class TypeCosmetic extends Type {
|
||||
Actions.runActions(user, actionStrings);
|
||||
|
||||
} catch (SerializationException e) {
|
||||
throw new RuntimeException(e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Fixes issue with offhand cosmetics not appearing. Yes, I know this is dumb
|
||||
Runnable run = () -> user.updateCosmetic(cosmetic.getSlot());
|
||||
@@ -90,6 +98,7 @@ public class TypeCosmetic extends Type {
|
||||
}
|
||||
}
|
||||
run.run();
|
||||
MessagesUtil.sendDebugMessages("Finished Type Click Run");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user