VoteNetwork: plugin de vote reseau Velocity <-> Spigot
Reception directe en jeu (plugin messaging) ou stockage des votes en attente (MySQL ou YAML configurable), /claim, VoteParty local par serveur, mode maintenance, API publique pour scoreboard/GUI. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
# VoteNetwork
|
||||
|
||||
Systeme de vote reseau en deux modules, pour une architecture **proxy Velocity + serveurs Spigot/Paper** (modes A, B, C, ...).
|
||||
|
||||
- `velocity/` — module proxy. Recoit `votenetwork vote <pseudo>` (console uniquement) et route le vote en direct ou le met en attente.
|
||||
- `spigot/` — module serveur. Recoit le signal en direct via Plugin Messaging, gere `/claim`, le VoteParty local et le mode maintenance.
|
||||
|
||||
Compatible **Java 17**, compile contre l'API Spigot **1.18.2** (additive, donc compatible en avant vers 1.19 → 1.21.x et versions futures).
|
||||
|
||||
---
|
||||
|
||||
## Sommaire
|
||||
|
||||
- [Installation](#installation)
|
||||
- [Build depuis les sources](#build-depuis-les-sources)
|
||||
- [Configuration](#configuration)
|
||||
- [Stockage : MySQL ou YAML](#stockage--mysql-ou-yaml)
|
||||
- [Fonctionnement du vote](#fonctionnement-du-vote)
|
||||
- [Commandes & permissions](#commandes--permissions)
|
||||
- [VoteParty](#voteparty)
|
||||
- [API publique (scoreboard / GUI)](#api-publique-scoreboard--gui)
|
||||
- [Structure de la base de données](#structure-de-la-base-de-données)
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
1. `velocity/target/VoteNetwork-Velocity.jar` → `plugins/` du proxy Velocity.
|
||||
2. `spigot/target/VoteNetwork-Spigot.jar` → `plugins/` de **chaque** serveur Spigot/Paper (A, B, C, ...).
|
||||
3. Démarrer une fois pour générer les fichiers de config, puis les éditer :
|
||||
- Proxy : `plugins/votenetwork/config.properties`
|
||||
- Serveur : `plugins/votenetwork/config.yml`
|
||||
4. Redémarrer.
|
||||
|
||||
## Build depuis les sources
|
||||
|
||||
```
|
||||
mvn clean package
|
||||
```
|
||||
|
||||
Jars produits dans `velocity/target/` et `spigot/target/`.
|
||||
|
||||
## Configuration
|
||||
|
||||
Chaque composant a son propre fichier, tous deux dans un dossier **`votenetwork`** :
|
||||
|
||||
| Composant | Fichier | Dossier |
|
||||
|---|---|---|
|
||||
| Velocity | `config.properties` | `plugins/votenetwork/` (racine du proxy) |
|
||||
| Spigot | `config.yml` | `plugins/votenetwork/` (sur chaque serveur) |
|
||||
|
||||
Le `config.yml` Spigot regroupe tout ce qui est personnalisable :
|
||||
|
||||
```yaml
|
||||
storage:
|
||||
type: mysql # mysql ou yaml
|
||||
|
||||
mysql:
|
||||
host: 127.0.0.1
|
||||
port: 3306
|
||||
database: votenetwork
|
||||
user: root
|
||||
password: changeme
|
||||
pool-size: 5
|
||||
|
||||
rewards:
|
||||
vote-commands: # executees pour CHAQUE vote (direct ou via /claim, une fois par vote)
|
||||
- "goldencrates give %player% vote_key 1"
|
||||
|
||||
voteparty:
|
||||
votes-requis: 100 # déclenche le VoteParty à ce cumul (par serveur)
|
||||
commands: # executees UNE fois quand le VoteParty se déclenche
|
||||
- "goldencrates broadcast_give vote_key 1"
|
||||
broadcast:
|
||||
enabled: true
|
||||
progress-message: "&b[Vote] &f%current%&7/&f%required% &fvotes avant le prochain VoteParty !"
|
||||
triggered-message: "&a[Vote] &fVoteParty declenche ! Profitez des recompenses !"
|
||||
|
||||
messages:
|
||||
direct-vote: "&a[Vote] &fMerci pour ton vote !"
|
||||
claim-success: "&a[Vote] &fVous avez recupere &e%amount% &fvote(s) en attente !"
|
||||
claim-empty: "&c[Vote] &fVous n'avez aucun vote en attente."
|
||||
maintenance: "&c[Vote] &fLe systeme de vote est actuellement en maintenance."
|
||||
maintenance-enabled: "&c[Vote] &fMode maintenance active."
|
||||
maintenance-disabled: "&a[Vote] &fMode maintenance desactive."
|
||||
no-permission: "&cVous n'avez pas la permission d'utiliser cette commande."
|
||||
```
|
||||
|
||||
- `%player%` dans `rewards.vote-commands` est remplacé par le pseudo du joueur.
|
||||
- `%current%` / `%required%` dans les messages de progression VoteParty.
|
||||
- `%amount%` dans le message de succès `/claim`.
|
||||
- Codes couleur `&` supportés partout.
|
||||
|
||||
## Stockage : MySQL ou YAML
|
||||
|
||||
Chaque composant choisit indépendamment son stockage via `storage.type` :
|
||||
|
||||
- **`mysql`** (recommandé pour un vrai réseau) : partagé entre le proxy et tous les serveurs. La table `nb_votes_attente` est créée automatiquement au démarrage si absente.
|
||||
- **`yaml`** : fichier local `pending-votes.yml` dans le dossier du plugin. Pratique en solo/test, **mais pas synchronisé automatiquement** entre le fichier du proxy et celui d'un serveur — chacun a sa propre copie locale. N'utilisez ce mode en réseau multi-machines que si les dossiers de plugins sont partagés sur le même disque (montage réseau, symlink). Sinon, un vote stocké côté proxy en YAML ne sera jamais vu par `/claim` sur un serveur Spigot séparé.
|
||||
|
||||
Testez la connexion/l'accès au stockage configuré côté Spigot avec :
|
||||
|
||||
```
|
||||
/vote testdb
|
||||
```
|
||||
|
||||
## Fonctionnement du vote
|
||||
|
||||
1. Un site de vote appelle la console du proxy : `votenetwork vote <pseudo>`.
|
||||
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.
|
||||
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.
|
||||
|
||||
## Commandes & permissions
|
||||
|
||||
| Commande | Où | Qui | Description |
|
||||
|---|---|---|---|
|
||||
| `votenetwork vote <pseudo>` | Velocity | Console uniquement | Enregistre un vote pour le joueur |
|
||||
| `/claim` | Spigot | Joueurs | Récupère les votes en attente |
|
||||
| `/vote stop\|start` | Spigot | `votenetwork.admin` (op par défaut) | Bascule le mode maintenance |
|
||||
| `/vote testdb` | Spigot | `votenetwork.admin` (op par défaut) | Teste le stockage configuré (MySQL ou YAML) |
|
||||
|
||||
## VoteParty
|
||||
|
||||
- Compteur indépendant **par serveur**, persistant localement (`plugins/votenetwork/voteparty.yml`), survit aux redémarrages.
|
||||
- `voteparty.votes-requis` définit le seuil de déclenchement.
|
||||
- `voteparty.commands` s'exécutent une fois le seuil atteint, puis le compteur repart à 0 (avec report de l'excédent si plusieurs votes arrivent d'un coup, ex. via `/claim` de N votes).
|
||||
- Messages de progression et de déclenchement personnalisables (`voteparty.broadcast`).
|
||||
|
||||
## API publique (scoreboard / GUI)
|
||||
|
||||
Un autre plugin sur le même serveur Spigot peut lire l'état du vote via `fr.northblue.vote.spigot.api.NorthBlueVoteAPI` :
|
||||
|
||||
```java
|
||||
NorthBlueVoteAPI api = NorthBlueVoteAPI.get();
|
||||
// ou : Bukkit.getServicesManager().getRegistration(NorthBlueVoteAPI.class).getProvider();
|
||||
|
||||
int current = api.getVotePartyCurrentVotes();
|
||||
int required = api.getVotePartyRequiredVotes();
|
||||
boolean maintenance = api.isMaintenanceEnabled();
|
||||
|
||||
api.getPendingVotes(player.getUniqueId(), pending -> {
|
||||
// callback rappelé sur le thread principal — safe pour un scoreboard/GUI
|
||||
scoreboardLine.setText("Votes en attente: " + pending);
|
||||
});
|
||||
```
|
||||
|
||||
- `getVotePartyCurrentVotes()` / `getVotePartyRequiredVotes()` : lecture directe en mémoire, thread principal uniquement.
|
||||
- `getPendingVotes(...)` : lecture asynchrone du stockage configuré (MySQL ou YAML), ne consomme pas les votes contrairement à `/claim`.
|
||||
|
||||
## Structure de la base de données
|
||||
|
||||
Créée automatiquement si absente (mode `mysql`) :
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS nb_votes_attente (
|
||||
player_uuid VARCHAR(36) NOT NULL PRIMARY KEY,
|
||||
player_name VARCHAR(16) NOT NULL,
|
||||
nombre_votes INT DEFAULT 0
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes techniques
|
||||
|
||||
- HikariCP + MySQL Connector/J sont shadés et relocalisés dans les deux jars (rien à installer manuellement sur le serveur). Le driver JDBC est chargé explicitement par son nom de classe relocalisé pour rester fiable après le shading.
|
||||
- Toutes les requêtes SQL et I/O fichier sont asynchrones — aucun accès réseau ou disque ne bloque le thread principal du serveur ni celui du proxy.
|
||||
- Si la connexion MySQL échoue au démarrage, le plugin reste actif (pas de crash) : corrigez `config.yml`/`config.properties` puis utilisez `/vote testdb`, ou redémarrez.
|
||||
Reference in New Issue
Block a user