2022-04-30 09:41:17 -04:00
// • ▌ ▄ ·. ▄▄▄· ▄▄ • ▪ ▄▄· ▄▄▄▄· ▄▄▄· ▐▄▄▄ ▄▄▄ .
// ·██ ▐███▪▐█ ▀█ ▐█ ▀ ▪██ ▐█ ▌▪▐█ ▀█▪▐█ ▀█ •█▌ ▐█▐▌·
// ▐█ ▌▐▌▐█·▄█▀▀█ ▄█ ▀█▄▐█·██ ▄▄▐█▀▀█▄▄█▀▀█ ▐█▐ ▐▌▐▀▀▀
// ██ ██▌▐█▌▐█ ▪▐▌▐█▄▪▐█▐█▌▐███▌██▄▪▐█▐█ ▪▐▌██▐ █▌▐█▄▄▌
// ▀▀ █▪▀▀▀ ▀ ▀ ·▀▀▀▀ ▀▀▀·▀▀▀ ·▀▀▀▀ ▀ ▀ ▀▀ █▪ ▀▀▀
// Magicbane Emulator Project © 2013 - 2022
// www.magicbane.com
package engine.workthreads ;
import engine.Enum ;
2023-01-21 11:11:34 -05:00
import engine.InterestManagement.WorldGrid ;
import engine.db.archive.DataWarehouse ;
import engine.db.archive.MineRecord ;
import engine.gameManager.* ;
import engine.net.DispatchMessage ;
2022-04-30 09:41:17 -04:00
import engine.net.MessageDispatcher ;
2023-01-21 11:11:34 -05:00
import engine.net.client.msg.chat.ChatSystemMsg ;
2022-04-30 09:41:17 -04:00
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 ;
2023-01-21 08:18:40 -05:00
import static engine.server.MBServerStatics.MINE_LATE_WINDOW ;
2022-04-30 09:41:17 -04:00
public class HourlyJobThread implements Runnable {
2023-01-21 08:18:40 -05:00
public HourlyJobThread () {
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
}
2022-04-30 09:41:17 -04:00
2023-02-24 00:09:57 -05:00
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 ;
}
2023-01-21 08:18:40 -05:00
public void run () {
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
// *** REFACTOR: TRY TRY TRY TRY {{{{{{{{{{{ OMG
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
Logger . info ( "Hourly job is now running." );
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
try {
2023-02-22 16:40:11 -05:00
2023-02-22 17:25:48 -05:00
// Use the same hotZone this hour up and until
// the HotZone_Duration from the ConfigManager
2023-02-22 17:35:30 -05:00
if ( ZoneManager . hotZone == null )
ZoneManager . generateAndSetRandomHotzone ();
else
ZoneManager . hotZoneCycle = ZoneManager . hotZoneCycle + 1 ;
2023-02-22 16:40:11 -05:00
2023-02-22 17:25:48 -05:00
if ( ZoneManager . hotZoneCycle > Integer . parseInt ( ConfigManager . MB_HOTZONE_DURATION . getValue ()))
2023-02-18 15:04:34 -06:00
ZoneManager . generateAndSetRandomHotzone ();
2023-02-22 16:40:11 -05:00
if ( ZoneManager . hotZone == null ) {
Logger . error ( "Null HotZone returned from ZoneManager" );
2023-01-21 08:18:40 -05:00
} else {
2023-02-22 16:40:11 -05:00
Logger . info ( "HotZone switched to: " + ZoneManager . hotZone . getName ());
2023-01-21 08:18:40 -05:00
}
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
} catch ( Exception e ) {
Logger . error ( e . toString ());
}
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
// Open or Close mines for the current mine window.
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
processMineWindow ();
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
// Deposit mine resources to Guilds
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
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 ;
}
}
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
// Mines can only be claimed once per cycle.
// This will reset at 1am after the last mine
// window closes.
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
if ( LocalDateTime . now (). getHour () == MINE_LATE_WINDOW + 1 ) {
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
for ( Mine mine : Mine . getMines ()) {
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
if ( mine . wasClaimed == true )
mine . wasClaimed = false ;
}
}
2022-04-30 09:41:17 -04:00
2023-01-21 08:53:57 -05:00
// Decay Shrines at midnight every day
if ( LocalDateTime . now (). getHour () == MINE_LATE_WINDOW )
decayShrines ();
2023-01-21 08:18:40 -05:00
// Update city population values
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
ConcurrentHashMap < Integer , AbstractGameObject > map = DbManager . getMap ( Enum . GameObjectType . City );
2022-04-30 09:41:17 -04:00
2023-01-21 08:18:40 -05:00
if ( map != null ) {
2023-01-19 11:21:08 -05:00
2023-01-21 08:18:40 -05:00
for ( AbstractGameObject ago : map . values ()) {
2023-01-19 11:21:08 -05:00
2023-01-21 08:18:40 -05:00
City city = ( City ) ago ;
2023-01-19 11:21:08 -05:00
2023-01-21 08:18:40 -05:00
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" );
}
2023-01-19 11:21:08 -05:00
2023-01-21 08:18:40 -05:00
// Log metrics to console
Logger . info ( WorldServer . getUptimeString ());
Logger . info ( SimulationManager . getPopulationString ());
Logger . info ( MessageDispatcher . getNetstatString ());
Logger . info ( PurgeOprhans . recordsDeleted . toString () + "orphaned items deleted" );
}
2022-04-30 09:41:17 -04:00
}