[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:
hg
2025-03-11 02:13:29 -04:00
committed by GitHub
parent 84708edccf
commit 051ce3736f
7 changed files with 95 additions and 2 deletions
+37
View File
@@ -7,6 +7,7 @@
#include "zoneserver.h"
#include "../common/rulesys.h"
#include "../common/repositories/dynamic_zone_lockouts_repository.h"
#include <cereal/types/utility.hpp>
extern ClientList client_list;
extern ZSList zoneserver_list;
@@ -169,6 +170,33 @@ void DynamicZoneManager::LoadTemplates()
}
}
void DynamicZoneManager::SendBulkMemberStatuses(uint32_t zone_id, uint16_t inst_id)
{
std::vector<std::pair<uint32_t, std::vector<DynamicZoneMember>>> dzs;
dzs.reserve(dynamic_zone_cache.size());
for (const auto& [dz_id, dz] : dynamic_zone_cache)
{
dzs.emplace_back(dz_id, dz->GetMembers());
}
std::ostringstream ss;
{
cereal::BinaryOutputArchive archive(ss);
archive(dzs);
}
std::string_view sv = ss.view();
size_t size = sizeof(ServerDzCerealData_Struct) + sv.size();
ServerPacket pack(ServerOP_DzGetBulkMemberStatuses, static_cast<uint32_t>(size));
auto buf = reinterpret_cast<ServerDzCerealData_Struct*>(pack.pBuffer);
buf->cereal_size = static_cast<uint32_t>(sv.size());
memcpy(buf->cereal_data, sv.data(), sv.size());
zoneserver_list.SendPacket(zone_id, inst_id, &pack);
}
void DynamicZoneManager::HandleZoneMessage(ServerPacket* pack)
{
switch (pack->opcode)
@@ -338,6 +366,15 @@ void DynamicZoneManager::HandleZoneMessage(ServerPacket* pack)
}
break;
}
case ServerOP_DzGetBulkMemberStatuses:
{
auto buf = reinterpret_cast<ServerDzCerealData_Struct*>(pack->pBuffer);
if (buf->zone_id != 0 && !dynamic_zone_cache.empty())
{
SendBulkMemberStatuses(buf->zone_id, buf->inst_id);
}
break;
}
case ServerOP_DzUpdateMemberStatus:
{
auto buf = reinterpret_cast<ServerDzMemberStatus_Struct*>(pack->pBuffer);