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.
284 lines
10 KiB
284 lines
10 KiB
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . |
|
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· |
|
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ |
|
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ |
|
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ |
|
// 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()); |
|
|
|
} |
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|