diff --git a/src/engine/objects/Mine.java b/src/engine/objects/Mine.java index 7a2a4b56..5940d749 100644 --- a/src/engine/objects/Mine.java +++ b/src/engine/objects/Mine.java @@ -51,6 +51,11 @@ public class Mine extends AbstractGameObject { private int buildingID; private MineProduction mineType; + public int openHour; + public int openMinute; + public int capSize; + public LocalDateTime liveTime; + /** * ResultSet Constructor */ @@ -90,6 +95,10 @@ public class Mine extends AbstractGameObject { this.production = Resource.valueOf(rs.getString("mine_resource")); this.lastClaimer = null; + this.openHour = rs.getInt("mineLiveHour"); + this.openMinute = rs.getInt("mineLiveMinute"); + this.capSize = rs.getInt("capSize"); + this.liveTime = LocalDateTime.now().withHour(this.openHour).withMinute(this.openMinute); } diff --git a/src/engine/server/world/WorldServer.java b/src/engine/server/world/WorldServer.java index eafae89b..85089efb 100644 --- a/src/engine/server/world/WorldServer.java +++ b/src/engine/server/world/WorldServer.java @@ -40,10 +40,7 @@ import engine.net.client.msg.chat.ChatSystemMsg; import engine.objects.*; import engine.server.MBServerStatics; import engine.util.ThreadUtils; -import engine.workthreads.DisconnectTrashTask; -import engine.workthreads.HourlyJobThread; -import engine.workthreads.PurgeOprhans; -import engine.workthreads.WarehousePushThread; +import engine.workthreads.*; import org.pmw.tinylog.Configurator; import org.pmw.tinylog.Level; import org.pmw.tinylog.Logger; @@ -201,6 +198,7 @@ public class WorldServer { LocalDateTime nextPopulationFileTime = LocalDateTime.now(); LocalDateTime nextFlashTrashCheckTime = LocalDateTime.now(); LocalDateTime nextHourlyJobTime = LocalDateTime.now().withMinute(0).withSecond(0).plusHours(1); + LocalDateTime nextHalfHourlyJobTime = LocalDateTime.now().withMinute(0).withSecond(0); LocalDateTime nextWareHousePushTime = LocalDateTime.now(); // Begin execution of main game loop @@ -232,6 +230,13 @@ public class WorldServer { nextHourlyJobTime = LocalDateTime.now().withMinute(0).withSecond(0).plusHours(1); } + if (LocalDateTime.now().isAfter(nextHalfHourlyJobTime)) { + Thread halfHourlyJobThread = new Thread(new HalfHourlyJobThread()); + halfHourlyJobThread.setName("halfHourlyJob"); + halfHourlyJobThread.start(); + nextHalfHourlyJobTime = nextHalfHourlyJobTime.plusMinutes(30); + } + if (LocalDateTime.now().isAfter(nextWareHousePushTime)) { Thread warehousePushThread = new Thread(new WarehousePushThread()); warehousePushThread.setName("warehousePush"); diff --git a/src/engine/workthreads/HalfHourlyJobThread.java b/src/engine/workthreads/HalfHourlyJobThread.java new file mode 100644 index 00000000..6419f495 --- /dev/null +++ b/src/engine/workthreads/HalfHourlyJobThread.java @@ -0,0 +1,171 @@ +// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ . +// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌· +// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀ +// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌ +// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀ +// 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 HalfHourlyJobThread implements Runnable { + + public HalfHourlyJobThread() { + + } + + + public static void processMineWindow() { + + try { + + ArrayList mines = Mine.getMines(); + + for (Mine mine : mines) { + if (LocalDateTime.now().getHour() == 1400) { + mine.wasClaimed = false; + } + try { + + // Open Errant Mines + + if (mine.getOwningGuild().isEmptyGuild()) { + HalfHourlyJobThread.mineWindowOpen(mine); + continue; + } + + // Open Mines owned by nations having their WOO + // set to the current mine window. + + if (mine.openHour == LocalDateTime.now().getHour() && mine.openMinute == LocalDateTime.now().getMinute() && !mine.wasClaimed) { + HalfHourlyJobThread.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() { + + Logger.info("Half-Hourly job is now running."); + + // Open or Close mines for the current mine window. + + processMineWindow(); + + // Mines can only be claimed once per cycle. + // This will reset at 1am after the last mine + // window closes. + + if (LocalDateTime.now().getHour() == 1) { + + for (Mine mine : Mine.getMines()) { + try { + mine.depositMineResources(); + } catch (Exception e) { + Logger.info(e.getMessage() + " for Mine " + mine.getObjectUUID()); + } + if (mine.wasClaimed == true) + mine.wasClaimed = false; + } + } + } +} diff --git a/src/engine/workthreads/HourlyJobThread.java b/src/engine/workthreads/HourlyJobThread.java index dbf17e0c..d418a467 100644 --- a/src/engine/workthreads/HourlyJobThread.java +++ b/src/engine/workthreads/HourlyJobThread.java @@ -189,76 +189,6 @@ public class HourlyJobThread implements Runnable { 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 map = DbManager.getMap(Enum.GameObjectType.City);