bug fixes and cooldown added

This commit is contained in:
rockyhawk64 2025-10-06 16:46:04 +11:00
parent 1001d8b6b8
commit e4cacd5e4e
9 changed files with 74 additions and 28 deletions

View File

@ -48,7 +48,7 @@ public class TabComplete {
if (sender instanceof Player player) {
for (String panelName : ctx.plugin.panels.keySet()) {
Panel panel = ctx.plugin.panels.get(panelName);
if (panel.canOpen(player, ctx)) {
if (panel.passesConditions(player, ctx)) {
output.add(panelName);
}
}

View File

@ -51,7 +51,7 @@ public class OpenCommand implements SubCommand {
}
}
if(sender instanceof Player && !panel.canOpen((Player) sender, ctx)){
if(sender instanceof Player && !panel.passesConditions((Player) sender, ctx)){
ctx.text.sendError(sender, Message.COMMAND_NO_PERMISSION);
return true;
}

View File

@ -111,6 +111,7 @@ public enum Message {
// Misc
DIALOG_NO_BUTTONS("Dialog needs at least one button"),
COOLDOWN_ERROR("You're opening panels too quickly"),
TELEPORT_ERROR("Error with teleport tag"),
REQUIRE_HEADDATABASE("Download the HeadDatabase plugin to use this feature!");

View File

@ -59,7 +59,7 @@ public class PanelOpenCommand implements Listener {
}
// Stop and do not open panel if conditions are false
if (!panel.canOpen(e.getPlayer(), ctx)) {
if (!panel.passesConditions(e.getPlayer(), ctx)) {
continue;
}

View File

@ -3,6 +3,8 @@ 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 me.rockyhawk.commandpanels.formatter.language.Message;
import me.rockyhawk.commandpanels.session.inventory.InventoryPanel;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
@ -30,7 +32,8 @@ public abstract class Panel {
this.type = config.getString("type", "inventory");
}
public boolean canOpen(Player player, Context ctx) {
// Check run for permission checks with commands
public boolean passesConditions(Player player, Context ctx) {
// Check the panel condition
if (this.conditions.trim().isEmpty()) return true;
try {
@ -41,11 +44,30 @@ public abstract class Panel {
}
}
// Checks for opening fresh panels
public boolean canOpen(Player p, Context ctx) {
// Do not open if user is in cooldown period
NamespacedKey keyTime = new NamespacedKey(ctx.plugin, "last_open_time");
Long lastOpen = p.getPersistentDataContainer().get(keyTime, PersistentDataType.LONG);
if (lastOpen != null && System.currentTimeMillis() - lastOpen < 250) { // 5 ticks
ctx.text.sendError(p, Message.COOLDOWN_ERROR);
return false;
}
// Do not allow the same panel to be opened again if already open
return !(p.getOpenInventory().getTopInventory().getHolder() instanceof InventoryPanel panel)
|| !panel.getName().equals(getName());
}
// 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");
NamespacedKey keyTime = new NamespacedKey(ctx.plugin, "last_open_time");
PersistentDataContainer container = p.getPersistentDataContainer();
// Time the player last opened any panel
container.set(keyTime, PersistentDataType.LONG, System.currentTimeMillis());
// Move current previous
String current = container.get(keyCurrent, PersistentDataType.STRING);

View File

@ -64,7 +64,10 @@ public class DialogPanel extends Panel {
}
if(isNewPanelSession) {
// Update panel data values
// Don't open same panel if its already open
if(!canOpen(player, ctx)){
return;
}
updatePanelData(ctx, player);
// Run panel commands

View File

@ -54,7 +54,10 @@ public class FloodgatePanel extends Panel {
}
if(isNewPanelSession) {
// Update panel data values
// Don't open same panel if its already open
if(!canOpen(player, ctx)){
return;
}
updatePanelData(ctx, player);
// Run panel commands

View File

@ -67,7 +67,7 @@ public class InventoryPanel extends Panel implements InventoryHolder {
if(isNewPanelSession) {
// Don't open same panel if its already open
if(checkCurrentPanel(player)){
if(!canOpen(player, ctx)){
return;
}
updatePanelData(ctx, player);
@ -88,14 +88,6 @@ public class InventoryPanel extends Panel implements InventoryHolder {
}
}
// 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() {
return rows;
}

View File

@ -15,34 +15,39 @@ import org.bukkit.persistence.PersistentDataType;
public class InventoryPanelUpdater {
private ScheduledTask task;
private ScheduledTask checkTask;
private ScheduledTask updateTask;
/**
* Panel updater will maintain itself with a checkTask that will end the updater
* If it finds the panel has been closed it will end the updater tasks
*/
public void start(Context ctx, Player p, InventoryPanel panel) {
// If restarted, stop current event
// Stop existing tasks if any
stop();
InventoryPanelBuilder panelBuilder = new InventoryPanelBuilder(ctx, p);
ItemBuilder builder = new ItemBuilder(ctx, panelBuilder);
// Determine update delay (same as your original logic)
int updateDelay = 20;
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) {
this.task = null;
this.updateTask = null;
return;
}
// Schedule repeating GUI update task on the player's region
this.task = Bukkit.getRegionScheduler().runAtFixedRate(
InventoryPanelBuilder panelBuilder = new InventoryPanelBuilder(ctx, p);
ItemBuilder builder = new ItemBuilder(ctx, panelBuilder);
// Main update task
this.updateTask = Bukkit.getRegionScheduler().runAtFixedRate(
ctx.plugin,
p.getLocation(),
(scheduledTask) -> {
Inventory inv = p.getOpenInventory().getTopInventory();
InventoryHolder holder = inv.getHolder();
if (!(holder instanceof InventoryPanel) || holder != panel) {
stop();
@ -88,12 +93,32 @@ public class InventoryPanelUpdater {
updateDelay,
updateDelay
);
// Fast check task
this.checkTask = Bukkit.getRegionScheduler().runAtFixedRate(
ctx.plugin,
p.getLocation(),
(scheduledTask) -> {
Inventory inv = p.getOpenInventory().getTopInventory();
InventoryHolder holder = inv.getHolder();
if (!(holder instanceof InventoryPanel) || holder != panel) {
stop();
}
},
5,
5
);
}
public void stop() {
if (task != null) {
task.cancel();
task = null;
if (checkTask != null) {
checkTask.cancel();
checkTask = null;
}
if (updateTask != null) {
updateTask.cancel();
updateTask = null;
}
}
}