From e585f1546bf41bcd130c3168684508e87e17868d Mon Sep 17 00:00:00 2001 From: M_Viper Date: Thu, 7 May 2026 19:39:39 +0000 Subject: [PATCH] Soft-delete copy _trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/economy/EconomyDatabase.java --- .../modules/economy/EconomyDatabase.java | 183 ++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 _trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/economy/EconomyDatabase.java diff --git a/_trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/economy/EconomyDatabase.java b/_trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/economy/EconomyDatabase.java new file mode 100644 index 0000000..69dcec2 --- /dev/null +++ b/_trash/2026-05-07T19-39-23-130Z/src/main/java/net/viper/status/modules/economy/EconomyDatabase.java @@ -0,0 +1,183 @@ +package net.viper.status.modules.economy; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import net.md_5.bungee.api.plugin.Plugin; + +import java.sql.*; +import java.util.UUID; +import java.util.logging.Logger; + +/** + * Verwaltet die MySQL-Verbindung (HikariCP) und die Tabelle bc_accounts. + * Wird vom EconomyModule gehalten und an den EconomyManager weitergegeben. + */ +public class EconomyDatabase { + + private static final String TABLE = "bc_accounts"; + + private final Logger log; + private HikariDataSource dataSource; + + public EconomyDatabase(Plugin plugin, String host, int port, String database, String user, String password) { + this.log = plugin.getLogger(); + + HikariConfig cfg = new HikariConfig(); + cfg.setJdbcUrl("jdbc:mysql://" + host + ":" + port + "/" + database + + "?useSSL=false&autoReconnect=true&characterEncoding=UTF-8&useUnicode=true"); + cfg.setUsername(user); + cfg.setPassword(password); + cfg.setMaximumPoolSize(5); + cfg.setMinimumIdle(1); + cfg.setConnectionTimeout(10_000); + cfg.setIdleTimeout(600_000); + cfg.setMaxLifetime(1_800_000); + cfg.setPoolName("StatusAPI-Economy"); + cfg.addDataSourceProperty("cachePrepStmts", "true"); + cfg.addDataSourceProperty("prepStmtCacheSize", "250"); + cfg.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); + + try { + dataSource = new HikariDataSource(cfg); + } catch (Exception e) { + log.severe("[Economy] MySQL-Verbindung fehlgeschlagen: " + e.getMessage()); + log.severe("[Economy] Bitte Zugangsdaten in verify.properties prüfen!"); + return; + } + + // Tabelle anlegen falls nicht vorhanden (kompatibel mit SurvivalPlus) + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "CREATE TABLE IF NOT EXISTS `" + TABLE + "` (" + + " `player_name` VARCHAR(36) NOT NULL," + + " `balance` VARCHAR(255) NOT NULL DEFAULT '0'," + + " PRIMARY KEY (`player_name`)" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;")) { + ps.executeUpdate(); + } catch (SQLException e) { + log.severe("[Economy] Tabellen-Setup (bc_accounts) fehlgeschlagen: " + e.getMessage()); + } + + // bc_player_names Tabelle anlegen + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "CREATE TABLE IF NOT EXISTS `bc_player_names` (" + + " `uuid` VARCHAR(36) NOT NULL PRIMARY KEY," + + " `name` VARCHAR(16) NOT NULL," + + " `updated` BIGINT NOT NULL" + + ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;")) { + ps.executeUpdate(); + log.info("[Economy] MySQL verbunden – Tabellen bereit."); + } catch (SQLException e) { + log.severe("[Economy] Tabellen-Setup (bc_player_names) fehlgeschlagen: " + e.getMessage()); + } + } + + public boolean isConnected() { + return dataSource != null && !dataSource.isClosed(); + } + + public void close() { + if (dataSource != null && !dataSource.isClosed()) { + dataSource.close(); + } + } + + /** + * Sucht UUID in CMI_users – nutzt eine separate DB-Verbindung falls + * economy.cmi.database konfiguriert ist, sonst dieselbe DB. + */ + public java.util.UUID findUUIDByName(String name) { + if (!isConnected()) return null; + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "SELECT `player_uuid` FROM `CMI_users` WHERE `username` = ? LIMIT 1")) { + ps.setString(1, name); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + String uuidStr = rs.getString("player_uuid"); + if (uuidStr != null && !uuidStr.isEmpty()) { + return java.util.UUID.fromString(uuidStr); + } + } + } + } catch (SQLException | IllegalArgumentException e) { + // CMI_users nicht in dieser DB – kein Problem, bc_player_names ist der Primär-Lookup + } + return null; + } + + /** Speichert den Spielernamen in einer eigenen Lookup-Tabelle. */ + public void saveNameMapping(java.util.UUID uuid, String name) { + if (!isConnected()) return; + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "INSERT INTO `bc_player_names` (`uuid`, `name`, `updated`) VALUES (?, ?, ?) " + + "ON DUPLICATE KEY UPDATE `name` = VALUES(`name`), `updated` = VALUES(`updated`)")) { + ps.setString(1, uuid.toString()); + ps.setString(2, name); + ps.setLong(3, System.currentTimeMillis()); + ps.executeUpdate(); + } catch (SQLException e) { + log.warning("[Economy] Name-Mapping fehlgeschlagen: " + e.getMessage()); + } + } + + /** UUID-Lookup über bc_player_names (eigene Tabelle). */ + public java.util.UUID findUUIDByNameOwn(String name) { + if (!isConnected()) return null; + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "SELECT `uuid` FROM `bc_player_names` WHERE `name` = ? LIMIT 1")) { + ps.setString(1, name); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return java.util.UUID.fromString(rs.getString("uuid")); + } + } + } catch (SQLException | IllegalArgumentException e) { + // Tabelle noch nicht vorhanden + } + return null; + } + + /** Kombinierter UUID-Lookup: erst eigene Tabelle, dann CMI_users. */ + public java.util.UUID resolveUUID(String name) { + java.util.UUID uuid = findUUIDByNameOwn(name); + if (uuid != null) return uuid; + return findUUIDByName(name); + } + + /** Lädt den Kontostand direkt aus der DB. Gibt -1 zurück wenn kein Eintrag. */ + public double load(UUID uuid) { + if (!isConnected()) return -1; + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "SELECT `balance` FROM `" + TABLE + "` WHERE `player_name` = ?")) { + ps.setString(1, uuid.toString()); + try (ResultSet rs = ps.executeQuery()) { + if (rs.next()) { + return Double.parseDouble(rs.getString("balance")); + } + } + } catch (SQLException | NumberFormatException e) { + log.warning("[Economy] Load fehlgeschlagen für " + uuid + ": " + e.getMessage()); + } + return -1; + } + + /** Schreibt einen Kontostand in die DB (INSERT oder UPDATE). */ + public void save(UUID uuid, double balance) { + if (!isConnected()) return; + try (Connection con = dataSource.getConnection(); + PreparedStatement ps = con.prepareStatement( + "INSERT INTO `" + TABLE + "` (`player_name`, `balance`) VALUES (?, ?) " + + "ON DUPLICATE KEY UPDATE `balance` = VALUES(`balance`)")) { + ps.setString(1, uuid.toString()); + ps.setString(2, String.valueOf(balance)); + ps.executeUpdate(); + } catch (SQLException e) { + log.warning("[Economy] Save fehlgeschlagen für " + uuid + ": " + e.getMessage()); + } + } +}