Scanning Optimizations (#1133)

* Scanning optimizations this more properly applies idle / moving scanning algorithms and applies update_others when a client is moving

* Fix bots

* Perform a self and other scan when npc's pop
This commit is contained in:
Chris Miles 2020-10-25 23:01:30 -05:00 committed by GitHub
parent 62efae2e00
commit 80ce499f67
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 80 additions and 32 deletions

View File

@ -547,7 +547,8 @@ RULE_INT(Aggro, IntAggroThreshold, 75, "Int lesser or equal the value will aggro
RULE_BOOL(Aggro, AllowTickPulling, false, "tick pulling is an exploit in an NPC's call for help fixed sometime in 2006 on live")
RULE_INT(Aggro, MinAggroLevel, 18, "Minimum level for use with UseLevelAggro")
RULE_BOOL(Aggro, UseLevelAggro, true, "MinAggroLevel rule value+ and Undead will aggro regardless of level difference. This will disabled Rule:IntAggroThreshold if set to true")
RULE_INT(Aggro, ClientAggroCheckInterval, 6, "Interval in which clients actually check for aggro - in seconds")
RULE_INT(Aggro, ClientAggroCheckMovingInterval, 1000, "Interval in which clients actually check for aggro while moving - in milliseconds - this should be lower than ClientAggroCheckIdleInterval")
RULE_INT(Aggro, ClientAggroCheckIdleInterval, 6000, "Interval in which clients actually check for aggro while idle - in milliseconds - this should be higher than ClientAggroCheckMovingInterval")
RULE_REAL(Aggro, PetAttackRange, 40000.0, "Maximum squared range /pet attack works at default is 200")
RULE_BOOL(Aggro, NPCAggroMaxDistanceEnabled, true, "If enabled, NPC's will drop aggro beyond 600 units or what is defined at the zone level")
RULE_CATEGORY_END()

View File

@ -2211,12 +2211,12 @@ bool Bot::Process()
return false;
}
if (mob_scan_close.Check()) {
if (mob_close_scan_timer.Check()) {
LogAIScanClose(
"is_moving [{}] bot [{}] timer [{}]",
moving ? "true" : "false",
GetCleanName(),
mob_scan_close.GetDuration()
mob_close_scan_timer.GetDuration()
);
entity_list.ScanCloseClientMobs(close_mobs, this);

View File

@ -139,7 +139,7 @@ Client::Client(EQStreamInterface* ieqs)
endupkeep_timer(1000),
forget_timer(0),
autosave_timer(RuleI(Character, AutosaveIntervalS) * 1000),
client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckInterval) * 1000),
client_scan_npc_aggro_timer(RuleI(Aggro, ClientAggroCheckIdleInterval)),
client_zone_wide_full_position_update_timer(5 * 60 * 1000),
tribute_timer(Tribute_duration),
proximity_timer(ClientProximity_interval),

View File

@ -4533,23 +4533,63 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
rewind_timer.Start(30000, true);
}
/* Handle client aggro scanning timers NPCs */
is_client_moving = (cy == m_Position.y && cx == m_Position.x) ? false : true;
is_client_moving = !(cy == m_Position.y && cx == m_Position.x);
/**
* Client aggro scanning
*/
const uint16 client_scan_npc_aggro_timer_idle = RuleI(Aggro, ClientAggroCheckIdleInterval);
const uint16 client_scan_npc_aggro_timer_moving = RuleI(Aggro, ClientAggroCheckMovingInterval);
LogAggroDetail(
"ClientUpdate [{}] {}moving, scan timer [{}]",
GetCleanName(),
is_client_moving ? "" : "NOT ",
client_scan_npc_aggro_timer.GetRemainingTime()
);
if (is_client_moving) {
LogDebug("ClientUpdate: Client is moving - scan timer is: [{}]", client_scan_npc_aggro_timer.GetDuration());
if (client_scan_npc_aggro_timer.GetDuration() > 1000) {
if (client_scan_npc_aggro_timer.GetRemainingTime() > client_scan_npc_aggro_timer_moving) {
LogAggroDetail("Client [{}] Restarting with moving timer", GetCleanName());
client_scan_npc_aggro_timer.Disable();
client_scan_npc_aggro_timer.Start(500);
client_scan_npc_aggro_timer.Start(client_scan_npc_aggro_timer_moving);
client_scan_npc_aggro_timer.Trigger();
}
}
else {
LogDebug("ClientUpdate: Client is NOT moving - scan timer is: [{}]", client_scan_npc_aggro_timer.GetDuration());
if (client_scan_npc_aggro_timer.GetDuration() < 1000) {
client_scan_npc_aggro_timer.Disable();
client_scan_npc_aggro_timer.Start(3000);
else if (client_scan_npc_aggro_timer.GetDuration() == client_scan_npc_aggro_timer_moving) {
LogAggroDetail("Client [{}] Restarting with idle timer", GetCleanName());
client_scan_npc_aggro_timer.Disable();
client_scan_npc_aggro_timer.Start(client_scan_npc_aggro_timer_idle);
}
/**
* Client mob close list cache scan timer
*/
const uint16 client_mob_close_scan_timer_moving = 6000;
const uint16 client_mob_close_scan_timer_idle = 60000;
LogAIScanCloseDetail(
"Client [{}] {}moving, scan timer [{}]",
GetCleanName(),
is_client_moving ? "" : "NOT ",
mob_close_scan_timer.GetRemainingTime()
);
if (is_client_moving) {
if (mob_close_scan_timer.GetRemainingTime() > client_mob_close_scan_timer_moving) {
LogAIScanCloseDetail("Client [{}] Restarting with moving timer", GetCleanName());
mob_close_scan_timer.Disable();
mob_close_scan_timer.Start(client_mob_close_scan_timer_moving);
mob_close_scan_timer.Trigger();
}
}
else if (mob_close_scan_timer.GetDuration() == client_mob_close_scan_timer_moving) {
LogAIScanCloseDetail("Client [{}] Restarting with idle timer", GetCleanName());
mob_close_scan_timer.Disable();
mob_close_scan_timer.Start(client_mob_close_scan_timer_idle);
}
/**
* On a normal basis we limit mob movement updates based on distance

View File

@ -257,7 +257,7 @@ bool Client::Process() {
* Used in aggro checks
*/
if (mob_close_scan_timer.Check()) {
entity_list.ScanCloseMobs(close_mobs, this, true);
entity_list.ScanCloseMobs(close_mobs, this, is_client_moving);
}
bool may_use_attacks = false;

View File

@ -712,6 +712,8 @@ void EntityList::AddNPC(NPC *npc, bool SendSpawnPacket, bool dontqueue)
npc_list.insert(std::pair<uint16, NPC *>(npc->GetID(), npc));
mob_list.insert(std::pair<uint16, Mob *>(npc->GetID(), npc));
entity_list.ScanCloseMobs(npc->close_mobs, npc, true);
/* Zone controller process EVENT_SPAWN_ZONE */
if (RuleB(Zone, UseZoneController)) {
if (entity_list.GetNPCByNPCTypeID(ZONE_CONTROLLER_NPC_ID) && npc->GetNPCTypeID() != ZONE_CONTROLLER_NPC_ID){

View File

@ -118,7 +118,7 @@ Mob::Mob(
attack_anim_timer(500),
position_update_melee_push_timer(500),
hate_list_cleanup_timer(6000),
mob_scan_close(6000),
mob_close_scan_timer(6000),
mob_check_moving_timer(1000)
{
mMovementManager = &MobMovementManager::Get();
@ -463,7 +463,7 @@ Mob::Mob(
m_manual_follow = false;
#endif
mob_scan_close.Trigger();
mob_close_scan_timer.Trigger();
}
Mob::~Mob()

View File

@ -172,8 +172,8 @@ public:
void DisplayInfo(Mob *mob);
std::unordered_map<uint16, Mob *> close_mobs;
Timer mob_scan_close;
Timer mob_check_moving_timer;
Timer mob_close_scan_timer;
Timer mob_check_moving_timer;
//Somewhat sorted: needs documenting!

View File

@ -723,22 +723,27 @@ bool NPC::Process()
SpellProcess();
if (mob_scan_close.Check()) {
if (mob_close_scan_timer.Check()) {
entity_list.ScanCloseMobs(close_mobs, this);
if (moving) {
mob_scan_close.Disable();
mob_scan_close.Start(RandomTimer(3000, 6000));
}
else {
mob_scan_close.Disable();
mob_scan_close.Start(RandomTimer(6000, 60000));
}
}
if (mob_check_moving_timer.Check() && moving) {
mob_scan_close.Trigger();
const uint16 npc_mob_close_scan_timer_moving = 6000;
const uint16 npc_mob_close_scan_timer_idle = 60000;
if (mob_check_moving_timer.Check()) {
if (moving) {
if (mob_close_scan_timer.GetRemainingTime() > npc_mob_close_scan_timer_moving) {
LogAIScanCloseDetail("NPC [{}] Restarting with moving timer", GetCleanName());
mob_close_scan_timer.Disable();
mob_close_scan_timer.Start(npc_mob_close_scan_timer_moving);
mob_close_scan_timer.Trigger();
}
}
else if (mob_close_scan_timer.GetDuration() == npc_mob_close_scan_timer_moving) {
LogAIScanCloseDetail("NPC [{}] Restarting with idle timer", GetCleanName());
mob_close_scan_timer.Disable();
mob_close_scan_timer.Start(npc_mob_close_scan_timer_idle);
}
}
if (tic_timer.Check()) {