diff --git a/pom.xml b/pom.xml
index eace9821..413e2dae 100644
--- a/pom.xml
+++ b/pom.xml
@@ -74,6 +74,18 @@
commons-lang3
3.8.1
+
+
+ com.zaxxer
+ HikariCP
+ 3.4.1
+
+
+
+ mysql
+ mysql-connector-java
+ 8.0.18
+
me.markeh
@@ -244,4 +256,4 @@
${project.build.directory}
UTF-8
-
\ No newline at end of file
+
diff --git a/src/com/projectkorra/projectkorra/ProjectKorra.java b/src/com/projectkorra/projectkorra/ProjectKorra.java
index 4ddfe988..2b4b601e 100644
--- a/src/com/projectkorra/projectkorra/ProjectKorra.java
+++ b/src/com/projectkorra/projectkorra/ProjectKorra.java
@@ -8,6 +8,7 @@ import com.bekvon.bukkit.residence.protection.FlagPermissions;
import co.aikar.timings.lib.MCTiming;
import co.aikar.timings.lib.TimingManager;
+import com.projectkorra.projectkorra.module.ModuleManager;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Statistic;
@@ -77,6 +78,7 @@ public class ProjectKorra extends JavaPlugin {
}
Manager.startup();
+ ModuleManager.startup();
this.getServer().getPluginManager().registerEvents(new PKListener(this), this);
this.getServer().getScheduler().scheduleSyncRepeatingTask(this, new BendingManager(), 0, 1);
diff --git a/src/com/projectkorra/projectkorra/database/DatabaseConfig.java b/src/com/projectkorra/projectkorra/database/DatabaseConfig.java
new file mode 100644
index 00000000..8c6504d4
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/DatabaseConfig.java
@@ -0,0 +1,14 @@
+package com.projectkorra.projectkorra.database;
+
+public class DatabaseConfig
+{
+ public final DatabaseManager.Engine Engine = DatabaseManager.Engine.SQLITE;
+
+ public final String SQLite_File = "projectkorra.sql";
+
+ public final String MySQL_IP = "localhost";
+ public final String MySQL_Port = "3306";
+ public final String MySQL_DatabaseName = "projectkorra";
+ public final String MySQL_Username = "root";
+ public final String MySQL_Password = "password";
+}
diff --git a/src/com/projectkorra/projectkorra/database/DatabaseManager.java b/src/com/projectkorra/projectkorra/database/DatabaseManager.java
new file mode 100644
index 00000000..fddcac07
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/DatabaseManager.java
@@ -0,0 +1,57 @@
+package com.projectkorra.projectkorra.database;
+
+import com.projectkorra.projectkorra.database.engine.MySQLDatabase;
+import com.projectkorra.projectkorra.database.engine.SQLDatabase;
+import com.projectkorra.projectkorra.database.engine.SQLiteDatabase;
+import com.projectkorra.projectkorra.module.Module;
+
+import java.util.logging.Level;
+
+public class DatabaseManager extends Module
+{
+ private final DatabaseConfig _config;
+ private final SQLDatabase _database;
+
+ private DatabaseManager()
+ {
+ super("Database");
+
+ // TODO Pull from new ConfigManager
+ _config = new DatabaseConfig();
+
+ switch (_config.Engine)
+ {
+ case MYSQL:
+ _database = new MySQLDatabase(_config);
+ break;
+ case SQLITE:
+ _database = new SQLiteDatabase(this, _config);
+ break;
+ default:
+ log(Level.SEVERE, "Unknown database engine.");
+ _database = null;
+ break;
+ }
+ }
+
+ public DatabaseConfig getConfig()
+ {
+ return _config;
+ }
+
+ public SQLDatabase getDatabase()
+ {
+ return _database;
+ }
+
+ @Override
+ public void onDisable()
+ {
+ _database.close();
+ }
+
+ public enum Engine
+ {
+ MYSQL, SQLITE;
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/database/DatabaseQuery.java b/src/com/projectkorra/projectkorra/database/DatabaseQuery.java
new file mode 100644
index 00000000..7b2446d1
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/DatabaseQuery.java
@@ -0,0 +1,63 @@
+package com.projectkorra.projectkorra.database;
+
+import com.projectkorra.projectkorra.module.ModuleManager;
+
+public class DatabaseQuery
+{
+ private final String _mysql;
+ private final String _sqlite;
+
+ private DatabaseQuery(String mysql, String sqlite)
+ {
+ _mysql = mysql;
+ _sqlite = sqlite;
+ }
+
+ public String getQuery()
+ {
+ switch (ModuleManager.getModule(DatabaseManager.class).getConfig().Engine)
+ {
+ case MYSQL:
+ return _mysql;
+ case SQLITE:
+ return _sqlite;
+ }
+
+ return null;
+ }
+
+ public static Builder newBuilder()
+ {
+ return new Builder();
+ }
+
+ public static final class Builder
+ {
+ private String _mysql;
+ private String _sqlite;
+
+ public Builder mysql(String mysql)
+ {
+ _mysql = mysql;
+ return this;
+ }
+
+ public Builder sqlite(String sqlite)
+ {
+ _sqlite = sqlite;
+ return this;
+ }
+
+ public Builder query(String query)
+ {
+ _mysql = query;
+ _sqlite = query;
+ return this;
+ }
+
+ public DatabaseQuery build()
+ {
+ return new DatabaseQuery(_mysql, _sqlite);
+ }
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/database/DatabaseRepository.java b/src/com/projectkorra/projectkorra/database/DatabaseRepository.java
new file mode 100644
index 00000000..77db1e86
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/DatabaseRepository.java
@@ -0,0 +1,19 @@
+package com.projectkorra.projectkorra.database;
+
+import com.projectkorra.projectkorra.database.engine.SQLDatabase;
+import com.projectkorra.projectkorra.module.ModuleManager;
+
+public abstract class DatabaseRepository
+{
+ private final DatabaseManager databaseManager;
+
+ public DatabaseRepository()
+ {
+ this.databaseManager = ModuleManager.getModule(DatabaseManager.class);
+ }
+
+ protected SQLDatabase getDatabase()
+ {
+ return databaseManager.getDatabase();
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/database/engine/MySQLDatabase.java b/src/com/projectkorra/projectkorra/database/engine/MySQLDatabase.java
new file mode 100644
index 00000000..5080fb0c
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/engine/MySQLDatabase.java
@@ -0,0 +1,48 @@
+package com.projectkorra.projectkorra.database.engine;
+
+import com.projectkorra.projectkorra.database.DatabaseConfig;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+
+public class MySQLDatabase implements SQLDatabase
+{
+ private final HikariDataSource _hikari;
+
+ public MySQLDatabase(DatabaseConfig databaseConfig)
+ {
+ HikariConfig hikariConfig = new HikariConfig();
+
+ hikariConfig.setJdbcUrl("jdbc:mysql://" + databaseConfig.MySQL_IP + ":" + databaseConfig.MySQL_Port + "/" + databaseConfig.MySQL_DatabaseName);
+ hikariConfig.setDriverClassName("com.mysql.jdbc.Driver");
+ hikariConfig.setUsername(databaseConfig.MySQL_Username);
+ hikariConfig.setPassword(databaseConfig.MySQL_Password);
+ hikariConfig.setMinimumIdle(1);
+ hikariConfig.setMaximumPoolSize(10);
+ hikariConfig.setConnectionTimeout(10000);
+
+ _hikari = new HikariDataSource(hikariConfig);
+ }
+
+ @Override
+ public Connection getConnection()
+ {
+ try (Connection connection = _hikari.getConnection())
+ {
+ return connection;
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ @Override
+ public void close()
+ {
+ _hikari.close();
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/database/engine/SQLDatabase.java b/src/com/projectkorra/projectkorra/database/engine/SQLDatabase.java
new file mode 100644
index 00000000..b0645666
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/engine/SQLDatabase.java
@@ -0,0 +1,10 @@
+package com.projectkorra.projectkorra.database.engine;
+
+import java.sql.Connection;
+
+public interface SQLDatabase
+{
+ Connection getConnection();
+
+ void close();
+}
diff --git a/src/com/projectkorra/projectkorra/database/engine/SQLiteDatabase.java b/src/com/projectkorra/projectkorra/database/engine/SQLiteDatabase.java
new file mode 100644
index 00000000..29ee909d
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/database/engine/SQLiteDatabase.java
@@ -0,0 +1,83 @@
+package com.projectkorra.projectkorra.database.engine;
+
+import com.projectkorra.projectkorra.database.DatabaseConfig;
+import com.projectkorra.projectkorra.database.DatabaseManager;
+
+import java.io.File;
+import java.io.IOException;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+
+public class SQLiteDatabase implements SQLDatabase
+{
+ private final File _databaseFile;
+ private Connection _connection;
+
+ public SQLiteDatabase(DatabaseManager databaseManager, DatabaseConfig databaseConfig)
+ {
+ _databaseFile = new File(databaseManager.getPlugin().getDataFolder(), databaseConfig.SQLite_File);
+
+ if (!_databaseFile.getParentFile().exists())
+ {
+ _databaseFile.getParentFile().mkdirs();
+ }
+
+ if (!_databaseFile.exists())
+ {
+ try
+ {
+ _databaseFile.createNewFile();
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ open();
+ }
+
+ public void open()
+ {
+ try
+ {
+ _connection = DriverManager.getConnection("jdbc:sqlite:" + _databaseFile.getAbsolutePath());
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public Connection getConnection()
+ {
+ try
+ {
+ if (_connection == null || _connection.isClosed())
+ {
+ open();
+ }
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+
+ return _connection;
+ }
+
+ @Override
+ public void close()
+ {
+ try
+ {
+ _connection.close();
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/module/DatabaseModule.java b/src/com/projectkorra/projectkorra/module/DatabaseModule.java
new file mode 100644
index 00000000..221e40b7
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/module/DatabaseModule.java
@@ -0,0 +1,20 @@
+package com.projectkorra.projectkorra.module;
+
+import com.projectkorra.projectkorra.database.DatabaseRepository;
+
+public abstract class DatabaseModule extends Module
+{
+ private final T repository;
+
+ protected DatabaseModule(String name, T repository)
+ {
+ super(name);
+
+ this.repository = repository;
+ }
+
+ protected T getRepository()
+ {
+ return this.repository;
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/module/Module.java b/src/com/projectkorra/projectkorra/module/Module.java
new file mode 100644
index 00000000..692a8292
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/module/Module.java
@@ -0,0 +1,92 @@
+package com.projectkorra.projectkorra.module;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.projectkorra.projectkorra.ProjectKorra;
+import org.bukkit.event.HandlerList;
+import org.bukkit.event.Listener;
+import org.bukkit.plugin.java.JavaPlugin;
+
+import java.util.logging.Level;
+
+public abstract class Module implements Listener
+{
+ private static final String LOG_FORMAT = "(%s) %s";
+
+ private final String name;
+ private final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+
+ protected Module(String name)
+ {
+ this.name = name;
+ }
+
+ protected final void enable()
+ {
+ long startTime = System.currentTimeMillis();
+ log("Enabling...");
+
+ getPlugin().getServer().getPluginManager().registerEvents(this, getPlugin());
+ onEnable();
+
+ long finishTime = System.currentTimeMillis();
+ log(String.format("Enabled! [%sms]", finishTime - startTime));
+ }
+
+ public void onEnable()
+ {
+
+ }
+
+ protected final void disable()
+ {
+ long startTime = System.currentTimeMillis();
+ log("Disabling...");
+
+ HandlerList.unregisterAll(this);
+ onDisable();
+
+ long finishTime = System.currentTimeMillis();
+ log(String.format("Disabled! [%sms]", finishTime - startTime));
+ }
+
+ public void onDisable()
+ {
+
+ }
+
+ protected final void runSync(Runnable runnable)
+ {
+ getPlugin().getServer().getScheduler().runTask(getPlugin(), runnable);
+ }
+
+ protected final void runAsync(Runnable runnable)
+ {
+ getPlugin().getServer().getScheduler().runTaskAsynchronously(getPlugin(), runnable);
+ }
+
+ public String getName()
+ {
+ return this.name;
+ }
+
+ protected Gson getGson()
+ {
+ return this.gson;
+ }
+
+ public final void log(String message)
+ {
+ log(Level.INFO, message);
+ }
+
+ public final void log(Level level, String message)
+ {
+ getPlugin().getLogger().log(level, String.format(LOG_FORMAT, getName(), message));
+ }
+
+ public ProjectKorra getPlugin()
+ {
+ return JavaPlugin.getPlugin(ProjectKorra.class);
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/module/ModuleManager.java b/src/com/projectkorra/projectkorra/module/ModuleManager.java
new file mode 100644
index 00000000..afbc9531
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/module/ModuleManager.java
@@ -0,0 +1,74 @@
+package com.projectkorra.projectkorra.module;
+
+import com.google.common.base.Preconditions;
+import com.projectkorra.projectkorra.database.DatabaseManager;
+import com.projectkorra.projectkorra.player.BendingPlayerManager;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ModuleManager {
+
+ private static final Map, Module> MODULES = new HashMap<>();
+
+ /**
+ * Registers a new {@link Module} instance.
+ *
+ * @param moduleClass {@link Class} of the {@link Module} to be registered
+ * @throws NullPointerException if moduleClass is null
+ * @throws IllegalArgumentException if moduleClass has already been registered
+ */
+ public static void registerModule(Class extends Module> moduleClass) {
+ Preconditions.checkNotNull(moduleClass, "moduleClass cannot be null");
+ Preconditions.checkArgument(!MODULES.containsKey(moduleClass), "moduleClass has already been registered");
+
+ try {
+ Constructor extends Module> constructor = moduleClass.getDeclaredConstructor();
+ boolean accessible = constructor.isAccessible();
+ constructor.setAccessible(true);
+
+ Module module = constructor.newInstance();
+
+ MODULES.put(moduleClass, module);
+ module.enable();
+
+ constructor.setAccessible(accessible);
+ } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Returns a registered {@link Module} by its {@link Class}.
+ *
+ * @param moduleClass {@link Class} of the registered {@link Module}
+ * @return instance of the {@link Module} class
+ * @throws NullPointerException if moduleClass is null
+ * @throws IllegalArgumentException if moduleClass has not been registered
+ */
+ public static T getModule(Class moduleClass) {
+ Preconditions.checkNotNull(moduleClass, "moduleClass cannot be null");
+ Preconditions.checkArgument(MODULES.containsKey(moduleClass), "moduleClass has not been registered");
+
+ return moduleClass.cast(MODULES.get(moduleClass));
+ }
+
+ /**
+ * Register all our core {@link Module}s onEnable.
+ */
+ public static void startup() {
+ registerModule(DatabaseManager.class);
+ registerModule(BendingPlayerManager.class);
+ }
+
+ /**
+ * Disable all our core {@link Module}s onDisable.
+ */
+ public static void shutdown() {
+ getModule(BendingPlayerManager.class).disable();
+ getModule(DatabaseManager.class).disable();
+ }
+
+}
diff --git a/src/com/projectkorra/projectkorra/player/BendingPlayer.java b/src/com/projectkorra/projectkorra/player/BendingPlayer.java
new file mode 100644
index 00000000..7985c7ed
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/player/BendingPlayer.java
@@ -0,0 +1,29 @@
+package com.projectkorra.projectkorra.player;
+
+import java.util.UUID;
+
+public class BendingPlayer
+{
+ private final int _playerId;
+ private final UUID _uuid;
+ private final String _playerName;
+ private long _firstLogin;
+
+ public BendingPlayer(int playerId, UUID uuid, String playerName, long firstLogin)
+ {
+ _playerId = playerId;
+ _uuid = uuid;
+ _playerName = playerName;
+ _firstLogin = firstLogin;
+ }
+
+ public int getId()
+ {
+ return _playerId;
+ }
+
+ public long getFirstLogin()
+ {
+ return _firstLogin;
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/player/BendingPlayerManager.java b/src/com/projectkorra/projectkorra/player/BendingPlayerManager.java
new file mode 100644
index 00000000..7a1fa3b6
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/player/BendingPlayerManager.java
@@ -0,0 +1,52 @@
+package com.projectkorra.projectkorra.player;
+
+import com.projectkorra.projectkorra.module.DatabaseModule;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.PlayerLoginEvent;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+public class BendingPlayerManager extends DatabaseModule
+{
+ private final Map _players = new HashMap<>();
+
+ private BendingPlayerManager()
+ {
+ super("Bending Player", new BendingPlayerRepository());
+
+ runAsync(() ->
+ {
+ getRepository().createTable();
+
+ runSync(() ->
+ {
+ log("Created database table.");
+ });
+ });
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void onLogin(PlayerLoginEvent event)
+ {
+ Player player = event.getPlayer();
+
+ runAsync(() ->
+ {
+ BendingPlayer bendingPlayer = getRepository().selectPlayer(player);
+
+ runSync(() ->
+ {
+ _players.put(player.getUniqueId(), bendingPlayer);
+ });
+ });
+ }
+
+ public BendingPlayer getBendingPlayer(Player player)
+ {
+ return _players.get(player.getUniqueId());
+ }
+}
diff --git a/src/com/projectkorra/projectkorra/player/BendingPlayerRepository.java b/src/com/projectkorra/projectkorra/player/BendingPlayerRepository.java
new file mode 100644
index 00000000..557a8934
--- /dev/null
+++ b/src/com/projectkorra/projectkorra/player/BendingPlayerRepository.java
@@ -0,0 +1,135 @@
+package com.projectkorra.projectkorra.player;
+
+import com.projectkorra.projectkorra.database.DatabaseQuery;
+import com.projectkorra.projectkorra.database.DatabaseRepository;
+import org.bukkit.entity.Player;
+
+import java.nio.ByteBuffer;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.UUID;
+
+public class BendingPlayerRepository extends DatabaseRepository
+{
+ private static final DatabaseQuery CREATE_TABLE_BENDING_PLAYERS = DatabaseQuery.newBuilder()
+ .mysql("CREATE TABLE IF NOT EXISTS pk_bending_players (player_id INTEGER PRIMARY KEY AUTO_INCREMENT, uuid BINARY(16) NOT NULL, player_name VARCHAR(16) NOT NULL, first_login BIGINT NOT NULL, INDEX uuid_index (uuid));")
+ .sqlite("CREATE TABLE IF NOT EXISTS pk_bending_players (player_id INTEGER PRIMARY KEY AUTOINCREMENT, uuid BINARY(16) NOT NULL, player_name VARCHAR(16) NOT NULL, first_login BIGINT NOT NULL); CREATE INDEX uuid_index ON pk_bending_players (uuid);")
+ .build();
+
+ private static final DatabaseQuery SELECT_BENDING_PLAYER = DatabaseQuery.newBuilder()
+ .query("SELECT player_id, player_name, first_login FROM pk_bending_players WHERE uuid = ?;")
+ .build();
+
+ private static final DatabaseQuery INSERT_BENDING_PLAYER = DatabaseQuery.newBuilder()
+ .query("INSERT INTO pk_bending_players (uuid, player_name, first_login) VALUES (?, ?, ?);")
+ .build();
+
+ private static final DatabaseQuery UPDATE_BENDING_PLAYER = DatabaseQuery.newBuilder()
+ .query("UPDATE pk_bending_players SET player_name = ? WHERE player_id = ?;")
+ .build();
+
+ protected void createTable()
+ {
+ Connection connection = getDatabase().getConnection();
+
+ try (PreparedStatement statement = connection.prepareStatement(CREATE_TABLE_BENDING_PLAYERS.getQuery()))
+ {
+ statement.executeUpdate();
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+
+ protected BendingPlayer selectPlayer(Player player)
+ {
+ UUID uuid = player.getUniqueId();
+ byte[] binaryUUID = ByteBuffer.allocate(16).putLong(uuid.getMostSignificantBits()).putLong(uuid.getLeastSignificantBits()).array();
+
+ Connection connection = getDatabase().getConnection();
+
+ try (PreparedStatement statement = connection.prepareStatement(SELECT_BENDING_PLAYER.getQuery()))
+ {
+ statement.setBytes(1, binaryUUID);
+
+ try (ResultSet rs = statement.executeQuery())
+ {
+ if (!rs.next())
+ {
+ return insertPlayer(player.getUniqueId(), player.getName());
+ }
+
+ int playerId = rs.getInt("player_id");
+ String playerName = rs.getString("player_name");
+ long firstLogin = rs.getLong("first_login");
+
+ if (!player.getName().equals(playerName))
+ {
+ updatePlayer(playerId, player.getName());
+ }
+
+ return new BendingPlayer(playerId, uuid, playerName, firstLogin);
+ }
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ private BendingPlayer insertPlayer(UUID uuid, String playerName)
+ {
+ byte[] binaryUUID = ByteBuffer.allocate(16).putLong(uuid.getMostSignificantBits()).putLong(uuid.getLeastSignificantBits()).array();
+
+ Connection connection = getDatabase().getConnection();
+ long firstLogin = System.currentTimeMillis();
+
+ try (PreparedStatement statement = connection.prepareStatement(INSERT_BENDING_PLAYER.getQuery(), Statement.RETURN_GENERATED_KEYS))
+ {
+ statement.setBytes(1, binaryUUID);
+ statement.setString(2, playerName);
+ statement.setLong(3, firstLogin);
+
+ statement.executeUpdate();
+
+ try (ResultSet rs = statement.getGeneratedKeys())
+ {
+ if (rs.next())
+ {
+ int playerId = rs.getInt(1);
+
+ return new BendingPlayer(playerId, uuid, playerName, firstLogin);
+ }
+ }
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+
+ return null;
+ }
+
+ protected void updatePlayer(int playerId, String playerName)
+ {
+ Connection connection = getDatabase().getConnection();
+
+ try (PreparedStatement statement = connection.prepareStatement(UPDATE_BENDING_PLAYER.getQuery()))
+ {
+ statement.setInt(1, playerId);
+ statement.setString(2, playerName);
+
+ statement.executeUpdate();
+ }
+ catch (SQLException e)
+ {
+ e.printStackTrace();
+ }
+ }
+}