2022-04-30 09:41:17 -04:00
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.db.archive ;
import engine.Enum ;
2023-05-20 09:39:23 -04:00
import engine.gameManager.DbManager ;
2022-04-30 09:41:17 -04:00
import engine.objects.Bane ;
import engine.objects.City ;
import engine.workthreads.WarehousePushThread ;
import org.joda.time.DateTime ;
import org.pmw.tinylog.Logger ;
import java.sql.* ;
import java.time.LocalDateTime ;
import java.util.concurrent.LinkedBlockingQueue ;
import static engine.Enum.RecordEventType ;
public class BaneRecord extends DataRecord {
2023-07-15 09:23:48 -04:00
private static final LinkedBlockingQueue < BaneRecord > recordPool = new LinkedBlockingQueue <> ();
private RecordEventType eventType ;
private String cityHash ;
private String cityName ;
private String cityGuildHash ;
private String cityNationHash ;
private String baneDropperHash ;
private String baneGuildHash ;
private String baneNationHash ;
private DateTime baneLiveTime ;
private DateTime baneDropTime ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private BaneRecord ( Bane bane ) {
this . recordType = Enum . DataRecordType . BANE ;
this . eventType = RecordEventType . PENDING ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static BaneRecord borrow ( Bane bane , RecordEventType eventType ) {
BaneRecord baneRecord ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
baneRecord = recordPool . poll ();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( baneRecord == null ) {
baneRecord = new BaneRecord ( bane );
baneRecord . eventType = eventType ;
} else {
baneRecord . recordType = Enum . DataRecordType . BANE ;
baneRecord . eventType = eventType ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
baneRecord . cityHash = bane . getCity (). getHash ();
baneRecord . cityName = bane . getCity (). getCityName ();
baneRecord . cityGuildHash = bane . getCity (). getGuild (). getHash ();
baneRecord . cityNationHash = bane . getCity (). getGuild (). getNation (). getHash ();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( bane . getOwner () == null ) {
baneRecord . baneDropperHash = "ERRANT" ;
baneRecord . baneGuildHash = "ERRANT" ;
baneRecord . baneNationHash = "ERRANT" ;
} else {
baneRecord . baneDropperHash = DataWarehouse . hasher . encrypt ( bane . getOwner (). getObjectUUID ()); // getPlayerCharacter didn't check hash first? OMFG
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
baneRecord . baneGuildHash = bane . getOwner (). getGuild (). getHash ();
baneRecord . baneNationHash = bane . getOwner (). getGuild (). getNation (). getHash ();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
baneRecord . baneLiveTime = bane . getLiveDate ();
baneRecord . baneDropTime = bane . getPlacementDate ();
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return baneRecord ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static PreparedStatement buildBanePushStatement ( Connection connection , ResultSet rs ) throws SQLException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PreparedStatement outStatement = null ;
String queryString = "INSERT INTO `warehouse_banehistory` (`event_number`, `city_id`, `city_name`, `char_id`, `offGuild_id`, `offNat_id`, `defGuild_id`, `defNat_id`, `dropDatetime`, `liveDateTime`, `resolution`) VALUES(?,?,?,?,?,?,?,?,?,?,?)" ;
java . util . Date sqlDateTime ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement = connection . prepareStatement ( queryString );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Bind record data
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement . setInt ( 1 , rs . getInt ( "event_number" ));
outStatement . setString ( 2 , rs . getString ( "city_id" ));
outStatement . setString ( 3 , rs . getString ( "city_name" ));
outStatement . setString ( 4 , rs . getString ( "char_id" ));
outStatement . setString ( 5 , rs . getString ( "offGuild_id" ));
outStatement . setString ( 6 , rs . getString ( "offNat_id" ));
outStatement . setString ( 7 , rs . getString ( "defGuild_id" ));
outStatement . setString ( 8 , rs . getString ( "defNat_id" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
sqlDateTime = rs . getTimestamp ( "dropDatetime" );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( sqlDateTime == null )
outStatement . setNull ( 9 , Types . DATE );
else
outStatement . setTimestamp ( 9 , rs . getTimestamp ( "dropDatetime" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
sqlDateTime = rs . getTimestamp ( "dropDatetime" );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( sqlDateTime == null )
outStatement . setNull ( 10 , Types . DATE );
else
outStatement . setTimestamp ( 10 , rs . getTimestamp ( "liveDateTime" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement . setString ( 11 , rs . getString ( "resolution" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return outStatement ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static PreparedStatement buildBaneQueryStatement ( Connection connection ) throws SQLException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PreparedStatement outStatement = null ;
String queryString = "SELECT * FROM `warehouse_banehistory` WHERE `event_number` > ?" ;
outStatement = connection . prepareStatement ( queryString );
outStatement . setInt ( 1 , WarehousePushThread . baneIndex );
return outStatement ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static DateTime getLastBaneDateTime ( City city ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
DateTime outDateTime = null ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection connection = DbManager . getConnection ();
PreparedStatement statement = buildDateTimeQueryStatement ( connection , city );
ResultSet rs = statement . executeQuery ()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
while ( rs . next ()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outDateTime = new DateTime ( rs . getTimestamp ( "endDatetime" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch ( SQLException e ) {
Logger . error ( e . toString ());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return outDateTime ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static PreparedStatement buildDateTimeQueryStatement ( Connection connection , City city ) throws SQLException {
PreparedStatement outStatement ;
String queryString = "SELECT `endDatetime` FROM `warehouse_banehistory` WHERE `city_id` = ? ORDER BY `endDatetime` DESC LIMIT 1" ;
outStatement = connection . prepareStatement ( queryString );
outStatement . setString ( 1 , city . getHash ());
return outStatement ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static void updateLiveDate ( Bane bane , DateTime dateTime ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( bane == null )
return ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection connection = DbManager . getConnection ();
PreparedStatement statement = buildUpdateLiveDateStatement ( connection , bane , dateTime )) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
statement . execute ();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch ( SQLException e ) {
Logger . error ( e . toString ());
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static PreparedStatement buildUpdateLiveDateStatement ( Connection connection , Bane bane , DateTime dateTime ) throws SQLException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PreparedStatement outStatement = null ;
String queryString = "UPDATE `warehouse_banehistory` SET `liveDatetime` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'" ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement = connection . prepareStatement ( queryString );
outStatement . setTimestamp ( 1 , new java . sql . Timestamp ( dateTime . getMillis ()));
outStatement . setString ( 2 , bane . getCity (). getHash ());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return outStatement ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static PreparedStatement buildUpdateResolutionStatement ( Connection connection , Bane bane , RecordEventType eventType ) throws SQLException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PreparedStatement outStatement = null ;
String queryString = "UPDATE `warehouse_banehistory` SET `endDatetime` = ?, `resolution` = ?, `dirty` = 1 WHERE `city_id` = ? AND `resolution` = 'PENDING'" ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement = connection . prepareStatement ( queryString );
outStatement . setTimestamp ( 1 , Timestamp . valueOf ( LocalDateTime . now ()));
outStatement . setString ( 2 , eventType . name ());
outStatement . setString ( 3 , bane . getCity (). getHash ());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return outStatement ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static void updateResolution ( Bane bane , RecordEventType eventType ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection connection = DbManager . getConnection ();
PreparedStatement statement = buildUpdateResolutionStatement ( connection , bane , eventType )) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
statement . execute ();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch ( SQLException e ) {
Logger . error ( e . toString ());
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static String getBaneHistoryString () {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
String outString ;
String queryString ;
String dividerString ;
String newLine = System . getProperty ( "line.separator" );
outString = "[LUA_BANES() DATA WAREHOUSE]" + newLine ;
dividerString = "--------------------------------" + newLine ;
queryString = "CALL `baneHistory`()" ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection connection = DbManager . getConnection ();
PreparedStatement statement = connection . prepareCall ( queryString );
ResultSet rs = statement . executeQuery ()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
while ( rs . next ()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outString += "Magicbane unresolved banes: " + rs . getInt ( "PENDING" ) + '/' + rs . getInt ( "TOTAL" ) + newLine ;
outString += dividerString ;
outString += "Bane Resolution History" + newLine ;
outString += dividerString ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outString += "Destruction: " + rs . getInt ( "DESTROY" ) + newLine ;
outString += "Capture: " + rs . getInt ( "CAPTURE" ) + newLine ;
outString += "Defended: " + rs . getInt ( "DEFEND" ) + newLine ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch ( SQLException e ) {
e . printStackTrace ();
}
return outString ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public static void updateDirtyRecords () {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
String queryString = "SELECT * FROM `warehouse_banehistory` where `dirty` = 1" ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Reset character delta
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
WarehousePushThread . baneDelta = 0 ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection localConnection = DbManager . 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 ()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
while ( rs . next ()) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Only update the index and dirty flag
// if the remote database update succeeded
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( updateDirtyRecord ( rs ) == true )
WarehousePushThread . baneDelta ++ ;
else
continue ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Reset the dirty flag in the local database
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
rs . updateInt ( "dirty" , 0 );
rs . updateRow ();
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch ( SQLException e ) {
Logger . error ( e . toString ());
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static boolean updateDirtyRecord ( ResultSet rs ) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection remoteConnection = DataWarehouse . remoteConnectionPool . getConnection ();
PreparedStatement statement = buildUpdateDirtyStatement ( remoteConnection , rs )) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
statement . execute ();
return true ;
} catch ( SQLException e ) {
Logger . error ( e . toString ());
return false ;
}
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private static PreparedStatement buildUpdateDirtyStatement ( Connection connection , ResultSet rs ) throws SQLException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PreparedStatement outStatement ;
String queryString = "UPDATE `warehouse_banehistory` SET `liveDateTime` = ?, `endDateTime` = ?, `resolution` = ? WHERE `event_number` = ?" ;
java . util . Date sqlDateTime ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement = connection . prepareStatement ( queryString );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
// Bind record data
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
sqlDateTime = rs . getTimestamp ( "liveDateTime" );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( sqlDateTime == null )
outStatement . setNull ( 1 , Types . DATE );
else
outStatement . setTimestamp ( 1 , rs . getTimestamp ( "liveDateTime" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
sqlDateTime = rs . getTimestamp ( "endDateTime" );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( sqlDateTime == null )
outStatement . setNull ( 2 , Types . DATE );
else
outStatement . setTimestamp ( 2 , rs . getTimestamp ( "endDateTime" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement . setString ( 3 , rs . getString ( "resolution" ));
outStatement . setInt ( 4 , rs . getInt ( "event_number" ));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return outStatement ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
void reset () {
this . cityHash = null ;
this . cityGuildHash = null ;
this . cityNationHash = null ;
this . baneDropperHash = null ;
this . baneGuildHash = null ;
this . baneNationHash = null ;
this . baneLiveTime = null ;
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void release () {
this . reset ();
recordPool . add ( this );
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
public void write () {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
try ( Connection connection = DbManager . getConnection ();
PreparedStatement statement = buildBaneInsertStatement ( connection )) {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
statement . execute ();
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
} catch ( SQLException e ) {
Logger . error ( e . toString ());
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
}
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
private PreparedStatement buildBaneInsertStatement ( Connection connection ) throws SQLException {
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
PreparedStatement outStatement = null ;
String queryString = "INSERT INTO `warehouse_banehistory` (`city_id`, `city_name`, `char_id`, `offGuild_id`, `offNat_id`, `defGuild_id`, `defNat_id`, `dropDatetime`, `liveDateTime`, `resolution`) VALUES(?,?,?,?,?,?,?,?,?,?)" ;
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement = connection . prepareStatement ( queryString );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement . setString ( 1 , this . cityHash );
outStatement . setString ( 2 , this . cityName );
outStatement . setString ( 3 , this . baneDropperHash );
outStatement . setString ( 4 , this . baneGuildHash );
outStatement . setString ( 5 , this . baneNationHash );
outStatement . setString ( 6 , this . cityGuildHash );
outStatement . setString ( 7 , this . cityNationHash );
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( this . baneDropTime == null )
outStatement . setNull ( 8 , java . sql . Types . DATE );
else
outStatement . setTimestamp ( 8 , new java . sql . Timestamp ( this . baneDropTime . getMillis ()));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
if ( this . baneLiveTime == null )
outStatement . setNull ( 9 , java . sql . Types . DATE );
else
outStatement . setTimestamp ( 9 , new java . sql . Timestamp ( this . baneLiveTime . getMillis ()));
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
outStatement . setString ( 10 , this . eventType . name ());
2022-04-30 09:41:17 -04:00
2023-07-15 09:23:48 -04:00
return outStatement ;
}
2022-04-30 09:41:17 -04:00
} // END CLASS