diff --git a/README.md b/README.md index 9797da6..f544e30 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,92 @@ # BalSync -An open source Minecraft Economy Balance Synchronisation Plugin working with a MySQL/MariaDB Database and Vault \ No newline at end of file +BalSync is a powerful and reliable balance synchronization system for Minecraft servers. It ensures that player balances are securely stored, automatically updated, and consistently synchronized across your server network. + +--- + +## 🎯 Features + +### Automatic Balance Backup +- Player balances are automatically saved to a MySQL database at configurable intervals. +- No manual intervention required – everything runs seamlessly in the background. + +### Seamless Login Synchronization +- Player balances are automatically loaded from the database when they join the server. +- Optional: Reset balances to 0 before loading from the database (ideal for events or test servers). + +### Real-Time Monitoring +- The plugin regularly checks the database for external changes (e.g., made by admins or other systems). +- Any changes are immediately applied to online players. + +### Intelligent Offline Detection +- Changes to a player's balance are recognized even while they are offline. +- Example: If a player earns money in single-player mode, it is updated when they join the server. + +### Multi-Language Notifications +- Players are notified of important balance changes. +- Supports 7 languages: German, English, Spanish, French, Polish, Portuguese (Brazil), Russian. + +--- + +## 🎮 Player Experience + +- On server join: *"Your balance has been synchronized with the database."* +- On external updates: *"Your balance was updated externally: 100 → 150"* +- No data loss: Balances are always safely stored. +- Server switching supported: Players can move between servers and retain their balances. + +--- + +## 👨‍💼 Admin Commands + +| Command | Description | +|--------------------------|-----------------------------------------| +| `/balsync reload` | Reloads plugin configuration | +| `/balsync save` | Immediately saves all player balances | +| `/balsync load` | Reload your own balance from the database | +| `/balsync status` | Displays system status | + +--- + +## ⚙️ Configuration Options + +- Set automatic save intervals (e.g., every minute) +- Enable or disable notifications +- Configure database polling intervals +- Set starting balance for new players +- Customize the database table name + +--- + +## 🔒 Security & Performance + +- All transactions are logged +- Database connection supports SSL +- Connection pooling for optimal performance +- Fault-tolerant architecture ensures reliability + +--- + +## 📌 Supported Platforms + +- Paper +- Spigot +- Purpur +- And other compatible Minecraft server forks + +--- + +## 🚀 Getting Started + +1. Place the `BalSync.jar` file into your server's `plugins` folder. +2. Start the server once to generate the default configuration file. +3. Configure your MySQL database credentials and plugin settings in `config.yml`. +4. Restart the server to apply changes. +5. Enjoy secure, automatic balance synchronization for all your players! + +--- + +## 💬 Feedback & Support + +If you encounter issues or have feature suggestions, please open an issue on GitHub. Community contributions are welcome! + diff --git a/pom.xml b/pom.xml index 624517e..70a6ae3 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ com.user404_ BalSync - 1.0-beta + 1.0 jar BalSync diff --git a/src/main/java/com/user404_/balsync/BalSyncCommand.java b/src/main/java/com/user404_/balsync/BalSyncCommand.java index 017053e..eceea7d 100644 --- a/src/main/java/com/user404_/balsync/BalSyncCommand.java +++ b/src/main/java/com/user404_/balsync/BalSyncCommand.java @@ -34,6 +34,7 @@ public class BalSyncCommand implements CommandExecutor { break; case "save": + // Save all balances - Methode ist jetzt in BalanceManager balanceManager.saveAllBalances(); sender.sendMessage(plugin.getTranslationManager().formatMessage("balance-saved")); break; @@ -46,6 +47,10 @@ public class BalSyncCommand implements CommandExecutor { } break; + case "status": + sendStatusInfo(sender); + break; + default: sender.sendMessage(plugin.getTranslationManager().formatMessage("usage")); break; @@ -53,4 +58,12 @@ public class BalSyncCommand implements CommandExecutor { return true; } + + private void sendStatusInfo(CommandSender sender) { + sender.sendMessage("§6=== BalSync Status ==="); + sender.sendMessage("§7Auto-save interval: §e" + plugin.getConfigManager().getAutoSaveInterval() + "s"); + sender.sendMessage("§7Database polling: §e" + plugin.getConfigManager().getDbPollInterval() + "s"); + sender.sendMessage("§7Reset on join: §e" + plugin.getConfigManager().isResetOnJoin()); + sender.sendMessage("§7Offline monitoring: §e" + plugin.getConfigManager().monitorOfflineChanges()); + } } \ No newline at end of file diff --git a/src/main/java/com/user404_/balsync/BalSyncPlugin.java b/src/main/java/com/user404_/balsync/BalSyncPlugin.java index 5557e83..2301bcd 100644 --- a/src/main/java/com/user404_/balsync/BalSyncPlugin.java +++ b/src/main/java/com/user404_/balsync/BalSyncPlugin.java @@ -71,6 +71,7 @@ public class BalSyncPlugin extends JavaPlugin { // Save all balances on shutdown if (balanceManager != null) { balanceManager.saveAllBalances(); + balanceManager.shutdown(); // NEW: Cleanup polling tasks } // Close database connection diff --git a/src/main/java/com/user404_/balsync/BalanceManager.java b/src/main/java/com/user404_/balsync/BalanceManager.java index 82a94b6..6849c98 100644 --- a/src/main/java/com/user404_/balsync/BalanceManager.java +++ b/src/main/java/com/user404_/balsync/BalanceManager.java @@ -1,56 +1,96 @@ package com.user404_.balsync; import net.milkbowl.vault.economy.Economy; +import net.milkbowl.vault.economy.EconomyResponse; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.entity.Player; +import org.bukkit.scheduler.BukkitTask; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; -import java.util.UUID; +import java.util.*; import java.util.logging.Level; public class BalanceManager { private final BalSyncPlugin plugin; private final Economy economy; private final DatabaseManager databaseManager; + private BukkitTask dbPollingTask; + private final Map lastKnownBalances = new HashMap<>(); + private final Map lastKnownDbBalances = new HashMap<>(); + public void saveAllBalances() { + plugin.getPluginLogger().info("Saving all player balances to database..."); + Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { + int saved = 0; + for (OfflinePlayer player : Bukkit.getOfflinePlayers()) { + try { + if (economy.hasAccount(player)) { + double balance = economy.getBalance(player); + databaseManager.saveBalance(player.getUniqueId(), player.getName(), balance); + lastKnownBalances.put(player.getUniqueId(), balance); + lastKnownDbBalances.put(player.getUniqueId(), balance); + saved++; + } + } catch (SQLException e) { + plugin.getPluginLogger().log(Level.WARNING, + "Failed to save balance for: " + player.getName(), e); + } + } + plugin.getPluginLogger().info("Saved " + saved + " player balances to database."); + }); + } public BalanceManager(BalSyncPlugin plugin, Economy economy, DatabaseManager databaseManager) { this.plugin = plugin; this.economy = economy; this.databaseManager = databaseManager; + startDbPolling(); + startOfflineMonitoring(); } + // MODIFIED: Added reset functionality public void loadPlayerBalance(Player player) { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { double databaseBalance = databaseManager.getBalance(player.getUniqueId()); Bukkit.getScheduler().runTask(plugin, () -> { - // Sicherstellen, dass der Spieler ein Konto hat + // Ensure player has account if (!economy.hasAccount(player)) { economy.createPlayerAccount(player); } - // Aktuelle Balance abrufen + // RESET TO ZERO if configured double currentBalance = economy.getBalance(player); - - // KOMPLETTE ÜBERSCHREIBUNG der Balance - // 1. Zuerst auf 0 setzen (alles abheben oder auf 0 bringen) - if (currentBalance > 0) { - // Positive Balance abheben - economy.withdrawPlayer(player, currentBalance); - } else if (currentBalance < 0) { - // Negative Balance ausgleichen (einzahlen um auf 0 zu kommen) - economy.depositPlayer(player, Math.abs(currentBalance)); + if (plugin.getConfigManager().isResetOnJoin()) { + if (currentBalance > 0) { + economy.withdrawPlayer(player, currentBalance); + } else if (currentBalance < 0) { + economy.depositPlayer(player, Math.abs(currentBalance)); + } + plugin.getLogger().info("Reset balance to 0 for " + player.getName()); + currentBalance = 0; } - // 2. Datenbankbalance einzahlen (ÜBERSCHREIBT die alte Balance) - economy.depositPlayer(player, databaseBalance); + // Apply database balance (OVERWRITE) + double difference = databaseBalance - currentBalance; + if (difference > 0) { + economy.depositPlayer(player, difference); + } else if (difference < 0) { + economy.withdrawPlayer(player, Math.abs(difference)); + } - // Logging - plugin.getLogger().info("BALANCE OVERWRITTEN for " + player.getName() + - ": Old=" + currentBalance + ", New=" + databaseBalance + " (from DB)"); + // Update tracking maps + lastKnownBalances.put(player.getUniqueId(), databaseBalance); + lastKnownDbBalances.put(player.getUniqueId(), databaseBalance); - // Nachricht an Spieler + plugin.getLogger().info("Balance loaded for " + player.getName() + + ": " + databaseBalance + " (from DB)"); + + // Send message to player String message = plugin.getTranslationManager().getMessage("balance-loaded"); if (message != null && !message.isEmpty()) { player.sendMessage(plugin.getTranslationManager().formatMessage(message)); @@ -64,11 +104,169 @@ public class BalanceManager { }); } + // NEW: Poll database for external changes + private void startDbPolling() { + int interval = plugin.getConfigManager().getDbPollInterval(); + if (interval <= 0) return; + + dbPollingTask = Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { + pollDatabaseForChanges(); + }, interval * 20L, interval * 20L); + + plugin.getLogger().info("Started database polling every " + interval + " seconds"); + } + + // NEW: Check database for balance changes and apply to online players + private void pollDatabaseForChanges() { + List onlineUUIDs = getOnlinePlayerUUIDs(); + + // Keine online Spieler → nichts abfragen + if (onlineUUIDs.isEmpty()) { + return; + } + + try (Connection conn = databaseManager.getConnection()) { + // Platzhalter für die IN-Klausel erstellen + StringBuilder placeholders = new StringBuilder(); + for (int i = 0; i < onlineUUIDs.size(); i++) { + placeholders.append("?"); + if (i < onlineUUIDs.size() - 1) { + placeholders.append(","); + } + } + + String sql = String.format( + "SELECT player_uuid, balance FROM %s WHERE player_uuid IN (%s)", + plugin.getConfigManager().getTableName(), + placeholders.toString() + ); + + try (PreparedStatement stmt = conn.prepareStatement(sql)) { + // UUIDs als Parameter setzen + for (int i = 0; i < onlineUUIDs.size(); i++) { + stmt.setString(i + 1, onlineUUIDs.get(i).toString()); + } + + ResultSet rs = stmt.executeQuery(); + while (rs.next()) { + UUID playerUUID = UUID.fromString(rs.getString("player_uuid")); + double dbBalance = rs.getDouble("balance"); + + // Prüfen, ob sich die Datenbank-Balance geändert hat + Double lastDbBalance = lastKnownDbBalances.get(playerUUID); + if (lastDbBalance == null || Math.abs(dbBalance - lastDbBalance) > 0.001) { + // Datenbank hat sich geändert → auf Spieler anwenden + applyDbChangeToPlayer(playerUUID, dbBalance, lastDbBalance); + lastKnownDbBalances.put(playerUUID, dbBalance); + } + } + } + } catch (SQLException e) { + plugin.getLogger().log(Level.WARNING, "Error polling database for changes", e); + } + } + + // NEW: Apply database changes to online player + private void applyDbChangeToPlayer(UUID playerUUID, double newBalance, Double oldBalance) { + Player player = Bukkit.getPlayer(playerUUID); + if (player != null && player.isOnline()) { + Bukkit.getScheduler().runTask(plugin, () -> { + double currentBalance = economy.getBalance(player); + double difference = newBalance - currentBalance; + + if (Math.abs(difference) > 0.001) { + if (difference > 0) { + economy.depositPlayer(player, difference); + } else { + economy.withdrawPlayer(player, Math.abs(difference)); + } + + lastKnownBalances.put(playerUUID, newBalance); + + plugin.getLogger().info("Applied external DB change for " + + player.getName() + ": " + newBalance); + + // Notify player if configured + if (plugin.getConfigManager().notifyOnExternalChange()) { + String message = plugin.getTranslationManager().getMessage( + "balance-external-change"); + if (message != null && !message.isEmpty()) { + String formatted = message + .replace("{old}", String.format("%.2f", oldBalance != null ? oldBalance : currentBalance)) + .replace("{new}", String.format("%.2f", newBalance)) + .replace("&", "§"); + player.sendMessage(plugin.getTranslationManager().formatMessage("prefix") + formatted); + } + } + } + }); + } + } + + // NEW: Monitor offline player balance changes when auto-save-interval = 0 + private void startOfflineMonitoring() { + int autoSaveInterval = plugin.getConfigManager().getAutoSaveInterval(); + boolean monitorOffline = plugin.getConfigManager().monitorOfflineChanges(); + + if (autoSaveInterval == 0 && monitorOffline) { + // Check for balance changes every 30 seconds + Bukkit.getScheduler().runTaskTimerAsynchronously(plugin, () -> { + monitorOfflineBalanceChanges(); + }, 600L, 600L); // 30 seconds (600 ticks) + + plugin.getLogger().info("Started offline balance change monitoring"); + } + } + + // NEW: Detect and save offline balance changes + private void monitorOfflineBalanceChanges() { + for (OfflinePlayer offlinePlayer : Bukkit.getOfflinePlayers()) { + if (economy.hasAccount(offlinePlayer)) { + double currentBalance = economy.getBalance(offlinePlayer); + UUID uuid = offlinePlayer.getUniqueId(); + + Double lastBalance = lastKnownBalances.get(uuid); + if (lastBalance != null && Math.abs(currentBalance - lastBalance) > 0.001) { + // Balance has changed - save to database + try { + databaseManager.saveBalance(uuid, offlinePlayer.getName(), currentBalance); + lastKnownBalances.put(uuid, currentBalance); + plugin.getLogger().info("Detected offline change for " + + offlinePlayer.getName() + ": " + currentBalance); + } catch (SQLException e) { + plugin.getLogger().log(Level.WARNING, + "Failed to save offline change for " + offlinePlayer.getName(), e); + } + } else if (lastBalance == null) { + // First time seeing this player, store initial balance + lastKnownBalances.put(uuid, currentBalance); + } + } + } + } + + // NEW: Track balance when player quits + public void trackPlayerQuit(UUID playerUUID, double balance) { + lastKnownBalances.put(playerUUID, balance); + } + + // Helper method + private List getOnlinePlayerUUIDs() { + List uuids = new ArrayList<>(); + for (Player player : Bukkit.getOnlinePlayers()) { + uuids.add(player.getUniqueId()); + } + return uuids; + } + + // MODIFIED savePlayerBalance to update tracking public void savePlayerBalance(OfflinePlayer player) { Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { try { double balance = economy.getBalance(player); databaseManager.saveBalance(player.getUniqueId(), player.getName(), balance); + lastKnownBalances.put(player.getUniqueId(), balance); + lastKnownDbBalances.put(player.getUniqueId(), balance); } catch (SQLException e) { plugin.getPluginLogger().log(Level.SEVERE, "Failed to save balance for player: " + player.getName(), e); @@ -76,32 +274,12 @@ public class BalanceManager { }); } - public void saveAllBalances() { - plugin.getPluginLogger().info("Saving all player balances to database..."); - - Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { - int saved = 0; - for (OfflinePlayer player : Bukkit.getOfflinePlayers()) { - try { - if (economy.hasAccount(player)) { - double balance = economy.getBalance(player); - databaseManager.saveBalance(player.getUniqueId(), player.getName(), balance); - saved++; - } - } catch (SQLException e) { - plugin.getPluginLogger().log(Level.WARNING, - "Failed to save balance for: " + player.getName(), e); - } - } - plugin.getPluginLogger().info("Saved " + saved + " player balances to database."); - }); - } - - public double getCachedBalance(UUID playerUUID) { - OfflinePlayer player = Bukkit.getOfflinePlayer(playerUUID); - if (player != null && economy.hasAccount(player)) { - return economy.getBalance(player); + // Cleanup on disable + public void shutdown() { + if (dbPollingTask != null) { + dbPollingTask.cancel(); } - return plugin.getConfigManager().getStartingBalance(); + lastKnownBalances.clear(); + lastKnownDbBalances.clear(); } } \ No newline at end of file diff --git a/src/main/java/com/user404_/balsync/ConfigManager.java b/src/main/java/com/user404_/balsync/ConfigManager.java index b5063e7..0e88c1d 100644 --- a/src/main/java/com/user404_/balsync/ConfigManager.java +++ b/src/main/java/com/user404_/balsync/ConfigManager.java @@ -121,4 +121,19 @@ public class ConfigManager { public String getTableName() { return config.getString("tables.player_balances.table-name", "player_balances"); } + public boolean isResetOnJoin() { + return config.getBoolean("settings.reset-on-join", false); + } + + public boolean monitorOfflineChanges() { + return config.getBoolean("settings.monitor-offline-changes", true); + } + + public int getDbPollInterval() { + return config.getInt("settings.db-poll-interval", 10); + } + + public boolean notifyOnExternalChange() { + return config.getBoolean("settings.notify-on-external-change", true); + } } \ No newline at end of file diff --git a/src/main/java/com/user404_/balsync/PlayerEventListener.java b/src/main/java/com/user404_/balsync/PlayerEventListener.java index 62a2d04..f2ea01a 100644 --- a/src/main/java/com/user404_/balsync/PlayerEventListener.java +++ b/src/main/java/com/user404_/balsync/PlayerEventListener.java @@ -1,5 +1,7 @@ package com.user404_.balsync; +import net.milkbowl.vault.economy.Economy; +import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; @@ -8,10 +10,12 @@ import org.bukkit.event.player.PlayerQuitEvent; public class PlayerEventListener implements Listener { private final BalSyncPlugin plugin; private final BalanceManager balanceManager; + private final Economy economy; public PlayerEventListener(BalSyncPlugin plugin, BalanceManager balanceManager) { this.plugin = plugin; this.balanceManager = balanceManager; + this.economy = plugin.getEconomy(); // Economy vom Plugin holen } @EventHandler @@ -21,13 +25,22 @@ public class PlayerEventListener implements Listener { if (event.getPlayer().isOnline()) { balanceManager.loadPlayerBalance(event.getPlayer()); } - }, 300L); // 20 Ticks = 1 Sekunde, 300 Ticks = 15 Sekunden + }, 40L); } @EventHandler public void onPlayerQuit(PlayerQuitEvent event) { + Player player = event.getPlayer(); + if (plugin.getConfigManager().saveOnQuit()) { - balanceManager.savePlayerBalance(event.getPlayer()); + balanceManager.savePlayerBalance(player); + } + + // Track balance on quit for offline monitoring + if (plugin.getConfigManager().monitorOfflineChanges() && + plugin.getConfigManager().getAutoSaveInterval() == 0) { + double balance = economy.getBalance(player); + balanceManager.trackPlayerQuit(player.getUniqueId(), balance); } } } \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 506b8fd..a9be692 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,16 +1,4 @@ -# Database Configuration -database: - host: "localhost" - port: 3306 - database: "minecraft" - username: "root" - password: "password" - use-ssl: false - connection-pool: - maximum-pool-size: 10 - minimum-idle: 5 - connection-timeout: 30000 - idle-timeout: 600000 +# Database Configuration (existing)... # Plugin Settings settings: @@ -23,6 +11,18 @@ settings: # Locale for messages (en, de, etc.) locale: "en" + # Reset to zero before loading from database on join + reset-on-join: false + + # Monitor offline balance changes when auto-save-interval = 0 + monitor-offline-changes: true + + # Poll database for changes (interval in seconds, 0 = disabled) + db-poll-interval: 10 + + # Notification when balance is changed externally + notify-on-external-change: true + # Database Table Configuration tables: player_balances: diff --git a/src/main/resources/messages_at.yml b/src/main/resources/messages_at.yml new file mode 100644 index 0000000..c65238b --- /dev/null +++ b/src/main/resources/messages_at.yml @@ -0,0 +1,15 @@ +# This is an Easter egg language. If you found this, you're probably digging through the source code. +# Have fun with the Austrian/Wienerisch translation! :) + +prefix: "§8[§dGödSynk§8] §7" +no-permission: "§cHeast, du host ka Berechtigung für den Befehl!" +config-reloaded: "§aKonfig is wieda gscheit neig'laden!" +balance-loaded: "§aDei Gödstandl is jetzt mit da Datenbank a glei." +balance-saved: "§aOlle Gödstandln woan in da Datenbank gspeichert, passt so!" +database-connected: "§aJo fix, Verbindung zur Datenbank steht!" +database-error: "§cOida… do is a Fehler in da Datenbank. Schau amoi in die Konsole." +player-not-found: "§cDen Spieler find i net, host di vertippt?" +usage: "§cSo geht's: /balsync [reload|save|load]" +balance-external-change: "§eDei Gödstandl woan von außen gändat: §6{old} §e→ §6{new}" +balance-reset: "§aDei Gödstandl woan auf §e${0}§a zruckgsetzt, bevors aus da Datenbank kema san." +offline-change-detected: "§7A Änderung währendst ned do woarst is gmerkt und gspeichert wordn." diff --git a/src/main/resources/messages_de.yml b/src/main/resources/messages_de.yml index faa8179..6f1fd0e 100644 --- a/src/main/resources/messages_de.yml +++ b/src/main/resources/messages_de.yml @@ -4,6 +4,9 @@ config-reloaded: "§aKonfiguration erfolgreich neu geladen!" balance-loaded: "§aDein Kontostand wurde mit der Datenbank synchronisiert." balance-saved: "§aAlle Spielerkontostände wurden in der Datenbank gespeichert." database-connected: "§aErfolgreich mit der Datenbank verbunden!" -database-error: "§cDatenbankfehler aufgetreten. Überprüfe die Konsole für Details." +database-error: "§cDatenbankfehler aufgetreten. Überprüfe die Konsole oder die Logs für Details." player-not-found: "§cSpieler nicht gefunden!" -usage: "§cVerwendung: /balsync [reload|save|load]" \ No newline at end of file +usage: "§cVerwendung: /balsync [reload|save|load]" +balance-external-change: "§eDein Kontostand wurde extern (vielleicht von einem anderen Server) aktualisiert: §6{old} §e→ §6{new}" +balance-reset: "§aDein Kontostand wurde auf §e${0}§a zurückgesetzt, bevor er aus der Datenbank geladen wurde." +offline-change-detected: "§7Offline-Kontostandänderung erkannt und gespeichert." \ No newline at end of file diff --git a/src/main/resources/messages_en.yml b/src/main/resources/messages_en.yml index 8821b5a..7ff0865 100644 --- a/src/main/resources/messages_en.yml +++ b/src/main/resources/messages_en.yml @@ -6,4 +6,7 @@ balance-saved: "§aAll player balances have been saved to the database." database-connected: "§aSuccessfully connected to the database!" database-error: "§cDatabase error occurred. Check console for details." player-not-found: "§cPlayer not found!" -usage: "§cUsage: /balsync [reload|save|load]" \ No newline at end of file +usage: "§cUsage: /balsync [reload|save|load]" +balance-external-change: "§eYour balance was updated externally: §6{old} §e→ §6{new}" +balance-reset: "§aYour balance was reset to §e${0}§a before loading from database." +offline-change-detected: "§7Offline balance change detected and saved." \ No newline at end of file diff --git a/src/main/resources/messages_es.yml b/src/main/resources/messages_es.yml new file mode 100644 index 0000000..cfc6f76 --- /dev/null +++ b/src/main/resources/messages_es.yml @@ -0,0 +1,12 @@ +prefix: "§8[§6BalSync§8] §7" +no-permission: "§c¡No tienes permiso para usar este comando!" +config-reloaded: "§a¡Configuración recargada correctamente!" +balance-loaded: "§aTu saldo ha sido sincronizado con la base de datos." +balance-saved: "§aTodos los saldos de los jugadores han sido guardados en la base de datos." +database-connected: "§a¡Conexión exitosa a la base de datos!" +database-error: "§cOcurrió un error de base de datos. Revisa la consola para más detalles." +player-not-found: "§c¡Jugador no encontrado!" +usage: "§cUso: /balsync [reload|save|load]" +balance-external-change: "§eTu saldo fue actualizado externamente: §6{old} §e→ §6{new}" +balance-reset: "§aTu saldo fue restablecido a §e${0}§a antes de cargarse desde la base de datos." +offline-change-detected: "§7Cambio de saldo offline detectado y guardado." diff --git a/src/main/resources/messages_fr.yml b/src/main/resources/messages_fr.yml new file mode 100644 index 0000000..403d0d5 --- /dev/null +++ b/src/main/resources/messages_fr.yml @@ -0,0 +1,12 @@ +prefix: "§8[§6BalSync§8] §7" +no-permission: "§cVous n'avez pas la permission d'utiliser cette commande !" +config-reloaded: "§aConfiguration rechargée avec succès !" +balance-loaded: "§aVotre solde a été synchronisé avec la base de données." +balance-saved: "§aTous les soldes des joueurs ont été enregistrés dans la base de données." +database-connected: "§aConnexion réussie à la base de données !" +database-error: "§cUne erreur de base de données est survenue. Vérifiez la console pour plus de détails." +player-not-found: "§cJoueur introuvable !" +usage: "§cUtilisation : /balsync [reload|save|load]" +balance-external-change: "§eVotre solde a été mis à jour extérieurement : §6{old} §e→ §6{new}" +balance-reset: "§aVotre solde a été réinitialisé à §e${0}§a avant le chargement depuis la base de données." +offline-change-detected: "§7Modification du solde hors ligne détectée et enregistrée." diff --git a/src/main/resources/messages_pl.yml b/src/main/resources/messages_pl.yml new file mode 100644 index 0000000..403d0d5 --- /dev/null +++ b/src/main/resources/messages_pl.yml @@ -0,0 +1,12 @@ +prefix: "§8[§6BalSync§8] §7" +no-permission: "§cVous n'avez pas la permission d'utiliser cette commande !" +config-reloaded: "§aConfiguration rechargée avec succès !" +balance-loaded: "§aVotre solde a été synchronisé avec la base de données." +balance-saved: "§aTous les soldes des joueurs ont été enregistrés dans la base de données." +database-connected: "§aConnexion réussie à la base de données !" +database-error: "§cUne erreur de base de données est survenue. Vérifiez la console pour plus de détails." +player-not-found: "§cJoueur introuvable !" +usage: "§cUtilisation : /balsync [reload|save|load]" +balance-external-change: "§eVotre solde a été mis à jour extérieurement : §6{old} §e→ §6{new}" +balance-reset: "§aVotre solde a été réinitialisé à §e${0}§a avant le chargement depuis la base de données." +offline-change-detected: "§7Modification du solde hors ligne détectée et enregistrée." diff --git a/src/main/resources/messages_pt-br.yml b/src/main/resources/messages_pt-br.yml new file mode 100644 index 0000000..c028cf4 --- /dev/null +++ b/src/main/resources/messages_pt-br.yml @@ -0,0 +1,12 @@ +prefix: "§8[§6BalSync§8] §7" +no-permission: "§cVocê não tem permissão para usar este comando!" +config-reloaded: "§aConfiguração recarregada com sucesso!" +balance-loaded: "§aSeu saldo foi sincronizado com o banco de dados." +balance-saved: "§aTodos os saldos dos jogadores foram salvos no banco de dados." +database-connected: "§aConectado com sucesso ao banco de dados!" +database-error: "§cOcorreu um erro no banco de dados. Verifique o console para mais detalhes." +player-not-found: "§cJogador não encontrado!" +usage: "§cUso: /balsync [reload|save|load]" +balance-external-change: "§eSeu saldo foi atualizado externamente: §6{old} §e→ §6{new}" +balance-reset: "§aSeu saldo foi redefinido para §e${0}§a antes de carregar do banco de dados." +offline-change-detected: "§7Alteração de saldo offline detectada e salva." diff --git a/src/main/resources/messages_ru.yml b/src/main/resources/messages_ru.yml new file mode 100644 index 0000000..2001fac --- /dev/null +++ b/src/main/resources/messages_ru.yml @@ -0,0 +1,12 @@ +prefix: "§8[§6BalSync§8] §7" +no-permission: "§cУ вас нет прав для использования этой команды!" +config-reloaded: "§aКонфигурация успешно перезагружена!" +balance-loaded: "§aВаш баланс был синхронизирован с базой данных." +balance-saved: "§aВсе балансы игроков были сохранены в базе данных." +database-connected: "§aУспешно подключено к базе данных!" +database-error: "§cПроизошла ошибка базы данных. Проверьте консоль для деталей." +player-not-found: "§cИгрок не найден!" +usage: "§cИспользование: /balsync [reload|save|load]" +balance-external-change: "§eВаш баланс был обновлён извне: §6{old} §e→ §6{new}" +balance-reset: "§aВаш баланс был сброшен до §e${0}§a перед загрузкой из базы данных." +offline-change-detected: "§7Обнаружено и сохранено изменение баланса оффлайн." diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index eff64d6..5c3704e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: BalSync -version: 1.0-beta +version: 1.0 main: com.user404_.balsync.BalSyncPlugin api-version: '1.20' description: Synchronizes player balances with MySQL database