mirror of
https://github.com/rockyhawk64/CommandPanels.git
synced 2025-11-18 07:14:17 +01:00
Compare commits
6 Commits
d75d69ebcc
...
451867be70
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
451867be70 | ||
|
|
eead4eb543 | ||
|
|
e65a1f6636 | ||
|
|
91679a8345 | ||
|
|
00c67b84c5 | ||
|
|
0e54612746 |
@ -4,7 +4,7 @@ api-version: 1.21.9
|
||||
|
||||
main: me.rockyhawk.commandpanels.CommandPanels
|
||||
description: Fully Custom Interactive GUIs with Animations and Logic.
|
||||
folia-supported: false
|
||||
folia-supported: true
|
||||
|
||||
dependencies:
|
||||
server:
|
||||
|
||||
@ -5,7 +5,6 @@ import me.rockyhawk.commandpanels.formatter.Placeholders;
|
||||
import me.rockyhawk.commandpanels.formatter.language.TextFormatter;
|
||||
import me.rockyhawk.commandpanels.formatter.data.DataLoader;
|
||||
import me.rockyhawk.commandpanels.interaction.openpanel.PanelOpenCommand;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import me.rockyhawk.commandpanels.session.inventory.generator.GenerateManager;
|
||||
import me.rockyhawk.commandpanels.session.inventory.listeners.ClickEvents;
|
||||
import me.rockyhawk.commandpanels.session.inventory.listeners.InventoryEvents;
|
||||
@ -17,7 +16,6 @@ public class Context {
|
||||
public FileHandler fileHandler;
|
||||
public PanelOpenCommand panelCommand;
|
||||
public DataLoader dataLoader;
|
||||
public SessionManager session;
|
||||
public GenerateManager generator;
|
||||
|
||||
public Context(CommandPanels pl) {
|
||||
@ -30,7 +28,6 @@ public class Context {
|
||||
fileHandler = new FileHandler(this);
|
||||
panelCommand = new PanelOpenCommand(this);
|
||||
dataLoader = new DataLoader(this);
|
||||
session = new SessionManager(this);
|
||||
generator = new GenerateManager(this);
|
||||
|
||||
// Register plugin command
|
||||
@ -38,7 +35,6 @@ public class Context {
|
||||
plugin.registerCommand("pa", new MainCommand(this));
|
||||
|
||||
// Register events
|
||||
Bukkit.getServer().getPluginManager().registerEvents(session, plugin);
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new InventoryEvents(this), plugin);
|
||||
Bukkit.getServer().getPluginManager().registerEvents(panelCommand, plugin);
|
||||
Bukkit.getServer().getPluginManager().registerEvents(new ClickEvents(this), plugin);
|
||||
@ -47,8 +43,8 @@ public class Context {
|
||||
// Register proxy channels
|
||||
Bukkit.getServer().getMessenger().registerOutgoingPluginChannel(plugin, "BungeeCord");
|
||||
|
||||
// Register PlaceholderAPI in run task to ensure initialisation is complete
|
||||
Bukkit.getScheduler().runTask(plugin, () -> {
|
||||
// Register PlaceholderAPI
|
||||
Bukkit.getGlobalRegionScheduler().run(plugin, task -> {
|
||||
if (Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI")) {
|
||||
new Placeholders(this).register();
|
||||
}
|
||||
|
||||
@ -41,7 +41,7 @@ public class FileHandler {
|
||||
// Create panels folder and add example panels if not there
|
||||
if (!ctx.plugin.folder.exists()) {
|
||||
if (!ctx.plugin.folder.mkdirs()) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_PANELS_FAIL));
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_PANELS_FAIL));
|
||||
return;
|
||||
}
|
||||
createExamplePanels();
|
||||
@ -49,7 +49,7 @@ public class FileHandler {
|
||||
|
||||
// Load panels
|
||||
HashMap<String, Panel> panels = loadYamlFilesRecursively(ctx.plugin.folder);
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> {
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> {
|
||||
ctx.plugin.panels.clear();
|
||||
ctx.plugin.panels.putAll(panels);
|
||||
ctx.panelCommand.populateCommands();
|
||||
@ -120,7 +120,7 @@ public class FileHandler {
|
||||
FileConfiguration floodgateCustomFile = YamlConfiguration.loadConfiguration(getReaderFromStream(ctx.plugin.getResource("floodgate_custom.yml")));
|
||||
floodgateCustomFile.save(new File(ctx.plugin.folder, "floodgate_custom.yml"));
|
||||
} catch (IOException | NullPointerException e) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_EXAMPLE_FAIL));
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_EXAMPLE_FAIL));
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,8 +136,8 @@ public class FileHandler {
|
||||
try {
|
||||
messagesYaml.save(messagesFile);
|
||||
} catch (IOException ex) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin,
|
||||
() -> ctx.text.sendError(
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin,
|
||||
task -> ctx.text.sendError(
|
||||
ctx.plugin.getServer().getConsoleSender(),
|
||||
Message.FILE_CREATE_LANG_FAIL
|
||||
)
|
||||
@ -158,7 +158,7 @@ public class FileHandler {
|
||||
configFileConfiguration.save(configFile);
|
||||
config = YamlConfiguration.loadConfiguration(new File(ctx.plugin.getDataFolder(), "config.yml"));
|
||||
} catch (IOException var11) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_CONFIG_FAIL));
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_CREATE_CONFIG_FAIL));
|
||||
}
|
||||
}else{
|
||||
// Check if the config file has any missing elements
|
||||
@ -168,7 +168,7 @@ public class FileHandler {
|
||||
config.options().copyDefaults(true);
|
||||
config.save(new File(ctx.plugin.getDataFolder() + File.separator + "config.yml"));
|
||||
} catch (IOException var10) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_UPDATE_CONFIG_FAIL));
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> ctx.text.sendError(ctx.plugin.getServer().getConsoleSender(), Message.FILE_UPDATE_CONFIG_FAIL));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,6 @@ package me.rockyhawk.commandpanels.builder;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public abstract class PanelBuilder {
|
||||
@ -14,7 +13,7 @@ public abstract class PanelBuilder {
|
||||
this.player = player;
|
||||
}
|
||||
|
||||
public abstract void open(Panel panel, SessionManager.PanelOpenType openType);
|
||||
public abstract void open(Panel panel);
|
||||
|
||||
public Player getPlayer() {
|
||||
return player;
|
||||
|
||||
@ -14,8 +14,10 @@ import me.rockyhawk.commandpanels.session.dialog.components.DialogButton;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.event.ClickCallback;
|
||||
import net.kyori.adventure.text.event.ClickEvent;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class ActionBuilder implements Listener {
|
||||
private final Context ctx;
|
||||
@ -53,11 +55,17 @@ public class ActionBuilder implements Listener {
|
||||
|
||||
// Use the first non-null value
|
||||
if (text != null) {
|
||||
ctx.session.getPlayerSession((Player) audience).setData(id, text);
|
||||
player.getPersistentDataContainer()
|
||||
.set(new NamespacedKey(ctx.plugin, id),
|
||||
PersistentDataType.STRING, text);
|
||||
} else if (number != null) {
|
||||
ctx.session.getPlayerSession((Player) audience).setData(id, String.valueOf(number));
|
||||
player.getPersistentDataContainer()
|
||||
.set(new NamespacedKey(ctx.plugin, id),
|
||||
PersistentDataType.STRING, String.valueOf(number));
|
||||
} else if (bool != null) {
|
||||
ctx.session.getPlayerSession((Player) audience).setData(id, String.valueOf(bool));
|
||||
player.getPersistentDataContainer()
|
||||
.set(new NamespacedKey(ctx.plugin, id),
|
||||
PersistentDataType.STRING, String.valueOf(bool));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@ import me.rockyhawk.commandpanels.builder.logic.ConditionNode;
|
||||
import me.rockyhawk.commandpanels.builder.logic.ConditionParser;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import me.rockyhawk.commandpanels.session.dialog.DialogComponent;
|
||||
import me.rockyhawk.commandpanels.session.dialog.DialogPanel;
|
||||
import me.rockyhawk.commandpanels.session.dialog.components.*;
|
||||
@ -37,7 +36,7 @@ public class DialogPanelBuilder extends PanelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Panel openPanel, SessionManager.PanelOpenType openType) {
|
||||
public void open(Panel openPanel) {
|
||||
if (!(openPanel instanceof DialogPanel panel)) {
|
||||
throw new IllegalArgumentException("Expected DialogPanel, got " + openPanel.getClass());
|
||||
}
|
||||
@ -132,7 +131,6 @@ public class DialogPanelBuilder extends PanelBuilder {
|
||||
|
||||
// Show the dialog to player and create session
|
||||
player.showDialog(dialog);
|
||||
ctx.session.updateSession(this.getPlayer(), panel, openType);
|
||||
}
|
||||
|
||||
public float parseFloat(String raw) {
|
||||
|
||||
@ -9,7 +9,9 @@ import me.rockyhawk.commandpanels.interaction.commands.RequirementRunner;
|
||||
import me.rockyhawk.commandpanels.session.floodgate.FloodgateComponent;
|
||||
import me.rockyhawk.commandpanels.session.floodgate.FloodgatePanel;
|
||||
import me.rockyhawk.commandpanels.session.floodgate.components.*;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.geysermc.cumulus.response.CustomFormResponse;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
|
||||
@ -156,7 +158,9 @@ public class CustomForm {
|
||||
// Placeholder key will be the ID of the component and make session data from result string
|
||||
// Eg first button at the top will be index 0 %commandpanels_session_exampleslider%
|
||||
private void createSessionData(String key, String output) {
|
||||
ctx.session.getPlayerSession(builder.getPlayer()).setData(key, output);
|
||||
builder.getPlayer().getPersistentDataContainer()
|
||||
.set(new NamespacedKey(ctx.plugin, key),
|
||||
PersistentDataType.STRING, output);
|
||||
}
|
||||
|
||||
private String parseText(String raw) {
|
||||
|
||||
@ -3,7 +3,6 @@ package me.rockyhawk.commandpanels.builder.floodgate;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.builder.PanelBuilder;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import me.rockyhawk.commandpanels.session.floodgate.FloodgatePanel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -21,7 +20,7 @@ public class FloodgatePanelBuilder extends PanelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Panel openPanel, SessionManager.PanelOpenType openType){
|
||||
public void open(Panel openPanel){
|
||||
if (!(openPanel instanceof FloodgatePanel panel)) {
|
||||
throw new IllegalArgumentException("Expected FloodgatePanel, got " + openPanel.getClass());
|
||||
}
|
||||
@ -35,6 +34,5 @@ public class FloodgatePanelBuilder extends PanelBuilder {
|
||||
case "simple" -> this.simpleBuilder.sendForm(panel);
|
||||
case "custom" -> this.customBuilder.sendForm(panel);
|
||||
}
|
||||
ctx.session.updateSession(this.getPlayer(), panel, openType);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,9 +2,7 @@ package me.rockyhawk.commandpanels.builder.inventory;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.builder.PanelBuilder;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import me.rockyhawk.commandpanels.session.inventory.InventoryPanel;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
@ -19,16 +17,11 @@ public class InventoryPanelBuilder extends PanelBuilder {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Panel panel, SessionManager.PanelOpenType openType){
|
||||
public void open(Panel panel){
|
||||
if (!(panel instanceof InventoryPanel)) {
|
||||
throw new IllegalArgumentException("Expected InventoryPanel, got " + panel.getClass());
|
||||
}
|
||||
Inventory panelInv = panelFactory.createInventory((InventoryPanel) panel, this.getPlayer());
|
||||
if(panelInv.isEmpty()) {
|
||||
ctx.text.sendError(this.getPlayer(), Message.PANEL_NO_ITEMS);
|
||||
return;
|
||||
}
|
||||
this.getPlayer().openInventory(panelInv);
|
||||
ctx.session.updateSession(this.getPlayer(), panel, openType);
|
||||
}
|
||||
}
|
||||
@ -38,13 +38,13 @@ public class PanelFactory {
|
||||
if (rows.matches("\\d+")) {
|
||||
int rowsNum = Integer.parseInt(rows);
|
||||
if(rowsNum > 6) rowsNum = 6;
|
||||
inv = Bukkit.createInventory(p, rowsNum * 9, title);
|
||||
inv = Bukkit.createInventory(panel, rowsNum * 9, title);
|
||||
} else {
|
||||
try {
|
||||
inv = Bukkit.createInventory(p, InventoryType.valueOf(rows.toUpperCase()), title);
|
||||
inv = Bukkit.createInventory(panel, InventoryType.valueOf(rows.toUpperCase()), title);
|
||||
} catch (IllegalArgumentException e) {
|
||||
ctx.text.sendError(p, Message.PANEL_INVALID_TYPE);
|
||||
inv = Bukkit.createInventory(p, 9, title); // fallback to 1 row
|
||||
inv = Bukkit.createInventory(panel, 9, title); // fallback to 1 row
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -49,9 +49,7 @@ public class ItemBuilder {
|
||||
// Use PersistentDataContainer for item recognition
|
||||
NamespacedKey itemId = new NamespacedKey(ctx.plugin, "item_id");
|
||||
NamespacedKey baseItemId = new NamespacedKey(ctx.plugin, "base_item_id");
|
||||
NamespacedKey panelId = new NamespacedKey(ctx.plugin, "panel_id");
|
||||
itemStack.editPersistentDataContainer(c -> c.set(itemId, PersistentDataType.STRING, item.id()));
|
||||
itemStack.editPersistentDataContainer(c -> c.set(panelId, PersistentDataType.STRING, panel.getName()));
|
||||
itemStack.editPersistentDataContainer(c -> c.set(baseItemId, PersistentDataType.STRING, item.id()));
|
||||
|
||||
// Set item to the slot
|
||||
|
||||
@ -4,7 +4,6 @@ import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.commands.SubCommand;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -61,7 +60,7 @@ public class OpenCommand implements SubCommand {
|
||||
ctx.text.sendInfo(sender, Message.PANEL_OPEN_TRIGGERED);
|
||||
}
|
||||
|
||||
panel.open(ctx, target, SessionManager.PanelOpenType.EXTERNAL);
|
||||
panel.open(ctx, target, true);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,13 +20,15 @@ public class ReloadCommand implements SubCommand {
|
||||
|
||||
@Override
|
||||
public boolean execute(Context ctx, CommandSender sender, String[] args) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(ctx.plugin, () -> {
|
||||
Bukkit.getAsyncScheduler().runNow(ctx.plugin, task -> {
|
||||
ctx.text.lang.reloadTranslations();
|
||||
ctx.fileHandler.updateConfigFiles();
|
||||
ctx.fileHandler.reloadPanels();
|
||||
ctx.panelCommand.populateCommands();
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> ctx.text.sendInfo(sender, Message.PLUGIN_RELOADED));
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, t ->
|
||||
ctx.text.sendInfo(sender, Message.PLUGIN_RELOADED));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -47,12 +47,12 @@ public class DataLoader {
|
||||
File file = new File(ctx.plugin.getDataFolder(), "data.yml");
|
||||
dataConfig.save(file);
|
||||
} catch (IOException e) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () ->
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
|
||||
ctx.text.sendError(Bukkit.getConsoleSender(), Message.FILE_SAVE_DATA_FAIL));
|
||||
}
|
||||
}
|
||||
public void saveDataFileAsync() {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(ctx.plugin, this::saveDataFileSync);
|
||||
Bukkit.getAsyncScheduler().runNow(ctx.plugin, task -> saveDataFileSync());
|
||||
}
|
||||
|
||||
public void doDataMath(String playerName, String dataPoint, String dataValue){
|
||||
|
||||
@ -21,7 +21,6 @@ public enum Message {
|
||||
|
||||
// PanelBuilder / PanelFactory / OpenCommand
|
||||
PANEL_LAYOUT_NUMBER_MISSING("Panel layout is missing/skipping a number."),
|
||||
PANEL_NO_ITEMS("Panel must contain at least one item."),
|
||||
PANEL_INVALID_TYPE("Invalid inventory type."),
|
||||
PANEL_NOT_FOUND("Panel not found."),
|
||||
PANEL_OPEN_TRIGGERED("Panel open triggered for player."),
|
||||
|
||||
@ -2,9 +2,9 @@ package me.rockyhawk.commandpanels.formatter.placeholders;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.formatter.PlaceholderResolver;
|
||||
import me.rockyhawk.commandpanels.session.PanelSession;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class SessionDataPlaceholder implements PlaceholderResolver {
|
||||
@Override
|
||||
@ -16,12 +16,14 @@ public class SessionDataPlaceholder implements PlaceholderResolver {
|
||||
// Get data key
|
||||
String key = identifier.substring("session_".length());
|
||||
|
||||
// Get session if it exists
|
||||
PanelSession session = ctx.session.getPlayerSession((Player) player);
|
||||
if(session == null) return "no_session_found";
|
||||
// Get session data if it exists
|
||||
String data = player.getPersistentDataContainer()
|
||||
.get(new NamespacedKey(ctx.plugin, key),
|
||||
PersistentDataType.STRING);
|
||||
if(data == null) return "null";
|
||||
|
||||
// Get the data from session
|
||||
|
||||
return session.getData(key);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,6 +3,7 @@ package me.rockyhawk.commandpanels.interaction.commands;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.tags.*;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@ -38,7 +39,9 @@ public class CommandRunner {
|
||||
}
|
||||
|
||||
public void runCommands(Panel panel, Player player, List<String> commands) {
|
||||
runCommands(panel, player, commands, 0);
|
||||
// Keep command execution thread safe
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task ->
|
||||
runCommands(panel, player, commands, 0));
|
||||
}
|
||||
|
||||
private void runCommands(Panel panel, Player player, List<String> commands, int index) {
|
||||
@ -60,9 +63,11 @@ public class CommandRunner {
|
||||
}
|
||||
|
||||
int nextIndex = index + 1;
|
||||
ctx.plugin.getServer().getScheduler().runTaskLater(ctx.plugin,
|
||||
() -> runCommands(panel, player, commands, nextIndex),
|
||||
ticks);
|
||||
Bukkit.getGlobalRegionScheduler().runDelayed(
|
||||
ctx.plugin,
|
||||
task -> runCommands(panel, player, commands, nextIndex),
|
||||
ticks
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -15,9 +15,7 @@ public class ChatTag implements CommandTagResolver {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> {
|
||||
player.chat(command);
|
||||
});
|
||||
player.chat(command);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,8 +15,6 @@ public class ConsoleCmdTag implements CommandTagResolver {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> {
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
});
|
||||
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), command);
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
@ -20,36 +19,34 @@ public class GiveTag implements CommandTagResolver {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> {
|
||||
// Example: [give] DIAMOND 3
|
||||
// Basic give tag that gives normal items and drops them if inventory is full
|
||||
String[] parts = command.split("\\s+");
|
||||
// Example: [give] DIAMOND 3
|
||||
// Basic give tag that gives normal items and drops them if inventory is full
|
||||
String[] parts = command.split("\\s+");
|
||||
|
||||
if (parts.length < 1) return;
|
||||
if (parts.length < 1) return;
|
||||
|
||||
try {
|
||||
Material material = Material.matchMaterial(parts[0].toUpperCase());
|
||||
if (material == null || !material.isItem()) {
|
||||
ctx.text.sendError(player, Message.REQUIREMENT_ITEM_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
int amount = 1;
|
||||
if (parts.length >= 2) {
|
||||
amount = Math.max(1, Integer.parseInt(parts[1]));
|
||||
}
|
||||
|
||||
ItemStack item = new ItemStack(material, amount);
|
||||
|
||||
// Add item and handle overflow
|
||||
Map<Integer, ItemStack> leftover = player.getInventory().addItem(item);
|
||||
for (ItemStack left : leftover.values()) {
|
||||
player.getWorld().dropItemNaturally(player.getLocation(), left);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
ctx.text.sendError(player, Message.ITEM_GIVE_ERROR);
|
||||
try {
|
||||
Material material = Material.matchMaterial(parts[0].toUpperCase());
|
||||
if (material == null || !material.isItem()) {
|
||||
ctx.text.sendError(player, Message.REQUIREMENT_ITEM_INVALID);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
int amount = 1;
|
||||
if (parts.length >= 2) {
|
||||
amount = Math.max(1, Integer.parseInt(parts[1]));
|
||||
}
|
||||
|
||||
ItemStack item = new ItemStack(material, amount);
|
||||
|
||||
// Add item and handle overflow
|
||||
Map<Integer, ItemStack> leftover = player.getInventory().addItem(item);
|
||||
for (ItemStack left : leftover.values()) {
|
||||
player.getWorld().dropItemNaturally(player.getLocation(), left);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
ctx.text.sendError(player, Message.ITEM_GIVE_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4,7 +4,6 @@ import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.permissions.PermissionAttachment;
|
||||
|
||||
@ -17,33 +16,31 @@ public class GrantTag implements CommandTagResolver {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> {
|
||||
// Split arguments
|
||||
String[] parts = command.split("\\s+", 2);
|
||||
// Split arguments
|
||||
String[] parts = command.split("\\s+", 2);
|
||||
|
||||
if (parts.length < 2) {
|
||||
ctx.text.sendError(player, Message.ITEM_GRANT_SYNTAX_INVALID);
|
||||
return;
|
||||
}
|
||||
if (parts.length < 2) {
|
||||
ctx.text.sendError(player, Message.ITEM_GRANT_SYNTAX_INVALID);
|
||||
return;
|
||||
}
|
||||
|
||||
String permission = parts[0];
|
||||
String commandToExecute = parts[1];
|
||||
String permission = parts[0];
|
||||
String commandToExecute = parts[1];
|
||||
|
||||
boolean hadPermission = player.hasPermission(permission) || player.isOp();
|
||||
PermissionAttachment attachment = null;
|
||||
boolean hadPermission = player.hasPermission(permission) || player.isOp();
|
||||
PermissionAttachment attachment = null;
|
||||
|
||||
if (!hadPermission) {
|
||||
attachment = player.addAttachment(ctx.plugin);
|
||||
attachment.setPermission(permission, true);
|
||||
}
|
||||
if (!hadPermission) {
|
||||
attachment = player.addAttachment(ctx.plugin);
|
||||
attachment.setPermission(permission, true);
|
||||
}
|
||||
|
||||
// Perform chat operation with the permission attached
|
||||
player.chat(commandToExecute);
|
||||
// Perform chat operation with the permission attached
|
||||
player.chat(commandToExecute);
|
||||
|
||||
// Cleanup: remove permission only if it was not already granted
|
||||
if (attachment != null) {
|
||||
player.removeAttachment(attachment);
|
||||
}
|
||||
});
|
||||
// Cleanup: remove permission only if it was not already granted
|
||||
if (attachment != null) {
|
||||
player.removeAttachment(attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package me.rockyhawk.commandpanels.interaction.commands.tags;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class MessageTag implements CommandTagResolver {
|
||||
@ -15,10 +14,8 @@ public class MessageTag implements CommandTagResolver {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> {
|
||||
// Use Component parse so that advanced MiniMessage functionality works
|
||||
player.sendMessage(ctx.text.parseTextToComponent(player, raw));
|
||||
});
|
||||
// Use Component parse so that advanced MiniMessage functionality works
|
||||
player.sendMessage(ctx.text.parseTextToComponent(player, raw));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ package me.rockyhawk.commandpanels.interaction.commands.tags;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class OpenPanelTag implements CommandTagResolver {
|
||||
@ -21,7 +20,7 @@ public class OpenPanelTag implements CommandTagResolver {
|
||||
|
||||
// Open panel tag will gracefully move from one panel to the next within the same session
|
||||
Panel openPanel = ctx.plugin.panels.get(command);
|
||||
openPanel.open(ctx, player, SessionManager.PanelOpenType.INTERNAL);
|
||||
openPanel.open(ctx, player, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -3,9 +3,9 @@ package me.rockyhawk.commandpanels.interaction.commands.tags;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.PanelSession;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class PreviousPanelTag implements CommandTagResolver {
|
||||
|
||||
@ -17,10 +17,13 @@ public class PreviousPanelTag implements CommandTagResolver {
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
// Open the previous panel
|
||||
PanelSession session = ctx.session.getPlayerSession(player);
|
||||
if(ctx.session.getPlayerSession(player) != null){
|
||||
if(session.getPrevious() != null)
|
||||
session.getPrevious().open(ctx, player, SessionManager.PanelOpenType.INTERNAL);
|
||||
String previousPanel = player.getPersistentDataContainer()
|
||||
.get(new NamespacedKey(ctx.plugin, "previous"),
|
||||
PersistentDataType.STRING);
|
||||
|
||||
if(previousPanel != null){
|
||||
ctx.plugin.panels.get(previousPanel)
|
||||
.open(ctx, player, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,6 @@ package me.rockyhawk.commandpanels.interaction.commands.tags;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
public class RefreshPanelTag implements CommandTagResolver {
|
||||
@ -15,6 +14,6 @@ public class RefreshPanelTag implements CommandTagResolver {
|
||||
|
||||
@Override
|
||||
public void handle(Context ctx, Panel panel, Player player, String raw, String command) {
|
||||
panel.open(ctx, player, SessionManager.PanelOpenType.REFRESH);
|
||||
panel.open(ctx, player, false);
|
||||
}
|
||||
}
|
||||
@ -3,7 +3,10 @@ package me.rockyhawk.commandpanels.interaction.commands.tags;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandTagResolver;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
public class SessionTag implements CommandTagResolver {
|
||||
|
||||
@ -28,7 +31,9 @@ public class SessionTag implements CommandTagResolver {
|
||||
if (args.length < 3) return;
|
||||
String key = args[1];
|
||||
String value = joinArgs(args, 2);
|
||||
ctx.session.getPlayerSession(player).setData(key, value);
|
||||
player.getPersistentDataContainer()
|
||||
.set(new NamespacedKey(ctx.plugin, key),
|
||||
PersistentDataType.STRING, value);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -36,7 +41,8 @@ public class SessionTag implements CommandTagResolver {
|
||||
// [session] del key
|
||||
if (args.length < 2) return;
|
||||
String key = args[1];
|
||||
ctx.session.getPlayerSession(player).removeData(key);
|
||||
player.getPersistentDataContainer()
|
||||
.remove(new NamespacedKey(ctx.plugin, key));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@ -3,11 +3,12 @@ package me.rockyhawk.commandpanels.interaction.openpanel;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@ -52,7 +53,9 @@ public class PanelOpenCommand implements Listener {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
String key = pnlCmdArgs[i];
|
||||
String value = args[i];
|
||||
ctx.session.getPlayerSession(e.getPlayer()).setData(key, value);
|
||||
e.getPlayer().getPersistentDataContainer()
|
||||
.set(new NamespacedKey(ctx.plugin, key),
|
||||
PersistentDataType.STRING, value);
|
||||
}
|
||||
|
||||
// Stop and do not open panel if conditions are false
|
||||
@ -61,7 +64,7 @@ public class PanelOpenCommand implements Listener {
|
||||
}
|
||||
|
||||
e.setCancelled(true);
|
||||
Bukkit.getScheduler().runTask(ctx.plugin, () -> panel.open(ctx, e.getPlayer(), SessionManager.PanelOpenType.EXTERNAL));
|
||||
Bukkit.getGlobalRegionScheduler().run(ctx.plugin, task -> panel.open(ctx, e.getPlayer(), true));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@ -4,7 +4,6 @@ import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
// In session as it is reused for every type of Panel
|
||||
public record ClickActions(
|
||||
List<String> requirements,
|
||||
List<String> commands,
|
||||
|
||||
@ -3,8 +3,11 @@ package me.rockyhawk.commandpanels.session;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.builder.logic.ConditionNode;
|
||||
import me.rockyhawk.commandpanels.builder.logic.ConditionParser;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.persistence.PersistentDataContainer;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ -38,7 +41,23 @@ public abstract class Panel {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract void open(Context ctx, Player player, SessionManager.PanelOpenType openType);
|
||||
// Updates data to set the current panel and previous panel.
|
||||
public void updatePanelData(Context ctx, Player p) {
|
||||
NamespacedKey keyCurrent = new NamespacedKey(ctx.plugin, "current");
|
||||
NamespacedKey keyPrevious = new NamespacedKey(ctx.plugin, "previous");
|
||||
PersistentDataContainer container = p.getPersistentDataContainer();
|
||||
|
||||
// Move current → previous
|
||||
String current = container.get(keyCurrent, PersistentDataType.STRING);
|
||||
current = (current != null) ? current : "";
|
||||
container.set(keyPrevious, PersistentDataType.STRING, current);
|
||||
|
||||
// Set this panel as the new current
|
||||
container.set(keyCurrent, PersistentDataType.STRING, this.name);
|
||||
}
|
||||
|
||||
|
||||
public abstract void open(Context ctx, Player player, boolean isNewPanelSession);
|
||||
|
||||
public String getName() { return name; }
|
||||
|
||||
|
||||
@ -1,79 +0,0 @@
|
||||
package me.rockyhawk.commandpanels.session;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PanelSession {
|
||||
private Panel panel;
|
||||
private Panel previous;
|
||||
private final Player player;
|
||||
private final Map<String, String> data;
|
||||
|
||||
private PanelUpdater updater;
|
||||
|
||||
public PanelSession(Panel panel, Player player) {
|
||||
this.panel = panel;
|
||||
this.previous = null;
|
||||
this.player = player;
|
||||
this.data = new HashMap<>();
|
||||
}
|
||||
|
||||
public Panel getPanel() {
|
||||
return panel;
|
||||
}
|
||||
|
||||
public void setPanel(Panel panel) {
|
||||
// First panel since session start, update and return
|
||||
if(this.panel == null) {
|
||||
this.panel = panel;
|
||||
return;
|
||||
}
|
||||
// Update previous panel if new panel is different
|
||||
if(!panel.getName().equals(this.panel.getName())) {
|
||||
this.previous = this.panel;
|
||||
}
|
||||
this.panel = panel;
|
||||
}
|
||||
|
||||
public Player getPlayer(){
|
||||
return player;
|
||||
}
|
||||
|
||||
// Updater controls
|
||||
public void startUpdateTask(Context ctx, PanelUpdater updater) {
|
||||
removeUpdateTask();
|
||||
this.updater = updater;
|
||||
updater.start(ctx, this);
|
||||
}
|
||||
|
||||
public void removeUpdateTask() {
|
||||
if (updater != null){
|
||||
this.updater.stop();
|
||||
this.updater = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Session data
|
||||
public void setData(String key, String value) {
|
||||
data.put(key, value);
|
||||
}
|
||||
|
||||
public String getData(String key) {
|
||||
return data.get(key);
|
||||
}
|
||||
|
||||
public void removeData(String key) {
|
||||
data.remove(key);
|
||||
}
|
||||
|
||||
public void clearData() {
|
||||
data.clear();
|
||||
}
|
||||
|
||||
public Panel getPrevious() {
|
||||
return previous;
|
||||
}
|
||||
}
|
||||
@ -1,9 +0,0 @@
|
||||
package me.rockyhawk.commandpanels.session;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
|
||||
public interface PanelUpdater {
|
||||
void start(Context ctx, PanelSession session);
|
||||
void stop();
|
||||
}
|
||||
|
||||
@ -1,78 +0,0 @@
|
||||
package me.rockyhawk.commandpanels.session;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.formatter.language.Message;
|
||||
import me.rockyhawk.commandpanels.session.inventory.InventoryPanel;
|
||||
import me.rockyhawk.commandpanels.session.inventory.InventoryPanelUpdater;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
import org.bukkit.event.player.PlayerQuitEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SessionManager implements Listener {
|
||||
private final Context ctx;
|
||||
private final Map<UUID, PanelSession> panelSessions = new HashMap<>();
|
||||
|
||||
public SessionManager(Context ctx) {
|
||||
this.ctx = ctx;
|
||||
}
|
||||
|
||||
public PanelSession getPlayerSession(Player player) {
|
||||
return panelSessions.get(player.getUniqueId());
|
||||
}
|
||||
|
||||
public void updateSession(Player player, Panel panel, PanelOpenType openType) {
|
||||
UUID uuid = player.getUniqueId();
|
||||
boolean panelSnooper = ctx.fileHandler.config.getBoolean("panel-snooper");
|
||||
|
||||
panelSessions.compute(uuid, (key, session) -> {
|
||||
// Start a new session no panel open, or switch panel
|
||||
if (session == null) {
|
||||
session = new PanelSession(panel, player);
|
||||
} else {
|
||||
session.setPanel(panel);
|
||||
}
|
||||
if (panelSnooper && panel != null)
|
||||
ctx.text.sendInfo(Bukkit.getConsoleSender(), Message.PANEL_OPEN_LOG, player.getName(), panel.getName());
|
||||
|
||||
// Update data file when sessions are started
|
||||
ctx.dataLoader.saveDataFileAsync();
|
||||
|
||||
// Assign refresher for new panel
|
||||
if (panel instanceof InventoryPanel) {
|
||||
InventoryPanelUpdater updater = new InventoryPanelUpdater();
|
||||
session.startUpdateTask(ctx, updater);
|
||||
}
|
||||
return session;
|
||||
});
|
||||
}
|
||||
|
||||
public void removeSession(Player player) {
|
||||
panelSessions.remove(player.getUniqueId());
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerJoin(PlayerJoinEvent e) {
|
||||
// Start session with no panel to allow data to be added
|
||||
ctx.session.updateSession(e.getPlayer(), null, PanelOpenType.EXTERNAL);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||
// Always remove session once player leaves
|
||||
ctx.session.removeSession(e.getPlayer());
|
||||
}
|
||||
|
||||
public enum PanelOpenType {
|
||||
EXTERNAL, // Opened via external action
|
||||
INTERNAL, // Opened via in-panel navigation
|
||||
REFRESH // Internal and refresh only
|
||||
}
|
||||
|
||||
}
|
||||
@ -5,7 +5,6 @@ import me.rockyhawk.commandpanels.builder.PanelBuilder;
|
||||
import me.rockyhawk.commandpanels.builder.dialog.DialogPanelBuilder;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandRunner;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import me.rockyhawk.commandpanels.session.floodgate.FloodgatePanel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
@ -53,26 +52,29 @@ public class DialogPanel extends Panel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Context ctx, Player player, SessionManager.PanelOpenType openType){
|
||||
public void open(Context ctx, Player player, boolean isNewPanelSession){
|
||||
// Check for floodgate panel if bedrock player
|
||||
Panel panel = ctx.plugin.panels.get(floodgate);
|
||||
if (Bukkit.getPluginManager().getPlugin("floodgate") != null) {
|
||||
if (panel instanceof FloodgatePanel floodgatePanel &&
|
||||
FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) {
|
||||
floodgatePanel.open(ctx, player, openType);
|
||||
floodgatePanel.open(ctx, player, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Run panel commands
|
||||
if(openType != SessionManager.PanelOpenType.REFRESH) {
|
||||
if(isNewPanelSession) {
|
||||
// Update panel data values
|
||||
updatePanelData(ctx, player);
|
||||
|
||||
// Run panel commands
|
||||
CommandRunner runner = new CommandRunner(ctx);
|
||||
runner.runCommands(this, player, this.getCommands());
|
||||
}
|
||||
|
||||
// Build and open panel
|
||||
PanelBuilder builder = new DialogPanelBuilder(ctx, player);
|
||||
builder.open(this, openType);
|
||||
builder.open(this);
|
||||
}
|
||||
|
||||
public Map<String, DialogComponent> getComponents() { return components; }
|
||||
|
||||
@ -5,7 +5,6 @@ import me.rockyhawk.commandpanels.builder.PanelBuilder;
|
||||
import me.rockyhawk.commandpanels.builder.floodgate.FloodgatePanelBuilder;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandRunner;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
@ -49,20 +48,23 @@ public class FloodgatePanel extends Panel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Context ctx, Player player, SessionManager.PanelOpenType openType){
|
||||
public void open(Context ctx, Player player, boolean isNewPanelSession){
|
||||
if (Bukkit.getPluginManager().getPlugin("floodgate") == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Run panel commands
|
||||
if(openType != SessionManager.PanelOpenType.REFRESH) {
|
||||
if(isNewPanelSession) {
|
||||
// Update panel data values
|
||||
updatePanelData(ctx, player);
|
||||
|
||||
// Run panel commands
|
||||
CommandRunner runner = new CommandRunner(ctx);
|
||||
runner.runCommands(this, player, this.getCommands());
|
||||
}
|
||||
|
||||
// Build and open panel
|
||||
PanelBuilder builder = new FloodgatePanelBuilder(ctx, player);
|
||||
builder.open(this, openType);
|
||||
builder.open(this);
|
||||
}
|
||||
public String getSubtitle() { return simpleSubtitle; }
|
||||
public String getFloodgateType() { return floodgateType; }
|
||||
|
||||
@ -5,19 +5,20 @@ import me.rockyhawk.commandpanels.builder.PanelBuilder;
|
||||
import me.rockyhawk.commandpanels.builder.inventory.InventoryPanelBuilder;
|
||||
import me.rockyhawk.commandpanels.interaction.commands.CommandRunner;
|
||||
import me.rockyhawk.commandpanels.session.Panel;
|
||||
import me.rockyhawk.commandpanels.session.SessionManager;
|
||||
import me.rockyhawk.commandpanels.session.floodgate.FloodgatePanel;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.geysermc.floodgate.api.FloodgateApi;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class InventoryPanel extends Panel {
|
||||
public class InventoryPanel extends Panel implements InventoryHolder {
|
||||
private final String rows;
|
||||
private final Map<String, PanelItem> items = new HashMap<>();
|
||||
private final Map<String, List<String>> slots = new HashMap<>();
|
||||
@ -52,26 +53,45 @@ public class InventoryPanel extends Panel {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void open(Context ctx, Player player, SessionManager.PanelOpenType openType) {
|
||||
public void open(Context ctx, Player player, boolean isNewPanelSession) {
|
||||
// Check for floodgate panel if bedrock player
|
||||
Panel panel = ctx.plugin.panels.get(floodgate);
|
||||
if (Bukkit.getPluginManager().getPlugin("floodgate") != null) {
|
||||
if (panel instanceof FloodgatePanel floodgatePanel &&
|
||||
FloodgateApi.getInstance().isFloodgatePlayer(player.getUniqueId())) {
|
||||
floodgatePanel.open(ctx, player, openType);
|
||||
floodgatePanel.open(ctx, player, true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Run panel commands
|
||||
if(openType != SessionManager.PanelOpenType.REFRESH) {
|
||||
|
||||
if(isNewPanelSession) {
|
||||
// Don't open same panel if its already open
|
||||
if(checkCurrentPanel(player)){
|
||||
return;
|
||||
}
|
||||
updatePanelData(ctx, player);
|
||||
|
||||
// Run panel commands
|
||||
CommandRunner runner = new CommandRunner(ctx);
|
||||
runner.runCommands(this, player, this.getCommands());
|
||||
|
||||
// Start a panel updater
|
||||
InventoryPanelUpdater updater = new InventoryPanelUpdater();
|
||||
updater.start(ctx, player, this);
|
||||
}
|
||||
|
||||
// Build and open the panel
|
||||
PanelBuilder builder = new InventoryPanelBuilder(ctx, player);
|
||||
builder.open(this, openType);
|
||||
builder.open(this);
|
||||
}
|
||||
|
||||
// Do not open the same panel again if its already open
|
||||
private boolean checkCurrentPanel(Player p) {
|
||||
if(p.getOpenInventory().getTopInventory().getHolder() instanceof InventoryPanel panel){
|
||||
return panel.getName().equals(getName());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getRows() {
|
||||
@ -89,4 +109,10 @@ public class InventoryPanel extends Panel {
|
||||
public String getUpdateDelay() {
|
||||
return updateDelay;
|
||||
}
|
||||
|
||||
// For InventoryHolder implementation
|
||||
@Override
|
||||
public Inventory getInventory() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -1,88 +1,95 @@
|
||||
package me.rockyhawk.commandpanels.session.inventory;
|
||||
|
||||
import io.papermc.paper.persistence.PersistentDataContainerView;
|
||||
import io.papermc.paper.threadedregions.scheduler.ScheduledTask;
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.builder.inventory.InventoryPanelBuilder;
|
||||
import me.rockyhawk.commandpanels.builder.inventory.items.ItemBuilder;
|
||||
import me.rockyhawk.commandpanels.session.PanelUpdater;
|
||||
import me.rockyhawk.commandpanels.session.PanelSession;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
import org.bukkit.inventory.InventoryHolder;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
import org.bukkit.persistence.PersistentDataType;
|
||||
import org.bukkit.scheduler.BukkitRunnable;
|
||||
|
||||
public class InventoryPanelUpdater implements PanelUpdater {
|
||||
public class InventoryPanelUpdater {
|
||||
|
||||
private BukkitRunnable task;
|
||||
|
||||
@Override
|
||||
public void start(Context ctx, PanelSession session) {
|
||||
if (!(session.getPanel() instanceof InventoryPanel panel)) return;
|
||||
private ScheduledTask task;
|
||||
|
||||
public void start(Context ctx, Player p, InventoryPanel panel) {
|
||||
// If restarted, stop current event
|
||||
stop();
|
||||
|
||||
InventoryPanelBuilder panelBuilder = new InventoryPanelBuilder(ctx, session.getPlayer());
|
||||
InventoryPanelBuilder panelBuilder = new InventoryPanelBuilder(ctx, p);
|
||||
ItemBuilder builder = new ItemBuilder(ctx, panelBuilder);
|
||||
|
||||
int updateDelay = 20;
|
||||
if(panel.getUpdateDelay().matches("\\d+")){
|
||||
if (panel.getUpdateDelay().matches("\\d+")) {
|
||||
// Update delay value is a number
|
||||
updateDelay = Integer.parseInt(panel.getUpdateDelay());
|
||||
}
|
||||
|
||||
// If update delay is 0 then do not run the updater
|
||||
if(updateDelay == 0){
|
||||
if (updateDelay == 0) {
|
||||
this.task = null;
|
||||
return;
|
||||
}
|
||||
|
||||
this.task = new BukkitRunnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Inventory inv = session.getPlayer().getOpenInventory().getTopInventory();
|
||||
NamespacedKey itemIdKey = new NamespacedKey(ctx.plugin, "item_id");
|
||||
NamespacedKey baseIdKey = new NamespacedKey(ctx.plugin, "base_item_id");
|
||||
NamespacedKey fillItem = new NamespacedKey(ctx.plugin, "fill_item");
|
||||
|
||||
for (int slot = 0; slot < inv.getSize(); slot++) {
|
||||
ItemStack item = inv.getItem(slot);
|
||||
if (item == null || item.getType().isAir()) continue;
|
||||
|
||||
PersistentDataContainerView container = item.getPersistentDataContainer();
|
||||
if (!container.has(itemIdKey, PersistentDataType.STRING) ||
|
||||
container.has(fillItem, PersistentDataType.STRING)) continue;
|
||||
String itemId = container.get(itemIdKey, PersistentDataType.STRING);
|
||||
String baseItemId = container.get(baseIdKey, PersistentDataType.STRING);
|
||||
|
||||
PanelItem panelItem = panel.getItems().get(itemId);
|
||||
if(!panelItem.animate().isEmpty()){
|
||||
// If there is an animation
|
||||
PanelItem animateItem = panel.getItems().get(panelItem.animate());
|
||||
if(animateItem != null) panelItem = animateItem;
|
||||
|
||||
}else if(!baseItemId.equals(itemId)){
|
||||
// If baseItemId is different from itemId with no animation, change back to base item
|
||||
panelItem = panel.getItems().get(baseItemId);
|
||||
// Schedule repeating GUI update task on the player's region
|
||||
this.task = Bukkit.getRegionScheduler().runAtFixedRate(
|
||||
ctx.plugin,
|
||||
p.getLocation(),
|
||||
(scheduledTask) -> {
|
||||
Inventory inv = p.getOpenInventory().getTopInventory();
|
||||
|
||||
InventoryHolder holder = inv.getHolder();
|
||||
if (!(holder instanceof InventoryPanel) || holder != panel) {
|
||||
stop();
|
||||
return;
|
||||
}
|
||||
|
||||
// Build the new item
|
||||
ItemStack newItem = builder.buildItem(panel, panelItem);
|
||||
NamespacedKey itemIdKey = new NamespacedKey(ctx.plugin, "item_id");
|
||||
NamespacedKey baseIdKey = new NamespacedKey(ctx.plugin, "base_item_id");
|
||||
NamespacedKey fillItem = new NamespacedKey(ctx.plugin, "fill_item");
|
||||
|
||||
// Update base item to original base item
|
||||
newItem.editPersistentDataContainer(c -> c.set(baseIdKey, PersistentDataType.STRING, baseItemId));
|
||||
for (int slot = 0; slot < inv.getSize(); slot++) {
|
||||
ItemStack item = inv.getItem(slot);
|
||||
if (item == null || item.getType().isAir()) continue;
|
||||
|
||||
inv.setItem(slot, newItem);
|
||||
}
|
||||
}
|
||||
};
|
||||
PersistentDataContainerView container = item.getPersistentDataContainer();
|
||||
if (!container.has(itemIdKey, PersistentDataType.STRING) ||
|
||||
container.has(fillItem, PersistentDataType.STRING)) continue;
|
||||
|
||||
task.runTaskTimer(ctx.plugin, updateDelay, updateDelay);
|
||||
String itemId = container.get(itemIdKey, PersistentDataType.STRING);
|
||||
String baseItemId = container.get(baseIdKey, PersistentDataType.STRING);
|
||||
|
||||
PanelItem panelItem = panel.getItems().get(itemId);
|
||||
if (!panelItem.animate().isEmpty()) {
|
||||
// If there is an animation
|
||||
PanelItem animateItem = panel.getItems().get(panelItem.animate());
|
||||
if (animateItem != null) panelItem = animateItem;
|
||||
|
||||
} else if (!baseItemId.equals(itemId)) {
|
||||
// If baseItemId is different from itemId with no animation, change back to base item
|
||||
panelItem = panel.getItems().get(baseItemId);
|
||||
}
|
||||
|
||||
// Build the new item
|
||||
ItemStack newItem = builder.buildItem(panel, panelItem);
|
||||
|
||||
// Update base item to original base item
|
||||
newItem.editPersistentDataContainer(c ->
|
||||
c.set(baseIdKey, PersistentDataType.STRING, baseItemId));
|
||||
|
||||
inv.setItem(slot, newItem);
|
||||
}
|
||||
},
|
||||
updateDelay,
|
||||
updateDelay
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (task != null) {
|
||||
task.cancel();
|
||||
|
||||
@ -35,10 +35,7 @@ public class ClickEvents implements Listener {
|
||||
public void onInventoryClick(InventoryClickEvent e) {
|
||||
if (!(e.getWhoClicked() instanceof Player player)) return;
|
||||
if (e.getClickedInventory() == null) return;
|
||||
|
||||
// Only block top inventory interactions
|
||||
Inventory topInventory = e.getView().getTopInventory();
|
||||
if (!e.getClickedInventory().equals(topInventory)) return;
|
||||
if (!(e.getClickedInventory().getHolder() instanceof InventoryPanel panel)) return;
|
||||
|
||||
ItemStack item = e.getCurrentItem();
|
||||
if (item == null || !item.hasItemMeta()) return;
|
||||
@ -47,18 +44,14 @@ public class ClickEvents implements Listener {
|
||||
PersistentDataContainer container = meta.getPersistentDataContainer();
|
||||
|
||||
NamespacedKey baseIdKey = new NamespacedKey(ctx.plugin, "base_item_id");
|
||||
NamespacedKey panelIdKey = new NamespacedKey(ctx.plugin, "panel_id");
|
||||
|
||||
if (!container.has(baseIdKey, PersistentDataType.STRING) ||
|
||||
!container.has(panelIdKey, PersistentDataType.STRING)) return;
|
||||
if (!container.has(baseIdKey, PersistentDataType.STRING)) return;
|
||||
|
||||
// Cancel interaction and prevent taking the item
|
||||
e.setCancelled(true);
|
||||
e.setResult(Event.Result.DENY);
|
||||
|
||||
String itemId = container.get(baseIdKey, PersistentDataType.STRING);
|
||||
String panelId = container.get(panelIdKey, PersistentDataType.STRING);
|
||||
InventoryPanel panel = (InventoryPanel) ctx.plugin.panels.get(panelId);
|
||||
|
||||
// Check valid interaction types
|
||||
switch (e.getClick()) {
|
||||
@ -79,12 +72,11 @@ public class ClickEvents implements Listener {
|
||||
|
||||
@EventHandler
|
||||
public void onInventoryDrag(InventoryDragEvent event) {
|
||||
if (!(event.getWhoClicked() instanceof Player)) return;
|
||||
|
||||
Inventory topInventory = event.getView().getTopInventory();
|
||||
int topSize = topInventory.getSize();
|
||||
if(!(topInventory.getHolder() instanceof InventoryPanel)) return;
|
||||
|
||||
// Only care about drag targets in the top inventory
|
||||
int topSize = topInventory.getSize();
|
||||
boolean draggingOverPanelItem = event.getRawSlots().stream()
|
||||
.filter(slot -> slot < topSize) // only slots in the top inventory
|
||||
.anyMatch(slot -> {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
package me.rockyhawk.commandpanels.session.inventory.listeners;
|
||||
|
||||
import me.rockyhawk.commandpanels.Context;
|
||||
import me.rockyhawk.commandpanels.session.PanelSession;
|
||||
import me.rockyhawk.commandpanels.session.inventory.InventoryPanel;
|
||||
import org.bukkit.NamespacedKey;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
@ -33,11 +33,9 @@ public class InventoryEvents implements Listener {
|
||||
if (!(event.getPlayer() instanceof Player player)) return;
|
||||
|
||||
// Only remove the session if the player has one
|
||||
PanelSession session = ctx.session.getPlayerSession(player);
|
||||
if (isPanelInventory(event.getInventory())) {
|
||||
if (event.getInventory().getHolder() instanceof InventoryPanel) {
|
||||
itemSanitiser(player.getInventory());
|
||||
itemDropper(player, event.getInventory());
|
||||
if(session != null) session.removeUpdateTask();
|
||||
}
|
||||
}
|
||||
|
||||
@ -58,29 +56,12 @@ public class InventoryEvents implements Listener {
|
||||
|
||||
private void closePanels(Player p){
|
||||
if (p.getOpenInventory() != null) { // Player has an open inventory
|
||||
if (isPanelInventory(p.getOpenInventory().getTopInventory())) {
|
||||
if (p.getOpenInventory().getTopInventory().getHolder() instanceof InventoryPanel) {
|
||||
p.closeInventory();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPanelInventory(Inventory inv) {
|
||||
NamespacedKey itemIdKey = new NamespacedKey(ctx.plugin, "item_id");
|
||||
|
||||
for (ItemStack item : inv) {
|
||||
if (item == null) continue;
|
||||
ItemMeta meta = item.getItemMeta();
|
||||
if (meta == null) continue;
|
||||
if (meta.getPersistentDataContainer().has(itemIdKey, PersistentDataType.STRING)) {
|
||||
String val = meta.getPersistentDataContainer().get(itemIdKey, PersistentDataType.STRING);
|
||||
if (val != null) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void itemSanitiser(PlayerInventory inv) {
|
||||
if (inv == null) return;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user