diff --git a/common/servertalk.h b/common/servertalk.h index ab9ff17ca..80185ea05 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -2055,6 +2055,7 @@ struct ServerExpeditionLockout_Struct { uint32 sender_zone_id; uint16 sender_instance_id; uint8 remove; + uint8 members_only; char event_name[256]; }; diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 3ed57a099..eaa90c382 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -448,15 +448,34 @@ void Expedition::AddReplayLockout(uint32_t seconds) void Expedition::AddLockout(const std::string& event_name, uint32_t seconds) { - // any current lockouts for the event are updated with new expiration time ExpeditionLockoutTimer lockout{m_uuid, m_expedition_name, event_name, 0, seconds}; lockout.Reset(); // sets expire time + AddLockout(lockout); +} - ExpeditionDatabase::InsertLockout(m_id, lockout); +void Expedition::AddLockout(const ExpeditionLockoutTimer& lockout, bool members_only) +{ + if (!members_only) + { + ExpeditionDatabase::InsertLockout(m_id, lockout); + } ExpeditionDatabase::InsertMembersLockout(m_members, lockout); - ProcessLockoutUpdate(lockout, false); - SendWorldLockoutUpdate(lockout, false); + ProcessLockoutUpdate(lockout, false, members_only); + SendWorldLockoutUpdate(lockout, false, members_only); +} + +void Expedition::UpdateLockoutDuration( + const std::string& event_name, uint32_t seconds, bool members_only) +{ + // some live expeditions update existing lockout timers during progression + auto it = m_lockouts.find(event_name); + if (it != m_lockouts.end()) + { + uint64_t expire_time = it->second.GetStartTime() + seconds; + ExpeditionLockoutTimer lockout{m_uuid, m_expedition_name, event_name, expire_time, seconds}; + AddLockout(lockout, members_only); + } } void Expedition::RemoveLockout(const std::string& event_name) @@ -1223,15 +1242,19 @@ void Expedition::ProcessMemberRemoved(std::string removed_char_name, uint32_t re ); } -void Expedition::ProcessLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove) +void Expedition::ProcessLockoutUpdate( + const ExpeditionLockoutTimer& lockout, bool remove, bool members_only) { - if (!remove) + if (!members_only) { - m_lockouts[lockout.GetEventName()] = lockout; - } - else - { - m_lockouts.erase(lockout.GetEventName()); + if (!remove) + { + m_lockouts[lockout.GetEventName()] = lockout; + } + else + { + m_lockouts.erase(lockout.GetEventName()); + } } for (const auto& member : m_members) @@ -1453,7 +1476,7 @@ void Expedition::SendWorldLeaderChanged() } void Expedition::SendWorldLockoutUpdate( - const ExpeditionLockoutTimer& lockout, bool remove) + const ExpeditionLockoutTimer& lockout, bool remove, bool members_only) { uint32_t pack_size = sizeof(ServerExpeditionLockout_Struct); auto pack = std::unique_ptr(new ServerPacket(ServerOP_ExpeditionLockout, pack_size)); @@ -1464,6 +1487,7 @@ void Expedition::SendWorldLockoutUpdate( buf->sender_zone_id = zone ? zone->GetZoneID() : 0; buf->sender_instance_id = zone ? zone->GetInstanceID() : 0; buf->remove = remove; + buf->members_only = members_only; strn0cpy(buf->event_name, lockout.GetEventName().c_str(), sizeof(buf->event_name)); worldserver.SendPacket(pack.get()); } @@ -1655,7 +1679,7 @@ void Expedition::HandleWorldMessage(ServerPacket* pack) ExpeditionLockoutTimer lockout{ expedition->GetUUID(), expedition->GetName(), buf->event_name, buf->expire_time, buf->duration }; - expedition->ProcessLockoutUpdate(lockout, buf->remove); + expedition->ProcessLockoutUpdate(lockout, buf->remove, buf->members_only); } } break; diff --git a/zone/expedition.h b/zone/expedition.h index 53cc32306..5e9d4c28f 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -109,6 +109,7 @@ public: bool HasReplayLockout(); void RemoveLockout(const std::string& event_name); void SetReplayLockoutOnMemberJoin(bool add_on_join, bool update_db = false); + void UpdateLockoutDuration(const std::string& event_name, uint32_t seconds, bool members_only = true); bool CanClientLootCorpse(Client* client, uint32_t npc_type_id, uint32_t spawn_id); std::string GetLootEventByNPCTypeID(uint32_t npc_id); @@ -143,12 +144,13 @@ private: static void CacheExpeditions(MySQLRequestResult& results); static void SendWorldGetOnlineMembers(const std::vector>& expedition_character_ids); + void AddLockout(const ExpeditionLockoutTimer& lockout, bool members_only = false); void AddInternalMember(const std::string& char_name, uint32_t char_id, ExpeditionMemberStatus status); bool ChooseNewLeader(); bool ConfirmLeaderCommand(Client* requester); bool ProcessAddConflicts(Client* leader_client, Client* add_client, bool swapping); void ProcessLeaderChanged(uint32_t new_leader_id, const std::string& new_leader_name); - void ProcessLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove); + void ProcessLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove, bool members_only = false); void ProcessMakeLeader(Client* old_leader, Client* new_leader, const std::string& new_leader_name, bool is_online); void ProcessMemberAdded(std::string added_char_name, uint32_t added_char_id); void ProcessMemberRemoved(std::string removed_char_name, uint32_t removed_char_id); @@ -161,7 +163,7 @@ private: void SendWorldExpeditionUpdate(uint16_t server_opcode); void SendWorldAddPlayerInvite(const std::string& inviter_name, const std::string& swap_remove_name, const std::string& add_name, bool pending = false); void SendWorldLeaderChanged(); - void SendWorldLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove); + void SendWorldLockoutUpdate(const ExpeditionLockoutTimer& lockout, bool remove, bool members_only = false); void SendWorldMakeLeaderRequest(const std::string& requester_name, const std::string& new_leader_name); void SendWorldMemberChanged(const std::string& char_name, uint32_t char_id, bool remove); void SendWorldMemberStatus(uint32_t character_id, ExpeditionMemberStatus status); diff --git a/zone/expedition_lockout_timer.h b/zone/expedition_lockout_timer.h index af3042b0c..5325d0f78 100644 --- a/zone/expedition_lockout_timer.h +++ b/zone/expedition_lockout_timer.h @@ -43,6 +43,7 @@ public: uint32_t GetDuration() const { return static_cast(m_duration.count()); } uint64_t GetExpireTime() const { return std::chrono::system_clock::to_time_t(m_expire_time); } + uint64_t GetStartTime() const { return std::chrono::system_clock::to_time_t(m_expire_time - m_duration); } uint32_t GetSecondsRemaining() const; DaysHoursMinutes GetDaysHoursMinutesRemaining() const; const std::string& GetExpeditionName() const { return m_expedition_name; } diff --git a/zone/lua_expedition.cpp b/zone/lua_expedition.cpp index c819b4092..55abece45 100644 --- a/zone/lua_expedition.cpp +++ b/zone/lua_expedition.cpp @@ -180,6 +180,16 @@ void Lua_Expedition::SetZoneInLocation(float x, float y, float z, float heading) self->SetDzZoneInLocation(x, y, z, heading, true); } +void Lua_Expedition::UpdateLockoutDuration(std::string event_name, uint32_t duration) { + Lua_Safe_Call_Void(); + self->UpdateLockoutDuration(event_name, duration); +} + +void Lua_Expedition::UpdateLockoutDuration(std::string event_name, uint32_t duration, bool members_only) { + Lua_Safe_Call_Void(); + self->UpdateLockoutDuration(event_name, duration, members_only); +} + luabind::scope lua_register_expedition() { return luabind::class_("Expedition") .def(luabind::constructor<>()) @@ -211,7 +221,9 @@ luabind::scope lua_register_expedition() { .def("SetReplayLockoutOnMemberJoin", (void(Lua_Expedition::*)(bool))&Lua_Expedition::SetReplayLockoutOnMemberJoin) .def("SetSafeReturn", (void(Lua_Expedition::*)(uint32_t, float, float, float, float))&Lua_Expedition::SetSafeReturn) .def("SetSafeReturn", (void(Lua_Expedition::*)(std::string, float, float, float, float))&Lua_Expedition::SetSafeReturn) - .def("SetZoneInLocation", (void(Lua_Expedition::*)(float, float, float, float))&Lua_Expedition::SetZoneInLocation); + .def("SetZoneInLocation", (void(Lua_Expedition::*)(float, float, float, float))&Lua_Expedition::SetZoneInLocation) + .def("UpdateLockoutDuration", (void(Lua_Expedition::*)(std::string, uint32_t))&Lua_Expedition::UpdateLockoutDuration) + .def("UpdateLockoutDuration", (void(Lua_Expedition::*)(std::string, uint32_t, bool))&Lua_Expedition::UpdateLockoutDuration); } #endif // LUA_EQEMU diff --git a/zone/lua_expedition.h b/zone/lua_expedition.h index 09881bf0f..adc54a65a 100644 --- a/zone/lua_expedition.h +++ b/zone/lua_expedition.h @@ -79,6 +79,8 @@ public: void SetSafeReturn(uint32_t zone_id, float x, float y, float z, float heading); void SetSafeReturn(std::string zone_name, float x, float y, float z, float heading); void SetZoneInLocation(float x, float y, float z, float heading); + void UpdateLockoutDuration(std::string event_name, uint32_t duration); + void UpdateLockoutDuration(std::string event_name, uint32_t duration, bool members_only); }; #endif // LUA_EQEMU