From e1df72d64d985061c4d276ee08d0c57b893cec05 Mon Sep 17 00:00:00 2001 From: Chris Miles Date: Fri, 3 Sep 2021 19:47:25 -0500 Subject: [PATCH] [Hitpoints] Remove HP Update Throttling (#1517) * Remove HP update throttling and increase HP update resolution and accuracy * Make some log statements detail * Add better logging messages * Remove old self update throttle block check preventing updates to self --- zone/client.cpp | 4 +- zone/client.h | 2 - zone/client_process.cpp | 5 +- zone/mob.cpp | 110 ++++++++++++++++------------------------ 4 files changed, 48 insertions(+), 73 deletions(-) diff --git a/zone/client.cpp b/zone/client.cpp index 7b499c62a..499fc659f 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -169,8 +169,6 @@ Client::Client(EQStreamInterface* ieqs) last_region_type(RegionTypeUnsupported), m_dirtyautohaters(false), mob_close_scan_timer(6000), - hp_self_update_throttle_timer(300), - hp_other_update_throttle_timer(500), position_update_timer(10000), consent_throttle_timer(2000), tmSitting(0) @@ -2503,7 +2501,7 @@ uint16 Client::GetMaxSkillAfterSpecializationRules(EQ::skills::SkillType skillid uint16 PrimarySpecialization = 0, SecondaryForte = 0; uint16 PrimarySkillValue = 0, SecondarySkillValue = 0; - + uint16 MaxSpecializations = aabonuses.SecondaryForte ? 2 : 1; if (skillid >= EQ::skills::SkillSpecializeAbjure && skillid <= EQ::skills::SkillSpecializeEvocation) diff --git a/zone/client.h b/zone/client.h index f9d0e724c..11cbac385 100644 --- a/zone/client.h +++ b/zone/client.h @@ -1818,8 +1818,6 @@ private: Timer helm_toggle_timer; Timer aggro_meter_timer; Timer mob_close_scan_timer; - Timer hp_self_update_throttle_timer; /* This is to prevent excessive packet sending under trains/fast combat */ - Timer hp_other_update_throttle_timer; /* This is to keep clients from DOSing the server with macros that change client targets constantly */ Timer position_update_timer; /* Timer used when client hasn't updated within a 10 second window */ Timer consent_throttle_timer; Timer dynamiczone_removal_timer; diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 2739db30f..428c734ab 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -119,8 +119,9 @@ bool Client::Process() { // SendHPUpdate calls hpupdate_timer.Start so it can delay this timer, so lets not reset with the check // since the function will anyways - if (hpupdate_timer.Check(false)) + if (hpupdate_timer.Check(false)) { SendHPUpdate(); + } /* I haven't naturally updated my position in 10 seconds, updating manually */ if (!is_client_moving && position_update_timer.Check()) { @@ -466,7 +467,7 @@ bool Client::Process() { if (gravity_timer.Check()) DoGravityEffect(); } - + if (shield_timer.Check()) { ShieldAbilityFinish(); } diff --git a/zone/mob.cpp b/zone/mob.cpp index 0e7314951..58ac71d21 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1355,82 +1355,72 @@ void Mob::CreateHPPacket(EQApplicationPacket* app) } } -void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/) { +void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= false*/) +{ - /** - * If our HP is different from last HP update call - let's update selves - */ + // If our HP is different from last HP update call - let's update selves if (IsClient()) { - // delay to allow the client to catch up on buff states + // delay allowing the client to catch up on buff states if (max_hp != last_max_hp) { - last_max_hp = max_hp; - CastToClient()->hp_self_update_throttle_timer.Trigger(); - return; } if (current_hp != last_hp || force_update_all) { - /** - * This is to prevent excessive packet sending under trains/fast combat - */ - if (this->CastToClient()->hp_self_update_throttle_timer.Check() || force_update_all) { - Log(Logs::General, Logs::HPUpdate, - "Mob::SendHPUpdate :: Update HP of self (%s) HP: %i/%i last: %i/%i skip_self: %s", - this->GetCleanName(), - current_hp, - max_hp, - last_hp, - last_max_hp, - (skip_self ? "true" : "false") - ); + // This is to prevent excessive packet sending under trains/fast combat + LogHPUpdate( + "[SendHPUpdate] Update HP of self [{}] HP: [{}/{}] last: [{}/{}] skip_self: [{}]", + GetCleanName(), + current_hp, + max_hp, + last_hp, + last_max_hp, + (skip_self ? "true" : "false") + ); - if (!skip_self || this->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD) { - auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); - auto *hp_packet_client = (SpawnHPUpdate_Struct *) client_packet->pBuffer; + if (!skip_self || this->CastToClient()->ClientVersion() >= EQ::versions::ClientVersion::SoD) { + auto client_packet = new EQApplicationPacket(OP_HPUpdate, sizeof(SpawnHPUpdate_Struct)); + auto *hp_packet_client = (SpawnHPUpdate_Struct *) client_packet->pBuffer; - hp_packet_client->cur_hp = static_cast(CastToClient()->GetHP() - itembonuses.HP); - hp_packet_client->spawn_id = GetID(); - hp_packet_client->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; + hp_packet_client->cur_hp = static_cast(CastToClient()->GetHP() - itembonuses.HP); + hp_packet_client->spawn_id = GetID(); + hp_packet_client->max_hp = CastToClient()->GetMaxHP() - itembonuses.HP; - CastToClient()->QueuePacket(client_packet); + CastToClient()->QueuePacket(client_packet); - safe_delete(client_packet); + safe_delete(client_packet); - ResetHPUpdateTimer(); - } - - /** - * Used to check if HP has changed to update self next round - */ - last_hp = current_hp; + ResetHPUpdateTimer(); } + + // Used to check if HP has changed to update self next round + last_hp = current_hp; } } auto current_hp_percent = GetIntHPRatio(); - Log(Logs::General, - Logs::HPUpdate, - "Mob::SendHPUpdate :: SendHPUpdate %s HP is %i last %i", - this->GetCleanName(), + LogHPUpdateDetail( + "[SendHPUpdate] Client [{}] HP is [{}] last [{}]", + GetCleanName(), current_hp_percent, - last_hp_percent); + last_hp_percent + ); if (current_hp_percent == last_hp_percent && !force_update_all) { - Log(Logs::General, Logs::HPUpdate, "Mob::SendHPUpdate :: Same HP - skipping update"); + LogHPUpdateDetail("[SendHPUpdate] Same HP for mob [{}] skipping update", GetCleanName()); ResetHPUpdateTimer(); return; } else { if (IsClient() && RuleB(Character, MarqueeHPUpdates)) { - this->CastToClient()->SendHPUpdateMarquee(); + CastToClient()->SendHPUpdateMarquee(); } - Log(Logs::General, Logs::HPUpdate, "Mob::SendHPUpdate :: HP Changed - Send update"); + LogHPUpdate("[SendHPUpdate] HP Changed for mob [{}] send update", GetCleanName()); last_hp_percent = current_hp_percent; } @@ -1440,24 +1430,16 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal CreateHPPacket(&hp_packet); - /** - * Update those who have us targeted - */ + // update those who have us targeted entity_list.QueueClientsByTarget(this, &hp_packet, false, 0, false, true, EQ::versions::maskAllClients); - /** - * Update those who have us on x-target - */ + // Update those who have us on x-target entity_list.QueueClientsByXTarget(this, &hp_packet, false); - /** - * Update groups using Group LAA health name tag counter - */ + // Update groups using Group LAA health name tag counter entity_list.QueueToGroupsForNPCHealthAA(this, &hp_packet); - /** - * Group - */ + // Group if (IsGrouped()) { group = entity_list.GetGroupByMob(this); if (group) { @@ -1465,9 +1447,7 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal } } - /** - * Raid - */ + // Raid if (IsClient()) { Raid *raid = entity_list.GetRaidByClient(CastToClient()); if (raid) { @@ -1475,9 +1455,7 @@ void Mob::SendHPUpdate(bool skip_self /*= false*/, bool force_update_all /*= fal } } - /** - * Pet - */ + // Pet if (GetOwner() && GetOwner()->IsClient()) { GetOwner()->CastToClient()->QueuePacket(&hp_packet, false); group = entity_list.GetGroupByClient(GetOwner()->CastToClient()); @@ -3282,8 +3260,8 @@ void Mob::SetTarget(Mob *mob) else if (IsClient()) { parse->EventPlayer(EVENT_TARGET_CHANGE, CastToClient(), "", 0); - if (this->CastToClient()->admin > 200) { - this->DisplayInfo(mob); + if (CastToClient()->admin > 200) { + DisplayInfo(mob); } #ifdef BOTS @@ -3295,8 +3273,8 @@ void Mob::SetTarget(Mob *mob) GetOwner()->CastToClient()->UpdateXTargetType(MyPetTarget, mob); } - if (this->IsClient() && this->GetTarget() && this->CastToClient()->hp_other_update_throttle_timer.Check()) { - this->GetTarget()->SendHPUpdate(false, true); + if (IsClient() && GetTarget()) { + GetTarget()->SendHPUpdate(false, true); } }