// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . // ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· // ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ // ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ // ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ // Magicbane Emulator Project © 2013 - 2022 // www.magicbane.com package engine.workthreads; /* * This thread pushes cumulative warehouse data to * a remote database. * */ import engine.Enum; import engine.db.archive.*; import engine.gameManager.ConfigManager; import engine.gameManager.DbManager; import org.pmw.tinylog.Logger; import java.sql.*; public class WarehousePushThread implements Runnable { // Used to track last push. These are read // at thread startup and written back out // when we're done public static int charIndex, charDelta; public static int cityIndex, cityDelta; public static int guildIndex, guildDelta; public static int realmIndex, realmDelta; public static int baneIndex, baneDelta; public static int pvpIndex, pvpDelta; public static int mineIndex, mineDelta; public WarehousePushThread() { } public void run() { int recordCount = 0; boolean writeSuccess = true; if ( ConfigManager.MB_WORLD_WAREHOUSE_PUSH.getValue().equals("false")) { Logger.info("WAREHOUSEPUSH DISABLED: EARLY EXIT"); return; } // Cache where we left off from the last push // for each of the warehouse tables if (readWarehouseIndex() == false) return; // Log run to console Logger.info( "Pushing records to remote..."); // Push records to remote database for (Enum.DataRecordType recordType : Enum.DataRecordType.values()) { switch (recordType) { case PVP: if (pushPvpRecords() == true) { recordCount = Math.max(0, pvpDelta - pvpIndex); pvpIndex += recordCount; } else writeSuccess = false; break; case CHARACTER: if (pushCharacterRecords() == true) { recordCount = Math.max(0, charDelta - charIndex); charIndex += recordCount; } else writeSuccess = false; break; case REALM: if (pushRealmRecords() == true) { recordCount = Math.max(0, realmDelta - realmIndex); realmIndex += recordCount; } else writeSuccess = false; break; case GUILD: if (pushGuildRecords() == true) { recordCount = Math.max(0, guildDelta - guildIndex); guildIndex += recordCount; } else writeSuccess = false; break; case BANE: if (pushBaneRecords() == true) { recordCount = Math.max(0, baneDelta - baneIndex); baneIndex += recordCount; } else writeSuccess = false; break; case CITY: if (pushCityRecords() == true) { recordCount = Math.max(0, cityDelta - cityIndex); cityIndex += recordCount; } else writeSuccess = false; break; case MINE: if (pushMineRecords() == true) { recordCount = Math.max(0, mineDelta - mineIndex); mineIndex += recordCount; } else writeSuccess = false; break; default: recordCount = 0; writeSuccess = false; break; // unhandled type } if (writeSuccess == true) Logger.info( recordCount + " " + recordType.name() + " records sent to remote"); else Logger.info( recordCount + " returning failed success"); } // Iterate switch // Update indices updateWarehouseIndex(); // Update dirty records Logger.info( "Pushing updates of dirty warehouse records"); CharacterRecord.updateDirtyRecords(); if (charDelta > 0) Logger.info( charDelta + " dirty character records were sent"); ; BaneRecord.updateDirtyRecords(); if (baneDelta > 0) Logger.info( baneDelta + " dirty bane records were sent"); Logger.info( "Process has completed"); } public static boolean pushMineRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = MineRecord.buildMineQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { pushMineRecord(rs); mineDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); e.printStackTrace(); return false; } } public static boolean pushCharacterRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = CharacterRecord.buildCharacterQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { pushCharacterRecord(rs); charDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); e.printStackTrace(); return false; } } private static boolean pushGuildRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = GuildRecord.buildGuildQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { pushGuildRecord(rs); guildDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); e.printStackTrace(); return false; } } private static boolean pushMineRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = MineRecord.buildMinePushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error( e.toString()); return false; } } private static boolean pushGuildRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = GuildRecord.buildGuildPushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error(e.toString()); return false; } } private static boolean pushBaneRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = BaneRecord.buildBaneQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { pushBaneRecord(rs); baneDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); e.printStackTrace(); return false; } } private static boolean pushBaneRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = BaneRecord.buildBanePushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error(e.toString()); return false; } } private static boolean pushCityRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = CityRecord.buildCityQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { pushCityRecord(rs); cityDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); e.printStackTrace(); return false; } } private static boolean pushPvpRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = PvpRecord.buildPvpQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { if (pushPvpRecord(rs) == true) pvpDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); return false; } } private static boolean pushPvpRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = PvpRecord.buildPvpPushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error(e.toString()); return false; } } private static boolean pushRealmRecords() { try (Connection localConnection = DbManager.getConnection(); PreparedStatement statement = RealmRecord.buildRealmQueryStatement(localConnection); ResultSet rs = statement.executeQuery()) { while (rs.next()) { if (pushRealmRecord(rs) == true) realmDelta = rs.getInt("event_number"); } return true; } catch (SQLException e) { Logger.error("Error with local DB connection: " + e.toString()); e.printStackTrace(); return false; } } private static boolean pushRealmRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = RealmRecord.buildRealmPushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error( e.toString()); return false; } } private static boolean pushCharacterRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = CharacterRecord.buildCharacterPushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error(e.toString()); return false; } } private static boolean pushCityRecord(ResultSet rs) { try (Connection remoteConnection = DataWarehouse.remoteConnectionPool.getConnection(); PreparedStatement statement = CityRecord.buildCityPushStatement(remoteConnection, rs)) { statement.execute(); return true; } catch (SQLException e) { Logger.error( e.toString()); return false; } } private static boolean readWarehouseIndex() { // Member variable declaration String queryString; queryString = "SELECT * FROM `warehouse_index`"; try (Connection localConnection = DbManager.getConnection(); CallableStatement statement = localConnection.prepareCall(queryString); ResultSet rs = statement.executeQuery()) { while (rs.next()) { charIndex = rs.getInt("charIndex"); cityIndex = rs.getInt("cityIndex"); guildIndex = rs.getInt("guildIndex"); realmIndex = rs.getInt("realmIndex"); baneIndex = rs.getInt("baneIndex"); pvpIndex = rs.getInt("pvpIndex"); mineIndex = rs.getInt("mineIndex"); } return true; } catch (SQLException e) { Logger.error( "Error reading warehouse index" + e.toString()); e.printStackTrace(); return false; } } private static boolean updateWarehouseIndex() { try (Connection connection = DbManager.getConnection(); PreparedStatement statement = WarehousePushThread.buildIndexUpdateStatement(connection)) { statement.execute(); return true; } catch (SQLException e) { Logger.error(e.toString()); return false; } } private static PreparedStatement buildIndexUpdateStatement(Connection connection) throws SQLException { PreparedStatement outStatement = null; String queryString = "UPDATE `warehouse_index` SET `charIndex` = ?, `cityIndex` = ?, `guildIndex` = ?, `realmIndex` = ?, `baneIndex` = ?, `pvpIndex` = ?, `mineIndex` = ?"; outStatement = connection.prepareStatement(queryString); // Bind record data outStatement.setInt(1, charIndex); outStatement.setInt(2, cityIndex); outStatement.setInt(3, guildIndex); outStatement.setInt(4, realmIndex); outStatement.setInt(5, baneIndex); outStatement.setInt(6, pvpIndex); outStatement.setInt(7, mineIndex); return outStatement; } }