diff --git a/common/features.h b/common/features.h index a80fb9f3c..0fce08c96 100644 --- a/common/features.h +++ b/common/features.h @@ -150,7 +150,7 @@ enum { //reuse times enum { //timer settings, all in milliseconds AImovement_duration = 100, - AIthink_duration = 150, + AIthink_duration = 50, AIscanarea_delay = 6000, AIfeignremember_delay = 500, AItarget_check_duration = 500, diff --git a/zone/client.cpp b/zone/client.cpp index 0bc42f8b0..2448897f9 100644 --- a/zone/client.cpp +++ b/zone/client.cpp @@ -119,7 +119,6 @@ Client::Client(EQStreamInterface* ieqs) 0, 0 ), - position_timer(250), hpupdate_timer(2000), camp_timer(29000), process_timer(100), @@ -221,7 +220,6 @@ Client::Client(EQStreamInterface* ieqs) npcflag = false; npclevel = 0; pQueuedSaveWorkID = 0; - position_timer_counter = 0; position_update_same_count = 0; fishing_timer.Disable(); shield_timer.Disable(); @@ -278,14 +276,6 @@ Client::Client(EQStreamInterface* ieqs) XPRate = 100; current_endurance = 0; - m_TimeSinceLastPositionCheck = 0; - m_DistanceSinceLastPositionCheck = 0.0f; - m_ShadowStepExemption = 0; - m_KnockBackExemption = 0; - m_PortExemption = 0; - m_SenseExemption = 0; - m_AssistExemption = 0; - m_CheatDetectMoved = false; CanUseReport = true; aa_los_them_mob = nullptr; los_status = false; @@ -5282,177 +5272,6 @@ void Client::ShowSkillsWindow() this->SendPopupToClient(WindowTitle, WindowText.c_str()); } -void Client::SetShadowStepExemption(bool v) -{ - if(v == true) - { - uint32 cur_time = Timer::GetCurrentTime(); - if((cur_time - m_TimeSinceLastPositionCheck) > 1000) - { - float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); - int runs = GetRunspeed(); - if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - printf("%s %i moving too fast! moved: %.2f in %ims, speed %.2f\n", __FILE__, __LINE__, - m_DistanceSinceLastPositionCheck, (cur_time - m_TimeSinceLastPositionCheck), speed); - if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) - { - if(IsShadowStepExempted()) - { - if(m_DistanceSinceLastPositionCheck > 800) - { - CheatDetected(MQWarpShadowStep, GetX(), GetY(), GetZ()); - } - } - else if(IsKnockBackExempted()) - { - //still potential to trigger this if you're knocked back off a - //HUGE fall that takes > 2.5 seconds - if(speed > 30.0f) - { - CheatDetected(MQWarpKnockBack, GetX(), GetY(), GetZ()); - } - } - else if(!IsPortExempted()) - { - if(!IsMQExemptedArea(zone->GetZoneID(), GetX(), GetY(), GetZ())) - { - if(speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - CheatDetected(MQWarp, GetX(), GetY(), GetZ()); - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - } - else - { - CheatDetected(MQWarpLight, GetX(), GetY(), GetZ()); - } - } - } - } - } - } - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - } - m_ShadowStepExemption = v; -} - -void Client::SetKnockBackExemption(bool v) -{ - if(v == true) - { - uint32 cur_time = Timer::GetCurrentTime(); - if((cur_time - m_TimeSinceLastPositionCheck) > 1000) - { - float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); - int runs = GetRunspeed(); - if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) - { - printf("%s %i moving too fast! moved: %.2f in %ims, speed %.2f\n", __FILE__, __LINE__, - m_DistanceSinceLastPositionCheck, (cur_time - m_TimeSinceLastPositionCheck), speed); - if(IsShadowStepExempted()) - { - if(m_DistanceSinceLastPositionCheck > 800) - { - CheatDetected(MQWarpShadowStep, GetX(), GetY(), GetZ()); - } - } - else if(IsKnockBackExempted()) - { - //still potential to trigger this if you're knocked back off a - //HUGE fall that takes > 2.5 seconds - if(speed > 30.0f) - { - CheatDetected(MQWarpKnockBack, GetX(), GetY(), GetZ()); - } - } - else if(!IsPortExempted()) - { - if(!IsMQExemptedArea(zone->GetZoneID(), GetX(), GetY(), GetZ())) - { - if(speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - CheatDetected(MQWarp, GetX(), GetY(), GetZ()); - //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - } - else - { - CheatDetected(MQWarpLight, GetX(), GetY(), GetZ()); - } - } - } - } - } - } - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - } - m_KnockBackExemption = v; -} - -void Client::SetPortExemption(bool v) -{ - if(v == true) - { - uint32 cur_time = Timer::GetCurrentTime(); - if((cur_time - m_TimeSinceLastPositionCheck) > 1000) - { - float speed = (m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - m_TimeSinceLastPositionCheck); - int runs = GetRunspeed(); - if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - if(!GetGMSpeed() && (runs >= GetBaseRunspeed() || (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) - { - printf("%s %i moving too fast! moved: %.2f in %ims, speed %.2f\n", __FILE__, __LINE__, - m_DistanceSinceLastPositionCheck, (cur_time - m_TimeSinceLastPositionCheck), speed); - if(IsShadowStepExempted()) - { - if(m_DistanceSinceLastPositionCheck > 800) - { - CheatDetected(MQWarpShadowStep, GetX(), GetY(), GetZ()); - } - } - else if(IsKnockBackExempted()) - { - //still potential to trigger this if you're knocked back off a - //HUGE fall that takes > 2.5 seconds - if(speed > 30.0f) - { - CheatDetected(MQWarpKnockBack, GetX(), GetY(), GetZ()); - } - } - else if(!IsPortExempted()) - { - if(!IsMQExemptedArea(zone->GetZoneID(), GetX(), GetY(), GetZ())) - { - if(speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - CheatDetected(MQWarp, GetX(), GetY(), GetZ()); - //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - } - else - { - CheatDetected(MQWarpLight, GetX(), GetY(), GetZ()); - } - } - } - } - } - } - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - } - m_PortExemption = v; -} - void Client::Signal(uint32 data) { char buf[32]; @@ -5461,158 +5280,6 @@ void Client::Signal(uint32 data) parse->EventPlayer(EVENT_SIGNAL, this, buf, 0); } -const bool Client::IsMQExemptedArea(uint32 zoneID, float x, float y, float z) const -{ - float max_dist = 90000; - switch(zoneID) - { - case 2: - { - float delta = (x-(-713.6)); - delta *= delta; - float distance = delta; - delta = (y-(-160.2)); - delta *= delta; - distance += delta; - delta = (z-(-12.8)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - delta = (x-(-153.8)); - delta *= delta; - distance = delta; - delta = (y-(-30.3)); - delta *= delta; - distance += delta; - delta = (z-(8.2)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - break; - } - case 9: - { - float delta = (x-(-682.5)); - delta *= delta; - float distance = delta; - delta = (y-(147.0)); - delta *= delta; - distance += delta; - delta = (z-(-9.9)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - delta = (x-(-655.4)); - delta *= delta; - distance = delta; - delta = (y-(10.5)); - delta *= delta; - distance += delta; - delta = (z-(-51.8)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - break; - } - case 62: - case 75: - case 114: - case 209: - { - //The portals are so common in paineel/felwitheb that checking - //distances wouldn't be worth it cause unless you're porting to the - //start field you're going to be triggering this and that's a level of - //accuracy I'm willing to sacrifice - return true; - break; - } - - case 24: - { - float delta = (x-(-183.0)); - delta *= delta; - float distance = delta; - delta = (y-(-773.3)); - delta *= delta; - distance += delta; - delta = (z-(54.1)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - delta = (x-(-8.8)); - delta *= delta; - distance = delta; - delta = (y-(-394.1)); - delta *= delta; - distance += delta; - delta = (z-(41.1)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - delta = (x-(-310.3)); - delta *= delta; - distance = delta; - delta = (y-(-1411.6)); - delta *= delta; - distance += delta; - delta = (z-(-42.8)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - delta = (x-(-183.1)); - delta *= delta; - distance = delta; - delta = (y-(-1409.8)); - delta *= delta; - distance += delta; - delta = (z-(37.1)); - delta *= delta; - distance += delta; - - if(distance < max_dist) - return true; - - break; - } - - case 110: - case 34: - case 96: - case 93: - case 68: - case 84: - { - if(GetBoatID() != 0) - return true; - break; - } - default: - break; - } - return false; -} - void Client::SendRewards() { std::vector rewards; diff --git a/zone/client.h b/zone/client.h index b0c65e6e2..6279fba56 100644 --- a/zone/client.h +++ b/zone/client.h @@ -959,23 +959,7 @@ public: void SendRules(Client* client); std::list consent_list; - //Anti-Cheat Stuff - uint32 m_TimeSinceLastPositionCheck; - float m_DistanceSinceLastPositionCheck; - bool m_CheatDetectMoved; - void SetShadowStepExemption(bool v); - void SetKnockBackExemption(bool v); - void SetPortExemption(bool v); - void SetSenseExemption(bool v) { m_SenseExemption = v; } - void SetAssistExemption(bool v) { m_AssistExemption = v; } - const bool IsShadowStepExempted() const { return m_ShadowStepExemption; } - const bool IsKnockBackExempted() const { return m_KnockBackExemption; } - const bool IsPortExempted() const { return m_PortExemption; } - const bool IsSenseExempted() const { return m_SenseExemption; } - const bool IsAssistExempted() const { return m_AssistExemption; } const bool GetGMSpeed() const { return (gmspeed > 0); } - void CheatDetected(CheatTypes CheatType, float x, float y, float z); - const bool IsMQExemptedArea(uint32 zoneID, float x, float y, float z) const; bool CanUseReport; //This is used to later set the buff duration of the spell, in slot to duration. @@ -1153,7 +1137,6 @@ public: inline bool IsDraggingCorpse() { return (DraggedCorpses.size() > 0); } void DragCorpses(); inline void ClearDraggedCorpses() { DraggedCorpses.clear(); } - inline void ResetPositionTimer() { position_timer_counter = 0; } void SendAltCurrencies(); void SetAlternateCurrencyValue(uint32 currency_id, uint32 new_amount); void AddAlternateCurrencyValue(uint32 currency_id, int32 amount, int8 method = 0); @@ -1497,9 +1480,6 @@ private: WaterRegionType last_region_type; - Timer position_timer; - uint8 position_timer_counter; - // this is used to try to cut back on position update reflections int position_update_same_count; @@ -1582,11 +1562,6 @@ private: int XPRate; - bool m_ShadowStepExemption; - bool m_KnockBackExemption; - bool m_PortExemption; - bool m_SenseExemption; - bool m_AssistExemption; bool alternate_currency_loaded; std::map alternate_currency; std::queue> alternate_currency_queued_operations; diff --git a/zone/client_packet.cpp b/zone/client_packet.cpp index 3b954419a..0cd405765 100644 --- a/zone/client_packet.cpp +++ b/zone/client_packet.cpp @@ -505,7 +505,6 @@ void Client::CompleteConnect() client_state = CLIENT_CONNECTED; SendAllPackets(); hpupdate_timer.Start(); - position_timer.Start(); autosave_timer.Start(); SetDuelTarget(0); SetDueling(false); @@ -895,108 +894,6 @@ void Client::CompleteConnect() worldserver.RequestTellQueue(GetName()); } -void Client::CheatDetected(CheatTypes CheatType, float x, float y, float z) -{ - //ToDo: Break warp down for special zones. Some zones have special teleportation pads or bad .map files which can trigger the detector without a legit zone request. - - switch (CheatType) - { - case MQWarp: //Some zones may still have issues. Database updates will eliminate most if not all problems. - if (RuleB(Zone, EnableMQWarpDetector) - && ((this->Admin() < RuleI(Zone, MQWarpExemptStatus) - || (RuleI(Zone, MQWarpExemptStatus)) == -1))) - { - Message(13, "Large warp detected."); - char hString[250]; - sprintf(hString, "/MQWarp with location %.2f, %.2f, %.2f", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - } - break; - case MQWarpShadowStep: - if (RuleB(Zone, EnableMQWarpDetector) - && ((this->Admin() < RuleI(Zone, MQWarpExemptStatus) - || (RuleI(Zone, MQWarpExemptStatus)) == -1))) - { - char *hString = nullptr; - MakeAnyLenString(&hString, "/MQWarp(SS) with location %.2f, %.2f, %.2f, the target was shadow step exempt but we still found this suspicious.", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - safe_delete_array(hString); - } - break; - case MQWarpKnockBack: - if (RuleB(Zone, EnableMQWarpDetector) - && ((this->Admin() < RuleI(Zone, MQWarpExemptStatus) - || (RuleI(Zone, MQWarpExemptStatus)) == -1))) - { - char *hString = nullptr; - MakeAnyLenString(&hString, "/MQWarp(KB) with location %.2f, %.2f, %.2f, the target was Knock Back exempt but we still found this suspicious.", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - safe_delete_array(hString); - } - break; - - case MQWarpLight: - if (RuleB(Zone, EnableMQWarpDetector) - && ((this->Admin() < RuleI(Zone, MQWarpExemptStatus) - || (RuleI(Zone, MQWarpExemptStatus)) == -1))) - { - if (RuleB(Zone, MarkMQWarpLT)) - { - char *hString = nullptr; - MakeAnyLenString(&hString, "/MQWarp(LT) with location %.2f, %.2f, %.2f, running fast but not fast enough to get killed, possibly: small warp, speed hack, excessive lag, marked as suspicious.", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - safe_delete_array(hString); - } - } - break; - - case MQZone: - if (RuleB(Zone, EnableMQZoneDetector) && ((this->Admin() < RuleI(Zone, MQZoneExemptStatus) || (RuleI(Zone, MQZoneExemptStatus)) == -1))) - { - char hString[250]; - sprintf(hString, "/MQZone used at %.2f, %.2f, %.2f to %.2f %.2f %.2f", GetX(), GetY(), GetZ(), x, y, z); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - } - break; - case MQZoneUnknownDest: - if (RuleB(Zone, EnableMQZoneDetector) && ((this->Admin() < RuleI(Zone, MQZoneExemptStatus) || (RuleI(Zone, MQZoneExemptStatus)) == -1))) - { - char hString[250]; - sprintf(hString, "/MQZone used at %.2f, %.2f, %.2f", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - } - break; - case MQGate: - if (RuleB(Zone, EnableMQGateDetector) && ((this->Admin() < RuleI(Zone, MQGateExemptStatus) || (RuleI(Zone, MQGateExemptStatus)) == -1))) { - Message(13, "Illegal gate request."); - char hString[250]; - sprintf(hString, "/MQGate used at %.2f, %.2f, %.2f", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - if (zone) - { - this->SetZone(this->GetZoneID(), zone->GetInstanceID()); //Prevent the player from zoning, place him back in the zone where he tried to originally /gate. - } - else - { - this->SetZone(this->GetZoneID(), 0); //Prevent the player from zoning, place him back in the zone where he tried to originally /gate. - - } - } - break; - case MQGhost: //Not currently implemented, but the framework is in place - just needs detection scenarios identified - if (RuleB(Zone, EnableMQGhostDetector) && ((this->Admin() < RuleI(Zone, MQGhostExemptStatus) || (RuleI(Zone, MQGhostExemptStatus)) == -1))) { - database.SetMQDetectionFlag(this->account_name, this->name, "/MQGhost", zone->GetShortName()); - } - break; - default: - char *hString = nullptr; - MakeAnyLenString(&hString, "Unhandled HackerDetection flag with location %.2f, %.2f, %.2f.", GetX(), GetY(), GetZ()); - database.SetMQDetectionFlag(this->account_name, this->name, hString, zone->GetShortName()); - safe_delete_array(hString); - break; - } -} - // connecting opcode handlers /* void Client::Handle_Connect_0x3e33(const EQApplicationPacket *app) @@ -2948,7 +2845,6 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app) Mob *new_target = assistee->GetTarget(); if (new_target && (GetGM() || Distance(m_Position, assistee->GetPosition()) <= TARGETING_RANGE)) { - SetAssistExemption(true); eid->entity_id = new_target->GetID(); } else { eid->entity_id = 0; @@ -3920,6 +3816,8 @@ void Client::Handle_OP_BoardBoat(const EQApplicationPacket *app) return; controlling_boat_id = boat->GetID(); // set the client's BoatID to show that it's on this boat + Message(0, "Board boat: %s", boatname); + return; } @@ -4427,9 +4325,9 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { sizeof(PlayerPositionUpdateClient_Struct), app->size); return; } - + PlayerPositionUpdateClient_Struct *ppu = (PlayerPositionUpdateClient_Struct *) app->pBuffer; - + /* Boat handling */ if (ppu->spawn_id != GetID()) { /* If player is controlling boat */ @@ -4439,163 +4337,67 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { controlling_boat_id = 0; return; } - + auto boat_delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading)); boat->SetDelta(boat_delta); - + auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct *ppus = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer; boat->MakeSpawnUpdate(ppus); entity_list.QueueCloseClients(boat, outapp, true, 300, this, false); safe_delete(outapp); - + /* Update the boat's position on the server, without sending an update */ boat->GMMove(ppu->x_pos, ppu->y_pos, ppu->z_pos, EQ12toFloat(ppu->heading), false); return; } else return; } - - float dist = 0; - float tmp; - tmp = m_Position.x - ppu->x_pos; - dist += tmp * tmp; - tmp = m_Position.y - ppu->y_pos; - dist += tmp * tmp; - dist = sqrt(dist); - - /* Hack checks */ - if (dist == 0) { - if (m_DistanceSinceLastPositionCheck > 0.0) { - uint32 cur_time = Timer::GetCurrentTime(); - if ((cur_time - m_TimeSinceLastPositionCheck) > 0) { - float speed = - (m_DistanceSinceLastPositionCheck * 100) / (float) (cur_time - m_TimeSinceLastPositionCheck); - int runs = GetRunspeed(); - if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) { - if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || - (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { - if (IsShadowStepExempted()) { - if (m_DistanceSinceLastPositionCheck > 800) { - CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - } else if (IsKnockBackExempted()) { - if (speed > 30.0f) { - CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - } else if (!IsPortExempted()) { - if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) { - if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) { - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos); - //Death(this, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - } else { - CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - } - } - } - } - SetShadowStepExemption(false); - SetKnockBackExemption(false); - SetPortExemption(false); - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - m_CheatDetectMoved = false; - } - } else { - m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); - m_CheatDetectMoved = false; - } - } else { - m_DistanceSinceLastPositionCheck += dist; - m_CheatDetectMoved = true; - if (m_TimeSinceLastPositionCheck == 0) { - m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); - } else { - uint32 cur_time = Timer::GetCurrentTime(); - if ((cur_time - m_TimeSinceLastPositionCheck) > 2500) { - float speed = - (m_DistanceSinceLastPositionCheck * 100) / (float) (cur_time - m_TimeSinceLastPositionCheck); - int runs = GetRunspeed(); - if (speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) { - if (!GetGMSpeed() && (runs >= GetBaseRunspeed() || - (speed > (GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) { - if (IsShadowStepExempted()) { - if (m_DistanceSinceLastPositionCheck > 800) { - CheatDetected(MQWarpShadowStep, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - } else if (IsKnockBackExempted()) { - if (speed > 30.0f) { - CheatDetected(MQWarpKnockBack, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - } else if (!IsPortExempted()) { - if (!IsMQExemptedArea(zone->GetZoneID(), ppu->x_pos, ppu->y_pos, ppu->z_pos)) { - if (speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) { - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - CheatDetected(MQWarp, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } else { - CheatDetected(MQWarpLight, ppu->x_pos, ppu->y_pos, ppu->z_pos); - } - } - } - } - } - SetShadowStepExemption(false); - SetKnockBackExemption(false); - SetPortExemption(false); - m_TimeSinceLastPositionCheck = cur_time; - m_DistanceSinceLastPositionCheck = 0.0f; - } - } - - if (IsDraggingCorpse()) - DragCorpses(); - } + + if (IsDraggingCorpse()) + DragCorpses(); /* Check to see if PPU should trigger an update to the rewind position. */ float rewind_x_diff = 0; float rewind_y_diff = 0; - + rewind_x_diff = ppu->x_pos - m_RewindLocation.x; rewind_x_diff *= rewind_x_diff; rewind_y_diff = ppu->y_pos - m_RewindLocation.y; rewind_y_diff *= rewind_y_diff; - + /* We only need to store updated values if the player has moved. If the player has moved more than units for x or y, then we'll store his pre-PPU x and y for /rewind, in case he gets stuck. */ - + if ((rewind_x_diff > 750) || (rewind_y_diff > 750)) m_RewindLocation = glm::vec3(m_Position); - + /* If the PPU was a large jump, such as a cross zone gate or Call of Hero, just update rewind coordinates to the new ppu coordinates. This will prevent exploitation. */ - + if ((rewind_x_diff > 5000) || (rewind_y_diff > 5000)) m_RewindLocation = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos); - + if (proximity_timer.Check()) { entity_list.ProcessMove(this, glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos)); if (RuleB(TaskSystem, EnableTaskSystem) && RuleB(TaskSystem, EnableTaskProximity)) ProcessTaskProximities(ppu->x_pos, ppu->y_pos, ppu->z_pos); - + m_Proximity = glm::vec3(ppu->x_pos, ppu->y_pos, ppu->z_pos); } - + /* Update internal state */ m_Delta = glm::vec4(ppu->delta_x, ppu->delta_y, ppu->delta_z, EQ10toFloat(ppu->delta_heading)); - + if (IsTracking() && ((m_Position.x != ppu->x_pos) || (m_Position.y != ppu->y_pos))) { if (zone->random.Real(0, 100) < 70)//should be good CheckIncreaseSkill(EQEmu::skills::SkillTracking, nullptr, -20); } - + /* Break Hide if moving without sneaking and set rewind timer if moved */ if (ppu->y_pos != m_Position.y || ppu->x_pos != m_Position.x) { if ((hidden || improved_hidden) && !sneaking) { @@ -4614,17 +4416,17 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { } rewind_timer.Start(30000, true); } - + /* Handle client aggro scanning timers NPCs */ is_client_moving = (ppu->y_pos == m_Position.y && ppu->x_pos == m_Position.x) ? false : true; - + if (is_client_moving) { Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is moving - scan timer is: %u", 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(500); - + } } else { Log(Logs::Detail, Logs::Normal, "ClientUpdate: Client is NOT moving - scan timer is: %u", @@ -4634,15 +4436,15 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { client_scan_npc_aggro_timer.Start(3000); } } - + float new_heading = EQ12toFloat(ppu->heading); int32 new_animation = ppu->animation; - + /* Update internal server position from what the client has sent */ m_Position.x = ppu->x_pos; m_Position.y = ppu->y_pos; m_Position.z = ppu->z_pos; - + /* Visual Debugging */ if (RuleB(Character, OPClientUpdateVisualDebug)) { Log(Logs::General, Logs::Debug, "ClientUpdate: ppu x: %f y: %f z: %f h: %u", ppu->x_pos, ppu->y_pos, ppu->z_pos, @@ -4650,43 +4452,43 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { this->SendAppearanceEffect(78, 0, 0, 0, 0); this->SendAppearanceEffect(41, 0, 0, 0, 0); } - + /* Only feed real time updates when client is moving */ if (is_client_moving || new_heading != m_Position.w || new_animation != animation) { - + animation = ppu->animation; m_Position.w = EQ12toFloat(ppu->heading); - + /* Broadcast update to other clients */ auto outapp = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct *position_update = (PlayerPositionUpdateServer_Struct *) outapp->pBuffer; - + MakeSpawnUpdate(position_update); - + if (gm_hide_me) { entity_list.QueueClientsStatus(this, outapp, true, Admin(), 250); } else { entity_list.QueueCloseClients(this, outapp, true, RuleI(Range, ClientPositionUpdates), nullptr, true); } - - + + /* Always send position updates to group - send when beyond normal ClientPositionUpdate range */ Group *group = this->GetGroup(); Raid *raid = this->GetRaid(); - + if (raid) { raid->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); } else if (group) { group->QueueClients(this, outapp, true, true, (RuleI(Range, ClientPositionUpdates) * -1)); } - + safe_delete(outapp); } - + if (zone->watermap) { if (zone->watermap->InLiquid(glm::vec3(m_Position))) { CheckIncreaseSkill(EQEmu::skills::SkillSwimming, nullptr, -17); - + // Dismount horses when entering water if (GetHorseId() && RuleB(Character, DismountWater)) { SetHorseId(0); @@ -4695,7 +4497,6 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) { } CheckRegionTypeChanges(); } - return; } void Client::Handle_OP_CombatAbility(const EQApplicationPacket *app) @@ -13666,12 +13467,6 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app) GetTarget()->IsTargeted(1); return; } - else if (IsAssistExempted()) - { - GetTarget()->IsTargeted(1); - SetAssistExemption(false); - return; - } else if (GetTarget()->IsClient()) { //make sure this client is in our raid/group @@ -13689,17 +13484,6 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app) SetTarget((Mob*)nullptr); return; } - else if (IsPortExempted()) - { - GetTarget()->IsTargeted(1); - return; - } - else if (IsSenseExempted()) - { - GetTarget()->IsTargeted(1); - SetSenseExemption(false); - return; - } else if (IsXTarget(GetTarget())) { GetTarget()->IsTargeted(1); diff --git a/zone/client_process.cpp b/zone/client_process.cpp index 988b558ec..cea1dd49f 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -188,10 +188,6 @@ bool Client::Process() { if (IsStunned() && stunned_timer.Check()) Mob::UnStun(); - if (!m_CheatDetectMoved) { - m_TimeSinceLastPositionCheck = Timer::GetCurrentTime(); - } - if (bardsong_timer.Check() && bardsong != 0) { //NOTE: this is kinda a heavy-handed check to make sure the mob still exists before //doing the next pulse on them... @@ -412,31 +408,6 @@ bool Client::Process() { } } - if (position_timer.Check()) { - if (IsAIControlled()) - { - if (!IsMoving()) - { - animation = 0; - m_Delta = glm::vec4(0.0f, 0.0f, 0.0f, m_Delta.w); - SendPositionUpdate(true); - } - } - - // Send a position packet every 8 seconds - if not done, other clients - // see this char disappear after 10-12 seconds of inactivity - if (position_timer_counter >= 36) { // Approx. 4 ticks per second - entity_list.SendPositionUpdates(this, pLastUpdateWZ, RuleI(Range, MobPositionUpdates), GetTarget(), true); - pLastUpdate = Timer::GetCurrentTime(); - pLastUpdateWZ = pLastUpdate; - position_timer_counter = 0; - } - else { - pLastUpdate = Timer::GetCurrentTime(); - position_timer_counter++; - } - } - if (HasVirus()) { if (viral_timer.Check()) { viral_timer_counter++; diff --git a/zone/command.cpp b/zone/command.cpp index f57b99613..84cd3566a 100644 --- a/zone/command.cpp +++ b/zone/command.cpp @@ -67,6 +67,7 @@ #include "water_map.h" #include "worldserver.h" #include "fastmath.h" +#include "mob_movement_manager.h" extern QueryServ* QServ; extern WorldServer worldserver; @@ -265,6 +266,7 @@ int command_init(void) command_add("modifynpcstat", "- Modifys a NPC's stats", 150, command_modifynpcstat) || command_add("motd", "[new motd] - Set message of the day", 150, command_motd) || command_add("movechar", "[charname] [zonename] - Move charname to zonename", 50, command_movechar) || + command_add("movement", "Various movement commands", 200, command_movement) || command_add("myskills", "- Show details about your current skill levels", 0, command_myskills) || command_add("mysqltest", "Akkadius MySQL Bench Test", 250, command_mysqltest) || command_add("mysql", "Mysql CLI, see 'help' for options.", 250, command_mysql) || @@ -1258,6 +1260,63 @@ void command_movechar(Client *c, const Seperator *sep) } } +void command_movement(Client *c, const Seperator *sep) +{ + auto &mgr = MobMovementManager::Get(); + + if (sep->arg[1][0] == 0) { + c->Message(0, "Usage: #movement stats/clearstats"); + return; + } + + if (strcasecmp(sep->arg[1], "stats") == 0) + { + //mgr.DumpStats(c); + } + else if (strcasecmp(sep->arg[1], "clearstats") == 0) + { + //mgr.ClearStats(); + } + if (strcasecmp(sep->arg[1], "test") == 0) + { + auto target = c->GetTarget(); + if (!target) { + c->Message(0, "Requires target"); + } + + + auto heading = target->CalculateHeadingToTarget(c->GetX(), c->GetY()); + mgr.RotateTo(target, heading, 16.0f); + + //double a1 = atof(sep->arg[2]); + //double a2 = atof(sep->arg[3]); + //double a3 = atof(sep->arg[4]); + //double a4 = atof(sep->arg[5]); + //int a5 = atoi(sep->arg[6]); + // + ////PlayerPositionUpdateServer_Struct + //EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + //PlayerPositionUpdateServer_Struct *spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; + // + //memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); + //spu->spawn_id = target->GetID(); + //spu->x_pos = FloatToEQ19(target->GetX()); + //spu->y_pos = FloatToEQ19(target->GetY()); + //spu->z_pos = FloatToEQ19(target->GetZ()); + //spu->heading = FloatToEQ12(target->GetHeading()); + //spu->delta_x = FloatToEQ13(a1); + //spu->delta_y = FloatToEQ13(a2); + //spu->delta_z = FloatToEQ13(a3); + //spu->delta_heading = FloatToEQ10(a4); + //spu->animation = a5; + // + //c->QueuePacket(&outapp); + } + else { + c->Message(0, "Usage: #movement stats/clearstats"); + } +} + void command_viewpetition(Client *c, const Seperator *sep) { if (sep->arg[1][0] == 0) { @@ -7260,7 +7319,7 @@ void command_pf(Client *c, const Seperator *sep) c->Message(0, "POS: (%.2f, %.2f, %.2f)", who->GetX(), who->GetY(), who->GetZ()); c->Message(0, "WP: %s (%d/%d)", to_string(who->GetCurrentWayPoint()).c_str(), who->IsNPC()?who->CastToNPC()->GetMaxWp():-1); c->Message(0, "pause=%d RAspeed=%d", who->GetCWPP(), who->GetRunAnimSpeed()); - who->DumpMovement(c); + //who->DumpMovement(c); } else { c->Message(0, "ERROR: target required"); } diff --git a/zone/command.h b/zone/command.h index d3bae6c0c..95b9e77dd 100644 --- a/zone/command.h +++ b/zone/command.h @@ -168,6 +168,7 @@ void command_merchantopenshop(Client *c, const Seperator *sep); void command_modifynpcstat(Client *c, const Seperator *sep); void command_motd(Client *c, const Seperator *sep); void command_movechar(Client *c, const Seperator *sep); +void command_movement(Client *c, const Seperator *sep); void command_myskills(Client *c, const Seperator *sep); void command_mysql(Client *c, const Seperator *sep); void command_mysqltest(Client *c, const Seperator *sep); diff --git a/zone/entity.cpp b/zone/entity.cpp index 163d991c5..f7f5b4594 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -2650,56 +2650,6 @@ void EntityList::RemoveDebuffs(Mob *caster) } } -// Currently, a new packet is sent per entity. -// @todo: Come back and use FLAG_COMBINED to pack -// all updates into one packet. -void EntityList::SendPositionUpdates(Client *client, uint32 cLastUpdate, float update_range, Entity *always_send, bool iSendEvenIfNotChanged) -{ -// update_range = (update_range * update_range); -// -// EQApplicationPacket *outapp = 0; -// PlayerPositionUpdateServer_Struct *ppu = 0; -// Mob *mob = 0; -// -// auto it = mob_list.begin(); -// while (it != mob_list.end()) { -// -// mob = it->second; -// -// if ( -// mob && !mob->IsCorpse() -// && (it->second != client) -// && (mob->IsClient() || iSendEvenIfNotChanged || (mob->LastChange() >= cLastUpdate)) -// && (it->second->ShouldISpawnFor(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; -// } -// -// mob->MakeSpawnUpdate(ppu); -// -// safe_delete(outapp); -// outapp = 0; -// } -// } -// } -// -// ++it; -// } -// -// safe_delete(outapp); -} - char *EntityList::MakeNameUnique(char *name) { bool used[300]; diff --git a/zone/entity.h b/zone/entity.h index 816098294..7c9c06c31 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -372,7 +372,6 @@ public: Mob* FindDefenseNPC(uint32 npcid); void OpenDoorsNear(Mob* opener); void UpdateWho(bool iSendFullUpdate = false); - void SendPositionUpdates(Client* client, uint32 cLastUpdate = 0, float update_range = 0, Entity* always_send = 0, bool iSendEvenIfNotChanged = false); char* MakeNameUnique(char* name); static char* RemoveNumbers(char* name); void SignalMobsByNPCID(uint32 npc_type, int signal_id); diff --git a/zone/mob.cpp b/zone/mob.cpp index 3921d91f5..59691c78f 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -1453,12 +1453,12 @@ void Mob::StopMoving(float new_heading) { /* Used for mobs standing still - this does not send a delta */ void Mob::SendPosition() { - mMovementManager->SendPosition(this); + //mMovementManager->SendPosition(this); } /* Position updates for mobs on the move */ void Mob::SendPositionUpdate(bool iSendToSelf) { - mMovementManager->SendPositionUpdate(this, iSendToSelf); + //mMovementManager->SendPositionUpdate(this, iSendToSelf); } // this is for SendPosition() @@ -2710,13 +2710,7 @@ void Mob::FaceTarget(Mob* mob_to_face /*= 0*/) { float current_heading = GetHeading(); float new_heading = CalculateHeadingToTarget(faced_mob->GetX(), faced_mob->GetY()); if(current_heading != new_heading) { - SetHeading(new_heading); - if (moving) { - SendPositionUpdate(); - } - else { - SendPosition(); - } + mMovementManager->RotateTo(this, new_heading, 16.0f); } if(IsNPC() && !IsEngaged()) { @@ -3170,20 +3164,6 @@ void Mob::SetNextIncHPEvent( int inchpevent ) { nextinchpevent = inchpevent; } -//warp for quest function,from sandy -void Mob::Warp(const glm::vec3& location) -{ - if(IsNPC()) - entity_list.ProcessMove(CastToNPC(), location.x, location.y, location.z); - - m_Position = glm::vec4(location, m_Position.w); - - Mob* target = GetTarget(); - if (target) - FaceTarget( target ); - - SendPosition(); -} int16 Mob::GetResist(uint8 type) const { @@ -3571,6 +3551,14 @@ void Mob::SetFlyMode(GravityBehavior flymode) this->flymode = flymode; } +void Mob::Teleport(const glm::vec3 &pos) +{ +} + +void Mob::Teleport(const glm::vec4 &pos) +{ +} + bool Mob::IsNimbusEffectActive(uint32 nimbus_effect) { if(nimbus_effect1 == nimbus_effect || nimbus_effect2 == nimbus_effect || nimbus_effect3 == nimbus_effect) @@ -4592,8 +4580,6 @@ void Mob::DoKnockback(Mob *caster, uint32 pushback, uint32 pushup) { if(IsClient()) { - CastToClient()->SetKnockBackExemption(true); - auto outapp_push = new EQApplicationPacket(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp_push->pBuffer; diff --git a/zone/mob.h b/zone/mob.h index d9f180626..3f35a25b8 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -542,7 +542,6 @@ public: virtual inline int32 GetPrimaryFaction() const { return 0; } //Movement - void Warp(const glm::vec3& location); inline bool IsMoving() const { return moving; } virtual void SetMoving(bool move) { moving = move; m_Delta = glm::vec4(); } virtual void GoToBind(uint8 bindnum = 0) { } @@ -568,14 +567,15 @@ public: bool Spawned() { return spawned; }; virtual bool ShouldISpawnFor(Client *c) { return true; } void SetFlyMode(GravityBehavior flymode); - inline void Teleport(const glm::vec3 &NewPosition) { m_Position.x = NewPosition.x; m_Position.y = NewPosition.y; - m_Position.z = NewPosition.z; }; + void Teleport(const glm::vec3 &pos); + void Teleport(const glm::vec4 &pos); void TryMoveAlong(float distance, float angle, bool send = true); void ProcessForcedMovement(); inline void IncDeltaX(float in) { m_Delta.x += in; } inline void IncDeltaY(float in) { m_Delta.y += in; } inline void IncDeltaZ(float in) { m_Delta.z += in; } inline void SetForcedMovement(int in) { ForcedMovement = in; } + void SetHeading(float iHeading) { m_Position.w = iHeading; } //AI static uint32 GetLevelCon(uint8 mylevel, uint8 iOtherLevel); @@ -602,7 +602,6 @@ public: void SetAssistAggro(bool value) { AssistAggro = value; if (PrimaryAggro) AssistAggro = false; } bool HateSummon(); void FaceTarget(Mob* mob_to_face = 0); - void SetHeading(float iHeading) { m_Position.w = iHeading; } void WipeHateList(); void AddFeignMemory(Client* attacker); void RemoveFromFeignMemory(Client* attacker); @@ -980,7 +979,6 @@ public: void TryFixZ(int32 z_find_offset = 5, bool fix_client_z = false); void FixZ(int32 z_find_offset = 5, bool fix_client_z = false); float GetFixedZ(const glm::vec3 &destination, int32 z_find_offset = 5); - void DumpMovement(Client *to); void NPCSpecialAttacks(const char* parse, int permtag, bool reset = true, bool remove = false); inline uint32 DontHealMeBefore() const { return pDontHealMeBefore; } @@ -1251,8 +1249,8 @@ protected: uint8 level; uint8 orig_level; uint32 npctype_id; - glm::vec4 m_Position; + glm::vec4 m_Position; int animation; // this is really what MQ2 calls SpeedRun just packed like (int)(SpeedRun * 40.0f) float base_size; float size; diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index 9a0ffb8b7..3862f7857 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -916,7 +916,7 @@ void Client::AI_Process() float dist = DistanceSquared(m_Position, owner->GetPosition()); if (dist >= 202500) { // >= 450 distance - Teleport(static_cast(owner->GetPosition())); + Teleport(owner->GetPosition()); SendPositionUpdate(); // this shouldn't happen a lot (and hard to make it) so lets not rate limit } else if (dist >= 400) { // >=20 if (AI_movement_timer->Check()) { @@ -936,86 +936,86 @@ void Client::AI_Process() void Mob::ProcessForcedMovement() { - // we are being pushed, we will hijack this movement timer - // this also needs to be done before casting to have a chance to interrupt - // this flag won't be set if the mob can't be pushed (rooted etc) - if (AI_movement_timer->Check()) { - bool bPassed = true; - glm::vec3 normal; - - // no zone map = fucked - if (zone->HasMap()) { - // in front - m_CollisionBox[0].x = m_Position.x + 3.0f * g_Math.FastSin(0.0f); - m_CollisionBox[0].y = m_Position.y + 3.0f * g_Math.FastCos(0.0f); - m_CollisionBox[0].z = m_Position.z; - - // 45 right front - m_CollisionBox[1].x = m_Position.x + 3.0f * g_Math.FastSin(64.0f); - m_CollisionBox[1].y = m_Position.y + 3.0f * g_Math.FastCos(64.0f); - m_CollisionBox[1].z = m_Position.z; - - // to right - m_CollisionBox[2].x = m_Position.x + 3.0f * g_Math.FastSin(128.0f); - m_CollisionBox[2].y = m_Position.y + 3.0f * g_Math.FastCos(128.0f); - m_CollisionBox[2].z = m_Position.z; - - // 45 right back - m_CollisionBox[3].x = m_Position.x + 3.0f * g_Math.FastSin(192.0f); - m_CollisionBox[3].y = m_Position.y + 3.0f * g_Math.FastCos(192.0f); - m_CollisionBox[3].z = m_Position.z; - - // behind - m_CollisionBox[4].x = m_Position.x + 3.0f * g_Math.FastSin(256.0f); - m_CollisionBox[4].y = m_Position.y + 3.0f * g_Math.FastCos(256.0f); - m_CollisionBox[4].z = m_Position.z; - - // 45 left back - m_CollisionBox[5].x = m_Position.x + 3.0f * g_Math.FastSin(320.0f); - m_CollisionBox[5].y = m_Position.y + 3.0f * g_Math.FastCos(320.0f); - m_CollisionBox[5].z = m_Position.z; - - // to left - m_CollisionBox[6].x = m_Position.x + 3.0f * g_Math.FastSin(384.0f); - m_CollisionBox[6].y = m_Position.y + 3.0f * g_Math.FastCos(384.0f); - m_CollisionBox[6].z = m_Position.z; - - // 45 left front - m_CollisionBox[7].x = m_Position.x + 3.0f * g_Math.FastSin(448.0f); - m_CollisionBox[7].y = m_Position.y + 3.0f * g_Math.FastCos(448.0f); - m_CollisionBox[7].z = m_Position.z; - - // collision happened, need to move along the wall - float distance = 0.0f, shortest = std::numeric_limits::infinity(); - glm::vec3 tmp_nrm; - for (auto &vec : m_CollisionBox) { - if (zone->zonemap->DoCollisionCheck(vec, vec + m_Delta, tmp_nrm, distance)) { - bPassed = false; // lets try with new projection next pass - if (distance < shortest) { - normal = tmp_nrm; - shortest = distance; - } - } - } - } - - if (bPassed) { - ForcedMovement = 0; - Teleport(m_Position + m_Delta); - m_Delta = glm::vec4(); - SendPositionUpdate(); - FixZ(); // so we teleport to the ground locally, we want the client to interpolate falling etc - } else if (--ForcedMovement) { - if (normal.z < -0.15f) // prevent too much wall climbing. ex. OMM's room in anguish - normal.z = 0.0f; - auto proj = glm::proj(static_cast(m_Delta), normal); - m_Delta.x -= proj.x; - m_Delta.y -= proj.y; - m_Delta.z -= proj.z; - } else { - m_Delta = glm::vec4(); // well, we failed to find a spot to be forced to, lets give up - } - } + //// we are being pushed, we will hijack this movement timer + //// this also needs to be done before casting to have a chance to interrupt + //// this flag won't be set if the mob can't be pushed (rooted etc) + //if (AI_movement_timer->Check()) { + // bool bPassed = true; + // glm::vec3 normal; + // + // // no zone map = fucked + // if (zone->HasMap()) { + // // in front + // m_CollisionBox[0].x = m_Position.x + 3.0f * g_Math.FastSin(0.0f); + // m_CollisionBox[0].y = m_Position.y + 3.0f * g_Math.FastCos(0.0f); + // m_CollisionBox[0].z = m_Position.z; + // + // // 45 right front + // m_CollisionBox[1].x = m_Position.x + 3.0f * g_Math.FastSin(64.0f); + // m_CollisionBox[1].y = m_Position.y + 3.0f * g_Math.FastCos(64.0f); + // m_CollisionBox[1].z = m_Position.z; + // + // // to right + // m_CollisionBox[2].x = m_Position.x + 3.0f * g_Math.FastSin(128.0f); + // m_CollisionBox[2].y = m_Position.y + 3.0f * g_Math.FastCos(128.0f); + // m_CollisionBox[2].z = m_Position.z; + // + // // 45 right back + // m_CollisionBox[3].x = m_Position.x + 3.0f * g_Math.FastSin(192.0f); + // m_CollisionBox[3].y = m_Position.y + 3.0f * g_Math.FastCos(192.0f); + // m_CollisionBox[3].z = m_Position.z; + // + // // behind + // m_CollisionBox[4].x = m_Position.x + 3.0f * g_Math.FastSin(256.0f); + // m_CollisionBox[4].y = m_Position.y + 3.0f * g_Math.FastCos(256.0f); + // m_CollisionBox[4].z = m_Position.z; + // + // // 45 left back + // m_CollisionBox[5].x = m_Position.x + 3.0f * g_Math.FastSin(320.0f); + // m_CollisionBox[5].y = m_Position.y + 3.0f * g_Math.FastCos(320.0f); + // m_CollisionBox[5].z = m_Position.z; + // + // // to left + // m_CollisionBox[6].x = m_Position.x + 3.0f * g_Math.FastSin(384.0f); + // m_CollisionBox[6].y = m_Position.y + 3.0f * g_Math.FastCos(384.0f); + // m_CollisionBox[6].z = m_Position.z; + // + // // 45 left front + // m_CollisionBox[7].x = m_Position.x + 3.0f * g_Math.FastSin(448.0f); + // m_CollisionBox[7].y = m_Position.y + 3.0f * g_Math.FastCos(448.0f); + // m_CollisionBox[7].z = m_Position.z; + // + // // collision happened, need to move along the wall + // float distance = 0.0f, shortest = std::numeric_limits::infinity(); + // glm::vec3 tmp_nrm; + // for (auto &vec : m_CollisionBox) { + // if (zone->zonemap->DoCollisionCheck(vec, vec + m_Delta, tmp_nrm, distance)) { + // bPassed = false; // lets try with new projection next pass + // if (distance < shortest) { + // normal = tmp_nrm; + // shortest = distance; + // } + // } + // } + // } + // + // if (bPassed) { + // ForcedMovement = 0; + // Teleport(m_Position + m_Delta); + // m_Delta = glm::vec4(); + // SendPositionUpdate(); + // FixZ(); // so we teleport to the ground locally, we want the client to interpolate falling etc + // } else if (--ForcedMovement) { + // if (normal.z < -0.15f) // prevent too much wall climbing. ex. OMM's room in anguish + // normal.z = 0.0f; + // auto proj = glm::proj(static_cast(m_Delta), normal); + // m_Delta.x -= proj.x; + // m_Delta.y -= proj.y; + // m_Delta.z -= proj.z; + // } else { + // m_Delta = glm::vec4(); // well, we failed to find a spot to be forced to, lets give up + // } + //} } void Mob::AI_Process() { diff --git a/zone/mob_movement_manager.cpp b/zone/mob_movement_manager.cpp index b87e4f740..a6151a887 100644 --- a/zone/mob_movement_manager.cpp +++ b/zone/mob_movement_manager.cpp @@ -1,53 +1,81 @@ #include "mob_movement_manager.h" #include "client.h" #include "mob.h" -#include "../common/timer.h" +#include "../common/eq_packet_structs.h" +#include "../common/misc_functions.h" #include #include #include -extern uint64_t frame_time; +extern double frame_time; -struct MovementEntry +struct RotateCommand { - int animation; - float heading; - bool dirty; - double last_sent_time; - double last_sent_time_long_distance; - - MovementEntry(Mob *m) { - animation = 0; - heading = m->GetHeading(); - dirty = false; - last_sent_time = 0.0; - last_sent_time_long_distance = 0.0; + RotateCommand() { + rotate_to = 0.0; + rotate_to_speed = 0.0; + rotate_dir = 1.0; + active = false; + started = false; } + + double rotate_to; + double rotate_to_speed; + double rotate_dir; + bool active; + bool started; }; -struct MoveToEntry +struct MovementCommand { - float x; - float y; - float z; - float speed; - bool active; - - MoveToEntry() { - x = 0.0f; - y = 0.0f; - z = 0.0f; - speed = 0.0f; + MovementCommand() { + move_to_x = 0.0; + move_to_y = 0.0; + move_to_z = 0.0; + move_to_speed = 0.0; + last_sent_short_distance = 0.0; + last_sent_medium_distance = 0.0; + last_sent_long_distance = 0.0; active = false; } + + double move_to_x; + double move_to_y; + double move_to_z; + double move_to_speed; + double last_sent_short_distance; + double last_sent_medium_distance; + double last_sent_long_distance; + bool active; +}; + +struct MovementStats +{ + MovementStats() { + TotalSent = 0ULL; + TotalSentMovement = 0ULL; + TotalSentPosition = 0ULL; + TotalSentHeading = 0ULL; + } + + uint64_t TotalSent; + uint64_t TotalSentMovement; + uint64_t TotalSentPosition; + uint64_t TotalSentHeading; +}; + +struct MobMovementEntry +{ + RotateCommand RotateCommand; + MovementCommand MoveCommand; }; struct MobMovementManager::Implementation { - std::map Entries; - std::map MoveEntries; + std::map Entries; std::vector Clients; + MovementStats Stats; }; MobMovementManager::MobMovementManager() @@ -55,57 +83,132 @@ MobMovementManager::MobMovementManager() _impl.reset(new Implementation()); } +void MobMovementManager::ProcessRotateCommand(Mob *m, RotateCommand &cmd) +{ + if (m->IsEngaged()) { + auto to = FixHeading(cmd.rotate_to); + m->SetHeading(to); + SendCommandToAllClients(m, 0.0, 0.0, 0.0, 0.0, 0); + cmd.active = false; + return; + } + + if (!cmd.started) { + cmd.started = true; + + SendCommandToAllClients(m, 0.0, 0.0, 0.0, cmd.rotate_dir * cmd.rotate_to_speed, 0); + } + + auto from = FixHeading(m->GetHeading()); + auto to = FixHeading(cmd.rotate_to); + float dist = 0.0; + if (cmd.rotate_dir > 0.0) { + if (to > from) { + dist = to - from; + } + else { + dist = 512.0 - from + to; + } + } + else { + if (from > to) { + dist = from - to; + } + else { + dist = (512.0 - to) + from; + } + } + + auto td = cmd.rotate_to_speed * 19.0 * frame_time; + + if (td >= dist) { + m->SetHeading(to); + SendCommandToAllClients(m, 0.0, 0.0, 0.0, 0.0, 0); + cmd.active = false; + } + + from += td * cmd.rotate_dir; + m->SetHeading(FixHeading(from)); +} + +void MobMovementManager::SendCommandToAllClients(Mob *m, float dx, float dy, float dz, float dh, int anim) +{ + EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); + PlayerPositionUpdateServer_Struct *spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; + FillCommandStruct(spu, m, dx, dy, dz, dh, anim); + + for (auto &c : _impl->Clients) { + _impl->Stats.TotalSent++; + + if (anim != 0) { + _impl->Stats.TotalSentMovement++; + } + else if (dh != 0) { + _impl->Stats.TotalSentHeading++; + } + else { + _impl->Stats.TotalSentPosition++; + } + + c->QueuePacket(&outapp); + } +} + +void MobMovementManager::FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim) +{ + memset(spu, 0x00, sizeof(PlayerPositionUpdateServer_Struct)); + spu->spawn_id = m->GetID(); + spu->x_pos = FloatToEQ19(m->GetX()); + spu->y_pos = FloatToEQ19(m->GetY()); + spu->z_pos = FloatToEQ19(m->GetZ()); + spu->heading = FloatToEQ12(m->GetHeading()); + spu->delta_x = FloatToEQ13(dx); + spu->delta_y = FloatToEQ13(dy); + spu->delta_z = FloatToEQ13(dz); + spu->delta_heading = FloatToEQ10(dh); + spu->animation = anim; +} + +float MobMovementManager::FixHeading(float in) +{ + auto h = in; + while (h > 512.0) { + h -= 512.0; + } + + while (h < 0.0) { + h += 512.0; + } + + return h; +} + MobMovementManager::~MobMovementManager() { } void MobMovementManager::Process() { - double current_time = static_cast(Timer::GetCurrentTime()) / 1000.0; - - for (auto &mov : _impl->MoveEntries) { - auto &ent = mov.second; - - if (ent.active) { - ProcessMovement(mov.first, ent.x, ent.y, ent.z, ent.speed); - } - } - for (auto &iter : _impl->Entries) { auto &ent = iter.second; - if (ent.dirty) { - SendUpdate(iter.first, ent.animation, ent.heading); - ent.dirty = false; - ent.last_sent_time = current_time; - ent.last_sent_time_long_distance = current_time; - } else if (ent.animation != 0) { - double diff_short_range = current_time - ent.last_sent_time; - double diff_long_range = current_time - ent.last_sent_time_long_distance; + if (ent.RotateCommand.active) { + ProcessRotateCommand(iter.first, ent.RotateCommand); + } + else if (ent.MoveCommand.active) { - if (diff_short_range >= 2.0) { - SendUpdateShortDistance(iter.first, ent.animation, ent.heading); - ent.last_sent_time = current_time; - } - - if (diff_long_range >= 6.0) { - SendUpdateLongDistance(iter.first, ent.animation, ent.heading); - ent.last_sent_time_long_distance = current_time; - } } } } void MobMovementManager::AddMob(Mob *m) { - _impl->Entries.insert(std::make_pair(m, MovementEntry(m))); - _impl->MoveEntries.insert(std::make_pair(m, MoveToEntry())); + _impl->Entries.insert(std::make_pair(m, MobMovementEntry())); } void MobMovementManager::RemoveMob(Mob *m) { _impl->Entries.erase(m); - _impl->MoveEntries.erase(m); } void MobMovementManager::AddClient(Client *c) @@ -126,275 +229,52 @@ void MobMovementManager::RemoveClient(Client *c) } } -void MobMovementManager::SendPosition(Mob *who) +void MobMovementManager::RotateTo(Mob *who, float to, float speed) { auto iter = _impl->Entries.find(who); - auto &ent = iter->second; + auto &ent = (*iter); - auto anim = 0; - auto heading = who->GetHeading(); - - if (ent.animation != anim || !HeadingEqual(ent.heading, heading)) { - ent.animation = anim; - ent.heading = heading; - ent.dirty = true; + auto from = FixHeading(who->GetHeading()); + to = FixHeading(to); + + ent.second.RotateCommand.active = true; + ent.second.RotateCommand.started = false; + ent.second.RotateCommand.rotate_to = to; + ent.second.RotateCommand.rotate_to_speed = speed; + + double pdist = 0.0; + double ndist = 0.0; + if (to > from) { + pdist = to - from; + } + else { + pdist = 512.0 - from + to; + } + + if (from > to) { + ndist = from - to; + } + else { + ndist = (512.0 - to) + from; + } + + if (pdist <= ndist) { + ent.second.RotateCommand.rotate_dir = 1.0; + } + else { + ent.second.RotateCommand.rotate_dir = -1.0; } } -void MobMovementManager::SendPositionUpdate(Mob *who, bool send_to_self) +void MobMovementManager::Teleport(Mob *who, float x, float y, float z, float heading) { - auto iter = _impl->Entries.find(who); - auto &ent = iter->second; - - auto anim = 0; - auto heading = who->GetHeading(); - if (who->IsMoving()) { - if (who->IsClient()) { - anim = who->GetAnimation(); - } - else { - anim = who->GetRunAnimSpeed(); - } - } - - if (send_to_self && who->IsClient()) { - SendUpdateTo(who, who->CastToClient(), anim, heading); - } - - if (ent.animation != anim || !HeadingEqual(ent.heading, heading)) { - ent.animation = anim; - ent.heading = heading; - ent.dirty = true; - } } void MobMovementManager::NavigateTo(Mob *who, float x, float y, float z, float speed) { - auto iter = _impl->MoveEntries.find(who); - auto &ent = iter->second; - - ent.x = x; - ent.y = y; - ent.z = z; - ent.speed = speed; - ent.active = true; + } void MobMovementManager::StopNavigation(Mob *who) { - auto iter = _impl->MoveEntries.find(who); - auto &ent = iter->second; - ent.active = false; - - SendPosition(who); -} - -void MobMovementManager::Dump(Mob *m, Client *to) -{ - { - auto iter = _impl->Entries.find(m); - auto &ent = iter->second; - - to->Message(0, "Packet: anim=%d, heading=%.2f, dirty=%s, last_sent_time=%.2f, last_sent_time_long_dist=%.2f", - ent.animation, - ent.heading, - ent.dirty ? "true" : "false", - ent.last_sent_time, - ent.last_sent_time_long_distance); - } - - { - auto iter = _impl->MoveEntries.find(m); - auto &ent = iter->second; - - to->Message(0, "Movement: speed=%.2f, x=%.2f, y=%.2f, z=%.2f, active=%s", - ent.speed, - ent.x, - ent.y, - ent.z, - ent.active ? "true" : "false"); - } -} - -bool MobMovementManager::HeadingEqual(float a, float b) -{ - const float eps = 0.0001f; - return abs(a - b) < eps; -} - -void MobMovementManager::SendUpdateTo(Mob *who, Client *c, int anim, float heading) -{ - EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; - if (anim == 0) { - who->MakeSpawnUpdateNoDelta(spu); - } - else { - who->MakeSpawnUpdate(spu); - } - - c->QueuePacket(&outapp); -} - -void MobMovementManager::SendUpdate(Mob *who, int anim, float heading) -{ - EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; - if (anim == 0) { - who->MakeSpawnUpdateNoDelta(spu); - } - else { - who->MakeSpawnUpdate(spu); - } - for (auto &c : _impl->Clients) { - if (c != who) { - c->QueuePacket(&outapp); - } - else if (c->IsAIControlled()) { - c->QueuePacket(&outapp); - } - } -} - -void MobMovementManager::SendUpdateShortDistance(Mob *who, int anim, float heading) -{ - EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; - if (anim == 0) { - who->MakeSpawnUpdateNoDelta(spu); - } - else { - who->MakeSpawnUpdate(spu); - } - - for (auto &c : _impl->Clients) { - if (c != who) { - auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ()); - if (dist <= 1000.0f) { - c->QueuePacket(&outapp); - } - } - else if (c->IsAIControlled()) { - auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ()); - if (dist <= 1000.0f) { - c->QueuePacket(&outapp); - } - } - } -} - -void MobMovementManager::SendUpdateLongDistance(Mob *who, int anim, float heading) -{ - EQApplicationPacket outapp(OP_ClientUpdate, sizeof(PlayerPositionUpdateServer_Struct)); - PlayerPositionUpdateServer_Struct* spu = (PlayerPositionUpdateServer_Struct*)outapp.pBuffer; - if (anim == 0) { - who->MakeSpawnUpdateNoDelta(spu); - } - else { - who->MakeSpawnUpdate(spu); - } - - for (auto &c : _impl->Clients) { - if (c != who) { - auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ()); - if (dist > 1000.0f) { - c->QueuePacket(&outapp); - } - } - else if (c->IsAIControlled()) { - auto dist = who->CalculateDistance(c->GetX(), c->GetY(), c->GetZ()); - if (dist > 1000.0f) { - c->QueuePacket(&outapp); - } - } - } -} - -void MobMovementManager::ProcessMovement(Mob *who, float x, float y, float z, float speed) -{ - if (who->GetID() == 0) { - return; - } - - if (speed <= 0) { - who->SetCurrentSpeed(0); - return; - } - - if (IsPositionEqual(x, y, z, who->GetX(), who->GetY(), who->GetZ())) { - StopNavigation(who); - return; - } - - bool WaypointChanged = false; - bool NodeReached = false; - glm::vec3 Goal = who->UpdatePath( - x, y, z, speed, WaypointChanged, NodeReached - ); - - if (WaypointChanged || NodeReached) { - entity_list.OpenDoorsNear(who); - } - - who->SetCurrentSpeed(static_cast(speed)); - who->SetRunAnimSpeed(speed); - -#ifdef BOTS - if (who->IsClient() || who->IsBot()) -#else - if (who->IsClient()) -#endif - { - who->SetAnimation(speed * 0.55f); - } - - auto &p = who->GetPosition(); - - //Setup Vectors - glm::vec3 tar(Goal.x, Goal.y, Goal.z); - glm::vec3 pos(p.x, p.y, p.z); - double len = glm::distance(pos, tar); - if (len == 0) { - return; - } - - glm::vec3 dir = tar - pos; - glm::vec3 ndir = glm::normalize(dir); - double time_since_last = static_cast(frame_time) / 1000.0; - double distance_moved = time_since_last * speed * 0.4f * 1.4f; - - if (distance_moved > len) { - who->Teleport(Goal); - - if (who->IsNPC()) { - entity_list.ProcessMove(who->CastToNPC(), Goal.x, Goal.y, Goal.z); - } - - who->TryFixZ(); - return; - } - else { - glm::vec3 npos = pos + (ndir * static_cast(distance_moved)); - who->Teleport(npos); - - if (who->IsNPC()) { - entity_list.ProcessMove(who->CastToNPC(), npos.x, npos.y, npos.z); - } - } - - who->SetHeading(who->CalculateHeadingToTarget(Goal.x, Goal.y)); - SendPositionUpdate(who, false); - - who->TryFixZ(); - - who->SetMoving(true); - - if (who->IsClient()) { - who->SendPositionUpdate(); - who->CastToClient()->ResetPositionTimer(); - } - else { - who->SendPositionUpdate(); - who->SetAppearance(eaStanding, false); - } } diff --git a/zone/mob_movement_manager.h b/zone/mob_movement_manager.h index 2660e4b22..793c3406e 100644 --- a/zone/mob_movement_manager.h +++ b/zone/mob_movement_manager.h @@ -4,6 +4,9 @@ class Mob; class Client; +struct RotateCommand; +struct PlayerPositionUpdateServer_Struct; + class MobMovementManager { public: @@ -14,11 +17,13 @@ public: void AddClient(Client *c); void RemoveClient(Client *c); - void SendPosition(Mob *who); - void SendPositionUpdate(Mob *who, bool send_to_self); + void RotateTo(Mob *who, float to, float speed); + void Teleport(Mob *who, float x, float y, float z, float heading); void NavigateTo(Mob *who, float x, float y, float z, float speed); void StopNavigation(Mob *who); - void Dump(Mob *m, Client *to); + //void Dump(Mob *m, Client *to); + //void DumpStats(Client *to); + //void ClearStats(); static MobMovementManager &Get() { static MobMovementManager inst; @@ -30,12 +35,10 @@ private: MobMovementManager(const MobMovementManager&); MobMovementManager& operator=(const MobMovementManager&); - bool HeadingEqual(float a, float b); - void SendUpdateTo(Mob *who, Client *c, int anim, float heading); - void SendUpdate(Mob *who, int anim, float heading); - void SendUpdateShortDistance(Mob *who, int anim, float heading); - void SendUpdateLongDistance(Mob *who, int anim, float heading); - void ProcessMovement(Mob *who, float x, float y, float z, float speed); + void ProcessRotateCommand(Mob *m, RotateCommand &cmd); + void SendCommandToAllClients(Mob *m, float dx, float dy, float dz, float dh, int anim); + void FillCommandStruct(PlayerPositionUpdateServer_Struct *spu, Mob *m, float dx, float dy, float dz, float dh, int anim); + float FixHeading(float in); struct Implementation; std::unique_ptr _impl; diff --git a/zone/net.cpp b/zone/net.cpp index f51d50bb4..1dd1c9eb3 100644 --- a/zone/net.cpp +++ b/zone/net.cpp @@ -109,7 +109,7 @@ EQEmuLogSys LogSys; const SPDat_Spell_Struct* spells; int32 SPDAT_RECORDS = -1; const ZoneConfig *Config; -uint64_t frame_time = 0; +double frame_time = 0.0; void Shutdown(); extern void MapOpcodes(); @@ -447,7 +447,7 @@ int main(int argc, char** argv) { //Calculate frame time std::chrono::time_point frame_now = std::chrono::system_clock::now(); - frame_time = std::chrono::duration_cast(frame_now - frame_prev).count(); + frame_time = std::chrono::duration_cast>(frame_now - frame_prev).count(); frame_prev = frame_now; if (!eqsf_open && Config->ZonePort != 0) { @@ -674,4 +674,4 @@ void UpdateWindowTitle(char* iNewTitle) { } SetConsoleTitle(tmp); #endif -} \ No newline at end of file +} diff --git a/zone/pathfinder_nav_mesh.cpp b/zone/pathfinder_nav_mesh.cpp index 46e4ead56..7842d84a4 100644 --- a/zone/pathfinder_nav_mesh.cpp +++ b/zone/pathfinder_nav_mesh.cpp @@ -12,7 +12,7 @@ extern Zone *zone; -const int MaxNavmeshNodes = 4092; +const int MaxNavmeshNodes = 4096; struct PathfinderNavmesh::Implementation { @@ -43,9 +43,9 @@ IPathfinder::IPath PathfinderNavmesh::FindRoute(const glm::vec3 &start, const gl if (!m_impl->query) { m_impl->query = dtAllocNavMeshQuery(); - m_impl->query->init(m_impl->nav_mesh, MaxNavmeshNodes); } + m_impl->query->init(m_impl->nav_mesh, MaxNavmeshNodes); glm::vec3 current_location(start.x, start.z, start.y); glm::vec3 dest_location(end.x, end.z, end.y); diff --git a/zone/pathing.cpp b/zone/pathing.cpp index 49e84f72a..96916754c 100644 --- a/zone/pathing.cpp +++ b/zone/pathing.cpp @@ -92,7 +92,7 @@ glm::vec3 Mob::UpdatePath(float ToX, float ToY, float ToZ, float Speed, bool &Wa auto front = (*Route.begin()).pos; if (PathingLoopCount > 5) { - Teleport(front); + Teleport(front); //todo new teleport SendPosition(); Route.pop_front(); diff --git a/zone/perl_mob.cpp b/zone/perl_mob.cpp index ba0fe9b57..e7504c744 100644 --- a/zone/perl_mob.cpp +++ b/zone/perl_mob.cpp @@ -1166,55 +1166,6 @@ XS(XS_Mob_GMMove) { XSRETURN_EMPTY; } -XS(XS_Mob_SendPosUpdate); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendPosUpdate) { - dXSARGS; - if (items < 1 || items > 2) - Perl_croak(aTHX_ "Usage: Mob::SendPosUpdate(THIS, [uint8 send_to_self = 0])"); - { - Mob *THIS; - uint8 iSendToSelf; - - if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV *) SvRV(ST(0))); - THIS = INT2PTR(Mob *, tmp); - } else - Perl_croak(aTHX_ "THIS is not of type Mob"); - if (THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - if (items < 2) - iSendToSelf = 0; - else { - iSendToSelf = (uint8) SvUV(ST(1)); - } - - THIS->SendPositionUpdate(iSendToSelf != 0 ? true : false); - } - XSRETURN_EMPTY; -} - -XS(XS_Mob_SendPosition); /* prototype to pass -Wmissing-prototypes */ -XS(XS_Mob_SendPosition) { - dXSARGS; - if (items != 1) - Perl_croak(aTHX_ "Usage: Mob::SendPosition(THIS)"); - { - Mob *THIS; - - if (sv_derived_from(ST(0), "Mob")) { - IV tmp = SvIV((SV *) SvRV(ST(0))); - THIS = INT2PTR(Mob *, tmp); - } else - Perl_croak(aTHX_ "THIS is not of type Mob"); - if (THIS == nullptr) - Perl_croak(aTHX_ "THIS is nullptr, avoiding crash."); - - THIS->SendPosition(); - } - XSRETURN_EMPTY; -} - XS(XS_Mob_HasProcs); /* prototype to pass -Wmissing-prototypes */ XS(XS_Mob_HasProcs) { dXSARGS; @@ -8549,8 +8500,6 @@ XS(boot_Mob) { newXSproto(strcpy(buf, "DoAnim"), XS_Mob_DoAnim, file, "$$;$"); newXSproto(strcpy(buf, "ChangeSize"), XS_Mob_ChangeSize, file, "$$;$"); newXSproto(strcpy(buf, "GMMove"), XS_Mob_GMMove, file, "$$$$;$"); - newXSproto(strcpy(buf, "SendPosUpdate"), XS_Mob_SendPosUpdate, file, "$;$"); - newXSproto(strcpy(buf, "SendPosition"), XS_Mob_SendPosition, file, "$"); newXSproto(strcpy(buf, "HasProcs"), XS_Mob_HasProcs, file, "$"); newXSproto(strcpy(buf, "IsInvisible"), XS_Mob_IsInvisible, file, "$;$"); newXSproto(strcpy(buf, "SetInvisible"), XS_Mob_SetInvisible, file, "$$"); diff --git a/zone/questmgr.cpp b/zone/questmgr.cpp index 39d5b9f5d..0a86d9870 100644 --- a/zone/questmgr.cpp +++ b/zone/questmgr.cpp @@ -217,7 +217,7 @@ Mob* QuestManager::spawn2(int npc_type, int grid, int unused, const glm::vec4& p { npc->AssignWaypoints(grid); } - npc->SendPositionUpdate(); + return npc; } return nullptr; @@ -241,7 +241,7 @@ Mob* QuestManager::unique_spawn(int npc_type, int grid, int unused, const glm::v { npc->AssignWaypoints(grid); } - npc->SendPositionUpdate(); + return npc; } return nullptr; @@ -1693,8 +1693,6 @@ void QuestManager::respawn(int npcTypeID, int grid) { entity_list.AddNPC(owner->CastToNPC(),true,true); if(grid > 0) owner->CastToNPC()->AssignWaypoints(grid); - - owner->SendPositionUpdate(); } } diff --git a/zone/special_attacks.cpp b/zone/special_attacks.cpp index 538934694..ff3559db9 100644 --- a/zone/special_attacks.cpp +++ b/zone/special_attacks.cpp @@ -27,7 +27,7 @@ #include -extern uint64_t frame_time; +extern double frame_time; int Mob::GetBaseSkillDamage(EQEmu::skills::SkillType skill, Mob *target) { @@ -1033,7 +1033,7 @@ void Mob::ProjectileAttack() ProjectileAtk[i].skill = 0; ProjectileAtk[i].speed_mod = 0.0f; } else { - ProjectileAtk[i].increment += frame_time; + ProjectileAtk[i].increment += 1000 * frame_time; } } diff --git a/zone/spell_effects.cpp b/zone/spell_effects.cpp index da345fcdd..adcef8c76 100644 --- a/zone/spell_effects.cpp +++ b/zone/spell_effects.cpp @@ -826,8 +826,6 @@ bool Mob::SpellEffect(Mob* caster, uint16 spell_id, float partial, int level_ove #endif if(IsClient()) { - CastToClient()->SetSenseExemption(true); - if (CastToClient()->ClientVersionBit() & EQEmu::versions::bit_SoDAndLater) { bodyType bt = BT_Undead; @@ -4038,63 +4036,6 @@ void Mob::BuffFadeBySlot(int slot, bool iRecalcBonuses) SetLevel(GetOrigLevel()); break; } - - case SE_MovementSpeed: - { - if(IsClient()) - { - Client *my_c = CastToClient(); - uint32 cur_time = Timer::GetCurrentTime(); - if((cur_time - my_c->m_TimeSinceLastPositionCheck) > 1000) - { - float speed = (my_c->m_DistanceSinceLastPositionCheck * 100) / (float)(cur_time - my_c->m_TimeSinceLastPositionCheck); - float runs = my_c->GetRunspeed(); - if(speed > (runs * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - if(!my_c->GetGMSpeed() && (runs >= my_c->GetBaseRunspeed() || (speed > (my_c->GetBaseRunspeed() * RuleR(Zone, MQWarpDetectionDistanceFactor))))) - { - printf("%s %i moving too fast! moved: %.2f in %ims, speed %.2f\n", __FILE__, __LINE__, - my_c->m_DistanceSinceLastPositionCheck, (cur_time - my_c->m_TimeSinceLastPositionCheck), speed); - if(my_c->IsShadowStepExempted()) - { - if(my_c->m_DistanceSinceLastPositionCheck > 800) - { - my_c->CheatDetected(MQWarpShadowStep, my_c->GetX(), my_c->GetY(), my_c->GetZ()); - } - } - else if(my_c->IsKnockBackExempted()) - { - //still potential to trigger this if you're knocked back off a - //HUGE fall that takes > 2.5 seconds - if(speed > 30.0f) - { - my_c->CheatDetected(MQWarpKnockBack, my_c->GetX(), my_c->GetY(), my_c->GetZ()); - } - } - else if(!my_c->IsPortExempted()) - { - if(!my_c->IsMQExemptedArea(zone->GetZoneID(), my_c->GetX(), my_c->GetY(), my_c->GetZ())) - { - if(speed > (runs * 2 * RuleR(Zone, MQWarpDetectionDistanceFactor))) - { - my_c->m_TimeSinceLastPositionCheck = cur_time; - my_c->m_DistanceSinceLastPositionCheck = 0.0f; - my_c->CheatDetected(MQWarp, my_c->GetX(), my_c->GetY(), my_c->GetZ()); - //my_c->Death(my_c, 10000000, SPELL_UNKNOWN, _1H_BLUNT); - } - else - { - my_c->CheatDetected(MQWarpLight, my_c->GetX(), my_c->GetY(), my_c->GetZ()); - } - } - } - } - } - } - my_c->m_TimeSinceLastPositionCheck = cur_time; - my_c->m_DistanceSinceLastPositionCheck = 0.0f; - } - } } } diff --git a/zone/spells.cpp b/zone/spells.cpp index 60591b7b1..56f992dbe 100644 --- a/zone/spells.cpp +++ b/zone/spells.cpp @@ -305,8 +305,9 @@ bool Mob::CastSpell(uint16 spell_id, uint16 target_id, CastingSlot slot, } //To prevent NPC ghosting when spells are cast from scripts - if (IsNPC() && IsMoving() && cast_time > 0) - SendPosition(); + if (IsNPC() && IsMoving() && cast_time > 0) { + StopNavigation(); + } if(resist_adjust) { @@ -2665,23 +2666,6 @@ void Mob::BardPulse(uint16 spell_id, Mob *caster) { action->effect_flag = 4; - if(spells[spell_id].pushback != 0.0f || spells[spell_id].pushup != 0.0f) - { - if(IsClient()) - { - if(!IsBuffSpell(spell_id)) - { - CastToClient()->SetKnockBackExemption(true); - - } - } - } - - if(IsClient() && IsEffectInSpell(spell_id, SE_ShadowStep)) - { - CastToClient()->SetShadowStepExemption(true); - } - if(!IsEffectInSpell(spell_id, SE_BindAffinity)) { CastToClient()->QueuePacket(packet); @@ -3943,13 +3927,7 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r if(spells[spell_id].pushback != 0.0f || spells[spell_id].pushup != 0.0f) { - if(spelltar->IsClient()) - { - if(!IsBuffSpell(spell_id)) - { - spelltar->CastToClient()->SetKnockBackExemption(true); - } - } else if (RuleB(Spells, NPCSpellPush) && !spelltar->IsRooted() && spelltar->ForcedMovement == 0) { + if (RuleB(Spells, NPCSpellPush) && !spelltar->IsRooted() && spelltar->ForcedMovement == 0) { spelltar->m_Delta.x += action->force * g_Math.FastSin(action->hit_heading); spelltar->m_Delta.y += action->force * g_Math.FastCos(action->hit_heading); spelltar->m_Delta.z += action->hit_pitch; @@ -3957,11 +3935,6 @@ bool Mob::SpellOnTarget(uint16 spell_id, Mob *spelltar, bool reflect, bool use_r } } - if(spelltar->IsClient() && IsEffectInSpell(spell_id, SE_ShadowStep)) - { - spelltar->CastToClient()->SetShadowStepExemption(true); - } - if(!IsEffectInSpell(spell_id, SE_BindAffinity)) { if(spelltar != this && spelltar->IsClient()) // send to target @@ -4940,18 +4913,7 @@ void Mob::Mesmerize() if (casting_spell_id) InterruptSpell(); - SendPosition(); -/* this stuns the client for max time, with no way to break it - if (this->IsClient()){ - EQApplicationPacket* outapp = new EQApplicationPacket(OP_Stun, sizeof(Stun_Struct)); - Stun_Struct* stunon = (Stun_Struct*) outapp->pBuffer; - stunon->duration = 0xFFFF; - this->CastToClient()->QueuePacket(outapp); - safe_delete(outapp); - } else { - SetRunAnimSpeed(0); - } -*/ + StopNavigation(); } void Client::MakeBuffFadePacket(uint16 spell_id, int slot_id, bool send_message) diff --git a/zone/waypoints.cpp b/zone/waypoints.cpp index 2295cfd08..c49328848 100644 --- a/zone/waypoints.cpp +++ b/zone/waypoints.cpp @@ -93,7 +93,7 @@ void NPC::StopWandering() { // stops a mob from wandering, takes him off grid and sends him back to spawn point roamer = false; CastToNPC()->SetGrid(0); - SendPosition(); + StopNavigation(); Log(Logs::Detail, Logs::Pathing, "Stop Wandering requested."); return; } @@ -150,7 +150,7 @@ void NPC::PauseWandering(int pausetime) moving = false; DistractedFromGrid = true; Log(Logs::Detail, Logs::Pathing, "Paused Wandering requested. Grid %d. Resuming in %d ms (0=not until told)", GetGrid(), pausetime); - SendPosition(); + StopNavigation(); if (pausetime < 1) { // negative grid number stops him dead in his tracks until ResumeWandering() SetGrid(0 - GetGrid()); } @@ -619,11 +619,6 @@ float Mob::GetFixedZ(const glm::vec3 &destination, int32 z_find_offset) { return new_z; } -void Mob::DumpMovement(Client *to) -{ - mMovementManager->Dump(this, to); -} - void Mob::FixZ(int32 z_find_offset /*= 5*/, bool fix_client_z /*= false*/) { glm::vec3 current_loc(m_Position); diff --git a/zone/zone.cpp b/zone/zone.cpp index 1781dd819..7e2c597e0 100644 --- a/zone/zone.cpp +++ b/zone/zone.cpp @@ -1644,8 +1644,7 @@ ZonePoint* Zone::GetClosestZonePoint(const glm::vec3& location, uint32 to, Clien // this shouldn't open up any exploits since those situations are detected later on if ((zone->HasWaterMap() && !zone->watermap->InZoneLine(glm::vec3(client->GetPosition()))) || (!zone->HasWaterMap() && closest_dist > 400.0f && closest_dist < max_distance2)) { - if(client) - client->CheatDetected(MQZoneUnknownDest, location.x, location.y, location.z); // Someone is trying to use /zone + //TODO cheat detection Log(Logs::General, Logs::Status, "WARNING: Closest zone point for zone id %d is %f, you might need to update your zone_points table if you dont arrive at the right spot.", to, closest_dist); Log(Logs::General, Logs::Status, ". %s", to_string(location).c_str()); } diff --git a/zone/zoning.cpp b/zone/zoning.cpp index 9dcf0a774..1ca418eb8 100644 --- a/zone/zoning.cpp +++ b/zone/zoning.cpp @@ -95,7 +95,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //unable to find a zone point... is there anything else //that can be a valid un-zolicited zone request? - CheatDetected(MQZone, zc->x, zc->y, zc->z); + //Todo cheat detection Message(13, "Invalid unsolicited zone request."); Log(Logs::General, Logs::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); SendZoneCancel(zc); @@ -130,7 +130,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //then we assume this is invalid. if(!zone_point || zone_point->target_zone_id != target_zone_id) { Log(Logs::General, Logs::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%d'.", GetName(), target_zone_id); - CheatDetected(MQGate, zc->x, zc->y, zc->z); + //todo cheat detection SendZoneCancel(zc); return; } @@ -252,7 +252,7 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { //for now, there are no other cases... //could not find a valid reason for them to be zoning, stop it. - CheatDetected(MQZoneUnknownDest, 0.0, 0.0, 0.0); + //todo cheat detection Log(Logs::General, Logs::Error, "Zoning %s: Invalid unsolicited zone request to zone id '%s'. Not near a zone point.", GetName(), target_zone_name); SendZoneCancel(zc); return; @@ -296,7 +296,6 @@ void Client::Handle_OP_ZoneChange(const EQApplicationPacket *app) { void Client::SendZoneCancel(ZoneChange_Struct *zc) { //effectively zone them right back to where they were //unless we find a better way to stop the zoning process. - SetPortExemption(true); EQApplicationPacket *outapp = nullptr; outapp = new EQApplicationPacket(OP_ZoneChange, sizeof(ZoneChange_Struct)); ZoneChange_Struct *zc2 = (ZoneChange_Struct*)outapp->pBuffer; @@ -316,8 +315,6 @@ void Client::SendZoneError(ZoneChange_Struct *zc, int8 err) { Log(Logs::General, Logs::Error, "Zone %i is not available because target wasn't found or character insufficent level", zc->zoneID); - SetPortExemption(true); - EQApplicationPacket *outapp = nullptr; outapp = new EQApplicationPacket(OP_ZoneChange, sizeof(ZoneChange_Struct)); ZoneChange_Struct *zc2 = (ZoneChange_Struct*)outapp->pBuffer; @@ -488,8 +485,6 @@ void Client::ZonePC(uint32 zoneID, uint32 instance_id, float x, float y, float z pShortZoneName = database.GetZoneName(zoneID); database.GetZoneLongName(pShortZoneName, &pZoneName); - SetPortExemption(true); - if(!pZoneName) { Message(13, "Invalid zone number specified"); safe_delete_array(pZoneName);