[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
This commit is contained in:
Chris Miles 2021-09-03 19:47:25 -05:00 committed by GitHub
parent 7f823256f4
commit e1df72d64d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 48 additions and 73 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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();
}

View File

@ -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<uint32>(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<uint32>(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);
}
}