吾爱尚玩资源基地

标题: 老的魔兽世界私服防外挂补丁mangos代码(加速) [打印本页]

作者: admin    时间: 2016-4-18 22:25
标题: 老的魔兽世界私服防外挂补丁mangos代码(加速)
最初的mangos防加速外挂的C++代码--仅供参考使用

Index: game/MovementHandler.cpp===================================================================
--- game/MovementHandler.cpp        (revision 81)
+++ game/MovementHandler.cpp        (working copy)
@@ -30,6 +30,9 @@
#include "WaypointMovementGenerator.h"
#include "InstanceSaveMgr.h"

+/*Movement anticheat DEBUG defines */
+//#define MOVEMENT_ANTICHEAT_DEBUG true
+/*end Movement anticheate defines*/
void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ )
{
     sLog.outDebug( "WORLD: got MSG_MOVE_WORLDPORT_ACK." );
@@ -47,7 +50,8 @@
         LogoutPlayer(false);
         return;
     }
-
+    //reset falltimer at teleport
+    GetPlayer()->m_anti_justteleported = 1;
     // get the destination map entry, not the current one, this will fix homebind and reset greeting
     MapEntry const* mEntry = sMapStore.LookupEntry(loc.mapid);
     InstanceTemplate const* mInstance = objmgr.GetInstanceTemplate(loc.mapid);
@@ -179,8 +183,10 @@
     uint32 opcode = recv_data.GetOpcode();
     sLog.outDebug("WORLD: Recvd %s (%u, 0x%X) opcode", LookupOpcodeName(opcode), opcode, opcode);

-    if(GetPlayer()->GetDontMove())
+    if(GetPlayer()->GetDontMove()){
+        GetPlayer()->m_anti_justteleported = 1;
         return;
+    }

     /* extract packet */
     MovementInfo movementInfo;
@@ -202,48 +208,81 @@
     {
         // transports size limited
         // (also received at zeppelin leave by some reason with t_* as absolute in continent coordinates, can be safely skipped)
-        if( movementInfo.t_x > 50 || movementInfo.t_y > 50 || movementInfo.t_z > 50 )
+        if( movementInfo.t_x > 60 || movementInfo.t_y > 60 || movementInfo.t_x < -60 ||  movementInfo.t_y < -60 )
             return;

         if( !MaNGOS::IsValidMapCoord(movementInfo.x+movementInfo.t_x, movementInfo.y+movementInfo.t_y,
             movementInfo.z+movementInfo.t_z, movementInfo.o+movementInfo.t_o) )
             return;
-
-        // if we boarded a transport, add us to it
-        if (!GetPlayer()->m_transport)
+        if ((GetPlayer()->m_anti_transportGUID == 0) && (movementInfo.t_guid !=0))
         {
-            // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
-            for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
+            // if we boarded a transport, add us to it
+            if (!GetPlayer()->m_transport)
             {
-                if ((*iter)->GetGUID() == movementInfo.t_guid)
+                // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list
+                for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
                 {
-                    GetPlayer()->m_transport = (*iter);
-                    (*iter)->AddPassenger(GetPlayer());
-                    break;
+                    if ((*iter)->GetGUID() == movementInfo.t_guid)
+                    {
+                        GetPlayer()->m_transport = (*iter);
+                        (*iter)->AddPassenger(GetPlayer());
+                        break;
+                    }
                 }
             }
+            ///GetPlayer()->m_anti_transportGUID = GUID_LOPART(movementInfo.t_guid);
+            //Correct finding GO guid in DB (thanks to GriffonHeart)
+            GameObject *obj = HashMapHolder<GameObject>::Find(movementInfo.t_guid);
+            if(obj)
+                GetPlayer()->m_anti_transportGUID = obj->GetDBTableGUIDLow();
+            else
+                GetPlayer()->m_anti_transportGUID = GUID_LOPART(movementInfo.t_guid);
         }
     }
-    else if (GetPlayer()->m_transport)                      // if we were on a transport, leave
+    else if (GetPlayer()->m_anti_transportGUID != 0)
     {
-        GetPlayer()->m_transport->RemovePassenger(GetPlayer());
-        GetPlayer()->m_transport = NULL;
+        if (GetPlayer()->m_transport)                      // if we were on a transport, leave
+        {
+            GetPlayer()->m_transport->RemovePassenger(GetPlayer());
+            GetPlayer()->m_transport = NULL;
+        }
         movementInfo.t_x = 0.0f;
         movementInfo.t_y = 0.0f;
         movementInfo.t_z = 0.0f;
         movementInfo.t_o = 0.0f;
         movementInfo.t_time = 0;
         movementInfo.t_seat = -1;
+        GetPlayer()->m_anti_transportGUID = 0;
     }

     // fall damage generation (ignore in flight case that can be triggered also at lags in moment teleportation to another map).
     if (opcode == MSG_MOVE_FALL_LAND && !GetPlayer()->isInFlight())
     {
+        GetPlayer()->m_anti_justjumped = 0;
         // calculate total z distance of the fall
         float z_diff = GetPlayer()->m_lastFallZ - movementInfo.z;
         sLog.outDebug("zDiff = %f", z_diff);
         Player *target = GetPlayer();

+        /* //movement anticheat "No Fall Damage"
+        if (target->m_anti_beginfalltime != 0)
+        {
+            #ifdef MOVEMENT_ANTICHEAT_DEBUG
+            sLog.outDebug("Movement anticheat: alternate FallTime %d | client falltime %d | m_anti_justteleported = %d",movementInfo.time - GetPlayer()->m_anti_beginfalltime, movementInfo.fallTime, GetPlayer()->m_anti_justteleported );
+            #endif
+            if (target->m_anti_justteleported != 1){
+                uint32 alt_falltime = movementInfo.time - target->m_anti_beginfalltime;
+                movementInfo.fallTime = (alt_falltime < movementInfo.fallTime) ? movementInfo.fallTime : alt_falltime;
+            } else {
+                target->m_anti_justteleported = 0;
+            }
+            target->m_anti_beginfalltime = 0;
+        }
+        #ifdef MOVEMENT_ANTICHEAT_DEBUG
+        sLog.outError("Movement anticheat: FallTime %d", movementInfo.fallTime);
+        #endif
+        //end movement anticheate */
+
         //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
         // 14.57 can be calculated by resolving damageperc formular below to 0
         if (z_diff >= 14.57f && !target->isDead() && !target->isGameMaster() &&
@@ -291,9 +330,244 @@
         GetPlayer()->SetInWater( !GetPlayer()->IsInWater() || GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );
     }

+    #ifdef MOVEMENT_ANTICHEAT_DEBUG
+    sLog.outBasic("%s newcoord: tm:%d ftm:%d | %f,%f,%fo(%f) [%X][%s]| transport: %f,%f,%fo(%f)",GetPlayer()->GetName(),movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,movementInfo.flags, LookupOpcodeName(opcode),movementInfo.t_x,movementInfo.t_y,movementInfo.t_z,movementInfo.t_o);
+    sLog.outBasic("Transport: %d |  tguid: %d - %d", GetPlayer()->m_anti_transportGUID, GUID_LOPART(movementInfo.t_guid), GUID_HIPART(movementInfo.t_guid));
+    #endif
     /*----------------------*/
+    //---- anti-cheat features -->>>
+    bool check_passed = true;

+    //calc time deltas
+    int32 timedelta = 1500;
+    if (GetPlayer()->m_anti_lastmovetime !=0){
+        timedelta = movementInfo.time - GetPlayer()->m_anti_lastmovetime;
+        GetPlayer()->m_anti_deltamovetime += timedelta;
+        GetPlayer()->m_anti_lastmovetime = movementInfo.time;
+    } else {
+        GetPlayer()->m_anti_lastmovetime = movementInfo.time;
+    }
+
+    uint32 CurrentMStime=getMSTime();
+    uint32 CurrentMStimeDelta = 1500;
+    if (GetPlayer()->m_anti_lastMStime != 0){
+        CurrentMStimeDelta = CurrentMStime - GetPlayer()->m_anti_lastMStime;
+        GetPlayer()->m_anti_deltaMStime += CurrentMStimeDelta;
+        GetPlayer()->m_anti_lastMStime = CurrentMStime;
+    } else {
+        GetPlayer()->m_anti_lastMStime = CurrentMStime;
+    }
+
+    int32 sync_time = GetPlayer()->m_anti_deltamovetime - GetPlayer()->m_anti_deltaMStime;
+
+    #ifdef MOVEMENT_ANTICHEAT_DEBUG
+    sLog.outBasic("dtime: %d, stime: %d || dMS: %d - dMV: %d || dt: %d", timedelta, CurrentMStime, GetPlayer()->m_anti_deltaMStime,  GetPlayer()->m_anti_deltamovetime, sync_time);
+    #endif
+
+    uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination(); //check taxi flight
+    if ((GetPlayer()->m_anti_transportGUID == 0) && World::GetEnableMvAnticheat() && !curDest)
+    {
+        UnitMoveType move_type;
+
+        if (movementInfo.flags & MOVEMENTFLAG_FLYING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_FLIGHT_BACK : MOVE_FLIGHT;
+        else if (movementInfo.flags & MOVEMENTFLAG_SWIMMING) move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_SWIM;
+        else if (movementInfo.flags & MOVEMENTFLAG_WALK_MODE) move_type = MOVE_WALK;
+        //hmm... in first time after login player has MOVE_SWIMBACK instead MOVE_WALKBACK
+        else move_type = movementInfo.flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIM_BACK : MOVE_RUN;
+
+        float allowed_delta= 0;
+        float current_speed = GetPlayer()->GetSpeed(move_type);
+        float delta_x = GetPlayer()->GetPositionX() - movementInfo.x;
+        float delta_y = GetPlayer()->GetPositionY() - movementInfo.y;
+        float delta_z = GetPlayer()->GetPositionZ() - movementInfo.z;
+        float real_delta = delta_x * delta_x + delta_y * delta_y;
+        float tg_z = -99999; //tangens
+
+        int32 gmd = World::GetMistimingDelta();
+        if (sync_time > gmd || sync_time < -gmd){
+            timedelta = CurrentMStimeDelta;
+            GetPlayer()->m_anti_mistiming_count++;
+            
+            sLog.outError("Movement anticheat: %s is mistaming exception. Exception count: %d, mistiming: %d ms ", GetPlayer()->GetName(), GetPlayer()->m_anti_mistiming_count, sync_time);
+            if (GetPlayer()->m_anti_mistiming_count > World::GetMistimingAlarms())
+            {
+                GetPlayer()->GetSession()->KickPlayer();
+                ///sLog.outError("Movement anticheat: %s is mistaming exception. Exception count: %d, mistiming: %d ms ", GetPlayer()->GetName(), GetPlayer()->m_anti_mistiming_count, sync_time);
+            }
+            check_passed = false;
+        }
+
+        if (timedelta < 0) {timedelta = 0;}
+        float time_delta = (timedelta < 1500) ? (float)timedelta/1000 : 1.5f; //normalize time - 1.5 second allowed for heavy loaded server
+
+        if (!(movementInfo.flags & (MOVEMENTFLAG_FLYING | MOVEMENTFLAG_SWIMMING)))
+          tg_z = (real_delta !=0) ? (delta_z*delta_z / real_delta) : -99999;
+
+        /* //antiOFF fall-damage, MOVEMENTFLAG_UNK4 seted by client if player try movement when falling and unset in this case the MOVEMENTFLAG_FALLING flag.
+        if (movementInfo.flags & (MOVEMENTFLAG_FALLING | MOVEMENTFLAG_UNK4 | MOVEMENTFLAG_JUMPING))
+        {
+            if (GetPlayer()->m_anti_beginfalltime == 0)
+            {
+                GetPlayer()->m_anti_beginfalltime = movementInfo.time;
+                #ifdef MOVEMENT_ANTICHEAT_DEBUG
+                sLog.outDebug("Movement anticheat: begin fall-time %d",GetPlayer()->m_anti_beginfalltime);
+                #endif
+            }
+        } else {
+            if (GetPlayer()->m_anti_beginfalltime != 0)
+            {
+                GetPlayer()->m_anti_beginfalltime = 0; // reset timer if we landed without MSG_MOVE_FALL_LAND opcode
+                #ifdef MOVEMENT_ANTICHEAT_DEBUG
+                sLog.outDebug("Movement anticheat: end fall-time %d",GetPlayer()->m_anti_beginfalltime);
+                #endif
+            }
+        }
+        */
+
+        if (current_speed < GetPlayer()->m_anti_last_hspeed)
+        {
+            allowed_delta = GetPlayer()->m_anti_last_hspeed;
+            if (GetPlayer()->m_anti_lastspeed_changetime == 0 )
+                GetPlayer()->m_anti_lastspeed_changetime = movementInfo.time + (uint32)floor(((GetPlayer()->m_anti_last_hspeed / current_speed) * 1000)) + 100; //100ms above for random fluctuating =)))
+        } else allowed_delta = current_speed;
+        allowed_delta = allowed_delta * time_delta;
+        allowed_delta = allowed_delta * allowed_delta + 2;
+
+       // static char const* move_type_name[MAX_MOVE_TYPE] = {  "Walk", "Run", "Walkback", "Swim", "Swimback", "Turn", "Fly", "Flyback" };
+       // sLog.outBasic("%s newcoord: tm:%d ftm:%d | %f,%f,%fo(%f) [%X][%s]$%s",GetPlayer()->GetName(),movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,MovementFlags, LookupOpcodeName(opcode),move_type_name[move_type]);
+       // sLog.outBasic("%f",tg_z);
+
+        if (opcode == MSG_MOVE_JUMP && !GetPlayer()->IsInWater()){
+            if (GetPlayer()->m_anti_justjumped >= 1){
+                ///GetPlayer()->m_anti_justjumped = 0;
+                check_passed = false; //don't process new jump packet
+            } else {
+                GetPlayer()->m_anti_justjumped += 1;
+            }
+        } else if (GetPlayer()->IsInWater()) {
+             GetPlayer()->m_anti_justjumped = 0;
+        }
+        if ((real_delta > allowed_delta)) //&& (delta_z < 1)
+        {
+            #ifdef MOVEMENT_ANTICHEAT_DEBUG
+            sLog.outError("Movement anticheat: %s is speed exception. {real_delta=%f allowed_delta=%f | current_speed=%f preview_speed=%f time=%f}(%f %f %f %d)[%s]",GetPlayer()->GetName(),real_delta, allowed_delta, current_speed, GetPlayer()->m_anti_last_hspeed,time_delta,GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId(),LookupOpcodeName(opcode));
+            #endif
+            check_passed = false;
+        }
+        if ((real_delta>4900.0f) && !(real_delta < allowed_delta))
+        {
+            #ifdef MOVEMENT_ANTICHEAT_DEBUG
+            sLog.outError("Movement anticheat: %s is teleport exception. {real_delta=%f allowed_delta=%f | current_speed=%f preview_speed=%f time=%f}(%f %f %f %d)",GetPlayer()->GetName(),real_delta, allowed_delta, current_speed, GetPlayer()->m_anti_last_hspeed,time_delta,GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId());
+            #endif
+            check_passed = false;
+        }
+        if (movementInfo.time>GetPlayer()->m_anti_lastspeed_changetime)
+        {
+            GetPlayer()->m_anti_last_hspeed = current_speed; // store current speed
+            GetPlayer()->m_anti_last_vspeed = -3.2f;
+            if (GetPlayer()->m_anti_lastspeed_changetime != 0) GetPlayer()->m_anti_lastspeed_changetime = 0;
+        }
+
+        if ((tg_z > 1.56f) && (delta_z < GetPlayer()->m_anti_last_vspeed))
+        {
+            #ifdef MOVEMENT_ANTICHEAT_DEBUG
+            sLog.outError("Movement anticheat: %s is mountain exception. {tg_z=%f} (%f %f %f %d)",GetPlayer()->GetName(),tg_z, GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId());
+            #endif
+            check_passed = false;
+        }
+        if (((movementInfo.flags & (MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) != 0) && !GetPlayer()->isGameMaster() && !(GetPlayer()->HasAuraType(SPELL_AURA_FLY) || GetPlayer()->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED)))
+        {
+            #ifdef MOVEMENT_ANTICHEAT_DEBUG
+            sLog.outError("Movement anticheat: %s is fly cheater. {SPELL_AURA_FLY=[%X]} {SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED=[%X]} {SPELL_AURA_MOD_SPEED_FLIGHT=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS=[%X]} {SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK=[%X]}",
+               GetPlayer()->GetName(),
+               GetPlayer()->HasAuraType(SPELL_AURA_FLY), GetPlayer()->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED),
+               GetPlayer()->HasAuraType(SPELL_AURA_MOD_SPEED_FLIGHT), GetPlayer()->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_ALWAYS),
+               GetPlayer()->HasAuraType(SPELL_AURA_MOD_FLIGHT_SPEED_NOT_STACK));
+            #endif
+            check_passed = false;
+        }
+        if (((movementInfo.flags & MOVEMENTFLAG_WATERWALKING) != 0) && !GetPlayer()->isGameMaster() && !(GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK) | GetPlayer()->HasAuraType(SPELL_AURA_GHOST)))
+        {
+            #ifdef MOVEMENT_ANTICHEAT_DEBUG
+            sLog.outError("Movement anticheat: %s is water-walk exception. [%X]{SPELL_AURA_WATER_WALK=[%X]}", GetPlayer()->GetName(), movementInfo.flags, GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK));
+            #endif
+            check_passed = false;
+        }
+        if(movementInfo.z < 0.0001f && movementInfo.z > -0.0001f && ((movementInfo.flags & (MOVEMENTFLAG_SWIMMING | MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) == 0) && !GetPlayer()->isGameMaster() )
+        {
+            // Prevent using TeleportToPlan.
+            Map *map = GetPlayer()->GetMap();
+            if (map){
+                float plane_z = map->GetHeight(movementInfo.x, movementInfo.y, MAX_HEIGHT) - movementInfo.z;
+                plane_z = (plane_z < -500.0f) ? 0 : plane_z; //check holes in heigth map
+                if(plane_z > 0.1f || plane_z < -0.1f)
+                {
+                    GetPlayer()->m_anti_teletoplane_count++;
+                    check_passed = false;
+                    #ifdef MOVEMENT_ANTICHEAT_DEBUG
+                    sLog.outDebug("Movement anticheat: %s is teleport to plan exception. plane_z: %f ", GetPlayer()->GetName(), plane_z);
+                    #endif
+                    if (GetPlayer()->m_anti_teletoplane_count > World::GetTeleportToPlaneAlarms())
+                    {
+                        GetPlayer()->GetSession()->KickPlayer();
+                        sLog.outError("Movement anticheat: %s is teleport to plan exception. Exception count: %d ", GetPlayer()->GetName(), GetPlayer()->m_anti_teletoplane_count);
+                    }
+                }
+            }
+        } else {
+            if (GetPlayer()->m_anti_teletoplane_count !=0)
+                GetPlayer()->m_anti_teletoplane_count = 0;
+        }
+    } else if (movementInfo.flags & MOVEMENTFLAG_ONTRANSPORT) {
+            //antiwrap =)
+        if (GetPlayer()->m_transport)
+        {
+            float trans_rad = movementInfo.t_x*movementInfo.t_x + movementInfo.t_y*movementInfo.t_y + movementInfo.t_z*movementInfo.t_z;
+            if (trans_rad > 3600.0f)
+                check_passed = false;
+        } else {
+            if (GameObjectData const* go_data = objmgr.GetGOData(GetPlayer()->m_anti_transportGUID))
+            {
+                float delta_gox = go_data->posX - movementInfo.x;
+                float delta_goy = go_data->posY - movementInfo.y;
+                float delta_goz = go_data->posZ - movementInfo.z;
+                int mapid = go_data->mapid;
+                #ifdef MOVEMENT_ANTICHEAT_DEBUG
+                sLog.outDebug("Movement anticheat: %s on some transport. xyzo: %f,%f,%f", GetPlayer()->GetName(), go_data->posX,go_data->posY,go_data->posZ);
+                #endif
+                if (GetPlayer()->GetMapId() != mapid){
+                    check_passed = false;
+                } else if (mapid !=369) {
+                    float delta_go = delta_gox*delta_gox + delta_goy*delta_goy;
+                    if (delta_go > 3600.0f)
+                        check_passed = false;
+                }
+
+            } else {
+                #ifdef MOVEMENT_ANTICHEAT_DEBUG
+                sLog.outDebug("Movement anticheat: %s on undefined transport.", GetPlayer()->GetName());
+                #endif
+                check_passed = false;
+            }
+        }
+        if (!check_passed){
+            if (GetPlayer()->m_transport)
+                {
+                    GetPlayer()->m_transport->RemovePassenger(GetPlayer());
+                    GetPlayer()->m_transport = NULL;
+                }
+                movementInfo.t_x = 0.0f;
+                movementInfo.t_y = 0.0f;
+                movementInfo.t_z = 0.0f;
+                movementInfo.t_o = 0.0f;
+                movementInfo.t_time = 0;
+                GetPlayer()->m_anti_transportGUID = 0;
+        }
+    }
     /* process position-change */
+    if (check_passed)
+    {
+
     Unit *mover = _player->m_mover;
     recv_data.put<uint32>(6, getMSTime());                  // fix time, offset flags(4) + unk(2)
     WorldPacket data(recv_data.GetOpcode(), (mover->GetPackGUID().size()+recv_data.size()));
@@ -326,8 +600,8 @@
     if (GetPlayer()->m_lastFallTime >= movementInfo.fallTime || GetPlayer()->m_lastFallZ <=movementInfo.z || recv_data.GetOpcode() == MSG_MOVE_FALL_LAND)
         GetPlayer()->SetFallInformation(movementInfo.fallTime, movementInfo.z);

-    if(GetPlayer()->isMovingOrTurning())
-        GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);
+        if(GetPlayer()->isMovingOrTurning())
+            GetPlayer()->RemoveSpellsCausingAura(SPELL_AURA_FEIGN_DEATH);

     if(movementInfo.z < -500.0f)
     {
@@ -355,6 +629,20 @@
             GetPlayer()->RepopAtGraveyard();
         }
     }
+
+        if (GetPlayer()->m_anti_alarmcount > 0){
+            sLog.outError("Movement anticheat: %s produce %d anticheat alarms",GetPlayer()->GetName(),GetPlayer()->m_anti_alarmcount);
+            GetPlayer()->m_anti_alarmcount = 0;
+        }
+    } else {
+        GetPlayer()->m_anti_alarmcount++;
+        WorldPacket data;
+        GetPlayer()->SetUnitMovementFlags(0);
+        GetPlayer()->BuildTeleportAckMsg(&data, GetPlayer()->GetPositionX(), GetPlayer()->GetPositionY(), GetPlayer()->GetPositionZ(), GetPlayer()->GetOrientation());
+        GetPlayer()->GetSession()->SendPacket(&data);
+        GetPlayer()->BuildHeartBeatMsg(&data);
+        GetPlayer()->SendMessageToSet(&data, true);
+    }
}

void WorldSession::HandleForceSpeedChangeAck(WorldPacket &recv_data)
@@ -507,34 +795,31 @@
     GetPlayer()->SendMessageToSet(&data, false);
}

-void WorldSession::HandleMoveKnockBackAck( WorldPacket & /*recv_data*/ )
+void WorldSession::HandleMoveKnockBackAck( WorldPacket & recv_data )
{
     // CHECK_PACKET_SIZE(recv_data,?);
     sLog.outDebug("CMSG_MOVE_KNOCK_BACK_ACK");
     // Currently not used but maybe use later for recheck final player position
     // (must be at call same as into "recv_data >> x >> y >> z >> orientation;"

-    /*
-    uint32 flags, time;
-    float x, y, z, orientation;
-    uint64 guid;
-    uint32 sequence;
-    uint32 ukn1;
-    float xdirection,ydirection,hspeed,vspeed;
+    /* extract packet */
+    MovementInfo movementInfo;
+    uint32 unk1,unk2,unk3;
+    recv_data >> unk1 >> unk2 >> unk3;
+    ReadMovementInfo(recv_data, &movementInfo);

-    recv_data >> guid;
-    recv_data >> sequence;
-    recv_data >> flags >> time;
-    recv_data >> x >> y >> z >> orientation;
-    recv_data >> ukn1; //unknown
-    recv_data >> vspeed >> xdirection >> ydirection >> hspeed;
+    //Save movement flags
+    _player->SetUnitMovementFlags(movementInfo.flags);

-    // skip not personal message;
-    if(GetPlayer()->GetGUID()!=guid)
-        return;
+    #ifdef MOVEMENT_ANTICHEAT_DEBUG
+    sLog.outBasic("%s CMSG_MOVE_KNOCK_BACK_ACK: tm:%d ftm:%d | %f,%f,%fo(%f) [%X]",GetPlayer()->GetName(),movementInfo.time,movementInfo.fallTime,movementInfo.x,movementInfo.y,movementInfo.z,movementInfo.o,movementInfo.flags);
+    sLog.outBasic("%s CMSG_MOVE_KNOCK_BACK_ACK additional: vspeed:%f, hspeed:%f",GetPlayer()->GetName(), movementInfo.j_unk, movementInfo.j_xyspeed);
+    #endif

-    // check code
-    */
+    _player->m_movementInfo = movementInfo;
+    _player->m_anti_last_hspeed = movementInfo.j_xyspeed;
+    _player->m_anti_last_vspeed = movementInfo.j_unk < 3.2f ? movementInfo.j_unk - 1.0f : 3.2f;
+    _player->m_anti_lastspeed_changetime = movementInfo.time + 1750;
}

void WorldSession::HandleMoveHoverAck( WorldPacket& /*recv_data*/ )
Index: game/Player.cpp
===================================================================
--- game/Player.cpp        (revision 81)
+++ game/Player.cpp        (working copy)
@@ -398,7 +398,24 @@
     m_rest_bonus=0;
     rest_type=REST_TYPE_NO;
     ////////////////////Rest System/////////////////////
+    //movement anticheat
+    m_anti_lastmovetime = 0;     //last movement time
+    m_anti_transportGUID = 0;    //current transport GUID
+    m_anti_last_hspeed = 7.0f;   //horizontal speed, default RUN speed
+    m_anti_lastspeed_changetime = 0; //last speed change time
+    m_anti_last_vspeed = -2.0f;  //vertical speed, default max jump height
+    m_anti_beginfalltime = 0;    //alternative falling begin time
+    m_anti_justteleported = 0;   //seted when player was teleported
+    m_anti_teletoplane_count = 0;//Teleport To Plane alarm counter

+    m_anti_lastMStime = 0;       //last movement server time
+    m_anti_deltamovetime = 0;
+    m_anti_deltaMStime = 0;
+    m_anti_mistiming_count = 0;
+   
+    m_anti_justjumped = 0;       //jump already began  
+    m_anti_alarmcount = 0;       //alarm counter
+    /////////////////////////////////
     m_mailsLoaded = false;
     m_mailsUpdated = false;
     unReadMails = 0;
@@ -1493,7 +1510,8 @@
         sLog.outError("TeleportTo: invalid map %d or absent instance template.", mapid);
         return false;
     }
-
+    //reset falltimer at teleport
+    m_anti_justteleported = 1;
     // preparing unsummon pet if lost (we must get pet before teleportation or will not find it later)
     Pet* pet = GetPet();

Index: game/Player.h
===================================================================
--- game/Player.h        (revision 81)
+++ game/Player.h        (working copy)
@@ -2348,7 +2348,23 @@
         float m_rest_bonus;
         RestType rest_type;
         ////////////////////Rest System/////////////////////
+        //movement anticheat
+        uint32 m_anti_lastmovetime;     //last movement time
+        uint64 m_anti_transportGUID;    //current transport GUID
+        float  m_anti_last_hspeed;      //horizontal speed, default RUN speed
+        uint32 m_anti_lastspeed_changetime;  //last speed change time
+        float  m_anti_last_vspeed;      //vertical speed, default max jump height
+        uint32 m_anti_beginfalltime;    //alternative falling begin time
+        uint32 m_anti_justteleported;   //seted when player was teleported
+        uint32 m_anti_teletoplane_count;//Teleport To Plane alarm counter

+        uint32 m_anti_lastMStime;       //last movement server time
+        uint32 m_anti_deltamovetime;    //client side session time
+        uint32 m_anti_deltaMStime;      //server side session time
+        uint32 m_anti_mistiming_count;  //mistiming counts before kick
+
+        uint32 m_anti_justjumped;       //Jump already began, anti air jump check  
+        uint64 m_anti_alarmcount;       //alarm counter
         // Transports
         Transport * m_transport;

Index: game/TaxiHandler.cpp
===================================================================
--- game/TaxiHandler.cpp        (revision 81)
+++ game/TaxiHandler.cpp        (working copy)
@@ -192,7 +192,7 @@
     GetPlayer()->ActivateTaxiPathTo(nodes, 0, npc);
}

-void WorldSession::HandleTaxiNextDestinationOpcode(WorldPacket& /*recv_data*/)
+void WorldSession::HandleTaxiNextDestinationOpcode(WorldPacket& recv_data)
{
     sLog.outDebug( "WORLD: Received CMSG_MOVE_SPLINE_DONE" );

@@ -200,12 +200,79 @@
     // 1) end taxi path in far (multi-node) flight
     // 2) switch from one map to other in case multim-map taxi path
     // we need proccess only (1)
+
+    //movement anticheat code
+    /* extract packet */
+    MovementInfo movementInfo;
+    ReadMovementInfo(recv_data, &movementInfo);
+    //<<< end movement anticheat
+
     uint32 curDest = GetPlayer()->m_taxi.GetTaxiDestination();
     if(!curDest)
+    {
+        //movement anticheat code
+        GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+        GetPlayer()->m_movementInfo = movementInfo;
+        GetPlayer()->SetUnitMovementFlags(movementInfo.flags);
+
+        int32 timedelta = 0;
+        if (GetPlayer()->m_anti_lastmovetime !=0){
+            timedelta = movementInfo.time - GetPlayer()->m_anti_lastmovetime;
+            GetPlayer()->m_anti_deltamovetime += timedelta;
+            GetPlayer()->m_anti_lastmovetime = movementInfo.time;
+        } else {
+            GetPlayer()->m_anti_lastmovetime = movementInfo.time;
+        }
+
+        uint32 CurTime=getMSTime();
+        uint32 CurTimeDelta = 0;
+        if (GetPlayer()->m_anti_lastMStime != 0){
+            CurTimeDelta = CurTime - GetPlayer()->m_anti_lastMStime;
+            GetPlayer()->m_anti_deltaMStime += CurTimeDelta;
+            GetPlayer()->m_anti_lastMStime = CurTime;
+        } else {
+            GetPlayer()->m_anti_lastMStime = CurTime;
+        }
+
+        //sLog.outBasic("dtime: %d, stime: %d || dMS: %d - dMV: %d || dt: %d", timedelta, CurTime, GetPlayer()->m_anti_deltaMStime,  GetPlayer()->m_anti_deltamovetime);
+
+        GetPlayer()->m_anti_justteleported = 1;
+        //<<< end movement anticheat
         return;
+    }

     TaxiNodesEntry const* curDestNode = sTaxiNodesStore.LookupEntry(curDest);

+    if(curDestNode && curDestNode->map_id == GetPlayer()->GetMapId())
+    {
+        while(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()==FLIGHT_MOTION_TYPE)
+            GetPlayer()->GetMotionMaster()->MovementExpired(false);
+    }
+
+    //movement anticheat code
+    GetPlayer()->SetPosition(movementInfo.x, movementInfo.y, movementInfo.z, movementInfo.o);
+    GetPlayer()->m_movementInfo = movementInfo;
+    GetPlayer()->SetUnitMovementFlags(movementInfo.flags);
+    int32 timedelta = 0;
+    if (GetPlayer()->m_anti_lastmovetime !=0){
+        timedelta = movementInfo.time - GetPlayer()->m_anti_lastmovetime;
+        GetPlayer()->m_anti_deltamovetime += timedelta;
+        GetPlayer()->m_anti_lastmovetime = movementInfo.time;
+    } else {
+        GetPlayer()->m_anti_lastmovetime = movementInfo.time;
+    }
+
+    uint32 CurTime=getMSTime();
+    uint32 CurTimeDelta = 0;
+    if (GetPlayer()->m_anti_lastMStime != 0){
+        CurTimeDelta = CurTime - GetPlayer()->m_anti_lastMStime;
+        GetPlayer()->m_anti_deltaMStime += CurTimeDelta;
+        GetPlayer()->m_anti_lastMStime = CurTime;
+    } else {
+        GetPlayer()->m_anti_lastMStime = CurTime;
+    }
+    //<<< end movement anticheat
+
     // far teleport case
     if(curDestNode && curDestNode->map_id != GetPlayer()->GetMapId())
     {
Index: game/World.cpp
===================================================================
--- game/World.cpp        (revision 81)
+++ game/World.cpp        (working copy)
@@ -72,7 +72,11 @@
float World::m_MaxVisibleDistanceInFlight     = DEFAULT_VISIBILITY_DISTANCE;
float World::m_VisibleUnitGreyDistance        = 0;
float World::m_VisibleObjectGreyDistance      = 0;
-
+//movement anticheat
+bool World::m_EnableMvAnticheat = true;
+uint32  World::m_TeleportToPlaneAlarms = 50;
+uint32 World::m_MistimingAlarms = 20;
+uint32 World::m_MistimingDelta = 2000;
// ServerMessages.dbc
enum ServerMessageType
{
@@ -537,7 +541,35 @@
         sLog.outError("DurabilityLossChance.Block (%f) must be >=0. Using 0.0 instead.",rate_values[RATE_DURABILITY_LOSS_BLOCK]);
         rate_values[RATE_DURABILITY_LOSS_BLOCK] = 0.0f;
     }
-
+    // movement anticheat
+    m_EnableMvAnticheat = sConfig.GetBoolDefault("Anticheat.Movement.Enable",true);
+    m_TeleportToPlaneAlarms = sConfig.GetIntDefault("Anticheat.Movement.TeleportToPlaneAlarms", 50);
+    if (m_TeleportToPlaneAlarms<20){
+        sLog.outError("Anticheat.Movement.TeleportToPlaneAlarms (%d) must be >=20. Using 20 instead.",m_TeleportToPlaneAlarms);
+        m_TeleportToPlaneAlarms = 20;
+    }
+    if (m_TeleportToPlaneAlarms>100){
+        sLog.outError("Anticheat.Movement.TeleportToPlaneAlarms (%d) must be <=100. Using 100 instead.",m_TeleportToPlaneAlarms);
+        m_TeleportToPlaneAlarms = 100;
+    }
+    m_MistimingDelta = sConfig.GetIntDefault("Anticheat.Movement.MistimingDelta",2000);
+    if (m_MistimingDelta<1000){
+        sLog.outError("Anticheat.Movement.m_MistimingDelta (%d) must be >=1000ms. Using 1000 instead.",m_TeleportToPlaneAlarms);
+        m_MistimingDelta = 1000;
+    }
+    if (m_MistimingDelta>10000){
+        sLog.outError("Anticheat.Movement.m_MistimingDelta (%d) must be <=10000ms. Using 10000 instead.",m_TeleportToPlaneAlarms);
+        m_MistimingDelta = 10000;
+    }
+    m_MistimingAlarms = sConfig.GetIntDefault("Anticheat.Movement.MistimingAlarms",20);
+    if (m_MistimingAlarms<10) {
+        sLog.outError("Anticheat.Movement.MistimingAlarms (%d) must be >=20. Using 10 instead.",m_TeleportToPlaneAlarms);
+        m_MistimingAlarms = 10;
+    }
+    if (m_MistimingAlarms>50){
+        sLog.outError("Anticheat.Movement.m_MistimingAlarms (%d) must be <=50. Using 50 instead.",m_TeleportToPlaneAlarms);
+        m_MistimingAlarms = 50;
+    }
     ///- Read other configuration items from the config file

     m_configs[CONFIG_COMPRESSION] = sConfig.GetIntDefault("Compression", 1);
Index: game/World.h
===================================================================
--- game/World.h        (revision 81)
+++ game/World.h        (working copy)
@@ -473,7 +473,12 @@
         static float GetMaxVisibleDistanceInFlight()    { return m_MaxVisibleDistanceInFlight;    }
         static float GetVisibleUnitGreyDistance()       { return m_VisibleUnitGreyDistance;       }
         static float GetVisibleObjectGreyDistance()     { return m_VisibleObjectGreyDistance;     }
-
+        //movement anticheat
+        static bool GetEnableMvAnticheat()     {return m_EnableMvAnticheat;}
+        static uint32 GetTeleportToPlaneAlarms()  {return m_TeleportToPlaneAlarms;}
+        static uint32 GetMistimingDelta()  {return m_MistimingDelta;}
+        static uint32 GetMistimingAlarms() {return m_MistimingAlarms;}
+        //<<< end movement anticheat
         void ProcessCliCommands();
         void QueueCliCommand( CliCommandHolder::Print* zprintf, char const* input ) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); }

@@ -538,7 +543,11 @@
         static float m_MaxVisibleDistanceInFlight;
         static float m_VisibleUnitGreyDistance;
         static float m_VisibleObjectGreyDistance;
-
+        //movement anticheat enable flag
+        static bool m_EnableMvAnticheat;
+        static uint32 m_TeleportToPlaneAlarms;
+        static uint32 m_MistimingDelta;
+        static uint32 m_MistimingAlarms;
         // CLI command holder to be thread safe
         ZThread::LockedQueue<CliCommandHolder*, ZThread::FastMutex> cliCmdQueue;
         SqlResultQueue *m_resultQueue;
Index: mangosd/mangosd.conf.dist.in
===================================================================
--- mangosd/mangosd.conf.dist.in        (revision 81)
+++ mangosd/mangosd.conf.dist.in        (working copy)
@@ -1208,6 +1208,30 @@
Network.TcpNodelay = 1

###################################################################################################################
+# MOVEMENT ANTICHEAT
+#
+#    Anticheat.Movement.Enable
+#        Enable Movement Anticheat
+#        Default: 1 - on
+#                 0 - off
+#
+#    Anticheat.Movement.TeleportToPlaneAlarms
+#        maximum alarms before player will be kicked (default 50, allowed 20 - 100)
+#
+#    Anticheat.Movement.MistimingDelta
+#        mistiming intelval between client and serverside (default 2000 ms, allowed 1000 - 10000 ms)
+#
+#    Anticheat.Movement.MistimingAlarms
+#        mistiming alarms before player will be kicked (default 20, allowed 10 - 50)
+#
+###################################################################################################################
+
+Anticheat.Movement.Enable = 1
+Anticheat.Movement.TeleportToPlaneAlarms = 50
+Anticheat.Movement.MistimingDelta = 2000
+Anticheat.Movement.MistimingAlarms = 20
+
+###################################################################################################################
# CONSOLE AND REMOTE ACCESS
#
#    Console.Enable


作者: 微信    时间: 2016-11-5 12:14
提示: 作者被禁止或删除 内容自动屏蔽




欢迎光临 吾爱尚玩资源基地 (http://bbs.523play.com/) Powered by Discuz! X3.4