You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
10 KiB
285 lines
10 KiB
3 years ago
|
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||
|
// Magicbane Emulator Project © 2013 - 2022
|
||
|
// www.magicbane.com
|
||
|
|
||
|
|
||
|
package engine.db.archive;
|
||
|
|
||
|
import engine.Enum;
|
||
|
import engine.objects.Guild;
|
||
|
import engine.objects.PlayerCharacter;
|
||
|
import engine.workthreads.WarehousePushThread;
|
||
|
import org.pmw.tinylog.Logger;
|
||
|
|
||
|
import java.sql.*;
|
||
|
import java.time.LocalDateTime;
|
||
|
import java.util.concurrent.LinkedBlockingQueue;
|
||
|
|
||
|
/*
|
||
|
* This class warehouses character creation events. It also tracks
|
||
|
* updates to summary kills/death data and their promotion class.
|
||
|
*/
|
||
|
public class CharacterRecord extends DataRecord {
|
||
|
|
||
|
// Local object pool for class
|
||
|
|
||
|
private static final LinkedBlockingQueue<CharacterRecord> recordPool = new LinkedBlockingQueue<>();
|
||
|
|
||
|
private PlayerCharacter player;
|
||
|
|
||
|
private CharacterRecord(PlayerCharacter player) {
|
||
|
this.recordType = Enum.DataRecordType.CHARACTER;
|
||
|
this.player = player;
|
||
|
}
|
||
|
|
||
|
public static CharacterRecord borrow(PlayerCharacter player) {
|
||
|
CharacterRecord characterRecord;
|
||
|
|
||
|
characterRecord = recordPool.poll();
|
||
|
|
||
|
if (characterRecord == null) {
|
||
|
characterRecord = new CharacterRecord(player);
|
||
|
}
|
||
|
else {
|
||
|
characterRecord.recordType = Enum.DataRecordType.CHARACTER;
|
||
|
characterRecord.player = player;
|
||
|
|
||
|
}
|
||
|
|
||
|
return characterRecord;
|
||
|
}
|
||
|
|
||
|
private static PreparedStatement buildCharacterInsertStatement(Connection connection, PlayerCharacter player) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement = null;
|
||
|
String queryString = "INSERT INTO `warehouse_characterhistory` (`char_id`, `char_fname`, `char_lname`, `baseClass`, `race`, `promoteClass`, `startingGuild`, `datetime`) VALUES(?,?,?,?,?,?,?,?)";
|
||
|
Guild charGuild;
|
||
|
|
||
|
outStatement = connection.prepareStatement(queryString);
|
||
|
|
||
|
charGuild = player.getGuild();
|
||
|
|
||
|
// Bind character data
|
||
|
|
||
|
outStatement.setString(1, DataWarehouse.hasher.encrypt(player.getObjectUUID()));
|
||
|
outStatement.setString(2, player.getFirstName());
|
||
|
outStatement.setString(3, player.getLastName());
|
||
|
outStatement.setInt(4, player.getBaseClassID());
|
||
|
outStatement.setInt(5, player.getRaceID());
|
||
|
outStatement.setInt(6, player.getPromotionClassID());
|
||
|
outStatement.setString(7, DataWarehouse.hasher.encrypt(charGuild.getObjectUUID()));
|
||
|
outStatement.setTimestamp(8, Timestamp.valueOf(LocalDateTime.now()));
|
||
|
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
public static PreparedStatement buildCharacterPushStatement(Connection connection, ResultSet rs) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement = null;
|
||
|
String queryString = "INSERT INTO `warehouse_characterhistory` (`event_number`, `char_id`, `char_fname`, `char_lname`, `baseClass`, `race`, `promoteClass`, `startingGuild`, `datetime`) VALUES(?,?,?,?,?,?,?,?,?)";
|
||
|
|
||
|
outStatement = connection.prepareStatement(queryString);
|
||
|
|
||
|
// Bind record data
|
||
|
|
||
|
outStatement.setInt(1, rs.getInt("event_number"));
|
||
|
outStatement.setString(2, rs.getString("char_id"));
|
||
|
outStatement.setString(3, rs.getString("char_fname"));
|
||
|
outStatement.setString(4, rs.getString("char_lname"));
|
||
|
outStatement.setInt(5, rs.getInt("baseClass"));
|
||
|
outStatement.setInt(6, rs.getInt("race"));
|
||
|
outStatement.setInt(7, rs.getInt("promoteClass"));
|
||
|
outStatement.setString(8, rs.getString("startingGuild"));
|
||
|
outStatement.setTimestamp(9, rs.getTimestamp("datetime"));
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
public static PreparedStatement buildCharacterQueryStatement(Connection connection) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement = null;
|
||
|
String queryString = "SELECT * FROM `warehouse_characterhistory` WHERE `event_number` > ?";
|
||
|
outStatement = connection.prepareStatement(queryString);
|
||
|
outStatement.setInt(1, WarehousePushThread.charIndex);
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
public static void advanceKillCounter(PlayerCharacter player) {
|
||
|
|
||
|
try (Connection connection = DataWarehouse.connectionPool.getConnection();
|
||
|
PreparedStatement statement = buildKillCounterStatement(connection, player)) {
|
||
|
|
||
|
statement.execute();
|
||
|
|
||
|
} catch (SQLException e) {
|
||
|
Logger.error( e.toString());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
private static PreparedStatement buildKillCounterStatement(Connection connection, PlayerCharacter player) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement = null;
|
||
|
String queryString = "UPDATE `warehouse_characterhistory` SET `kills` = `kills` +1, `dirty` = 1 WHERE `char_id` = ?";
|
||
|
|
||
|
if (player == null)
|
||
|
return outStatement;
|
||
|
|
||
|
outStatement = connection.prepareStatement(queryString);
|
||
|
outStatement.setString(1, player.getHash());
|
||
|
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
public static void advanceDeathCounter(PlayerCharacter player) {
|
||
|
|
||
|
try (Connection connection = DataWarehouse.connectionPool.getConnection();
|
||
|
PreparedStatement statement = buildDeathCounterStatement(connection, player)) {
|
||
|
|
||
|
statement.execute();
|
||
|
|
||
|
} catch (SQLException e) {
|
||
|
Logger.error( e.toString());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
private static PreparedStatement buildDeathCounterStatement(Connection connection, PlayerCharacter player) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement = null;
|
||
|
String queryString = "UPDATE `warehouse_characterhistory` SET `deaths` = `deaths` +1, `dirty` = 1 WHERE `char_id` = ?";
|
||
|
|
||
|
if (player == null)
|
||
|
return outStatement;
|
||
|
|
||
|
outStatement = connection.prepareStatement(queryString);
|
||
|
outStatement.setString(1, player.getHash());
|
||
|
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
public static void updatePromotionClass(PlayerCharacter player) {
|
||
|
|
||
|
try (Connection connection = DataWarehouse.connectionPool.getConnection();
|
||
|
PreparedStatement statement = buildUpdatePromotionStatement(connection, player)) {
|
||
|
|
||
|
statement.execute();
|
||
|
|
||
|
} catch (SQLException e) {
|
||
|
Logger.error( e.toString());
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
private static PreparedStatement buildUpdatePromotionStatement(Connection connection, PlayerCharacter player) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement = null;
|
||
|
String queryString = "UPDATE `warehouse_characterhistory` SET `promoteClass` = ?, `dirty` = 1 WHERE `char_id` = ?";
|
||
|
|
||
|
if (player == null)
|
||
|
return outStatement;
|
||
|
|
||
|
outStatement = connection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
|
||
|
outStatement.setInt(1, player.getPromotionClassID());
|
||
|
outStatement.setString(2, player.getHash());
|
||
|
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
public static void updateDirtyRecords() {
|
||
|
|
||
|
String queryString = "SELECT * FROM `warehouse_characterhistory` where `dirty` = 1";
|
||
|
|
||
|
// Reset character delta
|
||
|
|
||
|
WarehousePushThread.charDelta = 0;
|
||
|
|
||
|
try (Connection localConnection = DataWarehouse.connectionPool.getConnection();
|
||
|
PreparedStatement statement = localConnection.prepareStatement(queryString, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE); // Make this an updatable result set as we'll reset the dirty flag as we go along
|
||
|
ResultSet rs = statement.executeQuery()) {
|
||
|
|
||
|
while (rs.next()) {
|
||
|
|
||
|
// Only update the index and dirty flag
|
||
|
// if the remote database update succeeded
|
||
|
|
||
|
if (updateDirtyRecord(rs) == true)
|
||
|
WarehousePushThread.charDelta++;
|
||
|
else
|
||
|
continue;
|
||
|
|
||
|
// Reset the dirty flag in the local database
|
||
|
|
||
|
rs.updateInt("dirty", 0);
|
||
|
rs.updateRow();
|
||
|
}
|
||
|
|
||
|
} catch (SQLException e) {
|
||
|
Logger.error(e.toString());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static boolean updateDirtyRecord(ResultSet rs) {
|
||
|
|
||
|
try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection();
|
||
|
PreparedStatement statement = buildUpdateDirtyStatement(remoteConnection, rs)) {
|
||
|
|
||
|
statement.execute();
|
||
|
return true;
|
||
|
} catch (SQLException e) {
|
||
|
Logger.error(e.toString());
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static PreparedStatement buildUpdateDirtyStatement(Connection connection, ResultSet rs) throws SQLException {
|
||
|
|
||
|
PreparedStatement outStatement;
|
||
|
String queryString = "UPDATE `warehouse_characterhistory` SET `promoteClass` = ?, `kills` = ?, `deaths` = ? WHERE `char_id` = ?";
|
||
|
|
||
|
outStatement = connection.prepareStatement(queryString);
|
||
|
|
||
|
// Bind record data
|
||
|
|
||
|
outStatement.setInt(1, rs.getInt("promoteClass"));
|
||
|
outStatement.setInt(2, rs.getInt("kills"));
|
||
|
outStatement.setInt(3, rs.getInt("deaths"));
|
||
|
outStatement.setString(4, rs.getString("char_id"));
|
||
|
|
||
|
return outStatement;
|
||
|
}
|
||
|
|
||
|
void reset() {
|
||
|
this.player = null;
|
||
|
}
|
||
|
|
||
|
public void release() {
|
||
|
this.reset();
|
||
|
recordPool.add(this);
|
||
|
}
|
||
|
|
||
|
public void write() {
|
||
|
|
||
|
try (Connection connection = DataWarehouse.connectionPool.getConnection();
|
||
|
PreparedStatement statement = buildCharacterInsertStatement(connection, this.player)) {
|
||
|
|
||
|
statement.execute();
|
||
|
|
||
|
} catch (SQLException e) {
|
||
|
Logger.error( "Error writing character record " + e.toString());
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|