diff --git a/pom.xml b/pom.xml index ca6490a..4760ce7 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ fr.votenetwork votenetwork-parent - 1.0.1 + 1.0.2 pom diff --git a/spigot/pom.xml b/spigot/pom.xml index f7e5135..bedc7e0 100644 --- a/spigot/pom.xml +++ b/spigot/pom.xml @@ -7,7 +7,7 @@ fr.votenetwork votenetwork-parent - 1.0.1 + 1.0.2 votenetwork-spigot diff --git a/spigot/src/main/java/fr/votenetwork/spigot/ClaimAction.java b/spigot/src/main/java/fr/votenetwork/spigot/ClaimAction.java new file mode 100644 index 0000000..4ab403d --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/ClaimAction.java @@ -0,0 +1,54 @@ +package fr.votenetwork.spigot; + +import fr.votenetwork.spigot.storage.PendingVoteStore; +import fr.votenetwork.spigot.voteparty.VoteParty; +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; + +/** + * Reclame les votes en attente d'un joueur et distribue les recompenses. Partagee entre la + * commande /claim (texte) et le menu de reclamation visuel (/votemenu). + */ +public final class ClaimAction { + + private ClaimAction() { + } + + public static void claim(VoteNetworkSpigot plugin, VoteConfig config, PendingVoteStore pendingVoteStore, + VoteParty voteParty, Player player) { + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> + pendingVoteStore.fetchAndClear( + player.getUniqueId(), + pendingVotes -> Bukkit.getScheduler().runTask(plugin, () -> apply(plugin, config, voteParty, player, pendingVotes)), + exception -> Bukkit.getScheduler().runTask(plugin, () -> { + plugin.getLogger().severe("Erreur reclamation pour " + player.getName() + ": " + exception.getMessage()); + player.sendMessage(config.getMessageMaintenance()); + }) + ) + ); + } + + private static void apply(VoteNetworkSpigot plugin, VoteConfig config, VoteParty voteParty, Player player, int pendingVotes) { + if (pendingVotes <= 0) { + player.sendMessage(config.getMessageClaimEmpty()); + return; + } + + for (int i = 0; i < pendingVotes; i++) { + for (String cmd : config.getVoteRewardCommands()) { + String parsed = cmd.replace("%player%", player.getName()); + Bukkit.dispatchCommand(Bukkit.getConsoleSender(), parsed); + } + } + + voteParty.addVotes(pendingVotes); + + player.sendMessage(config.getMessageClaimSuccess().replace("%amount%", String.valueOf(pendingVotes))); + + if (config.isVoteBroadcastEnabled()) { + Bukkit.broadcastMessage(config.getVoteBroadcastMessage() + .replace("%player%", player.getName()) + .replace("%amount%", String.valueOf(pendingVotes))); + } + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/VoteConfig.java b/spigot/src/main/java/fr/votenetwork/spigot/VoteConfig.java index 39e1d83..5670723 100644 --- a/spigot/src/main/java/fr/votenetwork/spigot/VoteConfig.java +++ b/spigot/src/main/java/fr/votenetwork/spigot/VoteConfig.java @@ -197,6 +197,108 @@ public class VoteConfig { return sites; } + // --- Menu principal (/votemenu) --- + + public String getMainMenuTitle() { + return colorize(cfg().getString("gui.main-menu.title", "&8VoteNetwork - Menu")); + } + + public List getMainMenuHeadLore() { + return colorizeList(cfg().getStringList("gui.main-menu.head-lore")); + } + + public String getMainMenuVoteItemMaterial() { + return cfg().getString("gui.main-menu.vote-item.material", "PAPER"); + } + + public String getMainMenuVoteItemName() { + return colorize(cfg().getString("gui.main-menu.vote-item.name", "&aVoter")); + } + + public List getMainMenuVoteItemLore() { + return colorizeList(cfg().getStringList("gui.main-menu.vote-item.lore")); + } + + public String getMainMenuClaimItemMaterial() { + return cfg().getString("gui.main-menu.claim-item.material", "CHEST"); + } + + public String getMainMenuClaimItemName() { + return colorize(cfg().getString("gui.main-menu.claim-item.name", "&eMes votes en attente")); + } + + public List getMainMenuClaimItemLore() { + return colorizeList(cfg().getStringList("gui.main-menu.claim-item.lore")); + } + + public String getMainMenuAdminItemMaterial() { + return cfg().getString("gui.main-menu.admin-item.material", "REDSTONE"); + } + + public String getMainMenuAdminItemName() { + return colorize(cfg().getString("gui.main-menu.admin-item.name", "&cAdministration")); + } + + public List getMainMenuAdminItemLore() { + return colorizeList(cfg().getStringList("gui.main-menu.admin-item.lore")); + } + + // --- Menu de reclamation (/claim visuel) --- + + public String getClaimMenuTitle() { + return colorize(cfg().getString("gui.claim-menu.title", "&8VoteNetwork - Reclamer")); + } + + public String getClaimMenuLoadingLore() { + return colorize(cfg().getString("gui.claim-menu.loading-lore", "&7Chargement...")); + } + + public String getClaimMenuAvailableMaterial() { + return cfg().getString("gui.claim-menu.available.material", "CHEST"); + } + + public String getClaimMenuAvailableName() { + return colorize(cfg().getString("gui.claim-menu.available.name", "&e%amount% vote(s) en attente")); + } + + public List getClaimMenuAvailableLore() { + return colorizeList(cfg().getStringList("gui.claim-menu.available.lore")); + } + + public String getClaimMenuEmptyMaterial() { + return cfg().getString("gui.claim-menu.empty.material", "BARRIER"); + } + + public String getClaimMenuEmptyName() { + return colorize(cfg().getString("gui.claim-menu.empty.name", "&7Aucun vote en attente")); + } + + public List getClaimMenuEmptyLore() { + return colorizeList(cfg().getStringList("gui.claim-menu.empty.lore")); + } + + // --- Menu d'administration (/votemenu, reserve aux ops) --- + + public String getAdminMenuTitle() { + return colorize(cfg().getString("gui.admin-menu.title", "&8VoteNetwork - Administration")); + } + + public String getAdminMenuItemMaterial() { + return cfg().getString("gui.admin-menu.item.material", "LEVER"); + } + + public String getAdminMenuItemNameEnabled() { + return colorize(cfg().getString("gui.admin-menu.item.name-maintenance-on", "&c&lMaintenance : ACTIVEE")); + } + + public String getAdminMenuItemNameDisabled() { + return colorize(cfg().getString("gui.admin-menu.item.name-maintenance-off", "&a&lMaintenance : DESACTIVEE")); + } + + public List getAdminMenuItemLore() { + return colorizeList(cfg().getStringList("gui.admin-menu.item.lore")); + } + private String colorize(String input) { return input == null ? "" : ChatColor.translateAlternateColorCodes('&', input); } diff --git a/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java b/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java index 1b76606..5509fbf 100644 --- a/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java +++ b/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java @@ -6,6 +6,8 @@ import fr.votenetwork.spigot.api.VoteNetworkAPIImpl; import fr.votenetwork.spigot.command.ClaimCommand; import fr.votenetwork.spigot.command.VoteAdminCommand; import fr.votenetwork.spigot.command.VoteGuiCommand; +import fr.votenetwork.spigot.command.VoteMenuCommand; +import fr.votenetwork.spigot.gui.VoteMenuListener; import fr.votenetwork.spigot.gui.VotePartyGuiListener; import fr.votenetwork.spigot.listener.VoteMessageListener; import fr.votenetwork.spigot.placeholder.VoteNetworkPlaceholders; @@ -58,7 +60,10 @@ public class VoteNetworkSpigot extends JavaPlugin { getCommand("claim").setExecutor(new ClaimCommand(this, voteConfig, pendingVoteStore, voteParty, maintenanceState)); getCommand("vote").setExecutor(new VoteAdminCommand(this, voteConfig, pendingVoteStore, maintenanceState)); getCommand("votegui").setExecutor(new VoteGuiCommand(voteConfig, voteParty)); + getCommand("votemenu").setExecutor(new VoteMenuCommand(voteConfig, voteParty)); getServer().getPluginManager().registerEvents(new VotePartyGuiListener(voteConfig), this); + getServer().getPluginManager().registerEvents( + new VoteMenuListener(this, voteConfig, pendingVoteStore, voteParty, maintenanceState), this); VoteNetworkAPI api = new VoteNetworkAPIImpl(this, voteConfig, pendingVoteStore, voteParty, maintenanceState); VoteNetworkAPIHolder.set(api); diff --git a/spigot/src/main/java/fr/votenetwork/spigot/command/ClaimCommand.java b/spigot/src/main/java/fr/votenetwork/spigot/command/ClaimCommand.java index 7a1db03..2d2b3d9 100644 --- a/spigot/src/main/java/fr/votenetwork/spigot/command/ClaimCommand.java +++ b/spigot/src/main/java/fr/votenetwork/spigot/command/ClaimCommand.java @@ -1,11 +1,11 @@ package fr.votenetwork.spigot.command; +import fr.votenetwork.spigot.ClaimAction; import fr.votenetwork.spigot.MaintenanceState; import fr.votenetwork.spigot.VoteNetworkSpigot; import fr.votenetwork.spigot.VoteConfig; import fr.votenetwork.spigot.storage.PendingVoteStore; import fr.votenetwork.spigot.voteparty.VoteParty; -import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandSender; @@ -42,41 +42,7 @@ public class ClaimCommand implements CommandExecutor { return true; } - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> - pendingVoteStore.fetchAndClear( - player.getUniqueId(), - pendingVotes -> Bukkit.getScheduler().runTask(plugin, () -> applyClaim(player, pendingVotes)), - exception -> Bukkit.getScheduler().runTask(plugin, () -> { - plugin.getLogger().severe("Erreur /claim pour " + player.getName() + ": " + exception.getMessage()); - player.sendMessage(config.getMessageMaintenance()); - }) - ) - ); - + ClaimAction.claim(plugin, config, pendingVoteStore, voteParty, player); return true; } - - private void applyClaim(Player player, int pendingVotes) { - if (pendingVotes <= 0) { - player.sendMessage(config.getMessageClaimEmpty()); - return; - } - - for (int i = 0; i < pendingVotes; i++) { - for (String cmd : config.getVoteRewardCommands()) { - String parsed = cmd.replace("%player%", player.getName()); - Bukkit.dispatchCommand(Bukkit.getConsoleSender(), parsed); - } - } - - voteParty.addVotes(pendingVotes); - - player.sendMessage(config.getMessageClaimSuccess().replace("%amount%", String.valueOf(pendingVotes))); - - if (config.isVoteBroadcastEnabled()) { - Bukkit.broadcastMessage(config.getVoteBroadcastMessage() - .replace("%player%", player.getName()) - .replace("%amount%", String.valueOf(pendingVotes))); - } - } } diff --git a/spigot/src/main/java/fr/votenetwork/spigot/command/VoteMenuCommand.java b/spigot/src/main/java/fr/votenetwork/spigot/command/VoteMenuCommand.java new file mode 100644 index 0000000..e758b76 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/command/VoteMenuCommand.java @@ -0,0 +1,31 @@ +package fr.votenetwork.spigot.command; + +import fr.votenetwork.spigot.VoteConfig; +import fr.votenetwork.spigot.gui.MainMenuGui; +import fr.votenetwork.spigot.voteparty.VoteParty; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class VoteMenuCommand implements CommandExecutor { + + private final VoteConfig config; + private final VoteParty voteParty; + + public VoteMenuCommand(VoteConfig config, VoteParty voteParty) { + this.config = config; + this.voteParty = voteParty; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage(ChatColor.RED + "Commande reservee aux joueurs."); + return true; + } + MainMenuGui.open(player, config, voteParty); + return true; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/AdminMenuGui.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/AdminMenuGui.java new file mode 100644 index 0000000..d193645 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/AdminMenuGui.java @@ -0,0 +1,47 @@ +package fr.votenetwork.spigot.gui; + +import fr.votenetwork.spigot.MaintenanceState; +import fr.votenetwork.spigot.VoteConfig; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Locale; + +/** Ops-only screen (permission votenetwork.admin) to toggle maintenance mode with one click. */ +public final class AdminMenuGui { + + private AdminMenuGui() { + } + + public static void open(Player player, VoteConfig config, MaintenanceState maintenanceState) { + AdminMenuHolder holder = new AdminMenuHolder(); + Inventory inventory = Bukkit.createInventory(holder, 27, config.getAdminMenuTitle()); + holder.setInventory(inventory); + + inventory.setItem(AdminMenuHolder.ITEM_SLOT, buildItem(config, maintenanceState.isStopped())); + + player.openInventory(inventory); + } + + public static ItemStack buildItem(VoteConfig config, boolean stopped) { + Material material; + try { + material = Material.valueOf(config.getAdminMenuItemMaterial().toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + material = Material.LEVER; + } + + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(stopped ? config.getAdminMenuItemNameEnabled() : config.getAdminMenuItemNameDisabled()); + meta.setLore(config.getAdminMenuItemLore()); + item.setItemMeta(meta); + } + return item; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/AdminMenuHolder.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/AdminMenuHolder.java new file mode 100644 index 0000000..2961e51 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/AdminMenuHolder.java @@ -0,0 +1,21 @@ +package fr.votenetwork.spigot.gui; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +/** Marker holder for the ops-only administration screen (toggle maintenance mode). */ +public class AdminMenuHolder implements InventoryHolder { + + public static final int ITEM_SLOT = 13; + + private Inventory inventory; + + @Override + public Inventory getInventory() { + return inventory; + } + + public void setInventory(Inventory inventory) { + this.inventory = inventory; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/ClaimMenuGui.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/ClaimMenuGui.java new file mode 100644 index 0000000..553a8f1 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/ClaimMenuGui.java @@ -0,0 +1,80 @@ +package fr.votenetwork.spigot.gui; + +import fr.votenetwork.spigot.VoteConfig; +import fr.votenetwork.spigot.VoteNetworkSpigot; +import fr.votenetwork.spigot.storage.PendingVoteStore; +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; + +import java.util.Locale; + +/** + * Visual counterpart of /claim: shows how many votes are waiting for the player, resolved + * asynchronously via {@link PendingVoteStore#peek}, and lets them claim by clicking the item. + */ +public final class ClaimMenuGui { + + private ClaimMenuGui() { + } + + public static void open(Player player, VoteNetworkSpigot plugin, VoteConfig config, PendingVoteStore pendingVoteStore) { + ClaimMenuHolder holder = new ClaimMenuHolder(); + Inventory inventory = Bukkit.createInventory(holder, 27, config.getClaimMenuTitle()); + holder.setInventory(inventory); + + ItemStack loading = new ItemStack(Material.CLOCK); + ItemMeta loadingMeta = loading.getItemMeta(); + if (loadingMeta != null) { + loadingMeta.setDisplayName(config.getClaimMenuLoadingLore()); + loading.setItemMeta(loadingMeta); + } + inventory.setItem(ClaimMenuHolder.ITEM_SLOT, loading); + + player.openInventory(inventory); + + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> + pendingVoteStore.peek( + player.getUniqueId(), + amount -> Bukkit.getScheduler().runTask(plugin, () -> { + holder.setPendingVotes(amount); + if (player.getOpenInventory().getTopInventory().getHolder() == holder) { + inventory.setItem(ClaimMenuHolder.ITEM_SLOT, buildItem(config, amount)); + } + }), + exception -> Bukkit.getScheduler().runTask(plugin, () -> { + plugin.getLogger().severe("Erreur menu reclamation pour " + player.getName() + ": " + exception.getMessage()); + player.closeInventory(); + }) + ) + ); + } + + public static ItemStack buildItem(VoteConfig config, int amount) { + boolean available = amount > 0; + String materialName = available ? config.getClaimMenuAvailableMaterial() : config.getClaimMenuEmptyMaterial(); + String name = available + ? config.getClaimMenuAvailableName().replace("%amount%", String.valueOf(amount)) + : config.getClaimMenuEmptyName(); + java.util.List lore = available ? config.getClaimMenuAvailableLore() : config.getClaimMenuEmptyLore(); + + Material material; + try { + material = Material.valueOf(materialName.toUpperCase(Locale.ROOT)); + } catch (IllegalArgumentException e) { + material = Material.CHEST; + } + + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(name); + meta.setLore(lore); + item.setItemMeta(meta); + } + return item; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/ClaimMenuHolder.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/ClaimMenuHolder.java new file mode 100644 index 0000000..3a35c72 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/ClaimMenuHolder.java @@ -0,0 +1,31 @@ +package fr.votenetwork.spigot.gui; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +/** Marker holder for the visual /claim screen opened from the main menu. */ +public class ClaimMenuHolder implements InventoryHolder { + + public static final int ITEM_SLOT = 13; + + private Inventory inventory; + private volatile int pendingVotes = -1; + + @Override + public Inventory getInventory() { + return inventory; + } + + public void setInventory(Inventory inventory) { + this.inventory = inventory; + } + + /** -1 while the async lookup is still pending, >= 0 once resolved. */ + public int getPendingVotes() { + return pendingVotes; + } + + public void setPendingVotes(int pendingVotes) { + this.pendingVotes = pendingVotes; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/MainMenuGui.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/MainMenuGui.java new file mode 100644 index 0000000..a2c0b78 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/MainMenuGui.java @@ -0,0 +1,74 @@ +package fr.votenetwork.spigot.gui; + +import fr.votenetwork.spigot.VoteConfig; +import fr.votenetwork.spigot.voteparty.VoteParty; +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Material; +import org.bukkit.entity.Player; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.ItemStack; +import org.bukkit.inventory.meta.ItemMeta; +import org.bukkit.inventory.meta.SkullMeta; + +/** + * /votemenu entry point: player head with VoteParty progress, plus navigation to the vote-site + * links (/votegui), the visual claim menu, and (ops only) the administration menu. + */ +public final class MainMenuGui { + + private MainMenuGui() { + } + + public static void open(Player player, VoteConfig config, VoteParty voteParty) { + MainMenuHolder holder = new MainMenuHolder(); + Inventory inventory = Bukkit.createInventory(holder, 27, config.getMainMenuTitle()); + holder.setInventory(inventory); + + int required = config.getVotePartyVotesRequired(); + int current = Math.min(voteParty.getCurrentVotes(), required); + + ItemStack head = new ItemStack(Material.PLAYER_HEAD); + SkullMeta skullMeta = (SkullMeta) head.getItemMeta(); + if (skullMeta != null) { + skullMeta.setOwningPlayer(player); + skullMeta.setDisplayName(ChatColor.translateAlternateColorCodes('&', "&b&l" + player.getName())); + skullMeta.setLore(config.getMainMenuHeadLore().stream() + .map(line -> line.replace("%player%", player.getName()) + .replace("%current%", String.valueOf(current)) + .replace("%required%", String.valueOf(required))) + .toList()); + head.setItemMeta(skullMeta); + } + inventory.setItem(4, head); + + inventory.setItem(MainMenuHolder.VOTE_SLOT, buildItem( + config.getMainMenuVoteItemMaterial(), config.getMainMenuVoteItemName(), config.getMainMenuVoteItemLore())); + inventory.setItem(MainMenuHolder.CLAIM_SLOT, buildItem( + config.getMainMenuClaimItemMaterial(), config.getMainMenuClaimItemName(), config.getMainMenuClaimItemLore())); + + if (player.hasPermission("votenetwork.admin")) { + inventory.setItem(MainMenuHolder.ADMIN_SLOT, buildItem( + config.getMainMenuAdminItemMaterial(), config.getMainMenuAdminItemName(), config.getMainMenuAdminItemLore())); + } + + player.openInventory(inventory); + } + + private static ItemStack buildItem(String materialName, String name, java.util.List lore) { + Material material; + try { + material = Material.valueOf(materialName.toUpperCase(java.util.Locale.ROOT)); + } catch (IllegalArgumentException e) { + material = Material.PAPER; + } + ItemStack item = new ItemStack(material); + ItemMeta meta = item.getItemMeta(); + if (meta != null) { + meta.setDisplayName(name); + meta.setLore(lore); + item.setItemMeta(meta); + } + return item; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/MainMenuHolder.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/MainMenuHolder.java new file mode 100644 index 0000000..eff9c54 --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/MainMenuHolder.java @@ -0,0 +1,23 @@ +package fr.votenetwork.spigot.gui; + +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +/** Marker holder for the /votemenu main screen. */ +public class MainMenuHolder implements InventoryHolder { + + public static final int VOTE_SLOT = 11; + public static final int CLAIM_SLOT = 13; + public static final int ADMIN_SLOT = 15; + + private Inventory inventory; + + @Override + public Inventory getInventory() { + return inventory; + } + + public void setInventory(Inventory inventory) { + this.inventory = inventory; + } +} diff --git a/spigot/src/main/java/fr/votenetwork/spigot/gui/VoteMenuListener.java b/spigot/src/main/java/fr/votenetwork/spigot/gui/VoteMenuListener.java new file mode 100644 index 0000000..fde6a2a --- /dev/null +++ b/spigot/src/main/java/fr/votenetwork/spigot/gui/VoteMenuListener.java @@ -0,0 +1,83 @@ +package fr.votenetwork.spigot.gui; + +import fr.votenetwork.spigot.ClaimAction; +import fr.votenetwork.spigot.MaintenanceState; +import fr.votenetwork.spigot.VoteConfig; +import fr.votenetwork.spigot.VoteNetworkSpigot; +import fr.votenetwork.spigot.storage.PendingVoteStore; +import fr.votenetwork.spigot.voteparty.VoteParty; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.inventory.InventoryClickEvent; + +/** Click handling for the main/claim/admin menus (/votemenu tree). */ +public class VoteMenuListener implements Listener { + + private final VoteNetworkSpigot plugin; + private final VoteConfig config; + private final PendingVoteStore pendingVoteStore; + private final VoteParty voteParty; + private final MaintenanceState maintenanceState; + + public VoteMenuListener(VoteNetworkSpigot plugin, VoteConfig config, PendingVoteStore pendingVoteStore, + VoteParty voteParty, MaintenanceState maintenanceState) { + this.plugin = plugin; + this.config = config; + this.pendingVoteStore = pendingVoteStore; + this.voteParty = voteParty; + this.maintenanceState = maintenanceState; + } + + @EventHandler + public void onInventoryClick(InventoryClickEvent event) { + Object rawHolder = event.getInventory().getHolder(); + if (!(event.getWhoClicked() instanceof Player player)) { + return; + } + + if (rawHolder instanceof MainMenuHolder) { + event.setCancelled(true); + handleMainMenuClick(player, event.getRawSlot()); + } else if (rawHolder instanceof ClaimMenuHolder holder) { + event.setCancelled(true); + handleClaimMenuClick(player, holder, event.getRawSlot()); + } else if (rawHolder instanceof AdminMenuHolder) { + event.setCancelled(true); + handleAdminMenuClick(player, event.getRawSlot()); + } + } + + private void handleMainMenuClick(Player player, int slot) { + if (slot == MainMenuHolder.VOTE_SLOT) { + VotePartyGui.open(player, config, voteParty); + } else if (slot == MainMenuHolder.CLAIM_SLOT) { + ClaimMenuGui.open(player, plugin, config, pendingVoteStore); + } else if (slot == MainMenuHolder.ADMIN_SLOT && player.hasPermission("votenetwork.admin")) { + AdminMenuGui.open(player, config, maintenanceState); + } + } + + private void handleClaimMenuClick(Player player, ClaimMenuHolder holder, int slot) { + if (slot != ClaimMenuHolder.ITEM_SLOT || holder.getPendingVotes() < 0) { + return; + } + if (maintenanceState.isStopped()) { + player.closeInventory(); + player.sendMessage(config.getMessageMaintenance()); + return; + } + player.closeInventory(); + ClaimAction.claim(plugin, config, pendingVoteStore, voteParty, player); + } + + private void handleAdminMenuClick(Player player, int slot) { + if (slot != AdminMenuHolder.ITEM_SLOT || !player.hasPermission("votenetwork.admin")) { + return; + } + boolean newState = !maintenanceState.isStopped(); + maintenanceState.setStopped(newState); + player.sendMessage(newState ? config.getMessageMaintenanceEnabled() : config.getMessageMaintenanceDisabled()); + player.getOpenInventory().getTopInventory().setItem(AdminMenuHolder.ITEM_SLOT, AdminMenuGui.buildItem(config, newState)); + } +} diff --git a/spigot/src/main/resources/config.yml b/spigot/src/main/resources/config.yml index 38ee5d1..c8c856d 100644 --- a/spigot/src/main/resources/config.yml +++ b/spigot/src/main/resources/config.yml @@ -71,6 +71,55 @@ gui: lore: - "&7Clique pour voter !" +# Menu principal /votemenu : profil du joueur, progression VoteParty, et boutons de +# navigation vers le menu de vote (/votegui), de reclamation et (pour les ops) d'administration. + main-menu: + title: "&8VoteNetwork - Menu" + head-lore: + - "&7Joueur : &f%player%" + - "&7Progression VoteParty :" + - "&f%current%&7/&f%required% &7votes" + vote-item: + material: PAPER + name: "&aVoter" + lore: + - "&7Clique pour voir les liens de vote." + claim-item: + material: CHEST + name: "&eMes votes en attente" + lore: + - "&7Clique pour reclamer tes votes stockes." + admin-item: + material: REDSTONE + name: "&cAdministration" + lore: + - "&7Clique pour gerer le mode maintenance." + + # Menu de reclamation visuel (equivalent GUI de /claim). + claim-menu: + title: "&8VoteNetwork - Reclamer" + loading-lore: "&7Chargement..." + available: + material: CHEST + name: "&e%amount% vote(s) en attente" + lore: + - "&7Clique pour reclamer !" + empty: + material: BARRIER + name: "&7Aucun vote en attente" + lore: + - "&7Reviens plus tard." + + # Menu d'administration (reserve aux ops, permission votenetwork.admin). + admin-menu: + title: "&8VoteNetwork - Administration" + item: + material: LEVER + name-maintenance-on: "&c&lMaintenance : ACTIVEE" + name-maintenance-off: "&a&lMaintenance : DESACTIVEE" + lore: + - "&7Clique pour basculer le mode maintenance." + messages: direct-vote: "&a[Vote] &fMerci pour ton vote !" claim-success: "&a[Vote] &fVous avez recupere &e%amount% &fvote(s) en attente !" diff --git a/spigot/src/main/resources/plugin.yml b/spigot/src/main/resources/plugin.yml index aaa65ab..3db4a4e 100644 --- a/spigot/src/main/resources/plugin.yml +++ b/spigot/src/main/resources/plugin.yml @@ -17,6 +17,9 @@ commands: votegui: description: Ouvre le GUI de progression du VoteParty avec les liens de vote. usage: /votegui + votemenu: + description: Ouvre le menu principal (profil, votes en attente, administration). + usage: /votemenu permissions: votenetwork.admin: diff --git a/velocity/pom.xml b/velocity/pom.xml index c858217..ecb63f5 100644 --- a/velocity/pom.xml +++ b/velocity/pom.xml @@ -7,7 +7,7 @@ fr.votenetwork votenetwork-parent - 1.0.1 + 1.0.2 votenetwork-velocity diff --git a/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java b/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java index a2dc281..cad1934 100644 --- a/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java +++ b/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java @@ -14,7 +14,7 @@ import java.nio.file.Path; @Plugin( id = "votenetwork", name = "VoteNetwork", - version = "1.0.1", + version = "1.0.2", description = "Systeme de vote reseau Velocity <-> Spigot", authors = {"Sar_Tron"} )