[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, 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")

View File

@ -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");

View File

@ -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 {

View File

@ -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<uint32>(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()) {
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))) {
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);
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) {

View File

@ -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();

View File

@ -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) {