mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-16 22:58:34 +00:00
[DynamicZones] Bulk request dz member statuses on zone boot (#4769)
When dynamic zones are cached on zone boot each dz requests member statuses from world separately. This causes a lot of network traffic between world and booted zones when there are a lot of active dzs. This changes it to make a single request to world on zone boot and a single bulk reply back.
This commit is contained in:
+44
-1
@@ -25,6 +25,7 @@
|
||||
#include "worldserver.h"
|
||||
#include "../common/repositories/character_expedition_lockouts_repository.h"
|
||||
#include "../common/repositories/dynamic_zone_lockouts_repository.h"
|
||||
#include <cereal/types/utility.hpp>
|
||||
|
||||
extern WorldServer worldserver;
|
||||
|
||||
@@ -162,14 +163,28 @@ void DynamicZone::CacheAllFromDatabase()
|
||||
}
|
||||
}
|
||||
|
||||
dz->UpdateMembers();
|
||||
zone->dynamic_zone_cache.emplace(dz_id, std::move(dz));
|
||||
}
|
||||
|
||||
if (!zone->dynamic_zone_cache.empty())
|
||||
{
|
||||
RequestMemberStatuses();
|
||||
}
|
||||
|
||||
LogInfo("Loaded [{}] dynamic zone(s)", Strings::Commify(zone->dynamic_zone_cache.size()));
|
||||
LogDynamicZones("Caching [{}] dynamic zone(s) took [{}s]", zone->dynamic_zone_cache.size(), bench.elapsed());
|
||||
}
|
||||
|
||||
void DynamicZone::RequestMemberStatuses()
|
||||
{
|
||||
ServerPacket pack(ServerOP_DzGetBulkMemberStatuses, sizeof(ServerDzCerealData_Struct));
|
||||
auto buf = reinterpret_cast<ServerDzCerealData_Struct*>(pack.pBuffer);
|
||||
buf->zone_id = static_cast<uint16_t>(zone->GetZoneID());
|
||||
buf->inst_id = static_cast<uint16_t>(zone->GetInstanceID());
|
||||
|
||||
worldserver.SendPacket(&pack);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
DynamicZone* FindDynamicZone(T pred)
|
||||
{
|
||||
@@ -849,6 +864,34 @@ void DynamicZone::HandleWorldMessage(ServerPacket* pack)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_DzGetBulkMemberStatuses:
|
||||
{
|
||||
if (zone)
|
||||
{
|
||||
std::vector<std::pair<uint32_t, std::vector<DynamicZoneMember>>> dzs;
|
||||
dzs.reserve(zone->dynamic_zone_cache.size());
|
||||
|
||||
auto buf = reinterpret_cast<ServerDzCerealData_Struct*>(pack->pBuffer);
|
||||
EQ::Util::MemoryStreamReader ss(buf->cereal_data, buf->cereal_size);
|
||||
{
|
||||
cereal::BinaryInputArchive archive(ss);
|
||||
archive(dzs);
|
||||
}
|
||||
|
||||
for (const auto& [dz_id, members] : dzs)
|
||||
{
|
||||
if (auto dz = DynamicZone::FindDynamicZoneByID(dz_id))
|
||||
{
|
||||
for (const auto& member : members)
|
||||
{
|
||||
dz->SetInternalMemberStatus(member.id, member.status);
|
||||
}
|
||||
dz->m_has_member_statuses = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ServerOP_DzUpdateMemberStatus:
|
||||
{
|
||||
auto buf = reinterpret_cast<ServerDzMemberStatus_Struct*>(pack->pBuffer);
|
||||
|
||||
+2
-1
@@ -92,13 +92,13 @@ public:
|
||||
void SendMemberNameToZoneMembers(const std::string& char_name, bool remove);
|
||||
void SendMemberStatusToZoneMembers(const DynamicZoneMember& member);
|
||||
void SetLocked(bool lock, bool update_db = false, DzLockMsg lock_msg = DzLockMsg::None, uint32_t color = Chat::Yellow);
|
||||
void UpdateMembers();
|
||||
|
||||
std::string GetLootEvent(uint32_t id, DzLootEvent::Type type) const;
|
||||
void SetLootEvent(uint32_t id, const std::string& event, DzLootEvent::Type type);
|
||||
|
||||
private:
|
||||
static void StartAllClientRemovalTimers();
|
||||
static void RequestMemberStatuses();
|
||||
|
||||
uint16_t GetCurrentInstanceID() const override;
|
||||
uint16_t GetCurrentZoneID() const override;
|
||||
@@ -125,6 +125,7 @@ private:
|
||||
void SendWorldPlayerInvite(const std::string& inviter, const std::string& swap_name, const std::string& add_name, bool pending = false);
|
||||
void SetUpdatedDuration(uint32_t seconds);
|
||||
void TryAddClient(Client* add_client, const std::string& inviter, const std::string& swap_name, Client* leader = nullptr);
|
||||
void UpdateMembers();
|
||||
|
||||
std::unique_ptr<EQApplicationPacket> CreateExpireWarningPacket(uint32_t minutes_remaining);
|
||||
std::unique_ptr<EQApplicationPacket> CreateInfoPacket(bool clear = false);
|
||||
|
||||
@@ -3410,6 +3410,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
|
||||
case ServerOP_DzRemoveAllMembers:
|
||||
case ServerOP_DzDurationUpdate:
|
||||
case ServerOP_DzGetMemberStatuses:
|
||||
case ServerOP_DzGetBulkMemberStatuses:
|
||||
case ServerOP_DzSetCompass:
|
||||
case ServerOP_DzSetSafeReturn:
|
||||
case ServerOP_DzSetZoneIn:
|
||||
|
||||
Reference in New Issue
Block a user