From a76c641b7d243986a783960962e8ae355a82fdf1 Mon Sep 17 00:00:00 2001 From: SarTron-NorthBlue Date: Sun, 12 Jul 2026 14:23:58 +0400 Subject: [PATCH] Merge auto des nouvelles options de config au demarrage Une mise a jour du plugin qui ajoute des cles de config n'obligeait pas a editer config.yml/config.properties a la main : les valeurs par defaut restaient invisibles pour l'admin. Desormais, au demarrage, les cles manquantes sont ajoutees dans le fichier existant sans toucher aux valeurs deja personnalisees. Spigot : merge via YamlConfiguration (perd les commentaires au prochain rewrite, limitation Bukkit). Velocity : simple ajout de lignes en fin de fichier, commentaires existants preserves. Co-Authored-By: Claude Sonnet 5 --- README.md | 1 + .../votenetwork/spigot/VoteNetworkSpigot.java | 43 +++++++++++++++++++ .../fr/votenetwork/velocity/VoteConfig.java | 38 ++++++++++++++++ 3 files changed, 82 insertions(+) diff --git a/README.md b/README.md index 6360d2d..c34d614 100644 --- a/README.md +++ b/README.md @@ -176,3 +176,4 @@ CREATE TABLE IF NOT EXISTS nb_votes_attente ( - 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. +- **Mise à jour de config** : à chaque démarrage, les nouvelles options apportées par une mise à jour du plugin (absentes de votre `config.yml`/`config.properties` existant) sont ajoutées automatiquement, **sans jamais toucher aux valeurs que vous avez déjà personnalisées**. Côté Spigot, la réécriture du `config.yml` fait perdre les commentaires (limitation de l'API Bukkit) ; côté Velocity, les nouvelles clés sont simplement ajoutées en bas du `config.properties`, les commentaires existants sont préservés. diff --git a/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java b/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java index d5de8f3..f8315d7 100644 --- a/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java +++ b/spigot/src/main/java/fr/votenetwork/spigot/VoteNetworkSpigot.java @@ -10,9 +10,14 @@ import fr.votenetwork.spigot.storage.MySqlPendingVoteStore; import fr.votenetwork.spigot.storage.PendingVoteStore; import fr.votenetwork.spigot.storage.YamlPendingVoteStore; import fr.votenetwork.spigot.voteparty.VoteParty; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.ServicePriority; import org.bukkit.plugin.java.JavaPlugin; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + public class VoteNetworkSpigot extends JavaPlugin { public static final String CHANNEL = "votenetwork:vote"; @@ -25,6 +30,7 @@ public class VoteNetworkSpigot extends JavaPlugin { @Override public void onEnable() { saveDefaultConfig(); + mergeMissingConfigKeys(); this.voteConfig = new VoteConfig(this); this.maintenanceState = new MaintenanceState(); @@ -55,6 +61,43 @@ public class VoteNetworkSpigot extends JavaPlugin { getLogger().info("VoteNetwork (Spigot) demarre."); } + /** + * Ajoute dans config.yml les cles presentes dans le config.yml embarque dans le jar mais + * absentes du fichier existant (nouvelles options apportees par une mise a jour du plugin), + * sans jamais modifier une valeur deja definie par l'admin. + * + * Limite connue : Bukkit ne preserve pas les commentaires lors de la reecriture du fichier. + */ + private void mergeMissingConfigKeys() { + try (InputStreamReader reader = new InputStreamReader(getResource("config.yml"), StandardCharsets.UTF_8)) { + YamlConfiguration defaults = YamlConfiguration.loadConfiguration(reader); + YamlConfiguration current = YamlConfiguration.loadConfiguration(getConfigFile()); + + boolean changed = false; + for (String key : defaults.getKeys(true)) { + if (defaults.isConfigurationSection(key)) { + continue; + } + if (!current.isSet(key)) { + current.set(key, defaults.get(key)); + changed = true; + } + } + + if (changed) { + current.save(getConfigFile()); + reloadConfig(); + getLogger().info("config.yml mis a jour avec les nouvelles options manquantes (valeurs existantes conservees)."); + } + } catch (IOException | java.io.UncheckedIOException e) { + getLogger().warning("Impossible de fusionner les nouvelles options de config.yml : " + e.getMessage()); + } + } + + private java.io.File getConfigFile() { + return new java.io.File(getDataFolder(), "config.yml"); + } + @Override public void onDisable() { getServer().getServicesManager().unregisterAll(this); diff --git a/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java b/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java index ee74a4f..3973410 100644 --- a/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java +++ b/velocity/src/main/java/fr/votenetwork/velocity/VoteConfig.java @@ -45,6 +45,8 @@ public class VoteConfig { } } + mergeMissingConfigKeys(configFile); + try (InputStream in = Files.newInputStream(configFile)) { properties.load(in); } @@ -68,6 +70,42 @@ public class VoteConfig { } } + /** + * Ajoute a la fin de config.properties les cles presentes dans le fichier par defaut du jar + * mais absentes du fichier existant (nouvelles options apportees par une mise a jour du + * plugin), sans jamais toucher aux lignes/valeurs deja presentes. Preserve donc aussi les + * commentaires existants (simple ajout de lignes, pas de reecriture complete). + */ + private void mergeMissingConfigKeys(Path configFile) throws IOException { + Properties defaults = new Properties(); + try (InputStream in = getClass().getClassLoader().getResourceAsStream("config.properties")) { + if (in == null) { + return; + } + defaults.load(in); + } + + Properties existing = new Properties(); + try (InputStream in = Files.newInputStream(configFile)) { + existing.load(in); + } + + StringBuilder toAppend = new StringBuilder(); + for (String key : defaults.stringPropertyNames()) { + if (!existing.containsKey(key)) { + toAppend.append(key).append('=').append(defaults.getProperty(key)).append(System.lineSeparator()); + } + } + + if (toAppend.length() > 0) { + String addition = System.lineSeparator() + + "# --- options ajoutees automatiquement par une mise a jour du plugin ---" + System.lineSeparator() + + toAppend; + Files.writeString(configFile, addition, java.nio.file.StandardOpenOption.APPEND); + logger.info("config.properties mis a jour avec les nouvelles options manquantes (valeurs existantes conservees)."); + } + } + public boolean isMysqlStorage() { return !"yaml".equalsIgnoreCase(storageType); }