diff --git a/world/expedition.cpp b/world/expedition.cpp index 15ce39dcb..f06f61a7c 100644 --- a/world/expedition.cpp +++ b/world/expedition.cpp @@ -43,6 +43,7 @@ Expedition::Expedition( m_duration(duration) { m_expire_time = m_start_time + m_duration; + m_warning_cooldown_timer.Enable(); } void Expedition::SendZonesExpeditionDeleted() @@ -64,6 +65,16 @@ void Expedition::SendZonesDurationUpdate() zoneserver_list.SendPacket(pack.get()); } +void Expedition::SendZonesExpireWarning(uint32_t minutes_remaining) +{ + uint32_t pack_size = sizeof(ServerExpeditionExpireWarning_Struct); + auto pack = std::unique_ptr(new ServerPacket(ServerOP_ExpeditionExpireWarning, pack_size)); + auto buf = reinterpret_cast(pack->pBuffer); + buf->expedition_id = GetID(); + buf->minutes_remaining = minutes_remaining; + zoneserver_list.SendPacket(pack.get()); +} + void Expedition::UpdateDzSecondsRemaining(uint32_t seconds_remaining) { auto now = std::chrono::system_clock::now(); @@ -88,6 +99,28 @@ void Expedition::UpdateDzSecondsRemaining(uint32_t seconds_remaining) } } +std::chrono::system_clock::duration Expedition::GetRemainingDuration() const +{ + return m_expire_time - std::chrono::system_clock::now(); +} + +void Expedition::CheckExpireWarning() +{ + if (m_warning_cooldown_timer.Check(false)) + { + using namespace std::chrono_literals; + auto remaining = GetRemainingDuration(); + if ((remaining > 14min && remaining < 15min) || + (remaining > 4min && remaining < 5min) || + (remaining > 0min && remaining < 1min)) + { + int minutes = std::chrono::duration_cast(remaining).count() + 1; + SendZonesExpireWarning(minutes); + m_warning_cooldown_timer.Start(70000); // 1 minute 10 seconds + } + } +} + void ExpeditionCache::LoadActiveExpeditions() { BenchTimer benchmark; @@ -205,6 +238,10 @@ void ExpeditionCache::Process() it->SetPendingDelete(true); } + else + { + it->CheckExpireWarning(); + } it = is_deleted ? m_expeditions.erase(it) : it + 1; } diff --git a/world/expedition.h b/world/expedition.h index f628c71a0..02a460f6e 100644 --- a/world/expedition.h +++ b/world/expedition.h @@ -79,6 +79,7 @@ public: void AddMember(uint32_t character_id) { m_member_ids.emplace(character_id); } void RemoveMember(uint32_t character_id) { m_member_ids.erase(character_id); } void RemoveAllMembers() { m_member_ids.clear(); } + void CheckExpireWarning(); uint32_t GetID() const { return m_expedition_id; } uint16_t GetInstanceID() const { return static_cast(m_dz_instance_id); } uint16_t GetZoneID() const { return static_cast(m_dz_zone_id); } @@ -87,14 +88,17 @@ public: bool IsPendingDelete() const { return m_pending_delete; } void SendZonesDurationUpdate(); void SendZonesExpeditionDeleted(); + void SendZonesExpireWarning(uint32_t minutes_remaining); void SetPendingDelete(bool pending) { m_pending_delete = pending; } void UpdateDzSecondsRemaining(uint32_t seconds_remaining); + std::chrono::system_clock::duration GetRemainingDuration() const; private: uint32_t m_expedition_id = 0; uint32_t m_dz_instance_id = 0; uint32_t m_dz_zone_id = 0; bool m_pending_delete = false; + Timer m_warning_cooldown_timer; std::unordered_set m_member_ids; std::chrono::seconds m_duration; std::chrono::time_point m_start_time; diff --git a/zone/expedition.cpp b/zone/expedition.cpp index f2fcd808a..d1713bc40 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -1742,16 +1742,6 @@ void Expedition::SendWorldSetSecondsRemaining(uint32_t seconds_remaining) worldserver.SendPacket(pack.get()); } -void Expedition::SendWorldExpireWarning(uint32_t minutes_remaining) -{ - uint32_t pack_size = sizeof(ServerExpeditionExpireWarning_Struct); - auto pack = std::unique_ptr(new ServerPacket(ServerOP_ExpeditionExpireWarning, pack_size)); - auto buf = reinterpret_cast(pack->pBuffer); - buf->expedition_id = GetID(); - buf->minutes_remaining = minutes_remaining; - worldserver.SendPacket(pack.get()); -} - void Expedition::AddLockoutByCharacterID( uint32_t character_id, const std::string& expedition_name, const std::string& event_name, uint32_t seconds, const std::string& uuid) diff --git a/zone/expedition.h b/zone/expedition.h index d8efb3052..1c8ee5ec5 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -142,7 +142,6 @@ public: void SetLootEventBySpawnID(uint32_t spawn_id, const std::string& event_name); void SendClientExpeditionInfo(Client* client); - void SendWorldExpireWarning(uint32_t minutes); void SendWorldPendingInvite(const ExpeditionInvite& invite, const std::string& add_name); void DzAddPlayer(Client* requester, const std::string& add_char_name, const std::string& swap_remove_name = {}); diff --git a/zone/zone.cpp b/zone/zone.cpp index a4bd6cabe..23e25c280 100755 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1524,16 +1524,13 @@ bool Zone::Process() { if (minutes_warning > 0) { + // expedition expire warnings are handled by world auto expedition = Expedition::FindCachedExpeditionByZoneInstance(GetZoneID(), GetInstanceID()); - if (expedition) - { - expedition->SendWorldExpireWarning(minutes_warning); - } - else + if (!expedition) { entity_list.ExpeditionWarning(minutes_warning); + Instance_Warning_timer = new Timer(10000); } - Instance_Warning_timer = new Timer(10000); } } else if(Instance_Warning_timer->Check())