From ec00daa5be0ffbfc61623abc5bc1235f95f7da4d Mon Sep 17 00:00:00 2001 From: Akkadius Date: Mon, 10 Jul 2017 23:03:40 -0500 Subject: [PATCH] Mob position updates now completely only send to 600 units range defined by Range:MobPositionUpdates Client updates nearby clients more often because they will disappear after 10 seconds without a position update to the client This results in a massive reduction in unnecessary traffic as we only update clients of their relevance around them This also resembles live-like packet sending behavior of positions --- common/ruletypes.h | 1 - zone/client_packet.cpp | 8 +++---- zone/client_process.cpp | 32 +++++++++++++++++-------- zone/entity.cpp | 45 ++++++++++++++++++++-------------- zone/entity.h | 2 +- zone/mob.cpp | 53 +++++++++++++++-------------------------- zone/mob.h | 1 - 7 files changed, 73 insertions(+), 69 deletions(-) diff --git a/common/ruletypes.h b/common/ruletypes.h index aac46003d..397f1a832 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -234,7 +234,6 @@ RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone AL RULE_CATEGORY_END() RULE_CATEGORY(Zone) -RULE_INT(Zone, NPCPositonUpdateTicCount, 32) //ms between intervals of sending a position update to the entire zone. RULE_INT(Zone, ClientLinkdeadMS, 180000) //the time a client remains link dead on the server after a sudden disconnection RULE_INT(Zone, GraveyardTimeMS, 1200000) //ms time until a player corpse is moved to a zone's graveyard, if one is specified for the zone RULE_BOOL(Zone, EnableShadowrest, 1) // enables or disables the shadowrest zone feature for player corpses. Default is turned on. diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index daf2e5f97..e4891b999 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -588,10 +588,10 @@ void Client::CompleteConnect() } } else { - Group *group_update = nullptr; - group_update = this->GetGroup(); - if (group_update) - group_update->SendHPPacketsTo(this); + Group *group = nullptr; + group = this->GetGroup(); + if (group) + group->SendHPPacketsTo(this); } diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 583ad627b..a5ced5d1a 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -256,17 +256,29 @@ bool Client::Process() { close_npcs.clear(); - auto &npc_list = entity_list.GetNPCList(); + auto &mob_list = entity_list.GetMobList(); + float scan_range = (RuleI(Range, ClientNPCScan) * RuleI(Range, ClientNPCScan)); + float client_update_range = (RuleI(Range, MobPositionUpdates) * RuleI(Range, MobPositionUpdates)); - float scan_range = RuleI(Range, ClientNPCScan); - for (auto itr = npc_list.begin(); itr != npc_list.end(); ++itr) { - NPC* npc = itr->second; - float distance = DistanceNoZ(m_Position, npc->GetPosition()); - if(distance <= scan_range) { - close_npcs.insert(std::pair(npc, distance)); + for (auto itr = mob_list.begin(); itr != mob_list.end(); ++itr) { + Mob* mob = itr->second; + float distance = DistanceSquared(m_Position, mob->GetPosition()); + if (mob->IsNPC()) { + if (distance <= scan_range) { + close_npcs.insert(std::pair(mob->CastToNPC(), distance)); + } + else if (mob->GetAggroRange() > scan_range) { + close_npcs.insert(std::pair(mob->CastToNPC(), distance)); + } } - else if (npc->GetAggroRange() > scan_range) { - close_npcs.insert(std::pair(npc, distance)); + + /* Clients need to be kept up to date for position updates more often otherwise they disappear */ + if (mob->IsClient() && this != mob && distance <= client_update_range) { + auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + PlayerPositionUpdateServer_Struct* spawn_update = (PlayerPositionUpdateServer_Struct*)app->pBuffer; + mob->MakeSpawnUpdateNoDelta(spawn_update); + this->FastQueuePacket(&app, false); + safe_delete(app); } } } @@ -455,7 +467,7 @@ bool Client::Process() { // Send a position packet every 8 seconds - if not done, other clients // see this char disappear after 10-12 seconds of inactivity if (position_timer_counter >= 36) { // Approx. 4 ticks per second - entity_list.SendPositionUpdates(this, pLastUpdateWZ, 500, GetTarget(), true); + entity_list.SendPositionUpdates(this, pLastUpdateWZ, RuleI(Range, MobPositionUpdates), GetTarget(), true); pLastUpdate = Timer::GetCurrentTime(); pLastUpdateWZ = pLastUpdate; position_timer_counter = 0; diff --git a/zone/entity.cpp b/zone/entity.cpp index 35d67a5d3..eee89ce0f 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -2634,10 +2634,9 @@ void EntityList::RemoveDebuffs(Mob *caster) // Currently, a new packet is sent per entity. // @todo: Come back and use FLAG_COMBINED to pack // all updates into one packet. -void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, - float range, Entity *alwayssend, bool iSendEvenIfNotChanged) +void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, float update_range, Entity *always_send, bool iSendEvenIfNotChanged) { - range = range * range; + update_range = (update_range * update_range); EQApplicationPacket *outapp = 0; PlayerPositionUpdateServer_Struct *ppu = 0; @@ -2645,27 +2644,37 @@ void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, auto it = mob_list.begin(); while (it != mob_list.end()) { - if (outapp == 0) { - outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; - } + mob = it->second; - if (mob && !mob->IsCorpse() && (it->second != client) + + if ( + mob && !mob->IsCorpse() + && (it->second != client) && (mob->IsClient() || iSendEvenIfNotChanged || (mob->LastChange() >= cLastUpdate)) - && (!it->second->IsClient() || !it->second->CastToClient()->GMHideMe(client))) { + && (!it->second->IsClient() || !it->second->CastToClient()->GMHideMe(client)) + ) { + if ( + update_range == 0 + || (it->second == always_send) + || mob->IsClient() + || (DistanceSquared(mob->GetPosition(), client->GetPosition()) <= update_range) + ) { + if (mob && mob->IsClient() && mob->GetID() > 0) { + client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED); - //bool Grouped = client->HasGroup() && mob->IsClient() && (client->GetGroup() == mob->CastToClient()->GetGroup()); + if (outapp == 0) { + outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer; + } - //if (range == 0 || (iterator.GetData() == alwayssend) || Grouped || (mob->DistNoRootNoZ(*client) <= range)) { - if (range == 0 || (it->second == alwayssend) || mob->IsClient() || (DistanceSquared(mob->GetPosition(), client->GetPosition()) <= range)) { - mob->MakeSpawnUpdate(ppu); - } - if(mob && mob->IsClient() && mob->GetID()>0) { - client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED); + mob->MakeSpawnUpdate(ppu); + + safe_delete(outapp); + outapp = 0; + } } } - safe_delete(outapp); - outapp = 0; + ++it; } diff --git a/zone/entity.h b/zone/entity.h index 7752e97b1..16249547b 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -370,7 +370,7 @@ public: Mob* FindDefenseNPC(uint32 npcid); void OpenDoorsNear(NPC* opener); void UpdateWho(bool iSendFullUpdate = false); - void SendPositionUpdates(Client* client, uint32 cLastUpdate = 0, float range = 0, Entity* alwayssend = 0, bool iSendEvenIfNotChanged = false); + void SendPositionUpdates(Client* client, uint32 cLastUpdate = 0, float update_range = 0, Entity* always_send = 0, bool iSendEvenIfNotChanged = false); char* MakeNameUnique(char* name); static char* RemoveNumbers(char* name); void SignalMobsByNPCID(uint32 npc_type, int signal_id); diff --git a/zone/mob.cpp b/zone/mob.cpp index 830ac9a61..256fd7df7 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -131,7 +131,6 @@ Mob::Mob(const char* in_name, SetMoving(false); moved=false; m_RewindLocation = glm::vec3(); - move_tic_count = 0; _egnode = nullptr; name[0]=0; @@ -1443,8 +1442,7 @@ void Mob::SendPosition() auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer; MakeSpawnUpdateNoDelta(spu); - move_tic_count = 0; - entity_list.QueueClients(this, app, true); + entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false); safe_delete(app); } @@ -1456,45 +1454,32 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) { if (iSendToSelf == 2) { if (IsClient()) { - CastToClient()->FastQueuePacket(&app,false); + CastToClient()->FastQueuePacket(&app, false); } } - else - { - if(move_tic_count == RuleI(Zone, NPCPositonUpdateTicCount)) - { - entity_list.QueueClients(this, app, (iSendToSelf == 0), false); - move_tic_count = 0; - } - else if(move_tic_count % 2 == 0) - { - entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false); - move_tic_count++; - } - else { - move_tic_count++; - } + else { + entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false); } safe_delete(app); } // this is for SendPosition() -void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){ - memset(spu,0xff,sizeof(PlayerPositionUpdateServer_Struct)); - spu->spawn_id = GetID(); - spu->x_pos = FloatToEQ19(m_Position.x); - spu->y_pos = FloatToEQ19(m_Position.y); - spu->z_pos = FloatToEQ19(m_Position.z); - spu->delta_x = NewFloatToEQ13(0); - spu->delta_y = NewFloatToEQ13(0); - spu->delta_z = NewFloatToEQ13(0); - spu->heading = FloatToEQ19(m_Position.w); - spu->animation = 0; +void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu) { + memset(spu, 0xff, sizeof(PlayerPositionUpdateServer_Struct)); + spu->spawn_id = GetID(); + spu->x_pos = FloatToEQ19(m_Position.x); + spu->y_pos = FloatToEQ19(m_Position.y); + spu->z_pos = FloatToEQ19(m_Position.z); + spu->delta_x = NewFloatToEQ13(0); + spu->delta_y = NewFloatToEQ13(0); + spu->delta_z = NewFloatToEQ13(0); + spu->heading = FloatToEQ19(m_Position.w); + spu->animation = 0; spu->delta_heading = NewFloatToEQ13(0); - spu->padding0002 =0; - spu->padding0006 =7; - spu->padding0014 =0x7f; - spu->padding0018 =0x5df27; + spu->padding0002 = 0; + spu->padding0006 = 7; + spu->padding0014 = 0x7f; + spu->padding0018 = 0x5df27; } diff --git a/zone/mob.h b/zone/mob.h index c1a300569..27ea48d4f 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1373,7 +1373,6 @@ protected: void ClearItemFactionBonuses(); void CalculateFearPosition(); - uint32 move_tic_count; bool flee_mode; Timer flee_timer;