Ajoute le GUI VoteParty avec liens de vote cliquables (v1.0.1)
CI / build (push) Successful in 12m13s
CI / build (push) Successful in 12m13s
Nouvelle commande /votegui : affiche la progression du VoteParty et un item par site de vote configure. Un clic ferme le GUI et envoie un message chat cliquable vers l'URL du site (Bukkit ne permet pas d'ouvrir un navigateur directement depuis un clic d'inventaire). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
35a8425254
commit
964f375841
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
<groupId>fr.votenetwork</groupId>
|
<groupId>fr.votenetwork</groupId>
|
||||||
<artifactId>votenetwork-parent</artifactId>
|
<artifactId>votenetwork-parent</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<modules>
|
<modules>
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>fr.votenetwork</groupId>
|
<groupId>fr.votenetwork</groupId>
|
||||||
<artifactId>votenetwork-parent</artifactId>
|
<artifactId>votenetwork-parent</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>votenetwork-spigot</artifactId>
|
<artifactId>votenetwork-spigot</artifactId>
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package fr.votenetwork.spigot;
|
package fr.votenetwork.spigot;
|
||||||
|
|
||||||
|
import fr.votenetwork.spigot.gui.VoteSite;
|
||||||
import org.bukkit.ChatColor;
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.Material;
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class VoteConfig {
|
public class VoteConfig {
|
||||||
@@ -141,6 +146,57 @@ public class VoteConfig {
|
|||||||
"&cVous n'avez pas la permission d'utiliser cette commande."));
|
"&cVous n'avez pas la permission d'utiliser cette commande."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getGuiTitle() {
|
||||||
|
return colorize(cfg().getString("gui.title", "&8VoteNetwork"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGuiProgressItemMaterial() {
|
||||||
|
return cfg().getString("gui.progress-item.material", "NETHER_STAR");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGuiProgressItemName() {
|
||||||
|
return colorize(cfg().getString("gui.progress-item.name", "&b&lVoteParty"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getGuiProgressItemLore() {
|
||||||
|
return colorizeList(cfg().getStringList("gui.progress-item.lore"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getGuiClickMessage() {
|
||||||
|
return colorize(cfg().getString("gui.click-message", "&a[Vote] Clique sur le lien pour voter :"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses gui.vote-sites (a YAML list of maps: name/material/url/lore) into VoteSite
|
||||||
|
* objects, one item per configured vote site.
|
||||||
|
*/
|
||||||
|
public List<VoteSite> getVoteSites() {
|
||||||
|
List<VoteSite> sites = new ArrayList<>();
|
||||||
|
for (Map<?, ?> raw : cfg().getMapList("gui.vote-sites")) {
|
||||||
|
String name = raw.containsKey("name") ? String.valueOf(raw.get("name")) : "&aVoter";
|
||||||
|
String materialName = raw.containsKey("material") ? String.valueOf(raw.get("material")) : "PAPER";
|
||||||
|
String url = raw.containsKey("url") ? String.valueOf(raw.get("url")) : "";
|
||||||
|
|
||||||
|
List<String> lore = new ArrayList<>();
|
||||||
|
Object loreObj = raw.get("lore");
|
||||||
|
if (loreObj instanceof List<?> loreList) {
|
||||||
|
for (Object line : loreList) {
|
||||||
|
lore.add(String.valueOf(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Material material;
|
||||||
|
try {
|
||||||
|
material = Material.valueOf(materialName.toUpperCase(Locale.ROOT));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
material = Material.PAPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
sites.add(new VoteSite(colorize(name), material, url, colorizeList(lore)));
|
||||||
|
}
|
||||||
|
return sites;
|
||||||
|
}
|
||||||
|
|
||||||
private String colorize(String input) {
|
private String colorize(String input) {
|
||||||
return input == null ? "" : ChatColor.translateAlternateColorCodes('&', input);
|
return input == null ? "" : ChatColor.translateAlternateColorCodes('&', input);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import fr.votenetwork.spigot.api.VoteNetworkAPIHolder;
|
|||||||
import fr.votenetwork.spigot.api.VoteNetworkAPIImpl;
|
import fr.votenetwork.spigot.api.VoteNetworkAPIImpl;
|
||||||
import fr.votenetwork.spigot.command.ClaimCommand;
|
import fr.votenetwork.spigot.command.ClaimCommand;
|
||||||
import fr.votenetwork.spigot.command.VoteAdminCommand;
|
import fr.votenetwork.spigot.command.VoteAdminCommand;
|
||||||
|
import fr.votenetwork.spigot.command.VoteGuiCommand;
|
||||||
|
import fr.votenetwork.spigot.gui.VotePartyGuiListener;
|
||||||
import fr.votenetwork.spigot.listener.VoteMessageListener;
|
import fr.votenetwork.spigot.listener.VoteMessageListener;
|
||||||
import fr.votenetwork.spigot.placeholder.VoteNetworkPlaceholders;
|
import fr.votenetwork.spigot.placeholder.VoteNetworkPlaceholders;
|
||||||
import fr.votenetwork.spigot.storage.MySqlPendingVoteStore;
|
import fr.votenetwork.spigot.storage.MySqlPendingVoteStore;
|
||||||
@@ -55,6 +57,8 @@ public class VoteNetworkSpigot extends JavaPlugin {
|
|||||||
|
|
||||||
getCommand("claim").setExecutor(new ClaimCommand(this, voteConfig, pendingVoteStore, voteParty, maintenanceState));
|
getCommand("claim").setExecutor(new ClaimCommand(this, voteConfig, pendingVoteStore, voteParty, maintenanceState));
|
||||||
getCommand("vote").setExecutor(new VoteAdminCommand(this, voteConfig, pendingVoteStore, maintenanceState));
|
getCommand("vote").setExecutor(new VoteAdminCommand(this, voteConfig, pendingVoteStore, maintenanceState));
|
||||||
|
getCommand("votegui").setExecutor(new VoteGuiCommand(voteConfig, voteParty));
|
||||||
|
getServer().getPluginManager().registerEvents(new VotePartyGuiListener(voteConfig), this);
|
||||||
|
|
||||||
VoteNetworkAPI api = new VoteNetworkAPIImpl(this, voteConfig, pendingVoteStore, voteParty, maintenanceState);
|
VoteNetworkAPI api = new VoteNetworkAPIImpl(this, voteConfig, pendingVoteStore, voteParty, maintenanceState);
|
||||||
VoteNetworkAPIHolder.set(api);
|
VoteNetworkAPIHolder.set(api);
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package fr.votenetwork.spigot.command;
|
||||||
|
|
||||||
|
import fr.votenetwork.spigot.VoteConfig;
|
||||||
|
import fr.votenetwork.spigot.gui.VotePartyGui;
|
||||||
|
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 VoteGuiCommand implements CommandExecutor {
|
||||||
|
|
||||||
|
private final VoteConfig config;
|
||||||
|
private final VoteParty voteParty;
|
||||||
|
|
||||||
|
public VoteGuiCommand(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;
|
||||||
|
}
|
||||||
|
VotePartyGui.open(player, config, voteParty);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package fr.votenetwork.spigot.gui;
|
||||||
|
|
||||||
|
import fr.votenetwork.spigot.VoteConfig;
|
||||||
|
import fr.votenetwork.spigot.voteparty.VoteParty;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
import org.bukkit.inventory.meta.ItemMeta;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Builds and opens the VoteParty progress GUI: a progress item (slot 4) plus one item per
|
||||||
|
* configured vote site (starting at slot 9), each opening its URL when clicked.
|
||||||
|
*/
|
||||||
|
public final class VotePartyGui {
|
||||||
|
|
||||||
|
public static final int PROGRESS_SLOT = 4;
|
||||||
|
public static final int SITES_START_SLOT = 9;
|
||||||
|
|
||||||
|
private VotePartyGui() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void open(Player player, VoteConfig config, VoteParty voteParty) {
|
||||||
|
List<VoteSite> sites = config.getVoteSites();
|
||||||
|
int size = ((SITES_START_SLOT + sites.size() + 8) / 9) * 9;
|
||||||
|
size = Math.max(size, 18);
|
||||||
|
|
||||||
|
VotePartyGuiHolder holder = new VotePartyGuiHolder();
|
||||||
|
Inventory inventory = Bukkit.createInventory(holder, size, config.getGuiTitle());
|
||||||
|
holder.setInventory(inventory);
|
||||||
|
|
||||||
|
int required = config.getVotePartyVotesRequired();
|
||||||
|
int current = Math.min(voteParty.getCurrentVotes(), required);
|
||||||
|
|
||||||
|
ItemStack progressItem = new ItemStack(materialOrFallback(config.getGuiProgressItemMaterial()));
|
||||||
|
ItemMeta progressMeta = progressItem.getItemMeta();
|
||||||
|
if (progressMeta != null) {
|
||||||
|
progressMeta.setDisplayName(config.getGuiProgressItemName());
|
||||||
|
progressMeta.setLore(config.getGuiProgressItemLore().stream()
|
||||||
|
.map(line -> line.replace("%current%", String.valueOf(current))
|
||||||
|
.replace("%required%", String.valueOf(required)))
|
||||||
|
.toList());
|
||||||
|
progressItem.setItemMeta(progressMeta);
|
||||||
|
}
|
||||||
|
inventory.setItem(PROGRESS_SLOT, progressItem);
|
||||||
|
|
||||||
|
int slot = SITES_START_SLOT;
|
||||||
|
for (VoteSite site : sites) {
|
||||||
|
ItemStack item = new ItemStack(site.getMaterial());
|
||||||
|
ItemMeta meta = item.getItemMeta();
|
||||||
|
if (meta != null) {
|
||||||
|
meta.setDisplayName(site.getName());
|
||||||
|
meta.setLore(site.getLore());
|
||||||
|
item.setItemMeta(meta);
|
||||||
|
}
|
||||||
|
inventory.setItem(slot, item);
|
||||||
|
slot++;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.openInventory(inventory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static org.bukkit.Material materialOrFallback(String name) {
|
||||||
|
try {
|
||||||
|
return org.bukkit.Material.valueOf(name.toUpperCase(java.util.Locale.ROOT));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
return org.bukkit.Material.NETHER_STAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package fr.votenetwork.spigot.gui;
|
||||||
|
|
||||||
|
import org.bukkit.inventory.Inventory;
|
||||||
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker holder used to recognize our own GUI inventory in InventoryClickEvent, so the
|
||||||
|
* listener never touches clicks happening in unrelated inventories (chests, other plugins'
|
||||||
|
* GUIs, etc.).
|
||||||
|
*/
|
||||||
|
public class VotePartyGuiHolder implements InventoryHolder {
|
||||||
|
|
||||||
|
private Inventory inventory;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Inventory getInventory() {
|
||||||
|
return inventory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInventory(Inventory inventory) {
|
||||||
|
this.inventory = inventory;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
package fr.votenetwork.spigot.gui;
|
||||||
|
|
||||||
|
import fr.votenetwork.spigot.VoteConfig;
|
||||||
|
import net.md_5.bungee.api.chat.ClickEvent;
|
||||||
|
import net.md_5.bungee.api.chat.TextComponent;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bukkit cannot open a browser directly from an inventory click, so a click on a vote-site
|
||||||
|
* item closes the GUI and sends a clickable chat message (ClickEvent OPEN_URL) instead.
|
||||||
|
*/
|
||||||
|
public class VotePartyGuiListener implements Listener {
|
||||||
|
|
||||||
|
private final VoteConfig config;
|
||||||
|
|
||||||
|
public VotePartyGuiListener(VoteConfig config) {
|
||||||
|
this.config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onInventoryClick(InventoryClickEvent event) {
|
||||||
|
if (!(event.getInventory().getHolder() instanceof VotePartyGuiHolder)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
event.setCancelled(true);
|
||||||
|
|
||||||
|
int slot = event.getRawSlot();
|
||||||
|
if (slot < VotePartyGui.SITES_START_SLOT || !(event.getWhoClicked() instanceof Player player)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<VoteSite> sites = config.getVoteSites();
|
||||||
|
int index = slot - VotePartyGui.SITES_START_SLOT;
|
||||||
|
if (index < 0 || index >= sites.size()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
VoteSite site = sites.get(index);
|
||||||
|
if (site.getUrl() == null || site.getUrl().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player.closeInventory();
|
||||||
|
TextComponent message = new TextComponent(config.getGuiClickMessage() + " " + site.getUrl());
|
||||||
|
message.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, site.getUrl()));
|
||||||
|
player.spigot().sendMessage(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package fr.votenetwork.spigot.gui;
|
||||||
|
|
||||||
|
import org.bukkit.Material;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single vote-site entry configured in config.yml (gui.vote-sites): the display item and
|
||||||
|
* the URL opened (via a clickable chat message) when the player clicks it in the GUI.
|
||||||
|
*/
|
||||||
|
public class VoteSite {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final Material material;
|
||||||
|
private final String url;
|
||||||
|
private final List<String> lore;
|
||||||
|
|
||||||
|
public VoteSite(String name, Material material, String url, List<String> lore) {
|
||||||
|
this.name = name;
|
||||||
|
this.material = material;
|
||||||
|
this.url = url;
|
||||||
|
this.lore = lore;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Material getMaterial() {
|
||||||
|
return material;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUrl() {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getLore() {
|
||||||
|
return lore;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -47,6 +47,30 @@ voteparty:
|
|||||||
progress-message: "&b[Vote] &f%current%&7/&f%required% &fvotes avant le prochain VoteParty !"
|
progress-message: "&b[Vote] &f%current%&7/&f%required% &fvotes avant le prochain VoteParty !"
|
||||||
triggered-message: "&a[Vote] &fVoteParty declenche ! Profitez des recompenses !"
|
triggered-message: "&a[Vote] &fVoteParty declenche ! Profitez des recompenses !"
|
||||||
|
|
||||||
|
# GUI /votegui : affiche la progression du VoteParty et des items cliquables vers les sites
|
||||||
|
# de vote (ouvre le lien via un message chat cliquable, Bukkit ne peut pas ouvrir un navigateur
|
||||||
|
# directement depuis un clic d'inventaire).
|
||||||
|
gui:
|
||||||
|
title: "&8VoteNetwork"
|
||||||
|
progress-item:
|
||||||
|
material: NETHER_STAR
|
||||||
|
name: "&b&lVoteParty"
|
||||||
|
lore:
|
||||||
|
- "&7Progression actuelle :"
|
||||||
|
- "&f%current%&7/&f%required% &7votes"
|
||||||
|
click-message: "&a[Vote] Clique sur le lien pour voter :"
|
||||||
|
vote-sites:
|
||||||
|
- name: "&aVoter sur le site 1"
|
||||||
|
material: PAPER
|
||||||
|
url: "https://example.com/vote/site1"
|
||||||
|
lore:
|
||||||
|
- "&7Clique pour voter !"
|
||||||
|
- name: "&aVoter sur le site 2"
|
||||||
|
material: BOOK
|
||||||
|
url: "https://example.com/vote/site2"
|
||||||
|
lore:
|
||||||
|
- "&7Clique pour voter !"
|
||||||
|
|
||||||
messages:
|
messages:
|
||||||
direct-vote: "&a[Vote] &fMerci pour ton vote !"
|
direct-vote: "&a[Vote] &fMerci pour ton vote !"
|
||||||
claim-success: "&a[Vote] &fVous avez recupere &e%amount% &fvote(s) en attente !"
|
claim-success: "&a[Vote] &fVous avez recupere &e%amount% &fvote(s) en attente !"
|
||||||
|
|||||||
@@ -14,6 +14,9 @@ commands:
|
|||||||
description: Administration du systeme de vote (maintenance, test du stockage).
|
description: Administration du systeme de vote (maintenance, test du stockage).
|
||||||
usage: /vote <stop|start|testdb>
|
usage: /vote <stop|start|testdb>
|
||||||
permission: votenetwork.admin
|
permission: votenetwork.admin
|
||||||
|
votegui:
|
||||||
|
description: Ouvre le GUI de progression du VoteParty avec les liens de vote.
|
||||||
|
usage: /votegui
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
votenetwork.admin:
|
votenetwork.admin:
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>fr.votenetwork</groupId>
|
<groupId>fr.votenetwork</groupId>
|
||||||
<artifactId>votenetwork-parent</artifactId>
|
<artifactId>votenetwork-parent</artifactId>
|
||||||
<version>1.0.0</version>
|
<version>1.0.1</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<artifactId>votenetwork-velocity</artifactId>
|
<artifactId>votenetwork-velocity</artifactId>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import java.nio.file.Path;
|
|||||||
@Plugin(
|
@Plugin(
|
||||||
id = "votenetwork",
|
id = "votenetwork",
|
||||||
name = "VoteNetwork",
|
name = "VoteNetwork",
|
||||||
version = "1.0.0",
|
version = "1.0.1",
|
||||||
description = "Systeme de vote reseau Velocity <-> Spigot",
|
description = "Systeme de vote reseau Velocity <-> Spigot",
|
||||||
authors = {"Sar_Tron"}
|
authors = {"Sar_Tron"}
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user