diff --git a/changelog.txt b/changelog.txt index b561c34ab..29747ba45 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,5 +1,20 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50) ------------------------------------------------------- +== 7/9/2017 == +Akkadius: Massive reductions in unnecessary network traffic especially during high spam combat fights + - HP Updates now only send to others when HP percentage changes (0-100%) + - HP Updates were sending excessively even during idle zones when HP wasn't changing at all + - Attack animations now only send once per second versus up to a hundred times a second per Mob/Client + - 17,000 OP_ClientUpdate packets per second have been observed in combat scenarios, some of the major culprits have been + throttled without affecting what the client should see + - Before and After packet differences under similar load/tests (Packets per second) + - 7,000 - 8,000 OP_Animation pps After: 600-800 pps + - 13,0000 - 17,000 OP_MobHealth pps After: 1-10 pps + - 15,0000 - 20,000 OP_ClientUpdate pps After: 500-1,000 pps + - Packet reports from a 46 client test here: + https://gist.github.com/Akkadius/28b7ad2fdd82bdd15ea737c68f404346 + - Servers who use Marquee HP updates will also recieve far less packet spam as they will only be sent when HP changes + == 7/1/2017 == Akkadius: Resolve issues with NPC's hopping to the ceiling in small corridors Akkadius: Improved grounding issues with NPC's during combat diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index ed821831a..7ae5a0296 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -86,6 +86,7 @@ enum LogCategory { Login_Server, Client_Login, Headless_Client, + HP_Update, MaxCategoryID /* Don't Remove this*/ }; @@ -135,7 +136,9 @@ static const char* LogCategoryName[LogCategory::MaxCategoryID] = { "Packet :: Server -> Client (Dump)", "Packet :: Client -> Server (Dump)", "Login Server", - "Client Login" + "Client Login", + "Headless Client", + "HP Update" }; } diff --git a/zone/attack.cpp b/zone/attack.cpp index 819623148..ddd8c04ce 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -137,7 +137,10 @@ EQEmu::skills::SkillType Mob::AttackAnimation(int Hand, const EQEmu::ItemInstanc if (Hand == EQEmu::inventory::slotSecondary) // DW anim type = animDualWield; - DoAnim(type, 0, false); + if (attack_anim_timer.Check()) { + DoAnim(type, 0, false); + } + return skillinuse; } @@ -3397,8 +3400,6 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const SetHP(GetHP() - damage); - if (IsClient() && RuleB(Character, MarqueeHPUpdates)) - this->CastToClient()->SendHPUpdateMarquee(); if (HasDied()) { bool IsSaved = false; @@ -3549,8 +3550,11 @@ void Mob::CommonDamage(Mob* attacker, int &damage, const uint16 spell_id, const if (zone->zonemap && zone->zonemap->CheckLoS(glm::vec3(m_Position), new_pos)) { // If we have LoS on the new loc it should be reachable. if (IsNPC()) { // Is this adequate? + Teleport(new_pos); - SendPosUpdate(); + if (position_update_melee_push_timer.Check()) { + SendPosUpdate(); + } } } else { diff --git a/zone/client.cpp b/zone/client.cpp index 85956ea08..2df13f25b 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -8745,7 +8745,7 @@ void Client::SendHPUpdateMarquee(){ return; /* Health Update Marquee Display: Custom*/ - uint32 health_percentage = (uint32)(this->cur_hp * 100 / this->max_hp); + int8 health_percentage = (int8)(this->cur_hp * 100 / this->max_hp); if (health_percentage == 100) return; diff --git a/zone/mob.cpp b/zone/mob.cpp index 7e04221c3..e795cf040 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -114,7 +114,9 @@ Mob::Mob(const char* in_name, mitigation_ac(0), m_specialattacks(eSpecialAttacks::None), fix_z_timer(300), - fix_z_timer_engaged(100) + fix_z_timer_engaged(100), + attack_anim_timer(1000), + position_update_melee_push_timer(1000) { targeted = 0; tar_ndx=0; @@ -123,6 +125,8 @@ Mob::Mob(const char* in_name, last_z = 0; + last_hp = 100; + AI_Init(); SetMoving(false); moved=false; @@ -1299,6 +1303,20 @@ void Mob::CreateHPPacket(EQApplicationPacket* app) // sends hp update of this mob to people who might care void Mob::SendHPUpdate(bool skip_self) { + + int8 current_hp = (max_hp == 0 ? 0 : static_cast(cur_hp * 100 / max_hp)); + + Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: SendHPUpdate %s HP is %i last %i", this->GetCleanName(), current_hp, last_hp); + if (current_hp == last_hp) { + Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: Same HP - skipping update"); + ResetHPUpdateTimer(); + return; + } + else { + Log(Logs::General, Logs::HP_Update, "Mob::SendHPUpdate :: HP Changed - Send update"); + last_hp = current_hp; + } + EQApplicationPacket hp_app; Group *group = nullptr; diff --git a/zone/mob.h b/zone/mob.h index aa4b3fb29..1d692d977 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -1379,6 +1379,8 @@ protected: Timer flee_timer; Timer fix_z_timer; Timer fix_z_timer_engaged; + Timer attack_anim_timer; + Timer position_update_melee_push_timer; bool pAIControlled; bool roamer; @@ -1387,6 +1389,8 @@ protected: int wandertype; int pausetype; + int8 last_hp; + int cur_wp; glm::vec4 m_CurrentWayPoint; int cur_wp_pause; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 6b3be34d8..633dde297 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -997,17 +997,19 @@ void Mob::AI_Process() { if (engaged) { /* Fix Z when following during pull, not when engaged and stationary */ - if (moving && fix_z_timer_engaged.Check()) + if (moving && fix_z_timer_engaged.Check()) { if (this->GetTarget()) { /* If we are engaged, moving and following client, let's look for best Z more often */ - if (DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()) > 50) { + float target_distance = DistanceNoZ(this->GetPosition(), this->GetTarget()->GetPosition()); + if (target_distance >= 50) { this->FixZ(); } - /* If we are close to client and our Z differences aren't big, match the client */ - else if (std::abs(this->GetZ() - this->GetTarget()->GetZ()) <= 5 && this->GetTarget()->IsClient()) { - this->m_Position.z = this->GetTarget()->GetZ(); + else if (!this->CheckLosFN(this->GetTarget())) { + Mob* target = this->GetTarget(); + this->GMMove(target->GetX(), target->GetY(), target->GetZ(), target->GetHeading()); } } + } if (!(m_PlayerState & static_cast(PlayerState::Aggressive))) SendAddPlayerState(PlayerState::Aggressive); diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 9d272472f..fbbce67b9 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -497,7 +497,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Position.y = new_y; m_Position.z = new_z; - if(fix_z_timer.Check()) + if(fix_z_timer.Check() && !this->IsEngaged()) this->FixZ(); tar_ndx++; @@ -604,7 +604,7 @@ bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, boo m_Position.w = CalculateHeadingToTarget(x, y); } - if (fix_z_timer.Check()) + if (fix_z_timer.Check() && !this->IsEngaged()) this->FixZ(); SetMoving(true);