This commit is contained in:
@@ -42,7 +42,7 @@ public class BlockPartyPlugin extends JavaPlugin implements Listener {
|
||||
this.sessionManager = new SessionManager();
|
||||
this.soundUtil = new SoundUtil(this);
|
||||
this.rewardManager = new RewardManager(this);
|
||||
this.statsManager = new StatsManager(this);
|
||||
this.statsManager = new StatsManager(this, configManager.getStorageSettings());
|
||||
statsManager.init();
|
||||
|
||||
this.arenaManager = new ArenaManager(this);
|
||||
|
||||
@@ -80,4 +80,27 @@ public class ConfigManager {
|
||||
public boolean isPlaceholderApiEnabled() {
|
||||
return config.getBoolean("integrations.placeholderapi", true);
|
||||
}
|
||||
|
||||
public StorageSettings getStorageSettings() {
|
||||
String type = config.getString("storage.type", "sqlite");
|
||||
return new StorageSettings(
|
||||
type,
|
||||
config.getString("storage.mysql.host", "localhost"),
|
||||
config.getInt("storage.mysql.port", 3306),
|
||||
config.getString("storage.mysql.database", "blockparty"),
|
||||
config.getString("storage.mysql.username", "blockparty"),
|
||||
config.getString("storage.mysql.password", ""),
|
||||
config.getBoolean("storage.mysql.use-ssl", false),
|
||||
config.getString("storage.mysql.table-prefix", "bp_")
|
||||
);
|
||||
}
|
||||
|
||||
/** Immutable snapshot of the storage.* config section. */
|
||||
public record StorageSettings(String type, String host, int port, String database,
|
||||
String username, String password, boolean useSsl, String tablePrefix) {
|
||||
|
||||
public boolean isMysql() {
|
||||
return "mysql".equalsIgnoreCase(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package us.tss3.blockparty.persistence;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.tss3.blockparty.config.ConfigManager.StorageSettings;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
@@ -12,37 +13,72 @@ import java.sql.Statement;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/** SQLite-backed statistics storage. All public methods are safe to call from any thread;
|
||||
* callers are expected to invoke them off the main thread (see StatsManager). */
|
||||
/** SQLite- or MySQL-backed statistics storage, selected via storage.type in config.yml.
|
||||
* All public methods are safe to call from any thread; callers are expected to invoke
|
||||
* them off the main thread (see StatsManager). */
|
||||
public class StatsDatabase {
|
||||
|
||||
private final Plugin plugin;
|
||||
private final StorageSettings settings;
|
||||
private final String table;
|
||||
private Connection connection;
|
||||
|
||||
public StatsDatabase(Plugin plugin) {
|
||||
public StatsDatabase(Plugin plugin, StorageSettings settings) {
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
this.table = settings.isMysql() ? settings.tablePrefix() + "player_stats" : "player_stats";
|
||||
}
|
||||
|
||||
public synchronized void connect() {
|
||||
try {
|
||||
File dbFile = new File(plugin.getDataFolder(), "blockparty.db");
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath());
|
||||
if (settings.isMysql()) {
|
||||
connectMysql();
|
||||
} else {
|
||||
connectSqlite();
|
||||
}
|
||||
try (Statement st = connection.createStatement()) {
|
||||
st.execute("CREATE TABLE IF NOT EXISTS player_stats (" +
|
||||
"uuid TEXT PRIMARY KEY," +
|
||||
"games_played INTEGER NOT NULL DEFAULT 0," +
|
||||
"wins INTEGER NOT NULL DEFAULT 0," +
|
||||
"eliminations INTEGER NOT NULL DEFAULT 0," +
|
||||
"best_round INTEGER NOT NULL DEFAULT 0," +
|
||||
"total_rounds_survived INTEGER NOT NULL DEFAULT 0" +
|
||||
")");
|
||||
st.execute(createTableStatement());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to initialize SQLite stats database", ex);
|
||||
plugin.getLogger().log(Level.SEVERE, "Failed to initialize " +
|
||||
(settings.isMysql() ? "MySQL" : "SQLite") + " stats database", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void connectSqlite() throws Exception {
|
||||
File dbFile = new File(plugin.getDataFolder(), "blockparty.db");
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath());
|
||||
}
|
||||
|
||||
private void connectMysql() throws Exception {
|
||||
Class.forName("com.mysql.cj.jdbc.Driver");
|
||||
String url = "jdbc:mysql://" + settings.host() + ":" + settings.port() + "/" + settings.database()
|
||||
+ "?useSSL=" + settings.useSsl() + "&autoReconnect=true&characterEncoding=utf8";
|
||||
connection = DriverManager.getConnection(url, settings.username(), settings.password());
|
||||
}
|
||||
|
||||
private String createTableStatement() {
|
||||
if (settings.isMysql()) {
|
||||
return "CREATE TABLE IF NOT EXISTS " + table + " (" +
|
||||
"uuid VARCHAR(36) PRIMARY KEY," +
|
||||
"games_played INT NOT NULL DEFAULT 0," +
|
||||
"wins INT NOT NULL DEFAULT 0," +
|
||||
"eliminations INT NOT NULL DEFAULT 0," +
|
||||
"best_round INT NOT NULL DEFAULT 0," +
|
||||
"total_rounds_survived INT NOT NULL DEFAULT 0" +
|
||||
")";
|
||||
}
|
||||
return "CREATE TABLE IF NOT EXISTS " + table + " (" +
|
||||
"uuid TEXT PRIMARY KEY," +
|
||||
"games_played INTEGER NOT NULL DEFAULT 0," +
|
||||
"wins INTEGER NOT NULL DEFAULT 0," +
|
||||
"eliminations INTEGER NOT NULL DEFAULT 0," +
|
||||
"best_round INTEGER NOT NULL DEFAULT 0," +
|
||||
"total_rounds_survived INTEGER NOT NULL DEFAULT 0" +
|
||||
")";
|
||||
}
|
||||
|
||||
public synchronized void close() {
|
||||
try {
|
||||
if (connection != null && !connection.isClosed()) {
|
||||
@@ -53,8 +89,10 @@ public class StatsDatabase {
|
||||
}
|
||||
|
||||
private synchronized void ensureRow(String uuid) throws SQLException {
|
||||
try (PreparedStatement ps = connection.prepareStatement(
|
||||
"INSERT OR IGNORE INTO player_stats(uuid) VALUES (?)")) {
|
||||
String sql = settings.isMysql()
|
||||
? "INSERT IGNORE INTO " + table + "(uuid) VALUES (?)"
|
||||
: "INSERT OR IGNORE INTO " + table + "(uuid) VALUES (?)";
|
||||
try (PreparedStatement ps = connection.prepareStatement(sql)) {
|
||||
ps.setString(1, uuid);
|
||||
ps.executeUpdate();
|
||||
}
|
||||
@@ -67,7 +105,7 @@ public class StatsDatabase {
|
||||
try {
|
||||
ensureRow(uuid.toString());
|
||||
try (PreparedStatement ps = connection.prepareStatement(
|
||||
"SELECT games_played, wins, eliminations, best_round, total_rounds_survived FROM player_stats WHERE uuid=?")) {
|
||||
"SELECT games_played, wins, eliminations, best_round, total_rounds_survived FROM " + table + " WHERE uuid=?")) {
|
||||
ps.setString(1, uuid.toString());
|
||||
try (ResultSet rs = ps.executeQuery()) {
|
||||
if (rs.next()) {
|
||||
@@ -100,7 +138,7 @@ public class StatsDatabase {
|
||||
try {
|
||||
ensureRow(uuid.toString());
|
||||
try (PreparedStatement ps = connection.prepareStatement(
|
||||
"UPDATE player_stats SET best_round = MAX(best_round, ?), total_rounds_survived = total_rounds_survived + 1 WHERE uuid=?")) {
|
||||
"UPDATE " + table + " SET best_round = MAX(best_round, ?), total_rounds_survived = total_rounds_survived + 1 WHERE uuid=?")) {
|
||||
ps.setInt(1, round);
|
||||
ps.setString(2, uuid.toString());
|
||||
ps.executeUpdate();
|
||||
@@ -117,7 +155,7 @@ public class StatsDatabase {
|
||||
try {
|
||||
ensureRow(uuid.toString());
|
||||
try (PreparedStatement ps = connection.prepareStatement(
|
||||
"UPDATE player_stats SET " + setClause + " WHERE uuid=?")) {
|
||||
"UPDATE " + table + " SET " + setClause + " WHERE uuid=?")) {
|
||||
ps.setString(1, uuid.toString());
|
||||
ps.executeUpdate();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package us.tss3.blockparty.persistence;
|
||||
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.tss3.blockparty.config.ConfigManager.StorageSettings;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
@@ -11,9 +12,9 @@ public class StatsManager {
|
||||
private final Plugin plugin;
|
||||
private final StatsDatabase database;
|
||||
|
||||
public StatsManager(Plugin plugin) {
|
||||
public StatsManager(Plugin plugin, StorageSettings settings) {
|
||||
this.plugin = plugin;
|
||||
this.database = new StatsDatabase(plugin);
|
||||
this.database = new StatsDatabase(plugin, settings);
|
||||
}
|
||||
|
||||
public void init() {
|
||||
|
||||
Reference in New Issue
Block a user