diff --git a/common/ruletypes.h b/common/ruletypes.h index 00264e545..7acf0b1b4 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -789,7 +789,6 @@ RULE_CATEGORY(Expedition) RULE_INT(Expedition, MinStatusToBypassPlayerCountRequirements, 80, "Minimum GM status to bypass minimum player requirements for Expedition creation") RULE_BOOL(Expedition, EmptyDzShutdownEnabled, true, "Enable early instance shutdown after last member of expedition removed") RULE_INT(Expedition, EmptyDzShutdownDelaySeconds, 1500, "Seconds to set dynamic zone instance expiration if early shutdown enabled") -RULE_INT(Expedition, RequestExpiredLockoutLeewaySeconds, 60, "Seconds remaining on lockout to count as expired for creation requests (client hides timers under 60s remaining)") RULE_INT(Expedition, WorldExpeditionProcessRateMS, 6000, "Timer interval (ms) that world checks expedition states") RULE_BOOL(Expedition, AlwaysNotifyNewLeaderOnChange, false, "Always notify clients when made expedition leader. If false (live-like) new leaders are only notified when made leader via /dzmakeleader") RULE_REAL(Expedition, LockoutDurationMultiplier, 1.0, "Multiplies lockout duration by this value when new lockouts are added") diff --git a/zone/client.cpp b/zone/client.cpp index f05941ee6..361a10ccc 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -9766,6 +9766,10 @@ void Client::SendExpeditionLockoutTimers() { std::vector lockout_entries; + // client displays lockouts rounded down to nearest minute, send lockouts + // with 60s offset added to compensate (live does this too) + constexpr uint32_t rounding_seconds = 60; + // erases expired lockouts while building lockout timer list for (auto it = m_expedition_lockouts.begin(); it != m_expedition_lockouts.end();) { @@ -9778,7 +9782,7 @@ void Client::SendExpeditionLockoutTimers() { ExpeditionLockoutTimerEntry_Struct lockout; strn0cpy(lockout.expedition_name, it->GetExpeditionName().c_str(), sizeof(lockout.expedition_name)); - lockout.seconds_remaining = seconds_remaining; + lockout.seconds_remaining = seconds_remaining + rounding_seconds; lockout.event_type = it->IsReplayTimer() ? Expedition::REPLAY_TIMER_ID : Expedition::EVENT_TIMER_ID; strn0cpy(lockout.event_name, it->GetEventName().c_str(), sizeof(lockout.event_name)); diff --git a/zone/expedition_request.cpp b/zone/expedition_request.cpp index 1b8f5170b..e157498f2 100644 --- a/zone/expedition_request.cpp +++ b/zone/expedition_request.cpp @@ -191,12 +191,9 @@ bool ExpeditionRequest::LoadLeaderLockouts() // leader's lockouts are used to check member conflicts and later stored in expedition auto lockouts = ExpeditionDatabase::LoadCharacterLockouts(m_leader_id, m_expedition_name); - auto leeway_seconds = static_cast(RuleI(Expedition, RequestExpiredLockoutLeewaySeconds)); - for (auto& lockout : lockouts) { - bool is_expired = lockout.IsExpired() || lockout.GetSecondsRemaining() <= leeway_seconds; - if (!is_expired) + if (!lockout.IsExpired()) { m_lockouts.emplace(lockout.GetEventName(), lockout); @@ -226,8 +223,6 @@ bool ExpeditionRequest::CheckMembersForConflicts(const std::vector& std::vector member_lockout_conflicts; - auto leeway_seconds = static_cast(RuleI(Expedition, RequestExpiredLockoutLeewaySeconds)); - uint32_t last_character_id = 0; for (auto row = results.begin(); row != results.end(); ++row) { @@ -270,9 +265,7 @@ bool ExpeditionRequest::CheckMembersForConflicts(const std::vector& ExpeditionLockoutTimer lockout{row[3], m_expedition_name, row[6], expire_time, duration}; - // client window hides timers with less than 60s remaining, optionally count as expired - bool is_expired = lockout.IsExpired() || lockout.GetSecondsRemaining() <= leeway_seconds; - if (!is_expired) + if (!lockout.IsExpired()) { if (lockout.IsReplayTimer()) {