From a47376db3a25a1ddb3fa803278fcefd5588bd988 Mon Sep 17 00:00:00 2001 From: SarTron-NorthBlue Date: Sun, 12 Jul 2026 13:47:22 +0400 Subject: [PATCH] Fix : vote perdu si le joueur est sur un serveur sans le plugin Spigot Velocity envoyait le paquet direct des qu'un joueur etait en ligne, sans verifier que le serveur courant (ex: un lobby) avait bien VoteNetwork-Spigot installe. Message silencieusement perdu dans ce cas. Ajoute direct-vote.servers (config.properties) : liste blanche des serveurs equipes du plugin. Hors de cette liste, le vote est traite comme "joueur hors ligne" et stocke en base au lieu d'etre envoye en direct. Co-Authored-By: Claude Sonnet 5 --- README.md | 6 ++++-- .../fr/votenetwork/velocity/VoteCommand.java | 16 ++++++++++---- .../fr/votenetwork/velocity/VoteConfig.java | 21 +++++++++++++++++++ .../velocity/VoteNetworkVelocity.java | 2 +- velocity/src/main/resources/config.properties | 8 +++++++ 5 files changed, 46 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a898580..613d0d8 100644 --- a/README.md +++ b/README.md @@ -111,11 +111,13 @@ Testez la connexion/l'accès au stockage configuré côté Spigot avec : ## Fonctionnement du vote 1. Un site de vote appelle la console du proxy : `votenetwork vote `. -2. **Joueur connecté** : le proxy détecte son serveur actuel et envoie un paquet sur le canal `votenetwork:vote`. Le serveur Spigot donne la récompense immédiatement et incrémente son VoteParty local de +1. **Rien n'est écrit en base.** -3. **Joueur déconnecté** : le proxy résout son UUID (API Mojang, avec repli si indisponible) et incrémente son compteur de votes en attente (MySQL ou YAML selon la config), de façon asynchrone. +2. **Joueur connecté ET sur un serveur listé dans `direct-vote.servers`** : le proxy envoie un paquet sur le canal `votenetwork:vote`. Le serveur Spigot donne la récompense immédiatement et incrémente son VoteParty local de +1. **Rien n'est écrit en base.** +3. **Joueur déconnecté, OU connecté mais sur un serveur absent de `direct-vote.servers`** (ex: un lobby sans le plugin) : le proxy résout son UUID (API Mojang, avec repli si indisponible) et incrémente son compteur de votes en attente (MySQL ou YAML selon la config), de façon asynchrone. 4. Le joueur tape `/claim` sur un serveur Spigot : lecture asynchrone du compteur en attente, distribution des récompenses × N, VoteParty local +N, remise à 0. 5. `/vote stop` bloque `/claim` (mode maintenance, message personnalisable) ; `/vote start` le réactive. +> **Important** : `direct-vote.servers` (dans `config.properties` côté Velocity) doit lister les noms exacts des serveurs (tels que dans `velocity.toml`) où `VoteNetwork-Spigot.jar` est installé. Un joueur sur un serveur absent de cette liste (lobby, hub...) est traité comme "hors ligne" pour le vote — sinon le paquet direct part dans le vide (aucun plugin pour l'écouter) et le vote est perdu silencieusement. + ## Commandes & permissions | Commande | Où | Qui | Description | diff --git a/velocity/src/main/java/fr/votenetwork/velocity/VoteCommand.java b/velocity/src/main/java/fr/votenetwork/velocity/VoteCommand.java index 428964c..d6c8a25 100644 --- a/velocity/src/main/java/fr/votenetwork/velocity/VoteCommand.java +++ b/velocity/src/main/java/fr/votenetwork/velocity/VoteCommand.java @@ -17,12 +17,14 @@ import java.util.Optional; public class VoteCommand implements SimpleCommand { private final ProxyServer proxy; + private final VoteConfig config; private final PendingVoteStore pendingVoteStore; private final Logger logger; private final MojangUuidResolver uuidResolver; - public VoteCommand(ProxyServer proxy, PendingVoteStore pendingVoteStore, Logger logger) { + public VoteCommand(ProxyServer proxy, VoteConfig config, PendingVoteStore pendingVoteStore, Logger logger) { this.proxy = proxy; + this.config = config; this.pendingVoteStore = pendingVoteStore; this.logger = logger; this.uuidResolver = new MojangUuidResolver(logger); @@ -51,9 +53,15 @@ public class VoteCommand implements SimpleCommand { Optional serverConnection = player.getCurrentServer(); if (serverConnection.isPresent()) { - sendVoteSignal(serverConnection.get(), player); - logger.info("Vote direct envoye a {} pour le joueur {}", serverConnection.get().getServerInfo().getName(), player.getUsername()); - return; + String serverName = serverConnection.get().getServerInfo().getName(); + + if (config.isDirectVoteServer(serverName)) { + sendVoteSignal(serverConnection.get(), player); + logger.info("Vote direct envoye a {} pour le joueur {}", serverName, player.getUsername()); + return; + } + + logger.info("{} est sur {} (pas dans direct-vote.servers) : vote stocke en base au lieu d'un envoi direct.", player.getUsername(), serverName); } } diff --git a/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java b/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java index 0c6b059..ee74a4f 100644 --- a/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java +++ b/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java @@ -6,7 +6,11 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.util.Arrays; +import java.util.Locale; import java.util.Properties; +import java.util.Set; +import java.util.stream.Collectors; public class VoteConfig { @@ -21,6 +25,7 @@ public class VoteConfig { private String user; private String password; private int poolSize; + private Set directVoteServers; public VoteConfig(Path dataDirectory, Logger logger) { this.dataDirectory = dataDirectory; @@ -51,6 +56,13 @@ public class VoteConfig { this.user = properties.getProperty("mysql.user", "root"); this.password = properties.getProperty("mysql.password", ""); this.poolSize = Integer.parseInt(properties.getProperty("mysql.pool-size", "5")); + + String serversRaw = properties.getProperty("direct-vote.servers", ""); + this.directVoteServers = Arrays.stream(serversRaw.split(",")) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .map(s -> s.toLowerCase(Locale.ROOT)) + .collect(Collectors.toSet()); } catch (IOException e) { logger.error("Impossible de charger la configuration Velocity", e); } @@ -60,6 +72,15 @@ public class VoteConfig { return !"yaml".equalsIgnoreCase(storageType); } + /** + * true si le plugin VoteNetwork-Spigot est declare installe sur ce serveur (liste + * direct-vote.servers). Si la liste est vide, tous les serveurs sont consideres eligibles + * (comportement historique, a eviter des qu'un serveur type lobby n'a pas le plugin). + */ + public boolean isDirectVoteServer(String serverName) { + return directVoteServers.isEmpty() || directVoteServers.contains(serverName.toLowerCase(Locale.ROOT)); + } + public String getJdbcUrl() { return "jdbc:mysql://" + host + ":" + port + "/" + database + "?useSSL=false&autoReconnect=true&characterEncoding=utf8"; diff --git a/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java b/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java index 59d7f97..1ac5017 100644 --- a/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java +++ b/velocity/src/main/java/fr/votenetwork/velocity/VoteNetworkVelocity.java @@ -56,7 +56,7 @@ public class VoteNetworkVelocity { proxy.getCommandManager().register( proxy.getCommandManager().metaBuilder("votenetwork").build(), - new VoteCommand(proxy, pendingVoteStore, logger) + new VoteCommand(proxy, config, pendingVoteStore, logger) ); logger.info("VoteNetwork (Velocity) demarre."); diff --git a/velocity/src/main/resources/config.properties b/velocity/src/main/resources/config.properties index 8c6a691..378ac4b 100644 --- a/velocity/src/main/resources/config.properties +++ b/velocity/src/main/resources/config.properties @@ -12,3 +12,11 @@ mysql.database=votenetwork mysql.user=root mysql.password=changeme mysql.pool-size=5 + +# Liste (separee par des virgules) des noms de serveurs Velocity (tels que declares dans +# velocity.toml) ou le plugin VoteNetwork-Spigot est installe. Si le joueur qui vote est +# actuellement sur un serveur absent de cette liste (ex: un lobby sans le plugin), le vote +# est stocke en base au lieu d'etre envoye en direct (qui serait silencieusement perdu). +# Laisser vide = tous les serveurs sont consideres comme ayant le plugin (deconseille des +# qu'un lobby/hub sans VoteNetwork-Spigot existe sur le reseau). +direct-vote.servers=gen1,gen2