Build configurable BlockParty minigame
Build / build (push) Failing after 27s

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
Michael Burgess
2026-08-07 05:47:55 -04:00
co-authored by Claude Sonnet 5
commit 7b02b7efb7
49 changed files with 4349 additions and 0 deletions
@@ -0,0 +1,128 @@
package us.tss3.blockparty.persistence;
import org.bukkit.plugin.Plugin;
import java.io.File;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
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). */
public class StatsDatabase {
private final Plugin plugin;
private Connection connection;
public StatsDatabase(Plugin plugin) {
this.plugin = plugin;
}
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());
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" +
")");
}
} catch (Exception ex) {
plugin.getLogger().log(Level.SEVERE, "Failed to initialize SQLite stats database", ex);
}
}
public synchronized void close() {
try {
if (connection != null && !connection.isClosed()) {
connection.close();
}
} catch (SQLException ignored) {
}
}
private synchronized void ensureRow(String uuid) throws SQLException {
try (PreparedStatement ps = connection.prepareStatement(
"INSERT OR IGNORE INTO player_stats(uuid) VALUES (?)")) {
ps.setString(1, uuid);
ps.executeUpdate();
}
}
public synchronized PlayerStats getStats(UUID uuid) {
if (connection == null) {
return PlayerStats.empty(uuid);
}
try {
ensureRow(uuid.toString());
try (PreparedStatement ps = connection.prepareStatement(
"SELECT games_played, wins, eliminations, best_round, total_rounds_survived FROM player_stats WHERE uuid=?")) {
ps.setString(1, uuid.toString());
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
return new PlayerStats(uuid, rs.getInt(1), rs.getInt(2), rs.getInt(3), rs.getInt(4), rs.getInt(5));
}
}
}
} catch (SQLException ex) {
plugin.getLogger().log(Level.WARNING, "Failed to read stats for " + uuid, ex);
}
return PlayerStats.empty(uuid);
}
public synchronized void incrementGamesPlayed(UUID uuid) {
update(uuid, "games_played = games_played + 1");
}
public synchronized void incrementWins(UUID uuid) {
update(uuid, "wins = wins + 1");
}
public synchronized void incrementEliminations(UUID uuid) {
update(uuid, "eliminations = eliminations + 1");
}
public synchronized void recordRoundReached(UUID uuid, int round) {
if (connection == null) {
return;
}
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=?")) {
ps.setInt(1, round);
ps.setString(2, uuid.toString());
ps.executeUpdate();
}
} catch (SQLException ex) {
plugin.getLogger().log(Level.WARNING, "Failed to update round stats for " + uuid, ex);
}
}
private void update(UUID uuid, String setClause) {
if (connection == null) {
return;
}
try {
ensureRow(uuid.toString());
try (PreparedStatement ps = connection.prepareStatement(
"UPDATE player_stats SET " + setClause + " WHERE uuid=?")) {
ps.setString(1, uuid.toString());
ps.executeUpdate();
}
} catch (SQLException ex) {
plugin.getLogger().log(Level.WARNING, "Failed to update stats for " + uuid, ex);
}
}
}