Initial Repository Push
This commit is contained in:
@@ -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,52 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
|
||||
package engine.workthreads;
|
||||
|
||||
import engine.Enum;
|
||||
import engine.gameManager.DbManager;
|
||||
import engine.gameManager.SimulationManager;
|
||||
import engine.gameManager.ZoneManager;
|
||||
import engine.net.MessageDispatcher;
|
||||
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;
|
||||
|
||||
public class HourlyJobThread implements Runnable {
|
||||
|
||||
private static int hotzoneCount = 0;
|
||||
|
||||
public HourlyJobThread() {
|
||||
|
||||
}
|
||||
|
||||
public void run() {
|
||||
|
||||
// *** REFACTOR: TRY TRY TRY TRY {{{{{{{{{{{ OMG
|
||||
|
||||
Logger.info("Hourly job is now running.");
|
||||
|
||||
try {
|
||||
|
||||
ZoneManager.generateAndSetRandomHotzone();
|
||||
Zone hotzone = ZoneManager.getHotZone();
|
||||
|
||||
if (hotzone == null) {
|
||||
Logger.error( "Null hotzone returned from mapmanager");
|
||||
} else {
|
||||
Logger.info( "new hotzone: " + hotzone.getName());
|
||||
WorldServer.setLastHZChange(System.currentTimeMillis());
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.error( e.toString());
|
||||
}
|
||||
|
||||
//updateMines.
|
||||
try {
|
||||
|
||||
// Update mine effective date if this is a midnight window
|
||||
|
||||
if (LocalDateTime.now().getHour() == 0 || LocalDateTime.now().getHour() == 24)
|
||||
Mine.effectiveMineDate = LocalDateTime.now().withHour(0).withMinute(0).withSecond(0);
|
||||
|
||||
ArrayList<Mine> mines = Mine.getMines();
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
|
||||
for (Mine mine : mines) {
|
||||
try {
|
||||
|
||||
if (mine.getOwningGuild() == null) {
|
||||
mine.handleStartMineWindow();
|
||||
Mine.setLastChange(System.currentTimeMillis());
|
||||
continue;
|
||||
}
|
||||
|
||||
//handle claimed mines
|
||||
LocalDateTime mineWindow = mine.openDate.withMinute(0).withSecond(0).withNano(0);
|
||||
|
||||
if (mineWindow != null && now.plusMinutes(1).isAfter(mineWindow))
|
||||
if (!mine.getIsActive()) {
|
||||
mine.handleStartMineWindow();
|
||||
Mine.setLastChange(System.currentTimeMillis());
|
||||
|
||||
}
|
||||
else if (mine.handleEndMineWindow())
|
||||
Mine.setLastChange(System.currentTimeMillis());
|
||||
} catch (Exception e) {
|
||||
Logger.error ("mineID: " + mine.getObjectUUID(), e.toString());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.error( e.toString());
|
||||
}
|
||||
|
||||
for (Mine mine : Mine.getMines()) {
|
||||
|
||||
try {
|
||||
mine.depositMineResources();
|
||||
} catch (Exception e) {
|
||||
Logger.info(e.getMessage() + " for Mine " + mine.getObjectUUID());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 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");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// Magicbane Emulator Project © 2013 - 2022
|
||||
// www.magicbane.com
|
||||
|
||||
package engine.workthreads;
|
||||
|
||||
import engine.db.archive.DataWarehouse;
|
||||
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 = DataWarehouse.connectionPool.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,450 @@
|
||||
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
|
||||
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
|
||||
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
|
||||
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
|
||||
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
|
||||
// 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 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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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 = DataWarehouse.connectionPool.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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user