diff --git a/common/servertalk.h b/common/servertalk.h index 595f9d02e..ab9ff17ca 100644 --- a/common/servertalk.h +++ b/common/servertalk.h @@ -2034,6 +2034,7 @@ struct ServerExpeditionMemberStatus_Struct { }; struct ServerExpeditionCharacterEntry_Struct { + uint32 expedition_id; uint32 character_id; uint32 character_zone_id; uint16 character_instance_id; @@ -2041,7 +2042,6 @@ struct ServerExpeditionCharacterEntry_Struct { }; struct ServerExpeditionCharacters_Struct { - uint32 expedition_id; uint32 sender_zone_id; uint16 sender_instance_id; uint32 count; diff --git a/world/expedition.cpp b/world/expedition.cpp index 58c21a919..1d30fcd67 100644 --- a/world/expedition.cpp +++ b/world/expedition.cpp @@ -510,15 +510,15 @@ void ExpeditionMessage::GetOnlineMembers(ServerPacket* pack) for (uint32_t i = 0; i < buf->count; ++i) { - for (const auto& cle : all_clients) + auto it = std::find_if(all_clients.begin(), all_clients.end(), [&](const ClientListEntry* cle) { + return (cle && cle->CharID() == buf->entries[i].character_id); + }); + + if (it != all_clients.end()) { - if (cle && cle->CharID() == buf->entries[i].character_id) - { - buf->entries[i].character_zone_id = cle->zone(); - buf->entries[i].character_instance_id = cle->instance(); - buf->entries[i].character_online = true; - break; - } + buf->entries[i].character_zone_id = (*it)->zone(); + buf->entries[i].character_instance_id = (*it)->instance(); + buf->entries[i].character_online = true; } } diff --git a/zone/expedition.cpp b/zone/expedition.cpp index 2938882d4..ef7ea5b73 100644 --- a/zone/expedition.cpp +++ b/zone/expedition.cpp @@ -155,6 +155,7 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) std::vector expedition_ids; std::vector instance_ids; + std::vector> expedition_character_ids; using col = LoadExpeditionColumns::eLoadExpeditionColumns; @@ -170,7 +171,6 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) // finished parsing previous expedition members, send member updates if (current_expedition) { - current_expedition->SendWorldGetOnlineMembers(); current_expedition->SendUpdatesToZoneMembers(); } @@ -213,16 +213,19 @@ void Expedition::CacheExpeditions(MySQLRequestResult& results) current_expedition->AddInternalMember( row[col::member_name], member_id, ExpeditionMemberStatus::Offline, is_current_member ); + expedition_character_ids.emplace_back(std::make_pair(expedition_id, member_id)); } } // update for the last cached expedition if (current_expedition) { - current_expedition->SendWorldGetOnlineMembers(); current_expedition->SendUpdatesToZoneMembers(); } + // ask world for online members from all cached expeditions at once + Expedition::SendWorldGetOnlineMembers(expedition_character_ids); + // bulk load dynamic zone data and expedition lockouts for cached expeditions auto dynamic_zones = DynamicZone::LoadMultipleDzFromDatabase(instance_ids); auto expedition_lockouts = ExpeditionDatabase::LoadMultipleExpeditionLockouts(expedition_ids); @@ -1554,21 +1557,22 @@ void Expedition::SendWorldSettingChanged(uint16_t server_opcode, bool setting_va worldserver.SendPacket(pack.get()); } -void Expedition::SendWorldGetOnlineMembers() +void Expedition::SendWorldGetOnlineMembers( + const std::vector>& expedition_character_ids) { - // request online status of all characters in our expedition tracked by world - uint32_t count = static_cast(m_members.size()); + // request online status of characters + uint32_t count = static_cast(expedition_character_ids.size()); uint32_t entries_size = sizeof(ServerExpeditionCharacterEntry_Struct) * count; uint32_t pack_size = sizeof(ServerExpeditionCharacters_Struct) + entries_size; auto pack = std::unique_ptr(new ServerPacket(ServerOP_ExpeditionGetOnlineMembers, pack_size)); auto buf = reinterpret_cast(pack->pBuffer); - buf->expedition_id = GetID(); buf->sender_zone_id = zone ? zone->GetZoneID() : 0; buf->sender_instance_id = zone ? zone->GetInstanceID() : 0; buf->count = count; for (uint32_t i = 0; i < buf->count; ++i) { - buf->entries[i].character_id = m_members[i].char_id; + buf->entries[i].expedition_id = expedition_character_ids[i].first; + buf->entries[i].character_id = expedition_character_ids[i].second; buf->entries[i].character_zone_id = 0; buf->entries[i].character_instance_id = 0; buf->entries[i].character_online = false; @@ -1725,14 +1729,14 @@ void Expedition::HandleWorldMessage(ServerPacket* pack) } case ServerOP_ExpeditionGetOnlineMembers: { - // reply from world for online member statuses request + // reply from world for online member statuses request (for multiple expeditions) auto buf = reinterpret_cast(pack->pBuffer); - auto expedition = Expedition::FindCachedExpeditionByID(buf->expedition_id); - if (expedition) + for (uint32_t i = 0; i < buf->count; ++i) { - for (uint32_t i = 0; i < buf->count; ++i) + auto member = reinterpret_cast(&buf->entries[i]); + auto expedition = Expedition::FindCachedExpeditionByID(member->expedition_id); + if (expedition) { - auto member = reinterpret_cast(&buf->entries[i]); auto is_online = member->character_online; auto status = is_online ? ExpeditionMemberStatus::Online : ExpeditionMemberStatus::Offline; if (is_online && expedition->GetDynamicZone().IsInstanceID(member->character_instance_id)) diff --git a/zone/expedition.h b/zone/expedition.h index 11bc6fda4..0e58e18a5 100644 --- a/zone/expedition.h +++ b/zone/expedition.h @@ -74,7 +74,6 @@ public: static void CacheFromDatabase(uint32_t expedition_id); static bool CacheAllFromDatabase(); - static void CacheExpeditions(MySQLRequestResult& results); static Expedition* FindCachedExpeditionByCharacterID(uint32_t character_id); static Expedition* FindCachedExpeditionByCharacterName(const std::string& char_name); static Expedition* FindCachedExpeditionByID(uint32_t expedition_id); @@ -135,6 +134,9 @@ public: static const uint32_t EVENT_TIMER_ID; private: + static void CacheExpeditions(MySQLRequestResult& results); + static void SendWorldGetOnlineMembers(const std::vector>& expedition_character_ids); + void AddInternalLockout(ExpeditionLockoutTimer&& lockout_timer); void AddInternalMember(const std::string& char_name, uint32_t char_id, ExpeditionMemberStatus status, bool is_current_member = true); bool ChooseNewLeader(); @@ -152,7 +154,6 @@ private: void SendUpdatesToZoneMembers(bool clear = false, bool message_on_clear = true); void SendWorldDzLocationUpdate(uint16_t server_opcode, const DynamicZoneLocation& location); void SendWorldExpeditionUpdate(uint16_t server_opcode); - void SendWorldGetOnlineMembers(); 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 std::string& event_name, uint64_t expire_time, uint32_t duration, bool remove = false);