1
mirror of https://github.com/Shiewk/SModeration.git synced 2026-04-28 05:54:16 +02:00

Amend custom inventory logic

- Make click events based on slot numbers instead of comparing item stacks
- Removed ItemStack parameter from CustomInventory#click as it is no longer needed
This commit is contained in:
Shy
2026-04-03 15:33:32 +02:00
parent c4e1aedeca
commit 5c4feea042
7 changed files with 67 additions and 82 deletions
@@ -19,33 +19,30 @@ public class ConfirmationInventory implements CustomInventory {
private final Inventory inventory;
private final Player player;
private final Component prompt;
private final ItemStack yesStack;
private final ItemStack noStack;
private final Runnable onAccept;
private final Runnable onReject;
private final boolean reversed;
public ConfirmationInventory(Player player, Component prompt, Runnable onAccept, Runnable onReject, boolean reversed) {
public ConfirmationInventory(Player player, Component prompt, Runnable onAccept, Runnable onReject) {
this.player = player;
this.prompt = prompt;
this.onAccept = onAccept;
this.onReject = onReject;
this.reversed = reversed;
inventory = Bukkit.createInventory(this, InventoryType.HOPPER, this.prompt);
yesStack = new ItemStack(Material.LIME_STAINED_GLASS_PANE);
noStack = new ItemStack(Material.RED_STAINED_GLASS_PANE);
}
@Override
public void refresh() {
yesStack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, applyFormatting(translatable("smod.confirm.yes"))));
noStack.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, applyFormatting(translatable("smod.confirm.no"))));
ItemStack accept = new ItemStack(Material.LIME_STAINED_GLASS_PANE);
ItemStack confirmation = new ItemStack(Material.PAPER);
confirmation.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, prompt.colorIfAbsent(NamedTextColor.GOLD)));
ItemStack reject = new ItemStack(Material.RED_STAINED_GLASS_PANE);
inventory.setItem(reversed ? 4 : 0, noStack);
accept.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, applyFormatting(translatable("smod.confirm.yes"))));
confirmation.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, prompt.colorIfAbsent(NamedTextColor.GOLD)));
reject.setData(DataComponentTypes.ITEM_NAME, renderComponent(player, applyFormatting(translatable("smod.confirm.no"))));
inventory.setItem(0, accept);
inventory.setItem(2, confirmation);
inventory.setItem(reversed ? 0 : 4, yesStack);
inventory.setItem(4, reject);
}
@Override
@@ -55,11 +52,11 @@ public class ConfirmationInventory implements CustomInventory {
}
@Override
public void click(ItemStack stack, InventoryClickEvent event) {
if (yesStack.equals(stack)){
public void click(InventoryClickEvent event) {
if (event.getSlot() == 0){
inventory.close();
onAccept.run();
} else if (noStack.equals(stack)) {
} else if (event.getSlot() == 4) {
inventory.close();
onReject.run();
}
@@ -16,7 +16,7 @@ public interface CustomInventory extends InventoryHolder {
void refresh();
void open();
void click(ItemStack stack, InventoryClickEvent event);
void click(InventoryClickEvent event);
default ItemStack createEmptyStack(){
ItemStack stack = new ItemStack(Material.BLACK_STAINED_GLASS_PANE);
@@ -8,7 +8,6 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import static net.kyori.adventure.text.Component.text;
@@ -44,7 +43,7 @@ public class InvSeeEquipmentInventory implements AutoUpdatingCustomInventory {
}
@Override
public void click(ItemStack stack, InventoryClickEvent event) {
public void click(InventoryClickEvent event) {
if (viewer.hasPermission("smod.invsee.modify") && !subject.hasPermission("smod.invsee.preventmodify")){
event.setCancelled(false);
changing = true;
@@ -6,7 +6,6 @@ import org.bukkit.Bukkit;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import static net.kyori.adventure.text.Component.text;
@@ -46,7 +45,7 @@ public class InvSeeInventory implements AutoUpdatingCustomInventory {
}
@Override
public void click(ItemStack stack, InventoryClickEvent event) {
public void click(InventoryClickEvent event) {
if (viewer.hasPermission("smod.invsee.modify") && !subject.hasPermission("smod.invsee.preventmodify")){
event.setCancelled(false);
changing = true;
@@ -8,26 +8,30 @@ import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
public abstract class PageableCustomInventory implements CustomInventory {
public abstract int lastPage();
public abstract void switchPage();
private ItemStack previousStack = null;
private ItemStack nextStack = null;
protected final int prevSlot, nextSlot;
private int page = 0;
public PageableCustomInventory(int prevSlot, int nextSlot) {
this.prevSlot = prevSlot;
this.nextSlot = nextSlot;
}
public int getPage(){
return page;
}
public abstract int lastPage();
public abstract void switchPage();
@Override
public void click(ItemStack stack, InventoryClickEvent event) {
if (stack != null){
if (stack.equals(previousStack)){
public void click(InventoryClickEvent event) {
if (event.getSlot() == prevSlot) {
previousPage();
} else if (stack.equals(nextStack)) {
} else if (event.getSlot() == nextSlot) {
nextPage();
}
}
}
public void nextPage(){
if (page < lastPage()){
@@ -51,7 +55,6 @@ public abstract class PageableCustomInventory implements CustomInventory {
int skip = allowed ? page : page+1;
ItemStack stack = new ItemStack(allowed ? Material.GREEN_STAINED_GLASS_PANE : Material.RED_STAINED_GLASS_PANE);
stack.editMeta(meta -> meta.displayName(applyFormatting(Component.text("Previous page (%s/%s)".formatted(skip, lastPage()+1)).color(color))));
previousStack = stack;
return stack;
}
@@ -61,7 +64,6 @@ public abstract class PageableCustomInventory implements CustomInventory {
int skip = allowed ? page+2 : page+1;
ItemStack stack = new ItemStack(allowed ? Material.GREEN_STAINED_GLASS_PANE : Material.RED_STAINED_GLASS_PANE);
stack.editMeta(meta -> meta.displayName(applyFormatting(Component.text("Next page (%s/%s)".formatted(skip, lastPage()+1)).color(color))));
nextStack = stack;
return stack;
}
}
@@ -12,22 +12,19 @@ import de.shiewk.smoderation.paper.util.SchedulerUtil;
import de.shiewk.smoderation.paper.util.TimeUtil;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.ItemLore;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.Sound;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.bukkit.inventory.meta.SkullMeta;
import org.bukkit.persistence.PersistentDataContainer;
import org.bukkit.persistence.PersistentDataType;
import org.jetbrains.annotations.NotNull;
import java.util.Comparator;
@@ -73,22 +70,20 @@ public class SModMenu extends PageableCustomInventory {
this.comparator = comparator;
}
}
private static final NamespacedKey PUNISHMENT_STORE_KEY = new NamespacedKey("smod", "punishmentid");
private final Inventory inventory;
private final Player player;
private final PunishmentContainer container;
private final Int2ObjectArrayMap<Punishment> slotMap = new Int2ObjectArrayMap<>(45);
private List<Punishment> punishments;
private ItemStack sortStack = null;
private ItemStack filterStack = null;
private ItemStack searchStack = null;
private ItemStack typeStack = null;
private int sort = 0;
private int filter = 0;
private int type = -1;
private int rfId = 0;
private String searchQuery = null;
public SModMenu(Player player, PunishmentContainer container) {
super(45, 53);
this.player = player;
this.container = container;
this.inventory = Bukkit.createInventory(this, 54, translatable("smod.menu"));
@@ -209,7 +204,7 @@ public class SModMenu extends PageableCustomInventory {
loreBuilder.addLine(renderComponent(player, applyFormatting(translatable("smod.menu.filter.switch", NamedTextColor.GOLD))));
stack.setData(DataComponentTypes.LORE, loreBuilder.build());
return filterStack = stack;
return stack;
}
private ItemStack createTypeItem(){
@@ -233,7 +228,7 @@ public class SModMenu extends PageableCustomInventory {
loreBuilder.addLine(renderComponent(player, applyFormatting(translatable("smod.menu.type.switch", NamedTextColor.GOLD))));
stack.setData(DataComponentTypes.LORE, loreBuilder);
return typeStack = stack;
return stack;
}
private ItemStack createSortItem(){
@@ -254,7 +249,7 @@ public class SModMenu extends PageableCustomInventory {
loreBuilder.addLine(renderComponent(player, applyFormatting(translatable("smod.menu.sort.switch", NamedTextColor.GOLD))));
stack.setData(DataComponentTypes.LORE, loreBuilder);
return sortStack = stack;
return stack;
}
private ItemStack createSearchItem(){
@@ -280,7 +275,7 @@ public class SModMenu extends PageableCustomInventory {
loreBuilder.addLine(renderComponent(player, applyFormatting(translatable("smod.menu.search.remove", NamedTextColor.GOLD))));
}
stack.setData(DataComponentTypes.LORE, loreBuilder);
return searchStack = stack;
return stack;
}
private CompletableFuture<ItemStack> createPunishmentItem(Punishment punishment){
@@ -349,7 +344,6 @@ public class SModMenu extends PageableCustomInventory {
stack.setData(DataComponentTypes.LORE, lore);
}
private int rfId = 0;
@Override
public void refresh() {
int rfId = ++this.rfId;
@@ -357,11 +351,12 @@ public class SModMenu extends PageableCustomInventory {
previousPage();
}
inventory.clear();
slotMap.clear();
for (int i = 45; i < 54; i++) {
inventory.setItem(i, createEmptyStack());
}
inventory.setItem(45, createPreviousPageStack());
inventory.setItem(53, createNextPageStack());
inventory.setItem(prevSlot, createPreviousPageStack());
inventory.setItem(nextSlot, createNextPageStack());
inventory.setItem(47, createSearchItem());
inventory.setItem(48, createTypeItem());
inventory.setItem(50, createFilterItem());
@@ -372,13 +367,9 @@ public class SModMenu extends PageableCustomInventory {
if (punishments.size() > ci){
final Punishment punishment = punishments.get(ci);
int slot = i;
slotMap.put(slot, punishment);
createPunishmentItem(punishment).thenAccept(item -> {
if (rfId != this.rfId) return;
if (punishment.isActive()){
if ((punishment.type == PunishmentType.BAN && player.hasPermission("smod.unban")) || (punishment.type == PunishmentType.MUTE && player.hasPermission("smod.unmute"))) {
item.editMeta(meta -> meta.getPersistentDataContainer().set(PUNISHMENT_STORE_KEY, PersistentDataType.LONG, punishment.time));
}
}
inventory.setItem(slot, item);
}).exceptionally(x -> {
LOGGER.warn("Error creating punishment item", x);
@@ -391,14 +382,10 @@ public class SModMenu extends PageableCustomInventory {
}
@Override
public void click(ItemStack stack, InventoryClickEvent event) {
super.click(stack, event);
if (stack != null) {
if (stack.equals(filterStack)){
cycleFilter(event.isRightClick());
} else if (stack.equals(sortStack)){
cycleSort(event.isRightClick());
} else if (stack.equals(searchStack)){
public void click(InventoryClickEvent event) {
super.click(event);
int slot = event.getSlot();
if (slot == 47) {
if (event.isRightClick() && searchQuery != null){
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 0.8f);
searchQuery = null;
@@ -408,22 +395,23 @@ public class SModMenu extends PageableCustomInventory {
player.playSound(player, Sound.UI_BUTTON_CLICK, 1f, 2f);
promptSearchQuery();
}
} else if (stack.equals(typeStack)) {
} else if (slot == 48) {
cycleType(event.isRightClick());
}
final ItemMeta itemMeta = stack.getItemMeta();
if (itemMeta != null) {
final PersistentDataContainer persistentDataContainer = itemMeta.getPersistentDataContainer();
final Long timestamp = persistentDataContainer.get(PUNISHMENT_STORE_KEY, PersistentDataType.LONG);
if (timestamp != null) {
final Punishment punishment = container.findByTimestamp(timestamp);
if (punishment != null) {
} else if (slot == 50) {
cycleFilter(event.isRightClick());
} else if (slot == 51) {
cycleSort(event.isRightClick());
} else {
Punishment punishment = slotMap.get(slot);
if (punishment != null){
if (punishment.isActive()){
if ((punishment.type == PunishmentType.BAN && player.hasPermission("smod.unban")) || (punishment.type == PunishmentType.MUTE && player.hasPermission("smod.unmute"))) {
new ConfirmationInventory(player, translatable("smod.menu.undoConfirmation"), () -> {
punishment.undo(player.getUniqueId());
punishment.broadcastUndo(container);
player.playSound(player, Sound.BLOCK_NOTE_BLOCK_PLING, 1f, 2f);
this.open();
}, this::open, false).open();
}, this::open).open();
}
}
}
@@ -15,7 +15,7 @@ public class CustomInventoryListener implements Listener {
public void onInventoryClick(InventoryClickEvent event){
if (event.getInventory().getHolder() instanceof CustomInventory customInventory){
event.setCancelled(true);
customInventory.click(event.getCurrentItem(), event);
customInventory.click(event);
}
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)