Ajoute la portee per-server pour les votes en attente + credits/licence
pending-votes.scope (config.properties Velocity) = global (defaut, comportement historique) ou per-server. En per-server, un vote hors ligne incremente le compteur de chaque serveur de direct-vote.servers independamment (nouvelle table nb_votes_attente_serveur) ; /claim sur un serveur ne remet a 0 que ce serveur-la. Necessite server-name (config.yml) et storage.pending-votes-scope assortis cote Spigot. Ajoute LICENSE (MIT) et credit Sar_Tron (plugin.yml, @Plugin Velocity, pom parent, README) en vue de la publication publique. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
74b2914529
commit
261e220d1a
@@ -57,16 +57,24 @@ public class MySqlPendingVoteStore implements PendingVoteStore {
|
||||
}
|
||||
|
||||
private void createTableIfNotExists() {
|
||||
String sql = "CREATE TABLE IF NOT EXISTS nb_votes_attente (" +
|
||||
String globalSql = "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" +
|
||||
")";
|
||||
String perServerSql = "CREATE TABLE IF NOT EXISTS nb_votes_attente_serveur (" +
|
||||
"player_uuid VARCHAR(36) NOT NULL," +
|
||||
"server_name VARCHAR(64) NOT NULL," +
|
||||
"player_name VARCHAR(16) NOT NULL," +
|
||||
"nombre_votes INT DEFAULT 0," +
|
||||
"PRIMARY KEY (player_uuid, server_name)" +
|
||||
")";
|
||||
try (Connection connection = dataSource.getConnection();
|
||||
Statement statement = connection.createStatement()) {
|
||||
statement.execute(sql);
|
||||
statement.execute(globalSql);
|
||||
statement.execute(perServerSql);
|
||||
} catch (SQLException e) {
|
||||
logger.error("Impossible de creer la table nb_votes_attente", e);
|
||||
logger.error("Impossible de creer les tables de votes en attente", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,20 +85,46 @@ public class MySqlPendingVoteStore implements PendingVoteStore {
|
||||
logger.error("Impossible d'enregistrer le vote en attente pour {} : pool MySQL indisponible", playerName);
|
||||
return;
|
||||
}
|
||||
String sql = "INSERT INTO nb_votes_attente (player_uuid, player_name, nombre_votes) " +
|
||||
"VALUES (?, ?, 1) " +
|
||||
"ON DUPLICATE KEY UPDATE nombre_votes = nombre_votes + 1, player_name = VALUES(player_name)";
|
||||
try (Connection connection = dataSource.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, playerName);
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Erreur lors de l'insertion du vote en attente pour {}", playerName, e);
|
||||
if (config.isPerServerScope()) {
|
||||
addPendingVotePerServer(uuid, playerName);
|
||||
} else {
|
||||
addPendingVoteGlobal(uuid, playerName);
|
||||
}
|
||||
}, asyncExecutor);
|
||||
}
|
||||
|
||||
private void addPendingVoteGlobal(UUID uuid, String playerName) {
|
||||
String sql = "INSERT INTO nb_votes_attente (player_uuid, player_name, nombre_votes) " +
|
||||
"VALUES (?, ?, 1) " +
|
||||
"ON DUPLICATE KEY UPDATE nombre_votes = nombre_votes + 1, player_name = VALUES(player_name)";
|
||||
try (Connection connection = dataSource.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, playerName);
|
||||
statement.executeUpdate();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Erreur lors de l'insertion du vote en attente pour {}", playerName, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void addPendingVotePerServer(UUID uuid, String playerName) {
|
||||
String sql = "INSERT INTO nb_votes_attente_serveur (player_uuid, server_name, player_name, nombre_votes) " +
|
||||
"VALUES (?, ?, ?, 1) " +
|
||||
"ON DUPLICATE KEY UPDATE nombre_votes = nombre_votes + 1, player_name = VALUES(player_name)";
|
||||
try (Connection connection = dataSource.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(sql)) {
|
||||
for (String server : config.getDirectVoteServers()) {
|
||||
statement.setString(1, uuid.toString());
|
||||
statement.setString(2, server);
|
||||
statement.setString(3, playerName);
|
||||
statement.addBatch();
|
||||
}
|
||||
statement.executeBatch();
|
||||
} catch (SQLException e) {
|
||||
logger.error("Erreur lors de l'insertion du vote en attente (per-server) pour {}", playerName, e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
if (dataSource != null) {
|
||||
|
||||
@@ -26,6 +26,7 @@ public class VoteConfig {
|
||||
private String password;
|
||||
private int poolSize;
|
||||
private Set<String> directVoteServers;
|
||||
private String pendingVotesScope;
|
||||
|
||||
public VoteConfig(Path dataDirectory, Logger logger) {
|
||||
this.dataDirectory = dataDirectory;
|
||||
@@ -65,6 +66,13 @@ public class VoteConfig {
|
||||
.filter(s -> !s.isEmpty())
|
||||
.map(s -> s.toLowerCase(Locale.ROOT))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
this.pendingVotesScope = properties.getProperty("pending-votes.scope", "global");
|
||||
if (isPerServerScope() && directVoteServers.isEmpty()) {
|
||||
logger.warn("pending-votes.scope=per-server mais direct-vote.servers est vide : bascule sur 'global'. "
|
||||
+ "Renseignez direct-vote.servers pour utiliser le mode per-server.");
|
||||
this.pendingVotesScope = "global";
|
||||
}
|
||||
} catch (IOException e) {
|
||||
logger.error("Impossible de charger la configuration Velocity", e);
|
||||
}
|
||||
@@ -119,6 +127,19 @@ public class VoteConfig {
|
||||
return directVoteServers.isEmpty() || directVoteServers.contains(serverName.toLowerCase(Locale.ROOT));
|
||||
}
|
||||
|
||||
/**
|
||||
* true si chaque serveur doit avoir son propre compteur de votes en attente independant
|
||||
* (un /claim sur un serveur ne remet a 0 que ce serveur-la). Sinon (par defaut), un seul
|
||||
* compteur est partage entre tous les serveurs : /claim le remet a 0 partout a la fois.
|
||||
*/
|
||||
public boolean isPerServerScope() {
|
||||
return "per-server".equalsIgnoreCase(pendingVotesScope);
|
||||
}
|
||||
|
||||
public Set<String> getDirectVoteServers() {
|
||||
return directVoteServers;
|
||||
}
|
||||
|
||||
public String getJdbcUrl() {
|
||||
return "jdbc:mysql://" + host + ":" + port + "/" + database
|
||||
+ "?useSSL=false&autoReconnect=true&characterEncoding=utf8";
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.nio.file.Path;
|
||||
name = "VoteNetwork",
|
||||
version = "1.0.0",
|
||||
description = "Systeme de vote reseau Velocity <-> Spigot",
|
||||
authors = {"VoteNetwork"}
|
||||
authors = {"Sar_Tron"}
|
||||
)
|
||||
public class VoteNetworkVelocity {
|
||||
|
||||
|
||||
@@ -20,3 +20,17 @@ mysql.pool-size=5
|
||||
# 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
|
||||
|
||||
# Portee des votes en attente (joueur hors ligne au moment du vote), uniquement en storage.type=mysql :
|
||||
# global (par defaut) : un seul compteur partage entre tous les serveurs. Un /claim sur
|
||||
# N'IMPORTE QUEL serveur remet le compteur a 0 pour TOUS les serveurs a la fois.
|
||||
# per-server : chaque serveur de direct-vote.servers a son propre compteur independant. Un
|
||||
# vote hors ligne incremente le compteur de CHAQUE serveur de la liste. Un /claim
|
||||
# sur le serveur 1 ne remet a 0 QUE le compteur du serveur 1 : le joueur garde ses
|
||||
# votes en attente sur le serveur 2 et peut les reclamer separement la-bas.
|
||||
# Exemple concret en per-server : le joueur vote 2 fois hors ligne -> 2 votes en attente sur
|
||||
# CHAQUE serveur. Il fait /claim sur le serveur 1 -> recoit 2 recompenses, serveur 1 repasse a 0,
|
||||
# serveur 2 reste a 2. S'il revote une fois -> serveur 1 = 1, serveur 2 = 3.
|
||||
# Necessite direct-vote.servers rempli ET que chaque serveur Spigot declare son server-name
|
||||
# (config.yml) correspondant exactement a un nom de cette liste.
|
||||
pending-votes.scope=global
|
||||
|
||||
Reference in New Issue
Block a user