diff --git a/common/ruletypes.h b/common/ruletypes.h index 1a2dfa0fb..fad66a09c 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -283,7 +283,7 @@ RULE_CATEGORY(Zone) RULE_INT(Zone, ClientLinkdeadMS, 90000, "The time a client remains link dead on the server after a sudden disconnection (milliseconds)") RULE_INT(Zone, GraveyardTimeMS, 1200000, "Time until a player corpse is moved to a zone's graveyard, if one is specified for the zone (milliseconds)") RULE_BOOL(Zone, EnableShadowrest, 1, "Enables or disables the Shadowrest zone feature for player corpses. Default is turned on") -RULE_INT(Zone, AutoShutdownDelay, 5000, "How long a dynamic zone stays loaded while empty (milliseconds)") +RULE_INT(Zone, AutoShutdownDelay, 60000, "How long a dynamic zone stays loaded while empty (milliseconds)") RULE_INT(Zone, PEQZoneReuseTime, 900, "Seconds between two uses of the #peqzone command (Set to 0 to disable)") RULE_INT(Zone, PEQZoneDebuff1, 4454, "First debuff casted by #peqzone Default is Cursed Keeper's Blight") RULE_INT(Zone, PEQZoneDebuff2, 2209, "Second debuff casted by #peqzone Default is Tendrils of Apathy") diff --git a/zone/entity.cpp b/zone/entity.cpp index 22af183d4..5be724eb4 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -567,7 +567,6 @@ void EntityList::MobProcess() in.s_addr = mob->CastToClient()->GetIP(); LogInfo("Dropping client: Process=false, ip=[{}] port=[{}]", inet_ntoa(in), mob->CastToClient()->GetPort()); #endif - zone->StartShutdownTimer(); Group *g = GetGroupByMob(mob); if(g) { LogError("About to delete a client still in a group"); diff --git a/zone/worldserver.cpp b/zone/worldserver.cpp index 099a4d50c..ada8778a6 100644 --- a/zone/worldserver.cpp +++ b/zone/worldserver.cpp @@ -413,8 +413,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) ztz->response = -1; else { ztz->response = 1; - // since they asked about comming, lets assume they are on their way and not shut down. - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } SendPacket(pack); @@ -550,7 +548,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); if (zst->zoneid == zone->GetZoneID()) { // This packet also doubles as "incoming client" notification, lets not shut down before they get here - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); +// zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } else { SendEmoteMessage( @@ -590,8 +588,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p) zone->RemoveAuth(szic->lsid); zone->AddAuth(szic); - // This packet also doubles as "incoming client" notification, lets not shut down before they get here - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } } else { diff --git a/zone/zone.cpp b/zone/zone.cpp index d8b18e1e1..0f9cb2fc3 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -159,18 +159,12 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool is_static) { // Dynamic zones need to Sync here. // Static zones sync when they connect in worldserver.cpp. // Static zones cannot sync here as request is ignored by worldserver. - if (!is_static) - { + if (!is_static) { zone->GetTimeSync(); } zone->RequestUCSServerStatus(); - - /** - * Set Shutdown timer - */ - uint32 shutdown_timer = static_cast(content_db.getZoneShutDownDelay(zone->GetZoneID(), zone->GetInstanceVersion())); - zone->StartShutdownTimer(shutdown_timer); + zone->StartShutdownTimer(); /* * Set Logging @@ -903,11 +897,23 @@ void Zone::Shutdown(bool quiet) } zone->ldon_trap_entry_list.clear(); - LogInfo("Zone Shutdown: [{}] ([{}])", zone->GetShortName(), zone->GetZoneID()); + LogInfo( + "[Zone Shutdown] Zone [{}] zone_id [{}] version [{}] instance_id [{}]", + zone->GetShortName(), + zone->GetZoneID(), + zone->GetInstanceVersion(), + zone->GetInstanceID() + ); petition_list.ClearPetitions(); zone->SetZoneHasCurrentTime(false); if (!quiet) { - LogInfo("Zone Shutdown: Going to sleep"); + LogInfo( + "[Zone Shutdown] Zone [{}] zone_id [{}] version [{}] instance_id [{}] Going to sleep", + zone->GetShortName(), + zone->GetZoneID(), + zone->GetInstanceVersion(), + zone->GetInstanceID() + ); } is_zone_loaded = false; @@ -921,7 +927,7 @@ void Zone::Shutdown(bool quiet) LogSys.CloseFileLogs(); if (RuleB(Zone, KillProcessOnDynamicShutdown)) { - LogInfo("[KillProcessOnDynamicShutdown] Shutting down"); + LogInfo("[Zone Shutdown] Shutting down"); EQ::EventLoop::Get().Shutdown(); } } @@ -1002,7 +1008,6 @@ Zone::Zone(uint32 in_zoneid, uint32 in_instanceid, const char* in_short_name) if (long_name == 0) { long_name = strcpy(new char[18], "Long zone missing"); } - autoshutdown_timer.Start(AUTHENTICATION_TIMEOUT * 1000, false); Weather_Timer = new Timer(60000); Weather_Timer->Start(); LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", short_name, Weather_Timer->GetRemainingTime()/1000); @@ -1495,9 +1500,9 @@ bool Zone::Process() { } } - if(!staticzone) { + if (!staticzone) { if (autoshutdown_timer.Check()) { - StartShutdownTimer(); + ResetShutdownTimer(); if (numclients == 0) { return false; } @@ -1727,17 +1732,45 @@ bool Zone::HasWeather() return true; } -void Zone::StartShutdownTimer(uint32 set_time) { - if (set_time > autoshutdown_timer.GetRemainingTime()) { - if (set_time == (RuleI(Zone, AutoShutdownDelay))) { - set_time = static_cast(content_db.getZoneShutDownDelay(GetZoneID(), GetInstanceVersion())); +void Zone::StartShutdownTimer(uint32 set_time) +{ + // if we pass in the default value, we should pull from the zone and use it is different + std::string loaded_from = "rules"; + if (set_time == (RuleI(Zone, AutoShutdownDelay))) { + auto delay = content_db.getZoneShutDownDelay( + GetZoneID(), + GetInstanceVersion() + ); + if (delay != RuleI(Zone, AutoShutdownDelay)) { + set_time = delay; + loaded_from = "zone table"; } - - autoshutdown_timer.SetTimer(set_time); - LogDebug("Zone::StartShutdownTimer set to {}", set_time); } - LogDebug("Zone::StartShutdownTimer trigger - set_time: [{}] remaining_time: [{}] diff: [{}]", set_time, autoshutdown_timer.GetRemainingTime(), (set_time - autoshutdown_timer.GetRemainingTime())); + if (set_time != autoshutdown_timer.GetDuration()) { + LogInfo( + "[StartShutdownTimer] Reset to [{}] {} from original remaining time [{}] duration [{}] zone [{}]", + Strings::SecondsToTime(set_time, true), + !loaded_from.empty() ? fmt::format("(Loaded from [{}])", loaded_from) : "", + Strings::SecondsToTime(autoshutdown_timer.GetRemainingTime(), true), + Strings::SecondsToTime(autoshutdown_timer.GetDuration(), true), + zone->GetZoneDescription() + ); + } + + autoshutdown_timer.SetTimer(set_time); +} + +void Zone::ResetShutdownTimer() { + LogInfo( + "[ResetShutdownTimer] Reset to [{}] from original remaining time [{}] duration [{}] zone [{}]", + Strings::SecondsToTime(autoshutdown_timer.GetDuration(), true), + Strings::SecondsToTime(autoshutdown_timer.GetRemainingTime(), true), + Strings::SecondsToTime(autoshutdown_timer.GetDuration(), true), + zone->GetZoneDescription() + ); + + autoshutdown_timer.SetTimer(autoshutdown_timer.GetDuration()); } bool Zone::Depop(bool StartSpawnTimer) { diff --git a/zone/zone.h b/zone/zone.h index ef191d2b1..28bd76141 100755 --- a/zone/zone.h +++ b/zone/zone.h @@ -298,6 +298,7 @@ public: void SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp); void SpawnConditionChanged(const SpawnCondition &c, int16 old_value); void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay))); + void ResetShutdownTimer(); void UpdateQGlobal(uint32 qid, QGlobal newGlobal); void weatherSend(Client *client = nullptr); void ClearSpawnTimers(); diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 3c55d3761..aaca8f132 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -488,8 +488,6 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc zc2->success = 1; outapp->priority = 6; FastQueuePacket(&outapp); - - zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000); } else { // vesuvias - zoneing to another zone so we need to the let the world server //handle things with the client for a while @@ -513,6 +511,9 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc m_ZoneSummonLocation = glm::vec4(); zonesummon_id = 0; zonesummon_ignorerestrictions = 0; + + // this simply resets the zone shutdown timer + zone->ResetShutdownTimer(); } void Client::MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) {