[Cheat Detection] Anti-Cheat reimplementation (#1434)

* [Cheat Detection] Anti-Cheat reimplementation

* minor patch fixes

* ceiling to server side runspeed

Warp(LT) was picking up a bunch of expected 6.2 but it was reported back as 6.5, this should help reduce the amount of false positives we get

* use ceil instead of std::ceilf for linux

* boat false positive fix

* stopping the double detection

* fixes and cleanup

* auto merge tricked me...

* dummy divide by 0 checks

this should prevent anyone from setting Zone:MQWarpDetectionDistanceFactor to 0 and causing a crash.

* Formatting

* encapsulation to its own class and clean up

* more detections

* typo

* OP_UnderWorld implmentation

* Update client_packet.h

* Syntax changes, formatting, cleanup

* preventing crashes due to invalid packet size

* typos and clearer logic

* seperated the catagory for cheats

* Updated MQGhost for more detail

Co-authored-by: Akkadius <akkadius1@gmail.com>
This commit is contained in:
Dencelle
2021-08-31 01:08:31 -05:00
committed by GitHub
parent 26299354b6
commit 7b069dcf20
25 changed files with 664 additions and 26 deletions
+42 -2
View File
@@ -209,7 +209,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_FeignDeath] = &Client::Handle_OP_FeignDeath;
ConnectedOpcodes[OP_FindPersonRequest] = &Client::Handle_OP_FindPersonRequest;
ConnectedOpcodes[OP_Fishing] = &Client::Handle_OP_Fishing;
ConnectedOpcodes[OP_FloatListThing] = &Client::Handle_OP_Ignore;
ConnectedOpcodes[OP_FloatListThing] = &Client::Handle_OP_MovementHistoryList;
ConnectedOpcodes[OP_Forage] = &Client::Handle_OP_Forage;
ConnectedOpcodes[OP_FriendsWho] = &Client::Handle_OP_FriendsWho;
ConnectedOpcodes[OP_GetGuildMOTD] = &Client::Handle_OP_GetGuildMOTD;
@@ -413,6 +413,7 @@ void MapOpcodes()
ConnectedOpcodes[OP_YellForHelp] = &Client::Handle_OP_YellForHelp;
ConnectedOpcodes[OP_ZoneChange] = &Client::Handle_OP_ZoneChange;
ConnectedOpcodes[OP_ResetAA] = &Client::Handle_OP_ResetAA;
ConnectedOpcodes[OP_UnderWorld] = &Client::Handle_OP_UnderWorld;
}
void ClearMappedOpcode(EmuOpcode op)
@@ -2922,6 +2923,7 @@ void Client::Handle_OP_Assist(const EQApplicationPacket *app)
Mob *new_target = assistee->GetTarget();
if (new_target && (GetGM() ||
Distance(m_Position, assistee->GetPosition()) <= TARGETING_RANGE)) {
cheat_manager.SetExemptStatus(Assist, true);
eid->entity_id = new_target->GetID();
} else {
eid->entity_id = 0;
@@ -4488,7 +4490,7 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
double cosine = std::cos(thetar);
double sine = std::sin(thetar);
double normalizedx, normalizedy;
double normalizedx, normalizedy;
normalizedx = cx * cosine - -cy * sine;
normalizedy = -cx * sine + cy * cosine;
@@ -4500,6 +4502,8 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
}
}
cheat_manager.MovementCheck(glm::vec3(cx, cy, cz));
if (IsDraggingCorpse())
DragCorpses();
@@ -8765,6 +8769,7 @@ void Client::Handle_OP_ItemVerifyRequest(const EQApplicationPacket *app)
slot_id = request->slot;
target_id = request->target;
cheat_manager.ProcessItemVerifyRequest(request->slot, request->target);
EQApplicationPacket *outapp = nullptr;
outapp = new EQApplicationPacket(OP_ItemVerifyReply, sizeof(ItemVerifyReply_Struct));
@@ -9614,6 +9619,7 @@ return;
void Client::Handle_OP_MemorizeSpell(const EQApplicationPacket *app)
{
cheat_manager.CheckMemTimer();
OPMemorizeSpell(app);
return;
}
@@ -13465,6 +13471,8 @@ void Client::Handle_OP_SpawnAppearance(const EQApplicationPacket *app)
}
SpawnAppearance_Struct* sa = (SpawnAppearance_Struct*)app->pBuffer;
cheat_manager.ProcessSpawnApperance(sa->spawn_id, sa->type, sa->parameter);
if (sa->spawn_id != GetID())
return;
@@ -13917,6 +13925,11 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
GetTarget()->IsTargeted(1);
return;
}
else if (cheat_manager.GetExemptStatus(Assist)) {
GetTarget()->IsTargeted(1);
cheat_manager.SetExemptStatus(Assist, false);
return;
}
else if (GetTarget()->IsClient())
{
//make sure this client is in our raid/group
@@ -13932,6 +13945,15 @@ void Client::Handle_OP_TargetCommand(const EQApplicationPacket *app)
SetTarget((Mob*)nullptr);
return;
}
else if (cheat_manager.GetExemptStatus(Port)) {
GetTarget()->IsTargeted(1);
return;
}
else if (cheat_manager.GetExemptStatus(Sense)) {
GetTarget()->IsTargeted(1);
cheat_manager.SetExemptStatus(Sense, false);
return;
}
else if (IsXTarget(GetTarget()))
{
GetTarget()->IsTargeted(1);
@@ -15173,3 +15195,21 @@ void Client::Handle_OP_ResetAA(const EQApplicationPacket *app)
}
return;
}
void Client::Handle_OP_MovementHistoryList(const EQApplicationPacket* app) {
cheat_manager.ProcessMovementHistory(app);
}
void Client::Handle_OP_UnderWorld(const EQApplicationPacket* app) {
UnderWorld* m_UnderWorld = (UnderWorld*)app->pBuffer;
if (app->size != sizeof(UnderWorld))
{
LogDebug("Size mismatch in OP_UnderWorld, expected {}, got [{}]", sizeof(UnderWorld), app->size);
DumpPacket(app);
return;
}
auto dist = Distance(glm::vec3(m_UnderWorld->x, m_UnderWorld->y, zone->newzone_data.underworld), glm::vec3(m_UnderWorld->x, m_UnderWorld->y, m_UnderWorld->z));
cheat_manager.MovementCheck(glm::vec3(m_UnderWorld->x, m_UnderWorld->y, m_UnderWorld->z));
if (m_UnderWorld->spawn_id == GetID() && dist <= 5.0f && zone->newzone_data.underworld_teleport_index != 0)
cheat_manager.SetExemptStatus(Port, true);
}