Skip to content

Commit

Permalink
Mob position updates now completely only send to 600 units range defi…
Browse files Browse the repository at this point in the history
…ned 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
  • Loading branch information
Akkadius committed Jul 11, 2017
1 parent dceb79a commit ec00daa
Show file tree
Hide file tree
Showing 7 changed files with 74 additions and 70 deletions.
1 change: 0 additions & 1 deletion common/ruletypes.h
Expand Up @@ -234,7 +234,6 @@ RULE_BOOL(World, StartZoneSameAsBindOnCreation, true) //Should the start zone AL
RULE_CATEGORY_END() RULE_CATEGORY_END()


RULE_CATEGORY(Zone) 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, 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_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. RULE_BOOL(Zone, EnableShadowrest, 1) // enables or disables the shadowrest zone feature for player corpses. Default is turned on.
Expand Down
8 changes: 4 additions & 4 deletions zone/client_packet.cpp
Expand Up @@ -588,10 +588,10 @@ void Client::CompleteConnect()
} }
} }
else { else {
Group *group_update = nullptr; Group *group = nullptr;
group_update = this->GetGroup(); group = this->GetGroup();
if (group_update) if (group)
group_update->SendHPPacketsTo(this); group->SendHPPacketsTo(this);
} }




Expand Down
34 changes: 23 additions & 11 deletions zone/client_process.cpp
Expand Up @@ -256,17 +256,29 @@ bool Client::Process() {


close_npcs.clear(); 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 scan_range = RuleI(Range, ClientNPCScan); float client_update_range = (RuleI(Range, MobPositionUpdates) * RuleI(Range, MobPositionUpdates));
for (auto itr = npc_list.begin(); itr != npc_list.end(); ++itr) {
NPC* npc = itr->second; for (auto itr = mob_list.begin(); itr != mob_list.end(); ++itr) {
float distance = DistanceNoZ(m_Position, npc->GetPosition()); Mob* mob = itr->second;
if(distance <= scan_range) { float distance = DistanceSquared(m_Position, mob->GetPosition());
close_npcs.insert(std::pair<NPC *, float>(npc, distance)); if (mob->IsNPC()) {
if (distance <= scan_range) {
close_npcs.insert(std::pair<NPC *, float>(mob->CastToNPC(), distance));
}
else if (mob->GetAggroRange() > scan_range) {
close_npcs.insert(std::pair<NPC *, float>(mob->CastToNPC(), distance));
}
} }
else if (npc->GetAggroRange() > scan_range) {
close_npcs.insert(std::pair<NPC *, float>(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);
} }
} }
} }
Expand Down Expand Up @@ -455,7 +467,7 @@ bool Client::Process() {
// Send a position packet every 8 seconds - if not done, other clients // Send a position packet every 8 seconds - if not done, other clients
// see this char disappear after 10-12 seconds of inactivity // see this char disappear after 10-12 seconds of inactivity
if (position_timer_counter >= 36) { // Approx. 4 ticks per second 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(); pLastUpdate = Timer::GetCurrentTime();
pLastUpdateWZ = pLastUpdate; pLastUpdateWZ = pLastUpdate;
position_timer_counter = 0; position_timer_counter = 0;
Expand Down
45 changes: 27 additions & 18 deletions zone/entity.cpp
Expand Up @@ -2634,38 +2634,47 @@ void EntityList::RemoveDebuffs(Mob *caster)
// Currently, a new packet is sent per entity. // Currently, a new packet is sent per entity.
// @todo: Come back and use FLAG_COMBINED to pack // @todo: Come back and use FLAG_COMBINED to pack
// all updates into one packet. // all updates into one packet.
void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, float update_range, Entity *always_send, bool iSendEvenIfNotChanged)
float range, Entity *alwayssend, bool iSendEvenIfNotChanged)
{ {
range = range * range; update_range = (update_range * update_range);


EQApplicationPacket *outapp = 0; EQApplicationPacket *outapp = 0;
PlayerPositionUpdateServer_Struct *ppu = 0; PlayerPositionUpdateServer_Struct *ppu = 0;
Mob *mob = 0; Mob *mob = 0;


auto it = mob_list.begin(); auto it = mob_list.begin();
while (it != mob_list.end()) { while (it != mob_list.end()) {
if (outapp == 0) {
outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
}
mob = it->second; mob = it->second;
if (mob && !mob->IsCorpse() && (it->second != client)
if (
mob && !mob->IsCorpse()
&& (it->second != client)
&& (mob->IsClient() || iSendEvenIfNotChanged || (mob->LastChange() >= cLastUpdate)) && (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);

if (outapp == 0) {
outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
ppu = (PlayerPositionUpdateServer_Struct*)outapp->pBuffer;
}


//bool Grouped = client->HasGroup() && mob->IsClient() && (client->GetGroup() == mob->CastToClient()->GetGroup()); mob->MakeSpawnUpdate(ppu);


//if (range == 0 || (iterator.GetData() == alwayssend) || Grouped || (mob->DistNoRootNoZ(*client) <= range)) { safe_delete(outapp);
if (range == 0 || (it->second == alwayssend) || mob->IsClient() || (DistanceSquared(mob->GetPosition(), client->GetPosition()) <= range)) { outapp = 0;
mob->MakeSpawnUpdate(ppu); }
}
if(mob && mob->IsClient() && mob->GetID()>0) {
client->QueuePacket(outapp, false, Client::CLIENT_CONNECTED);
} }
} }
safe_delete(outapp);
outapp = 0;
++it; ++it;
} }


Expand Down
2 changes: 1 addition & 1 deletion zone/entity.h
Expand Up @@ -370,7 +370,7 @@ class EntityList
Mob* FindDefenseNPC(uint32 npcid); Mob* FindDefenseNPC(uint32 npcid);
void OpenDoorsNear(NPC* opener); void OpenDoorsNear(NPC* opener);
void UpdateWho(bool iSendFullUpdate = false); 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); char* MakeNameUnique(char* name);
static char* RemoveNumbers(char* name); static char* RemoveNumbers(char* name);
void SignalMobsByNPCID(uint32 npc_type, int signal_id); void SignalMobsByNPCID(uint32 npc_type, int signal_id);
Expand Down
53 changes: 19 additions & 34 deletions zone/mob.cpp
Expand Up @@ -131,7 +131,6 @@ Mob::Mob(const char* in_name,
SetMoving(false); SetMoving(false);
moved=false; moved=false;
m_RewindLocation = glm::vec3(); m_RewindLocation = glm::vec3();
move_tic_count = 0;


_egnode = nullptr; _egnode = nullptr;
name[0]=0; name[0]=0;
Expand Down Expand Up @@ -1443,8 +1442,7 @@ void Mob::SendPosition()
auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); auto app = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct));
PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer; PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)app->pBuffer;
MakeSpawnUpdateNoDelta(spu); MakeSpawnUpdateNoDelta(spu);
move_tic_count = 0; entity_list.QueueCloseClients(this, app, true, RuleI(Range, MobPositionUpdates), nullptr, false);
entity_list.QueueClients(this, app, true);
safe_delete(app); safe_delete(app);
} }


Expand All @@ -1456,45 +1454,32 @@ void Mob::SendPosUpdate(uint8 iSendToSelf) {


if (iSendToSelf == 2) { if (iSendToSelf == 2) {
if (IsClient()) { if (IsClient()) {
CastToClient()->FastQueuePacket(&app,false); CastToClient()->FastQueuePacket(&app, false);
} }
} }
else else {
{ entity_list.QueueCloseClients(this, app, (iSendToSelf == 0), RuleI(Range, MobPositionUpdates), nullptr, false);
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++;
}
} }
safe_delete(app); safe_delete(app);
} }


// this is for SendPosition() // this is for SendPosition()
void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu){ void Mob::MakeSpawnUpdateNoDelta(PlayerPositionUpdateServer_Struct *spu) {
memset(spu,0xff,sizeof(PlayerPositionUpdateServer_Struct)); memset(spu, 0xff, sizeof(PlayerPositionUpdateServer_Struct));
spu->spawn_id = GetID(); spu->spawn_id = GetID();
spu->x_pos = FloatToEQ19(m_Position.x); spu->x_pos = FloatToEQ19(m_Position.x);
spu->y_pos = FloatToEQ19(m_Position.y); spu->y_pos = FloatToEQ19(m_Position.y);
spu->z_pos = FloatToEQ19(m_Position.z); spu->z_pos = FloatToEQ19(m_Position.z);
spu->delta_x = NewFloatToEQ13(0); spu->delta_x = NewFloatToEQ13(0);
spu->delta_y = NewFloatToEQ13(0); spu->delta_y = NewFloatToEQ13(0);
spu->delta_z = NewFloatToEQ13(0); spu->delta_z = NewFloatToEQ13(0);
spu->heading = FloatToEQ19(m_Position.w); spu->heading = FloatToEQ19(m_Position.w);
spu->animation = 0; spu->animation = 0;
spu->delta_heading = NewFloatToEQ13(0); spu->delta_heading = NewFloatToEQ13(0);
spu->padding0002 =0; spu->padding0002 = 0;
spu->padding0006 =7; spu->padding0006 = 7;
spu->padding0014 =0x7f; spu->padding0014 = 0x7f;
spu->padding0018 =0x5df27; spu->padding0018 = 0x5df27;


} }


Expand Down
1 change: 0 additions & 1 deletion zone/mob.h
Expand Up @@ -1373,7 +1373,6 @@ class Mob : public Entity {
void ClearItemFactionBonuses(); void ClearItemFactionBonuses();


void CalculateFearPosition(); void CalculateFearPosition();
uint32 move_tic_count;


bool flee_mode; bool flee_mode;
Timer flee_timer; Timer flee_timer;
Expand Down

0 comments on commit ec00daa

Please sign in to comment.