Replace guild inventory menus with dialogs

This commit is contained in:
Taahh
2026-07-08 22:02:13 -07:00
parent 5f54368611
commit d7b8963f00
10 changed files with 256 additions and 473 deletions
+2 -6
View File
@@ -2,11 +2,10 @@ package dev.plex;
import dev.plex.command.GuildCommand;
import dev.plex.config.ModuleConfig;
import dev.plex.dialog.GuildDialogService;
import dev.plex.guild.GuildHolder;
import dev.plex.handler.ChatHandlerImpl;
import dev.plex.handler.GuildMenuListener;
import dev.plex.handler.GuildWorldProtectionListener;
import dev.plex.handler.RankPermissionMenuListener;
import dev.plex.module.PlexModule;
import dev.plex.api.storage.ModuleStorage;
import dev.plex.storage.GuildRepository;
@@ -22,9 +21,8 @@ public class Guilds extends PlexModule
{
private static Guilds module;
private final GuildHolder guildHolder = new GuildHolder();
private final GuildMenuListener guildMenuListener = new GuildMenuListener();
private final GuildDialogService guildDialogService = new GuildDialogService();
private final GuildWorldProtectionListener guildWorldProtectionListener = new GuildWorldProtectionListener();
private final RankPermissionMenuListener rankPermissionMenuListener = new RankPermissionMenuListener();
private final GuildWorldService guildWorldService = new GuildWorldService();
private GuildRepository guildRepository;
@@ -71,9 +69,7 @@ public class Guilds extends PlexModule
guildHolder.replaceAll(guilds);
});
registerListener(new ChatHandlerImpl());
registerListener(guildMenuListener);
registerListener(guildWorldProtectionListener);
registerListener(rankPermissionMenuListener);
}
@Override
@@ -59,7 +59,7 @@ public class GuildCommand extends SimplePlexCommand
return getSubs();
}
Guilds.get().getGuildHolder().getGuild(player.getUniqueId()).ifPresentOrElse(
guild -> Guilds.get().getGuildMenuListener().openHome(player, guild),
guild -> Guilds.get().getGuildDialogService().openHome(player, guild),
() -> player.sendMessage(messageComponent("guildNotFound"))
);
return null;
@@ -26,7 +26,7 @@ public class MenuSubCommand extends GuildSubCommand
{
assert player != null;
Guilds.get().getGuildHolder().getGuild(player.getUniqueId()).ifPresentOrElse(
guild -> Guilds.get().getGuildMenuListener().openHome(player, guild),
guild -> Guilds.get().getGuildDialogService().openHome(player, guild),
() -> send(player, messageComponent("guildNotFound"))
);
return null;
@@ -32,7 +32,7 @@ public class PermissionsSubCommand extends GuildSubCommand
send(player, messageComponent("guildNotOwner"));
return;
}
Guilds.get().getRankPermissionMenuListener().openRankList(player, guild);
Guilds.get().getGuildDialogService().openPermissions(player, guild);
}, () -> send(player, messageComponent("guildNotFound")));
return null;
}
@@ -0,0 +1,251 @@
package dev.plex.dialog;
import dev.plex.Guilds;
import dev.plex.guild.Guild;
import dev.plex.guild.data.GuildPermission;
import dev.plex.guild.data.GuildRole;
import dev.plex.guild.data.Member;
import io.papermc.paper.dialog.Dialog;
import io.papermc.paper.registry.data.dialog.ActionButton;
import io.papermc.paper.registry.data.dialog.DialogBase;
import io.papermc.paper.registry.data.dialog.action.DialogAction;
import io.papermc.paper.registry.data.dialog.body.DialogBody;
import io.papermc.paper.registry.data.dialog.type.DialogType;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickCallback;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.format.TextDecoration;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
public class GuildDialogService
{
private static final UUID MEMBER_PERMISSION_PROBE = new UUID(0L, 0L);
public void openHome(Player player, Guild guild)
{
player.showDialog(dialog(
title(guild.getName()),
List.of(
body("Welcome to your guild panel.", NamedTextColor.GRAY),
body("Manage members, enter your guild world, or configure member permissions.", NamedTextColor.DARK_AQUA)
),
List.of(
button("Members", "View online status and manage members", audience -> player(audience, viewer -> openMembers(viewer, guild))),
button("Guild World", "Load and enter your ASP guild world", audience -> player(audience, viewer -> enterWorld(viewer, guild))),
button("Permissions", "Configure member block permissions", audience -> player(audience, viewer -> openPermissions(viewer, guild)))
),
1
));
}
public void openMembers(Player player, Guild guild)
{
List<ActionButton> buttons = new ArrayList<>();
for (Member member : guild.getMembers())
{
boolean online = Bukkit.getPlayer(member.getUuid()) != null;
buttons.add(button(
member.getName(),
(online ? "Online" : "Offline") + " - " + (guild.isOwner(member.getUuid()) ? "Owner" : "Member"),
audience -> player(audience, viewer -> openMember(viewer, guild, member.getUuid()))
));
}
buttons.add(button("Back", "Return to the guild menu", audience -> player(audience, viewer -> openHome(viewer, guild))));
player.showDialog(dialog(
title(guild.getName() + " Members"),
List.of(body("Select a member to view or manage them.", NamedTextColor.GRAY)),
buttons,
1
));
}
public void openMember(Player player, Guild guild, UUID memberUuid)
{
Member member = guild.getMember(memberUuid);
if (member == null)
{
openMembers(player, guild);
return;
}
boolean online = Bukkit.getPlayer(member.getUuid()) != null;
List<DialogBody> body = List.of(
body("Status: " + (online ? "Online" : "Offline"), online ? NamedTextColor.GREEN : NamedTextColor.GRAY),
body("Role: " + (guild.isOwner(memberUuid) ? "Owner" : "Member"), guild.isOwner(memberUuid) ? NamedTextColor.GOLD : NamedTextColor.AQUA)
);
List<ActionButton> buttons = new ArrayList<>();
if (guild.isOwner(player.getUniqueId()) && !guild.isOwner(memberUuid))
{
buttons.add(button("Kick Member", "Remove this member from the guild", audience -> player(audience, viewer -> kickMember(viewer, guild, member))));
buttons.add(button("Transfer Ownership", "Make this member the guild owner", audience -> player(audience, viewer -> transferOwner(viewer, guild, member))));
}
if (guild.isOwner(player.getUniqueId()))
{
buttons.add(button("Permissions", "Edit member role permissions", audience -> player(audience, viewer -> openPermissions(viewer, guild))));
}
buttons.add(button("Back", "Return to members", audience -> player(audience, viewer -> openMembers(viewer, guild))));
player.showDialog(dialog(title(member.getName()), body, buttons, 1));
}
public void openPermissions(Player player, Guild guild)
{
if (!guild.isOwner(player.getUniqueId()))
{
player.sendMessage(Guilds.get().messageComponent("guildNotOwner"));
return;
}
List<ActionButton> buttons = new ArrayList<>();
for (GuildPermission permission : GuildPermission.values())
{
boolean enabled = guild.hasPermission(MEMBER_PERMISSION_PROBE, permission);
buttons.add(button(
permission.displayName() + ": " + (enabled ? "Enabled" : "Disabled"),
"Click to toggle " + permission.displayName().toLowerCase(),
audience -> player(audience, viewer -> togglePermission(viewer, guild, permission))
));
}
buttons.add(button("Back", "Return to the guild menu", audience -> player(audience, viewer -> openHome(viewer, guild))));
player.showDialog(dialog(
title("Member Permissions"),
List.of(
body("These permissions apply to regular guild members in the guild world.", NamedTextColor.GRAY),
body("Owners always bypass these restrictions.", NamedTextColor.GOLD)
),
buttons,
1
));
}
private void enterWorld(Player player, Guild guild)
{
player.sendMessage(Guilds.get().messageComponent("guildWorldLoading"));
Guilds.get().getGuildWorldService().ensureWorld(guild).whenComplete((world, throwable) ->
{
if (throwable != null)
{
Guilds.get().api().scheduler().executeGlobal(() ->
{
throwable.printStackTrace();
player.sendMessage(Guilds.get().messageComponent("guildWorldLoadFailed"));
});
return;
}
Guilds.get().api().scheduler().executeEntity(player, () -> player.teleportAsync(world.getSpawnLocation().toCenterLocation()), 1L);
});
}
private void kickMember(Player player, Guild guild, Member member)
{
if (!guild.isOwner(player.getUniqueId()) || guild.isOwner(member.getUuid()))
{
return;
}
Guilds.get().getGuildRepository().removeMember(guild.getGuildUuid(), member.getUuid()).whenComplete((unused, throwable) ->
{
if (throwable != null)
{
player.sendMessage(Guilds.get().messageComponent("guildStorageFailed"));
return;
}
guild.removeMember(member.getUuid());
Guilds.get().getGuildHolder().unindexMember(member.getUuid());
Guilds.get().getGuildWorldService().ejectNonMembers(guild);
player.sendMessage(Guilds.get().messageComponent("guildMemberKicked", member.getName()));
openMembers(player, guild);
});
}
private void transferOwner(Player player, Guild guild, Member member)
{
if (!guild.isOwner(player.getUniqueId()) || guild.isOwner(member.getUuid()))
{
return;
}
Member previousOwner = guild.getMember(player.getUniqueId());
Guilds.get().getGuildRepository().transferOwner(guild.getGuildUuid(), member.getUuid(), player.getUniqueId()).whenComplete((unused, throwable) ->
{
if (throwable != null)
{
player.sendMessage(Guilds.get().messageComponent("guildStorageFailed"));
return;
}
guild.setOwnerUuid(member.getUuid());
member.setRole(GuildRole.OWNER);
if (previousOwner != null)
{
previousOwner.setRole(GuildRole.MEMBER);
}
player.sendMessage(Guilds.get().messageComponent("guildOwnerSet", member.getName()));
openMember(player, guild, previousOwner == null ? member.getUuid() : previousOwner.getUuid());
});
}
private void togglePermission(Player player, Guild guild, GuildPermission permission)
{
boolean enabled = !guild.hasPermission(MEMBER_PERMISSION_PROBE, permission);
guild.setPermission(permission, enabled);
Guilds.get().getGuildRepository().updateMemberPermission(guild.getGuildUuid(), permission, enabled).whenComplete((unused, throwable) ->
{
if (throwable != null)
{
player.sendMessage(Guilds.get().messageComponent("guildStorageFailed"));
return;
}
openPermissions(player, guild);
});
}
private Dialog dialog(Component title, List<DialogBody> body, List<ActionButton> actions, int columns)
{
return Dialog.create(builder -> builder.empty()
.base(DialogBase.builder(title)
.body(body)
.canCloseWithEscape(true)
.build())
.type(DialogType.multiAction(actions)
.columns(columns)
.build()));
}
private ActionButton button(String label, String tooltip, java.util.function.Consumer<Audience> callback)
{
return ActionButton.builder(text(label, NamedTextColor.AQUA))
.tooltip(text(tooltip, NamedTextColor.GRAY))
.width(200)
.action(DialogAction.customClick((response, audience) -> callback.accept(audience), ClickCallback.Options.builder()
.uses(1)
.lifetime(Duration.ofMinutes(5))
.build()))
.build();
}
private DialogBody body(String text, NamedTextColor color)
{
return DialogBody.plainMessage(text(text, color));
}
private Component title(String value)
{
return text(value, NamedTextColor.DARK_AQUA);
}
private Component text(String value, NamedTextColor color)
{
return Component.text(value, color).decoration(TextDecoration.ITALIC, false);
}
private void player(Audience audience, java.util.function.Consumer<Player> playerConsumer)
{
if (audience instanceof Player player)
{
playerConsumer.accept(player);
}
}
}
@@ -1,17 +0,0 @@
package dev.plex.gui;
import dev.plex.guild.Guild;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;
import java.util.UUID;
public record GuildMenuInventoryHolder(Guild guild, GuildMenuView view, UUID memberUuid) implements InventoryHolder
{
@Override
public @NotNull Inventory getInventory()
{
throw new UnsupportedOperationException();
}
}
@@ -1,8 +0,0 @@
package dev.plex.gui;
public enum GuildMenuView
{
HOME,
MEMBERS,
MEMBER
}
@@ -1,15 +0,0 @@
package dev.plex.gui;
import dev.plex.guild.Guild;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.jetbrains.annotations.NotNull;
public record RankPermissionInventoryHolder(Guild guild, String rankName) implements InventoryHolder
{
@Override
public @NotNull Inventory getInventory()
{
throw new UnsupportedOperationException();
}
}
@@ -1,290 +0,0 @@
package dev.plex.handler;
import dev.plex.Guilds;
import dev.plex.guild.Guild;
import dev.plex.guild.data.GuildRole;
import dev.plex.guild.data.Member;
import dev.plex.gui.GuildMenuInventoryHolder;
import dev.plex.gui.GuildMenuView;
import net.kyori.adventure.text.Component;
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.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
public class GuildMenuListener implements Listener
{
private static final int MEMBERS_SLOT = 11;
private static final int WORLD_SLOT = 13;
private static final int PERMISSIONS_SLOT = 15;
private static final int BACK_SLOT = 26;
private static final int KICK_SLOT = 11;
private static final int OWNER_SLOT = 13;
private static final int RANK_PERMISSIONS_SLOT = 15;
public void openHome(Player player, Guild guild)
{
Inventory inventory = Bukkit.createInventory(new GuildMenuInventoryHolder(guild, GuildMenuView.HOME, null), 27, title("* " + guild.getName()));
inventory.setItem(MEMBERS_SLOT, item(Material.PLAYER_HEAD, "Guild Members", NamedTextColor.AQUA, List.of(
line("View online status", NamedTextColor.GRAY),
line("Click to manage members", NamedTextColor.YELLOW)
)));
inventory.setItem(WORLD_SLOT, item(Material.GRASS_BLOCK, "Guild World", NamedTextColor.GREEN, List.of(
line("Load and enter your guild world", NamedTextColor.GRAY),
line("Only guild members can access it", NamedTextColor.DARK_AQUA)
)));
if (guild.isOwner(player.getUniqueId()))
{
inventory.setItem(PERMISSIONS_SLOT, item(Material.COMPARATOR, "Rank Permissions", NamedTextColor.GOLD, List.of(
line("Configure member build permissions", NamedTextColor.GRAY),
line("Break - Place - Interact", NamedTextColor.YELLOW)
)));
}
player.openInventory(inventory);
}
private void openMembers(Player player, Guild guild)
{
Inventory inventory = Bukkit.createInventory(new GuildMenuInventoryHolder(guild, GuildMenuView.MEMBERS, null), 54, title("* " + guild.getName() + " Members"));
List<Member> members = guild.getMembers();
for (int i = 0; i < members.size() && i < 45; i++)
{
inventory.setItem(i, memberItem(guild, members.get(i)));
}
inventory.setItem(BACK_SLOT, item(Material.ARROW, "Back", NamedTextColor.YELLOW, List.of(line("Return to the guild menu", NamedTextColor.GRAY))));
player.openInventory(inventory);
}
private void openMember(Player player, Guild guild, Member member)
{
Inventory inventory = Bukkit.createInventory(new GuildMenuInventoryHolder(guild, GuildMenuView.MEMBER, member.getUuid()), 27, title("* " + member.getName()));
inventory.setItem(4, memberItem(guild, member));
if (guild.isOwner(player.getUniqueId()) && !guild.isOwner(member.getUuid()))
{
inventory.setItem(KICK_SLOT, item(Material.BARRIER, "Kick Member", NamedTextColor.RED, List.of(
line("Remove this player from the guild", NamedTextColor.GRAY),
line("They will lose guild world access", NamedTextColor.DARK_RED)
)));
inventory.setItem(OWNER_SLOT, item(Material.GOLDEN_HELMET, "Transfer Ownership", NamedTextColor.GOLD, List.of(
line("Make this player the guild owner", NamedTextColor.GRAY),
line("You will become a regular member", NamedTextColor.YELLOW)
)));
}
if (guild.isOwner(player.getUniqueId()))
{
inventory.setItem(RANK_PERMISSIONS_SLOT, item(Material.COMPARATOR, "Rank Permissions", NamedTextColor.AQUA, List.of(
line("Open the rank permission editor", NamedTextColor.GRAY)
)));
}
inventory.setItem(BACK_SLOT, item(Material.ARROW, "Back", NamedTextColor.YELLOW, List.of(line("Return to member list", NamedTextColor.GRAY))));
player.openInventory(inventory);
}
@EventHandler(priority = EventPriority.HIGH)
public void onClick(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player player) || !(event.getInventory().getHolder() instanceof GuildMenuInventoryHolder holder))
{
return;
}
event.setCancelled(true);
if (!holder.guild().isMember(player.getUniqueId()))
{
player.closeInventory();
player.sendMessage(Guilds.get().messageComponent("guildNotFound"));
return;
}
ItemStack clickedItem = event.getCurrentItem();
if (clickedItem == null || clickedItem.getType() == Material.AIR)
{
return;
}
switch (holder.view())
{
case HOME -> clickHome(player, holder.guild(), event.getRawSlot());
case MEMBERS -> clickMembers(player, holder.guild(), clickedItem, event.getRawSlot());
case MEMBER -> clickMember(player, holder.guild(), holder.memberUuid(), event.getRawSlot());
}
}
private void clickHome(Player player, Guild guild, int slot)
{
if (slot == MEMBERS_SLOT)
{
openMembers(player, guild);
return;
}
if (slot == WORLD_SLOT)
{
player.closeInventory();
Guilds.get().getGuildWorldService().ensureWorld(guild).whenComplete((world, throwable) ->
{
if (throwable != null)
{
Guilds.get().api().scheduler().executeGlobal(() -> player.sendMessage(Guilds.get().messageComponent("guildWorldLoadFailed")));
return;
}
Guilds.get().api().scheduler().executeEntity(player, () -> player.teleportAsync(world.getSpawnLocation().toCenterLocation()), 1L);
});
return;
}
if (slot == PERMISSIONS_SLOT && guild.isOwner(player.getUniqueId()))
{
Guilds.get().getRankPermissionMenuListener().openRankList(player, guild);
}
}
private void clickMembers(Player player, Guild guild, ItemStack clickedItem, int slot)
{
if (slot == BACK_SLOT)
{
openHome(player, guild);
return;
}
memberUuid(clickedItem).map(guild::getMember).filter(Objects::nonNull).ifPresent(member -> openMember(player, guild, member));
}
private void clickMember(Player player, Guild guild, UUID memberUuid, int slot)
{
Member member = guild.getMember(memberUuid);
if (member == null)
{
openMembers(player, guild);
return;
}
if (slot == BACK_SLOT)
{
openMembers(player, guild);
return;
}
if (!guild.isOwner(player.getUniqueId()))
{
return;
}
if (slot == KICK_SLOT && !guild.isOwner(memberUuid))
{
Guilds.get().getGuildRepository().removeMember(guild.getGuildUuid(), memberUuid).whenComplete((unused, throwable) ->
{
if (throwable != null)
{
player.sendMessage(Guilds.get().messageComponent("guildStorageFailed"));
return;
}
guild.removeMember(memberUuid);
Guilds.get().getGuildHolder().unindexMember(memberUuid);
Guilds.get().getGuildWorldService().ejectNonMembers(guild);
player.sendMessage(Guilds.get().messageComponent("guildMemberKicked", member.getName()));
openMembers(player, guild);
});
return;
}
if (slot == OWNER_SLOT && !guild.isOwner(memberUuid))
{
Member previousOwner = guild.getMember(player.getUniqueId());
Guilds.get().getGuildRepository().transferOwner(guild.getGuildUuid(), memberUuid, player.getUniqueId()).whenComplete((unused, throwable) ->
{
if (throwable != null)
{
player.sendMessage(Guilds.get().messageComponent("guildStorageFailed"));
return;
}
guild.setOwnerUuid(memberUuid);
member.setRole(GuildRole.OWNER);
if (previousOwner != null)
{
previousOwner.setRole(GuildRole.MEMBER);
}
player.sendMessage(Guilds.get().messageComponent("guildOwnerSet", member.getName()));
openMember(player, guild, previousOwner == null ? member : previousOwner);
});
return;
}
if (slot == RANK_PERMISSIONS_SLOT)
{
Guilds.get().getRankPermissionMenuListener().openRankList(player, guild);
}
}
private ItemStack memberItem(Guild guild, Member member)
{
boolean online = Bukkit.getPlayer(member.getUuid()) != null;
ItemStack itemStack = new ItemStack(online ? Material.LIME_WOOL : Material.GRAY_WOOL);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(text(member.getName(), online ? NamedTextColor.GREEN : NamedTextColor.GRAY));
List<Component> lore = new ArrayList<>();
lore.add(label("Status", online ? "Online" : "Offline", online ? NamedTextColor.GREEN : NamedTextColor.GRAY));
lore.add(label("Role", guild.isOwner(member.getUuid()) ? "Owner" : "Member", guild.isOwner(member.getUuid()) ? NamedTextColor.GOLD : NamedTextColor.AQUA));
lore.add(label("Rank", guild.isOwner(member.getUuid()) ? "Owner" : "Member", NamedTextColor.LIGHT_PURPLE));
lore.add(Component.empty());
lore.add(line("Click to manage", NamedTextColor.YELLOW));
itemMeta.lore(lore);
itemMeta.addItemFlags(ItemFlag.values());
itemMeta.getPersistentDataContainer().set(Keys.MEMBER_UUID, org.bukkit.persistence.PersistentDataType.STRING, member.getUuid().toString());
itemStack.setItemMeta(itemMeta);
return itemStack;
}
private ItemStack item(Material material, String name, NamedTextColor color, List<Component> lore)
{
ItemStack itemStack = new ItemStack(material);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(text(name, color));
itemMeta.lore(lore);
itemMeta.addItemFlags(ItemFlag.values());
itemStack.setItemMeta(itemMeta);
return itemStack;
}
private Component title(String value)
{
return text(value, NamedTextColor.DARK_AQUA);
}
private Component text(String value, NamedTextColor color)
{
return Component.text(value, color).decoration(TextDecoration.ITALIC, false);
}
private Component line(String value, NamedTextColor color)
{
return text("> " + value, color);
}
private Component label(String label, String value, NamedTextColor valueColor)
{
return text(label + ": ", NamedTextColor.GRAY).append(text(value, valueColor));
}
private java.util.Optional<UUID> memberUuid(ItemStack itemStack)
{
if (!itemStack.hasItemMeta())
{
return java.util.Optional.empty();
}
String value = itemStack.getItemMeta().getPersistentDataContainer().get(Keys.MEMBER_UUID, org.bukkit.persistence.PersistentDataType.STRING);
if (value == null)
{
return java.util.Optional.empty();
}
return java.util.Optional.of(UUID.fromString(value));
}
private static class Keys
{
private static final org.bukkit.NamespacedKey MEMBER_UUID = new org.bukkit.NamespacedKey("plex_guilds", "member_uuid");
}
}
@@ -1,134 +0,0 @@
package dev.plex.handler;
import dev.plex.Guilds;
import dev.plex.guild.Guild;
import dev.plex.guild.data.GuildPermission;
import dev.plex.gui.RankPermissionInventoryHolder;
import net.kyori.adventure.text.Component;
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.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import java.util.List;
import java.util.UUID;
public class RankPermissionMenuListener implements Listener
{
private static final UUID MEMBER_PERMISSION_PROBE = new UUID(0L, 0L);
public void openRankList(Player player, Guild guild)
{
Inventory inventory = Bukkit.createInventory(new RankPermissionInventoryHolder(guild, null), 27, title("* Guild Rank Permissions"));
inventory.setItem(13, rankItem());
player.openInventory(inventory);
}
@EventHandler(priority = EventPriority.HIGH)
public void onClick(InventoryClickEvent event)
{
if (!(event.getWhoClicked() instanceof Player player) || !(event.getInventory().getHolder() instanceof RankPermissionInventoryHolder holder))
{
return;
}
event.setCancelled(true);
if (!holder.guild().isOwner(player.getUniqueId()))
{
player.closeInventory();
player.sendMessage(Guilds.get().messageComponent("guildNotOwner"));
return;
}
ItemStack clickedItem = event.getCurrentItem();
if (clickedItem == null || clickedItem.getType() == Material.AIR)
{
return;
}
if (holder.rankName() == null)
{
openPermissionEditor(player, holder.guild());
return;
}
GuildPermission permission = permissionBySlot(event.getRawSlot());
if (permission == null)
{
return;
}
boolean enabled = !holder.guild().hasPermission(MEMBER_PERMISSION_PROBE, permission);
holder.guild().setPermission(permission, enabled);
Guilds.get().getGuildRepository().updateMemberPermission(holder.guild().getGuildUuid(), permission, enabled);
openPermissionEditor(player, holder.guild());
}
private void openPermissionEditor(Player player, Guild guild)
{
Inventory inventory = Bukkit.createInventory(new RankPermissionInventoryHolder(guild, "MEMBER"), 27, title("* Member Permissions"));
GuildPermission[] permissions = GuildPermission.values();
for (int i = 0; i < permissions.length; i++)
{
inventory.setItem(11 + i * 2, permissionItem(guild, permissions[i]));
}
player.openInventory(inventory);
}
private GuildPermission permissionBySlot(int slot)
{
return switch (slot)
{
case 11 -> GuildPermission.BLOCK_BREAKING;
case 13 -> GuildPermission.BLOCK_PLACING;
case 15 -> GuildPermission.INTERACTING;
default -> null;
};
}
private ItemStack rankItem()
{
ItemStack itemStack = new ItemStack(Material.NAME_TAG);
ItemMeta itemMeta = itemStack.getItemMeta();
itemMeta.displayName(text("Member", NamedTextColor.AQUA));
itemMeta.lore(List.of(
line("Manage member guild world access", NamedTextColor.GRAY),
line("Click to edit permissions", NamedTextColor.YELLOW)
));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
private ItemStack permissionItem(Guild guild, GuildPermission permission)
{
ItemStack itemStack = new ItemStack(permission.material());
ItemMeta itemMeta = itemStack.getItemMeta();
boolean enabled = guild.hasPermission(MEMBER_PERMISSION_PROBE, permission);
itemMeta.displayName(text(permission.displayName(), enabled ? NamedTextColor.GREEN : NamedTextColor.RED));
itemMeta.lore(List.of(
text("Status: ", NamedTextColor.GRAY).append(text(enabled ? "Enabled" : "Disabled", enabled ? NamedTextColor.GREEN : NamedTextColor.RED)),
Component.empty(),
line("Click to toggle", NamedTextColor.YELLOW)
));
itemStack.setItemMeta(itemMeta);
return itemStack;
}
private Component title(String value)
{
return text(value, NamedTextColor.DARK_AQUA);
}
private Component text(String value, NamedTextColor color)
{
return Component.text(value, color).decoration(TextDecoration.ITALIC, false);
}
private Component line(String value, NamedTextColor color)
{
return text("> " + value, color);
}
}