[Zone] Fix and simplify zone shutdown logic (#2390)

* Fix and simplify zone shutdown logic

* Add ResetShutdownTimer
This commit is contained in:
Chris Miles 2022-08-30 23:08:24 -05:00 committed by GitHub
parent 59584a8d94
commit 786a7e2169
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 61 additions and 31 deletions

View File

@ -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, 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_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_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, 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, 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") RULE_INT(Zone, PEQZoneDebuff2, 2209, "Second debuff casted by #peqzone Default is Tendrils of Apathy")

View File

@ -567,7 +567,6 @@ void EntityList::MobProcess()
in.s_addr = mob->CastToClient()->GetIP(); in.s_addr = mob->CastToClient()->GetIP();
LogInfo("Dropping client: Process=false, ip=[{}] port=[{}]", inet_ntoa(in), mob->CastToClient()->GetPort()); LogInfo("Dropping client: Process=false, ip=[{}] port=[{}]", inet_ntoa(in), mob->CastToClient()->GetPort());
#endif #endif
zone->StartShutdownTimer();
Group *g = GetGroupByMob(mob); Group *g = GetGroupByMob(mob);
if(g) { if(g) {
LogError("About to delete a client still in a group"); LogError("About to delete a client still in a group");

View File

@ -413,8 +413,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
ztz->response = -1; ztz->response = -1;
else { else {
ztz->response = 1; 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); SendPacket(pack);
@ -550,7 +548,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
SetZoneData(zone->GetZoneID(), zone->GetInstanceID()); SetZoneData(zone->GetZoneID(), zone->GetInstanceID());
if (zst->zoneid == zone->GetZoneID()) { if (zst->zoneid == zone->GetZoneID()) {
// This packet also doubles as "incoming client" notification, lets not shut down before they get here // 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 { else {
SendEmoteMessage( SendEmoteMessage(
@ -590,8 +588,6 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
zone->RemoveAuth(szic->lsid); zone->RemoveAuth(szic->lsid);
zone->AddAuth(szic); 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 { else {

View File

@ -159,18 +159,12 @@ bool Zone::Bootup(uint32 iZoneID, uint32 iInstanceID, bool is_static) {
// Dynamic zones need to Sync here. // Dynamic zones need to Sync here.
// Static zones sync when they connect in worldserver.cpp. // Static zones sync when they connect in worldserver.cpp.
// Static zones cannot sync here as request is ignored by worldserver. // Static zones cannot sync here as request is ignored by worldserver.
if (!is_static) if (!is_static) {
{
zone->GetTimeSync(); zone->GetTimeSync();
} }
zone->RequestUCSServerStatus(); zone->RequestUCSServerStatus();
zone->StartShutdownTimer();
/**
* Set Shutdown timer
*/
uint32 shutdown_timer = static_cast<uint32>(content_db.getZoneShutDownDelay(zone->GetZoneID(), zone->GetInstanceVersion()));
zone->StartShutdownTimer(shutdown_timer);
/* /*
* Set Logging * Set Logging
@ -903,11 +897,23 @@ void Zone::Shutdown(bool quiet)
} }
zone->ldon_trap_entry_list.clear(); 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(); petition_list.ClearPetitions();
zone->SetZoneHasCurrentTime(false); zone->SetZoneHasCurrentTime(false);
if (!quiet) { 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; is_zone_loaded = false;
@ -921,7 +927,7 @@ void Zone::Shutdown(bool quiet)
LogSys.CloseFileLogs(); LogSys.CloseFileLogs();
if (RuleB(Zone, KillProcessOnDynamicShutdown)) { if (RuleB(Zone, KillProcessOnDynamicShutdown)) {
LogInfo("[KillProcessOnDynamicShutdown] Shutting down"); LogInfo("[Zone Shutdown] Shutting down");
EQ::EventLoop::Get().Shutdown(); 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) { if (long_name == 0) {
long_name = strcpy(new char[18], "Long zone missing"); long_name = strcpy(new char[18], "Long zone missing");
} }
autoshutdown_timer.Start(AUTHENTICATION_TIMEOUT * 1000, false);
Weather_Timer = new Timer(60000); Weather_Timer = new Timer(60000);
Weather_Timer->Start(); Weather_Timer->Start();
LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", short_name, Weather_Timer->GetRemainingTime()/1000); LogDebug("The next weather check for zone: [{}] will be in [{}] seconds", short_name, Weather_Timer->GetRemainingTime()/1000);
@ -1497,7 +1502,7 @@ bool Zone::Process() {
if (!staticzone) { if (!staticzone) {
if (autoshutdown_timer.Check()) { if (autoshutdown_timer.Check()) {
StartShutdownTimer(); ResetShutdownTimer();
if (numclients == 0) { if (numclients == 0) {
return false; return false;
} }
@ -1727,17 +1732,45 @@ bool Zone::HasWeather()
return true; return true;
} }
void Zone::StartShutdownTimer(uint32 set_time) { void Zone::StartShutdownTimer(uint32 set_time)
if (set_time > autoshutdown_timer.GetRemainingTime()) { {
// 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))) { if (set_time == (RuleI(Zone, AutoShutdownDelay))) {
set_time = static_cast<uint32>(content_db.getZoneShutDownDelay(GetZoneID(), GetInstanceVersion())); auto delay = content_db.getZoneShutDownDelay(
GetZoneID(),
GetInstanceVersion()
);
if (delay != RuleI(Zone, AutoShutdownDelay)) {
set_time = delay;
loaded_from = "zone table";
}
}
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); 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())); 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) { bool Zone::Depop(bool StartSpawnTimer) {

View File

@ -298,6 +298,7 @@ public:
void SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp); void SetUCSServerAvailable(bool ucss_available, uint32 update_timestamp);
void SpawnConditionChanged(const SpawnCondition &c, int16 old_value); void SpawnConditionChanged(const SpawnCondition &c, int16 old_value);
void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay))); void StartShutdownTimer(uint32 set_time = (RuleI(Zone, AutoShutdownDelay)));
void ResetShutdownTimer();
void UpdateQGlobal(uint32 qid, QGlobal newGlobal); void UpdateQGlobal(uint32 qid, QGlobal newGlobal);
void weatherSend(Client *client = nullptr); void weatherSend(Client *client = nullptr);
void ClearSpawnTimers(); void ClearSpawnTimers();

View File

@ -488,8 +488,6 @@ void Client::DoZoneSuccess(ZoneChange_Struct *zc, uint16 zone_id, uint32 instanc
zc2->success = 1; zc2->success = 1;
outapp->priority = 6; outapp->priority = 6;
FastQueuePacket(&outapp); FastQueuePacket(&outapp);
zone->StartShutdownTimer(AUTHENTICATION_TIMEOUT * 1000);
} else { } else {
// vesuvias - zoneing to another zone so we need to the let the world server // vesuvias - zoneing to another zone so we need to the let the world server
//handle things with the client for a while //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(); m_ZoneSummonLocation = glm::vec4();
zonesummon_id = 0; zonesummon_id = 0;
zonesummon_ignorerestrictions = 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) { void Client::MovePC(const char* zonename, float x, float y, float z, float heading, uint8 ignorerestrictions, ZoneMode zm) {