chore: baseline subdate2 snapshot for AI refactoring

This commit is contained in:
SlaveOfMagicbot committed 2026-09-27 12:35:14 -05:00
commit 69aa91d403
827 files changed
+161223

No files matched your search

@@ -0,0 +1,155 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.workthreads;
/*
* This thread is spawned to process destruction
* of a player owned city, including subguild
* and database cleanup.
*
* The 'destroyed' city zone persists until the
* next reboot.
*/
import engine.Enum;
import engine.gameManager.DbManager;
import engine.gameManager.GuildManager;
import engine.gameManager.ZoneManager;
import engine.math.Vector3fImmutable;
import engine.objects.Building;
import engine.objects.City;
import engine.objects.Guild;
import engine.objects.Zone;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
public class DestroyCityThread implements Runnable {
City city;
public DestroyCityThread(City city) {
this.city = city;
}
public void run() {
// Member variable declaration
Zone cityZone;
Zone newParent;
Guild formerGuild;
Vector3fImmutable localCoords;
ArrayList<Guild> subGuildList;
// Member variable assignment
cityZone = city.getParent();
newParent = cityZone.getParent();
formerGuild = city.getTOL().getGuild();
// Former guild loses it's tree!
if (DbManager.GuildQueries.SET_GUILD_OWNED_CITY(formerGuild.getObjectUUID(), 0)) {
//Successful Update of guild
formerGuild.setGuildState(engine.Enum.GuildState.Errant);
formerGuild.setNation(null);
formerGuild.setCityUUID(0);
GuildManager.updateAllGuildTags(formerGuild);
GuildManager.updateAllGuildBinds(formerGuild, null);
}
// By losing the tree, the former owners lose all of their subguilds.
if (formerGuild.getSubGuildList().isEmpty() == false) {
subGuildList = new ArrayList<>();
for (Guild subGuild : formerGuild.getSubGuildList()) {
subGuildList.add(subGuild);
}
for (Guild subGuild : subGuildList) {
formerGuild.removeSubGuild(subGuild);
}
}
// Build list of buildings within this parent zone
for (Building cityBuilding : cityZone.zoneBuildingSet) {
// Sanity Check in case player deletes the building
// before this thread can get to it
if (cityBuilding == null)
continue;
// Do nothing with the banestone. It will be removed elsewhere
if (cityBuilding.getBlueprint().getBuildingGroup().equals(Enum.BuildingGroup.BANESTONE))
continue;
// All buildings are moved to a location relative
// to their new parent zone
localCoords = ZoneManager.worldToLocal(cityBuilding.getLoc(), newParent);
DbManager.BuildingQueries.MOVE_BUILDING(cityBuilding.getObjectUUID(), newParent.getObjectUUID(), localCoords.x, localCoords.y, localCoords.z);
// All buildings are re-parented to a zone one node
// higher in the tree (continent) as we will be
// deleting the city zone very shortly.
if (cityBuilding.getParentZoneID() != newParent.getParentZoneID())
cityBuilding.setParentZone(newParent);
// No longer a tree, no longer any protection contract!
cityBuilding.setProtectionState(Enum.ProtectionState.NONE);
// Destroy all remaining city assets
if ((cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.BARRACK)
|| (cityBuilding.getBlueprint().isWallPiece())
|| (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.SHRINE)
|| (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.TOL)
|| (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.SPIRE)
|| (cityBuilding.getBlueprint().getBuildingGroup() == Enum.BuildingGroup.WAREHOUSE)) {
if (cityBuilding.getRank() != -1)
cityBuilding.setRank(-1);
}
}
if (city.getRealm() != null)
city.getRealm().removeCity(city.getObjectUUID());
// It's now safe to delete the city zone from the database
// which will cause a cascade delete of everything else
if (DbManager.ZoneQueries.DELETE_ZONE(cityZone) == false) {
Logger.error("DestroyCityThread", "Database error when deleting city zone: " + cityZone.getObjectUUID());
return;
}
// Refresh the city for map requests
City.lastCityUpdate = System.currentTimeMillis();
// Zone and city should vanish upon next reboot
// if the codebase reaches here.
Logger.info(city.getParent().getName() + " uuid:" + city.getObjectUUID() + "has been destroyed!");
}
}
@@ -0,0 +1,53 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.workthreads;
import engine.Enum;
import engine.gameManager.DbManager;
import engine.gameManager.SessionManager;
import engine.objects.PlayerCharacter;
import engine.session.Session;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
import java.util.TimerTask;
public class DisconnectTrashTask extends TimerTask {
private final ArrayList<PlayerCharacter> trashList;
// Pass it a list of characters and it will disconnect them
// 5 seconds in the future.
public DisconnectTrashTask(ArrayList<PlayerCharacter> trashList) {
this.trashList = new ArrayList<>(trashList);
}
public void run() {
Logger.info("Disconnecting actives from pool of: " + trashList.size());
Session trashSession;
int accountUID;
for (PlayerCharacter trashPlayer : trashList) {
trashSession = SessionManager.getSession(trashPlayer);
accountUID = trashPlayer.getAccount().getObjectUUID();
if (trashSession != null)
trashSession.getConn().disconnect();
// Remove account from cache
DbManager.removeFromCache(Enum.GameObjectType.Account, accountUID);
}
}
;
}
+289
View File
@@ -0,0 +1,289 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.workthreads;
import engine.Enum;
import engine.InterestManagement.WorldGrid;
import engine.db.archive.DataWarehouse;
import engine.db.archive.MineRecord;
import engine.gameManager.*;
import engine.net.DispatchMessage;
import engine.net.MessageDispatcher;
import engine.net.client.msg.chat.ChatSystemMsg;
import engine.objects.*;
import engine.server.world.WorldServer;
import org.pmw.tinylog.Logger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import static engine.server.MBServerStatics.MINE_LATE_WINDOW;
public class HourlyJobThread implements Runnable {
public HourlyJobThread() {
}
public static void decayShrines() {
ArrayList<Shrine> shrineList = new ArrayList<>();
for (Shrine shrine : Shrine.shrinesByBuildingUUID.values()) {
try {
Building shrineBuilding = (Building) DbManager.getObject(Enum.GameObjectType.Building, shrine.getBuildingID());
if (shrineBuilding == null)
continue;
if (shrineBuilding.getOwner().equals(shrineBuilding.getCity().getOwner()) == false)
shrineBuilding.claim(shrineBuilding.getCity().getOwner());
} catch (Exception e) {
Logger.info("Shrine " + shrine.getBuildingID() + " Error " + e);
}
}
// Grab list of top two shrines of each type
for (Shrine shrine : Shrine.shrinesByBuildingUUID.values()) {
if (shrine.getRank() == 0 || shrine.getRank() == 1)
shrineList.add(shrine);
}
Logger.info("Decaying " + shrineList.size() + " shrines...");
// Top 2 shrines decay by 10% a day
for (Shrine shrine : shrineList) {
try {
shrine.decay();
} catch (Exception e) {
Logger.info("Shrine " + shrine.getBuildingID() + " Error " + e);
}
}
}
public static void processMineWindow() {
try {
ArrayList<Mine> mines = Mine.getMines();
for (Mine mine : mines) {
if (LocalDateTime.now().getHour() == 1400) {
mine.wasClaimed = false;
}
try {
// Open Errant Mines
if (mine.getOwningGuild().isEmptyGuild()) {
HourlyJobThread.mineWindowOpen(mine);
continue;
}
// Open Mines owned by nations having their WOO
// set to the current mine window.
if (mine.getOwningGuild().getNation().getMineTime() ==
LocalDateTime.now().getHour() && mine.wasClaimed == false) {
HourlyJobThread.mineWindowOpen(mine);
continue;
}
// Close the mine if it reaches this far
mineWindowClose(mine);
} catch (Exception e) {
Logger.error("mineID: " + mine.getObjectUUID(), e.toString());
}
}
} catch (Exception e) {
Logger.error(e.toString());
}
}
public static void mineWindowOpen(Mine mine) {
mine.setActive(true);
ChatManager.chatSystemChannel(mine.getZoneName() + "'s Mine is now Active!");
Logger.info(mine.getZoneName() + "'s Mine is now Active!");
}
public static boolean mineWindowClose(Mine mine) {
// No need to end the window of a mine which never opened.
if (mine.isActive == false)
return false;
Building mineBuilding = BuildingManager.getBuildingFromCache(mine.getBuildingID());
if (mineBuilding == null) {
Logger.debug("Null mine building for Mine " + mine.getObjectUUID() + " Building " + mine.getBuildingID());
return false;
}
// Mine building still stands; nothing to do.
// We can early exit here.
if (mineBuilding.getRank() > 0) {
mine.setActive(false);
mine.lastClaimer = null;
return true;
}
// This mine does not have a valid claimer
// we will therefore set it to errant
// and keep the window open.
if (!Mine.validateClaimer(mine.lastClaimer)) {
mine.lastClaimer = null;
mine.updateGuildOwner(null);
mine.setActive(true);
return false;
}
//Update ownership to map
mine.guildName = mine.getOwningGuild().getName();
mine.guildTag = mine.getOwningGuild().getGuildTag();
Guild nation = mine.getOwningGuild().getNation();
mine.nationName = nation.getName();
mine.nationTag = nation.getGuildTag();
mineBuilding.rebuildMine();
WorldGrid.updateObject(mineBuilding);
ChatSystemMsg chatMsg = new ChatSystemMsg(null, mine.lastClaimer.getName() + " has claimed the mine in " + mine.getParentZone().getParent().getName() + " for " + mine.getOwningGuild().getName() + ". The mine is no longer active.");
chatMsg.setMessageType(10);
chatMsg.setChannel(Enum.ChatChannelType.SYSTEM.getChannelID());
DispatchMessage.dispatchMsgToAll(chatMsg);
// Warehouse this claim event
MineRecord mineRecord = MineRecord.borrow(mine, mine.lastClaimer, Enum.RecordEventType.CAPTURE);
DataWarehouse.pushToWarehouse(mineRecord);
mineBuilding.setRank(mineBuilding.getRank());
mine.lastClaimer = null;
mine.setActive(false);
mine.wasClaimed = true;
return true;
}
public void run() {
// *** REFACTOR: TRY TRY TRY TRY {{{{{{{{{{{ OMG
Logger.info("Hourly job is now running.");
try {
// Use the same hotZone this hour up and until
// the HotZone_Duration from the ConfigManager
if (ZoneManager.hotZone == null)
ZoneManager.generateAndSetRandomHotzone();
else
ZoneManager.hotZoneCycle = ZoneManager.hotZoneCycle + 1;
if (ZoneManager.hotZoneCycle > Integer.parseInt(ConfigManager.MB_HOTZONE_DURATION.getValue()))
ZoneManager.generateAndSetRandomHotzone();
if (ZoneManager.hotZone == null) {
Logger.error("Null HotZone returned from ZoneManager");
} else {
Logger.info("HotZone switched to: " + ZoneManager.hotZone.getName());
}
} catch (Exception e) {
Logger.error(e.toString());
}
// Open or Close mines for the current mine window.
processMineWindow();
// Deposit mine resources to Guilds
for (Mine mine : Mine.getMines()) {
try {
mine.depositMineResources();
} catch (Exception e) {
Logger.info(e.getMessage() + " for Mine " + mine.getObjectUUID());
}
}
// Reset time-gated access to WOO slider.
// *** Do this after the mines open/close!
if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW) {
Guild guild;
for (AbstractGameObject dbObject : DbManager.getList(Enum.GameObjectType.Guild)) {
guild = (Guild) dbObject;
if (guild != null)
guild.wooWasModified = false;
}
}
// Mines can only be claimed once per cycle.
// This will reset at 1am after the last mine
// window closes.
if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW + 1) {
for (Mine mine : Mine.getMines()) {
if (mine.wasClaimed == true)
mine.wasClaimed = false;
}
}
// Decay Shrines at midnight every day
if (LocalDateTime.now().getHour() == MINE_LATE_WINDOW)
decayShrines();
// Update city population values
ConcurrentHashMap<Integer, AbstractGameObject> map = DbManager.getMap(Enum.GameObjectType.City);
if (map != null) {
for (AbstractGameObject ago : map.values()) {
City city = (City) ago;
if (city != null)
if (city.getGuild() != null) {
ArrayList<PlayerCharacter> guildList = Guild.GuildRoster(city.getGuild());
city.setPopulation(guildList.size());
}
}
City.lastCityUpdate = System.currentTimeMillis();
} else {
Logger.error("missing city map");
}
// Log metrics to console
Logger.info(WorldServer.getUptimeString());
Logger.info(SimulationManager.getPopulationString());
Logger.info(MessageDispatcher.getNetstatString());
Logger.info(PurgeOprhans.recordsDeleted.toString() + "orphaned items deleted");
}
}
+65
View File
@@ -0,0 +1,65 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.workthreads;
import engine.gameManager.DbManager;
import org.pmw.tinylog.Logger;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.concurrent.atomic.LongAdder;
/*
* This thread runs at bootstrap to ensure cleanup of
* orphaned items (deleted items). God does this mess
* ever need to be refactored and re-use of item uuid's
* implemented.
*/
public class PurgeOprhans implements Runnable {
public static LongAdder recordsDeleted = new LongAdder();
public PurgeOprhans() {
recordsDeleted.reset();
}
public static void startPurgeThread() {
Thread purgeOrphans;
purgeOrphans = new Thread(new PurgeOprhans());
purgeOrphans.setName("purgeOrphans");
purgeOrphans.start();
}
public void run() {
// Member variable declaration
try (
Connection connection = DbManager.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT * from `object` where `type` = 'item' AND `parent` IS NULL", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
rs.deleteRow();
recordsDeleted.increment();
}
} catch (Exception e) {
Logger.error(e.toString());
}
Logger.info("Thread is exiting with " + recordsDeleted.toString() + " items deleted");
}
}
@@ -0,0 +1,99 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.workthreads;
/*
* This thread is spawned to process transfer
* ownership of a player owned city, including
* subguild and database cleanup.
*
*/
import engine.Enum;
import engine.gameManager.BuildingManager;
import engine.gameManager.DbManager;
import engine.gameManager.GuildManager;
import engine.net.DispatchMessage;
import engine.net.client.msg.CityZoneMsg;
import engine.objects.AbstractCharacter;
import engine.objects.City;
import engine.objects.Guild;
import org.pmw.tinylog.Logger;
import java.util.ArrayList;
public class TransferCityThread implements Runnable {
City city;
AbstractCharacter newOwner;
public TransferCityThread(City city, AbstractCharacter newOwner) {
this.city = city;
this.newOwner = newOwner;
}
public void run() {
Guild formerGuild;
ArrayList<Guild> subGuildList;
formerGuild = this.city.getTOL().getGuild();
// Former guild loses it's tree!
if (formerGuild != null)
if (DbManager.GuildQueries.SET_GUILD_OWNED_CITY(formerGuild.getObjectUUID(), 0)) {
formerGuild.setGuildState(Enum.GuildState.Errant);
formerGuild.setNation(null);
formerGuild.setCityUUID(0);
GuildManager.updateAllGuildTags(formerGuild);
GuildManager.updateAllGuildBinds(formerGuild, null);
}
// By losing the tree, the former owners lose all of their subguilds.
if (formerGuild.getSubGuildList().isEmpty() == false) {
subGuildList = new ArrayList<>();
for (Guild subGuild : formerGuild.getSubGuildList()) {
subGuildList.add(subGuild);
}
for (Guild subGuild : subGuildList) {
formerGuild.removeSubGuild(subGuild);
}
}
//Reset TOL to rank 1
city.getTOL().setRank(1);
// Transfer all assets to new owner
city.claim(newOwner);
//Set name of City to attacker's guild name
BuildingManager.setUpgradeDateTime(city.getTOL(), null, 0);
city.getTOL().setName(newOwner.getGuild().getName());
// Send updated cityZone to players
CityZoneMsg czm = new CityZoneMsg(2, city.getTOL().getLoc().x, city.getTOL().getLoc().y, city.getTOL().getLoc().z, city.getTOL().getName(), city.getTOL().getParentZone(), 0f, 0f);
DispatchMessage.dispatchMsgToAll(czm);
// Reset city timer for map update
City.lastCityUpdate = System.currentTimeMillis();
Logger.info("uuid:" + city.getObjectUUID() + "transferred from " + formerGuild.getName() +
" to " + newOwner.getGuild().getName());
}
}
@@ -0,0 +1,448 @@
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// 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 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;
}
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");
}
}