All pastes #1495560 Raw Copy code Copy link Edit

Untitled

public diff v1 · immutable
#1495560 ·published 2009-07-15 09:00 UTC
rendered paste body
diff --git a/sql/anticheat.sql b/sql/anticheat.sqlnew file mode 100644index 0000000..c03acb5--- /dev/null+++ b/sql/anticheat.sql@@ -0,0 +1,20 @@+DROP TABLE IF EXISTS `cheaters`;+CREATE TABLE `cheaters` (+  `entry` bigint(20) NOT NULL auto_increment,+  `player` varchar(30) NOT NULL,+  `acctid` int(11) NOT NULL,+  `reason` varchar(255) NOT NULL default 'unknown',+  `speed` float NOT NULL default '0',+  `Val1` float NOT NULL default '0',+  `Val2` int(10) unsigned NOT NULL default '0',+  `count` int(11) NOT NULL default '0',+  `Map` smallint(5) NOT NULL default '-1',+  `Pos` varchar(255) NOT NULL default '0',+  `Level` mediumint(9) NOT NULL default '0',+  `first_date` datetime NOT NULL,+  `last_date` datetime NOT NULL,+  `Op` varchar(255) NOT NULL default 'unknown',+  PRIMARY KEY  (`entry`),+  KEY `idx_Count` (`count`),+  KEY `idx_Player` (`player`)+) ENGINE=MyISAM  DEFAULT CHARSET=utf8;diff --git a/src/game/Level3.cpp b/src/game/Level3.cppindex b79351e..34e095a 100644--- a/src/game/Level3.cpp+++ b/src/game/Level3.cpp@@ -5495,9 +5495,15 @@ bool ChatHandler::HandleGMFlyCommand(const char* args)      WorldPacket data(12);     if (strncmp(args, "on", 3) == 0)+    {         data.SetOpcode(SMSG_MOVE_SET_CAN_FLY);+        ((Player*)(target))->SetCanFly(true);+    }     else if (strncmp(args, "off", 4) == 0)+    {         data.SetOpcode(SMSG_MOVE_UNSET_CAN_FLY);+        ((Player*)(target))->SetCanFly(false);+    }     else     {         SendSysMessage(LANG_USE_BOL);diff --git a/src/game/MovementHandler.cpp b/src/game/MovementHandler.cppindex 3e5f39a..8406355 100644--- a/src/game/MovementHandler.cpp+++ b/src/game/MovementHandler.cpp@@ -31,6 +31,188 @@ #include "WaypointMovementGenerator.h" #include "InstanceSaveMgr.h" #include "ObjectMgr.h"+#include "World.h"++//#define __ANTI_DEBUG__++#ifdef __ANTI_DEBUG__+#include "Chat.h"+std::string FlagsToStr(const uint32 Flags)+{+    std::string Ret="";+    if(Flags==0)+    {+        Ret="None";+        return Ret;+    }+    +    if(Flags & MOVEMENTFLAG_FORWARD)+    {   Ret+="FW "; }+    if(Flags & MOVEMENTFLAG_BACKWARD)+    {   Ret+="BW "; }+    if(Flags & MOVEMENTFLAG_STRAFE_LEFT)+    {   Ret+="STL ";    }+    if(Flags & MOVEMENTFLAG_STRAFE_RIGHT)+    {   Ret+="STR ";    }+    if(Flags & MOVEMENTFLAG_LEFT)+    {   Ret+="LF "; }+    if(Flags & MOVEMENTFLAG_RIGHT)+    {   Ret+="RI "; }+    if(Flags & MOVEMENTFLAG_PITCH_UP)+    {   Ret+="PTUP ";   }+    if(Flags & MOVEMENTFLAG_PITCH_DOWN)+    {   Ret+="PTDW ";   }+    if(Flags & MOVEMENTFLAG_WALK_MODE)+    {   Ret+="WALK ";   }+    if(Flags & MOVEMENTFLAG_ONTRANSPORT)+    {   Ret+="TRANS ";  }+    if(Flags & MOVEMENTFLAG_LEVITATING)+    {   Ret+="LEVI ";   }+    if(Flags & MOVEMENTFLAG_FLY_UNK1)+    {   Ret+="FLYUNK1 ";    }+    if(Flags & MOVEMENTFLAG_JUMPING)+    {   Ret+="JUMP ";   }+    if(Flags & MOVEMENTFLAG_UNK4)+    {   Ret+="UNK4 ";   }+    if(Flags & MOVEMENTFLAG_FALLING)+    {   Ret+="FALL ";   }+    if(Flags & MOVEMENTFLAG_SWIMMING)+    {   Ret+="SWIM ";   }+    if(Flags & MOVEMENTFLAG_FLY_UP)+    {   Ret+="FLYUP ";  }+    if(Flags & MOVEMENTFLAG_CAN_FLY)+    {   Ret+="CFLY ";   }+    if(Flags & MOVEMENTFLAG_FLYING)+    {   Ret+="FLY ";    }+    if(Flags & MOVEMENTFLAG_FLYING2)+    {   Ret+="FLY2 ";   }+    if(Flags & MOVEMENTFLAG_WATERWALKING)+    {   Ret+="WTWALK "; }+    if(Flags & MOVEMENTFLAG_SAFE_FALL)+    {   Ret+="SAFE ";   }+    if(Flags & MOVEMENTFLAG_UNK3)+    {   Ret+="UNK3 ";   }+    if(Flags & MOVEMENTFLAG_SPLINE)+    {   Ret+="SPLINE ";     }+    if(Flags & MOVEMENTFLAG_SPLINE2)+    {   Ret+="SPLINE2 ";    }+    +    return Ret;+}+#endif // __ANTI_DEBUG__++bool WorldSession::Anti__ReportCheat(const char* Reason,float Speed,const char* Op,float Val1,uint32 Val2,MovementInfo* MvInfo)+{+    if(!Reason)+    {+        sLog.outError("Anti__ReportCheat: Missing Reason parameter!");+        return false;+    }+    const char* Player=GetPlayer()->GetName();+    uint32 Acc=GetPlayer()->GetSession()->GetAccountId();+    uint32 Map=GetPlayer()->GetMapId();+    if(!Player)+    {+        sLog.outError("Anti__ReportCheat: Player with no name?!?");+        return false;+    }++    QueryResult *Res=CharacterDatabase.PQuery("SELECT speed,Val1 FROM cheaters WHERE player='%s' AND reason LIKE '%s' AND Map='%u' AND last_date >= NOW()-300",Player,Reason,Map);+    if(Res)+    {+        Field* Fields = Res->Fetch();+        +        std::stringstream Query;+        Query << "UPDATE cheaters SET count=count+1,last_date=NOW()";+        Query.precision(5);+        if(Speed>0.0f && Speed > Fields[0].GetFloat())+        {+            Query << ",speed='";+            Query << std::fixed << Speed;+            Query << "'";+        }++        if(Val1>0.0f && Val1 > Fields[1].GetFloat())+        {+            Query << ",Val1='";+            Query << std::fixed << Val1;+            Query << "'";+        }+        +        Query << " WHERE player='" << Player << "' AND reason='" << Reason << "' AND Map='" << Map << "' AND last_date >= NOW()-300 ORDER BY entry DESC LIMIT 1";+        +        CharacterDatabase.Execute(Query.str().c_str());+        delete Res;+    }+    else+    {+        if(!Op)+        {   Op="";  }+        std::stringstream Pos;+        Pos << "OldPos: " << GetPlayer()->GetPositionX() << " " << GetPlayer()->GetPositionY() << " "+            << GetPlayer()->GetPositionZ();+        if(MvInfo)+        {+            Pos << "\nNew: " << MvInfo->x << " " << MvInfo->y << " " << MvInfo->z << "\n"+                << "Flags: " << MvInfo->flags << "\n"+                << "t_guid: " << MvInfo->t_guid << " falltime: " << MvInfo->fallTime;+        }+        CharacterDatabase.PExecute("INSERT INTO cheaters (player,acctid,reason,speed,count,first_date,last_date,`Op`,Val1,Val2,Map,Pos,Level) "+                                   "VALUES ('%s','%u','%s','%f','1',NOW(),NOW(),'%s','%f','%u','%u','%s','%u')",+                                   Player,Acc,Reason,Speed,Op,Val1,Val2,Map,+                                   Pos.str().c_str(),GetPlayer()->getLevel());+    }++    if(sWorld.GetMvAnticheatKill() && GetPlayer()->isAlive())+    {+        GetPlayer()->DealDamage(GetPlayer(), GetPlayer()->GetHealth(), NULL, DIRECT_DAMAGE, SPELL_SCHOOL_MASK_NORMAL, NULL, false);+    }+    if(sWorld.GetMvAnticheatKick())+    {+        GetPlayer()->GetSession()->KickPlayer();+    }+    if(sWorld.GetMvAnticheatBan() & 1)+    {+        sWorld.BanAccount(BAN_CHARACTER,Player,sWorld.GetMvAnticheatBanTime(),"Cheat","Anticheat");+    }+    if(sWorld.GetMvAnticheatBan() & 2)+    {+        QueryResult *result = loginDatabase.PQuery("SELECT last_ip FROM account WHERE id=%u", Acc);+        if(result)+        {++            Field *fields = result->Fetch();+            std::string LastIP = fields[0].GetCppString();+            if(!LastIP.empty())+            {+                sWorld.BanAccount(BAN_IP,LastIP,sWorld.GetMvAnticheatBanTime(),"Cheat","Anticheat");+            }+            delete result;+        }+    }+    return true;+}++bool WorldSession::Anti__CheatOccurred(uint32 CurTime,const char* Reason,float Speed,const char* Op,+                                float Val1,uint32 Val2,MovementInfo* MvInfo)+{+    if(!Reason)+    {+        sLog.outError("Anti__CheatOccurred: Missing Reason parameter!");+        return false;+    }+    +    GetPlayer()->m_anti_lastalarmtime = CurTime;+    GetPlayer()->m_anti_alarmcount = GetPlayer()->m_anti_alarmcount + 1;++    if (GetPlayer()->m_anti_alarmcount > sWorld.GetMvAnticheatAlarmCount())+    {+        Anti__ReportCheat(Reason,Speed,Op,Val1,Val2,MvInfo);+        return true;+    }+    return false;+}+  void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & /*recv_data*/ ) {@@ -67,6 +249,7 @@ void WorldSession::HandleMoveWorldportAckOpcode()     // relocate the player to the teleport destination     GetPlayer()->SetMapId(loc.mapid);     GetPlayer()->Relocate(loc.coord_x, loc.coord_y, loc.coord_z, loc.orientation);+    GetPlayer()->m_anti_TeleTime=time(NULL);      // since the MapId is set before the GetInstance call, the InstanceId must be set to 0     // to let GetInstance() determine the proper InstanceId based on the player's binds@@ -159,6 +342,8 @@ void WorldSession::HandleMoveWorldportAckOpcode()      // resummon pet     GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();+    GetPlayer()->Anti__SetLastTeleTime(::time(NULL));+    GetPlayer()->m_anti_BeginFallZ=INVALID_HEIGHT;      //lets process all delayed operations on successful teleport     GetPlayer()->ProcessDelayedOperations();@@ -205,6 +390,11 @@ void WorldSession::HandleMoveTeleportAck(WorldPacket& recv_data)      // resummon pet     GetPlayer()->ResummonPetTemporaryUnSummonedIfAny();+    if(plMover)+    {+        plMover->Anti__SetLastTeleTime(::time(NULL));+        plMover->m_anti_BeginFallZ=INVALID_HEIGHT;+    }      //lets process all delayed operations on successful teleport     GetPlayer()->ProcessDelayedOperations();@@ -249,6 +439,11 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )         // if we boarded a transport, add us to it         if (plMover && !plMover->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) // transport radius = 60 yards //cheater with on_transport_flag+            {+	            return;+            }             // elevators also cause the client to send MOVEMENTFLAG_ONTRANSPORT - just unmount if the guid can be found in the transport list             for (MapManager::TransportSet::const_iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)             {@@ -281,9 +476,145 @@ void WorldSession::HandleMovementOpcodes( WorldPacket & recv_data )     {         // now client not include swimming flag in case jumping under water         plMover->SetInWater( !plMover->IsInWater() || plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z) );+        if(plMover->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z-7.0f))+        {+            plMover->m_anti_BeginFallZ=INVALID_HEIGHT;+        }     } -    /*----------------------*/+    // ---- anti-cheat features -->>>+    uint32 Anti_TeleTimeDiff=plMover ? time(NULL) - plMover->Anti__GetLastTeleTime() : time(NULL);+    static const uint32 Anti_TeleTimeIgnoreDiff=sWorld.GetMvAnticheatIgnoreAfterTeleport();+    if (plMover && (plMover->m_transport == 0) && sWorld.GetMvAnticheatEnable() &&+        GetPlayer()->GetSession()->GetSecurity() <= sWorld.GetMvAnticheatGmLevel() &&+        GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()!=FLIGHT_MOTION_TYPE &&+        Anti_TeleTimeDiff>Anti_TeleTimeIgnoreDiff)+    {+        const uint32 CurTime=getMSTime();+        if(getMSTimeDiff(GetPlayer()->m_anti_lastalarmtime,CurTime) > sWorld.GetMvAnticheatAlarmPeriod())+        {+            GetPlayer()->m_anti_alarmcount = 0;+        }+        /* I really don't care about movement-type yet (todo)+        UnitMoveType move_type;++        if (movementInfo.flags & MOVEMENTFLAG_FLYING) move_type = MOVE_FLY;+        else if (movementInfo.flags & MOVEMENTFLAG_SWIMMING) move_type = MOVE_SWIM;+        else if (movementInfo.flags & MOVEMENTFLAG_WALK_MODE) move_type = MOVE_WALK;+        else move_type = MOVE_RUN;*/++        float delta_x = GetPlayer()->GetPositionX() - movementInfo.x;+        float delta_y = GetPlayer()->GetPositionY() - movementInfo.y;+        float delta_z = GetPlayer()->GetPositionZ() - movementInfo.z;+        float delta = sqrt(delta_x * delta_x + delta_y * delta_y); // Len of movement-vector via Pythagoras (a^2+b^2=Len^2)+        float tg_z = 0.0f; //tangens+        float delta_t = getMSTimeDiff(GetPlayer()->m_anti_lastmovetime,CurTime);+        +		GetPlayer()->m_anti_lastmovetime = CurTime;+        GetPlayer()->m_anti_MovedLen += delta;++        if(delta_t > 15000.0f)+        {   delta_t = 15000.0f;   }++        // Tangens of walking angel+        /*if (!(movementInfo.flags & (MOVEMENTFLAG_FLYING | MOVEMENTFLAG_SWIMMING)))+        {+            //Mount hack detection currently disabled+            tg_z = ((delta !=0.0f) && (delta_z > 0.0f)) ? (atan((delta_z*delta_z) / delta) * 180.0f / M_PI) : 0.0f;+        }*/++        //antiOFF fall-damage, MOVEMENTFLAG_UNK4 seted by client if player try movement when falling and unset in this case the MOVEMENTFLAG_FALLING flag.+        +		if((GetPlayer()->m_anti_BeginFallZ == INVALID_HEIGHT) &&+           (movementInfo.flags & (MOVEMENTFLAG_FALLING | MOVEMENTFLAG_UNK4)) != 0)+        {+            GetPlayer()->m_anti_BeginFallZ=(float)(movementInfo.z);+        }++        if(GetPlayer()->m_anti_NextLenCheck <= CurTime)+        {+            // Check every 500ms is a lot more advisable then 1000ms, because normal movment packet arrives every 500ms+            uint32 OldNextLenCheck=GetPlayer()->m_anti_NextLenCheck;+            float delta_xyt=GetPlayer()->m_anti_MovedLen/(float)(getMSTimeDiff(OldNextLenCheck-500,CurTime));+            GetPlayer()->m_anti_NextLenCheck = CurTime+500;+            GetPlayer()->m_anti_MovedLen = 0.0f;+            static const float MaxDeltaXYT = sWorld.GetMvAnticheatMaxXYT();++#ifdef __ANTI_DEBUG__+            SendAreaTriggerMessage("XYT: %f ; Flags: %s",delta_xyt,FlagsToStr(movementInfo.flags).c_str());+#endif //__ANTI_DEBUG__+            +			if(delta_xyt > MaxDeltaXYT && delta<=100.0f)+            {+                Anti__CheatOccurred(CurTime,"Speed hack",delta_xyt,LookupOpcodeName(opcode),+                                    (float)(GetPlayer()->GetMotionMaster()->GetCurrentMovementGeneratorType()),+                                    (float)(getMSTimeDiff(OldNextLenCheck-500,CurTime)),&movementInfo);+            }+        }++        if(delta > 100.0f)+        {+            Anti__ReportCheat("Tele hack",delta,LookupOpcodeName(opcode));+        }++        // Check for waterwalking+        if(((movementInfo.flags & MOVEMENTFLAG_WATERWALKING) != 0) &&+           ((movementInfo.flags ^ MOVEMENTFLAG_WATERWALKING) != 0) && // Client sometimes set waterwalk where it shouldn't do that...+           ((movementInfo.flags & MOVEMENTFLAG_JUMPING) == 0) &&+           GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z-6.0f) &&+           !(GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK) || GetPlayer()->HasAuraType(SPELL_AURA_GHOST)))+        {+            Anti__CheatOccurred(CurTime,"Water walking",0.0f,NULL,0.0f,(uint32)(movementInfo.flags));+        }+        +        // Check for walking upwards a mountain while not beeing able to do that+        /*if ((tg_z > 85.0f))+        {+            Anti__CheatOccurred(CurTime,"Mount hack",tg_z,NULL,delta,delta_z);+        }+		*/+        +        static const float DIFF_OVERGROUND = 10.0f;+        float Anti__GroundZ = GetPlayer()->GetMap()->GetHeight(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),MAX_HEIGHT);+        float Anti__FloorZ  = GetPlayer()->GetMap()->GetHeight(GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ());+        float Anti__MapZ = ((Anti__FloorZ <= (INVALID_HEIGHT+5.0f)) ? Anti__GroundZ : Anti__FloorZ) + DIFF_OVERGROUND;+        +        if(!GetPlayer()->CanFly() &&+           !GetPlayer()->GetBaseMap()->IsUnderWater(movementInfo.x, movementInfo.y, movementInfo.z-7.0f) &&+           Anti__MapZ < GetPlayer()->GetPositionZ() && Anti__MapZ > (INVALID_HEIGHT+DIFF_OVERGROUND + 5.0f))+        {+            static const float DIFF_AIRJUMP=25.0f; // 25 is realy high, but to many false positives...+            +			// Air-Jump-Detection definitively needs a better way to be detected...+            if((movementInfo.flags & (MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING | MOVEMENTFLAG_FLYING2)) != 0) // Fly Hack+            {+                Anti__CheatOccurred(CurTime,"Fly hack",+                                    ((uint8)(GetPlayer()->HasAuraType(SPELL_AURA_FLY))) ++                                    ((uint8)(GetPlayer()->HasAuraType(SPELL_AURA_MOD_INCREASE_FLIGHT_SPEED))*2),+                                    NULL,GetPlayer()->GetPositionZ()-Anti__MapZ);+            }+            +			/* Need a better way to do that - currently a lot of fake alarms+            else if((Anti__MapZ+DIFF_AIRJUMP < GetPlayer()->GetPositionZ() &&+			         (movementInfo.flags & (MOVEMENTFLAG_FALLING | MOVEMENTFLAG_UNK4))==0) ||+					(Anti__MapZ < GetPlayer()->GetPositionZ() && +					 opcode==MSG_MOVE_JUMP))+            {+                Anti__CheatOccurred(CurTime,"Possible Air Jump Hack",+                                    0.0f,LookupOpcodeName(opcode),0.0f,movementInfo.flags,&movementInfo);+            }*/+        }++        /*+		if(Anti__FloorZ < -199900.0f && Anti__GroundZ >= -199900.0f &&+           GetPlayer()->GetPositionZ()+5.0f < Anti__GroundZ)+        {+            Anti__CheatOccurred(CurTime,"Teleport2Plane hack",+                                GetPlayer()->GetPositionZ(),NULL,Anti__GroundZ);+        }*/+    } +	// <<---- anti-cheat features+      /* process position-change */     recv_data.put<uint32>(6, getMSTime());                  // fix time, offset flags(4) + unk(2)diff --git a/src/game/Player.cpp b/src/game/Player.cppindex 3d567d8..9cfe3dd 100644--- a/src/game/Player.cpp+++ b/src/game/Player.cpp@@ -404,6 +404,17 @@ Player::Player (WorldSession *session): Unit(), m_achievementMgr(this), m_reputa     rest_type=REST_TYPE_NO;     ////////////////////Rest System///////////////////// +    //movement anticheat+    m_anti_lastmovetime = 0;   //last movement time+    m_anti_NextLenCheck = 0;+    m_anti_MovedLen = 0.0f;+    m_anti_BeginFallZ = INVALID_HEIGHT;+    m_anti_lastalarmtime = 0;    //last time when alarm generated+    m_anti_alarmcount = 0;       //alarm counter+    m_anti_TeleTime = 0;+    m_CanFly=false;+    /////////////////////////////////+     m_mailsLoaded = false;     m_mailsUpdated = false;     unReadMails = 0;@@ -19669,7 +19680,9 @@ uint8 Player::CanEquipUniqueItem( ItemPrototype const* itemProto, uint8 except_s void Player::HandleFall(MovementInfo const& movementInfo) {     // calculate total z distance of the fall-    float z_diff = m_lastFallZ - movementInfo.z;+    float z_diff = (m_lastFallZ >= m_anti_BeginFallZ ? m_lastFallZ : m_anti_BeginFallZ) - movementInfo.z;+    +	m_anti_BeginFallZ=INVALID_HEIGHT;     sLog.outDebug("zDiff = %f", z_diff);      //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignoreddiff --git a/src/game/Player.h b/src/game/Player.hindex 20a917b..9f57c33 100644--- a/src/game/Player.h+++ b/src/game/Player.h@@ -1903,7 +1903,11 @@ class MANGOS_DLL_SPEC Player : public Unit         bool isMoving() const { return m_movementInfo.HasMovementFlag(movementFlagsMask); }         bool isMovingOrTurning() const { return m_movementInfo.HasMovementFlag(movementOrTurningFlagsMask); } -        bool CanFly() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }+        uint32 Anti__GetLastTeleTime() const { return m_anti_TeleTime; }+        void Anti__SetLastTeleTime(uint32 TeleTime) { m_anti_TeleTime=TeleTime; }+        //bool CanFly() const { return HasMovementFlag(MOVEMENTFLAG_CAN_FLY); }+        bool CanFly() const { return m_CanFly;  }+        void SetCanFly(bool CanFly) { m_CanFly=CanFly; }         bool IsFlying() const { return m_movementInfo.HasMovementFlag(MOVEMENTFLAG_FLYING); }         bool IsAllowUseFlyMountsHere() const; @@ -2246,6 +2250,16 @@ class MANGOS_DLL_SPEC Player : public Unit         RestType rest_type;         ////////////////////Rest System///////////////////// +        //movement anticheat+        uint32 m_anti_lastmovetime;     //last movement time+        float  m_anti_MovedLen;         //Length of traveled way+        uint32 m_anti_NextLenCheck;+        float  m_anti_BeginFallZ;    //alternative falling begin+        uint32 m_anti_lastalarmtime;    //last time when alarm generated+        uint32 m_anti_alarmcount;       //alarm counter+        uint32 m_anti_TeleTime;+        bool m_CanFly;+         // Transports         Transport * m_transport; diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cppindex 2a50fdc..f8ef720 100644--- a/src/game/SpellAuras.cpp+++ b/src/game/SpellAuras.cpp@@ -3905,9 +3905,15 @@ void Aura::HandleAuraModIncreaseFlightSpeed(bool apply, bool Real)     {         WorldPacket data;         if(apply)+        {+            ((Player*)m_target)->SetCanFly(true);             data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);+        }         else+        {             data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);+            ((Player*)m_target)->SetCanFly(false);+        }         data.append(m_target->GetPackGUID());         data << uint32(0);                                      // unknown         m_target->SendMessageToSet(&data, true);@@ -5467,9 +5473,15 @@ void Aura::HandleAuraAllowFlight(bool apply, bool Real)     // allow fly     WorldPacket data;     if(apply)+    {+        ((Player*)m_target)->SetCanFly(true);         data.Initialize(SMSG_MOVE_SET_CAN_FLY, 12);+    }     else+    {         data.Initialize(SMSG_MOVE_UNSET_CAN_FLY, 12);+        ((Player*)m_target)->SetCanFly(false);+    }     data.append(m_target->GetPackGUID());     data << uint32(0);                                      // unk     m_target->SendMessageToSet(&data, true);diff --git a/src/game/WaypointMovementGenerator.cpp b/src/game/WaypointMovementGenerator.cppindex 38cf80d..01bf9a4 100644--- a/src/game/WaypointMovementGenerator.cpp+++ b/src/game/WaypointMovementGenerator.cpp@@ -250,6 +250,7 @@ void FlightPathMovementGenerator::Finalize(Player & player)      float x, y, z;     i_destinationHolder.GetLocationNow(player.GetBaseMap(), x, y, z);+    player.Anti__SetLastTeleTime(time(NULL));     player.SetPosition(x, y, z, player.GetOrientation());      player.Unmount();diff --git a/src/game/World.cpp b/src/game/World.cppindex 93d6d65..3dc6810 100644--- a/src/game/World.cpp+++ b/src/game/World.cpp@@ -538,6 +538,18 @@ void World::LoadConfigSettings(bool reload)      ///- Read other configuration items from the config file +    // movement anticheat+    m_MvAnticheatEnable                     = sConfig.GetBoolDefault("Anticheat.Movement.Enable",false);+    m_MvAnticheatKick                       = sConfig.GetBoolDefault("Anticheat.Movement.Kick",false);+    m_MvAnticheatAlarmCount                 = (uint32)sConfig.GetIntDefault("Anticheat.Movement.AlarmCount", 5);+    m_MvAnticheatAlarmPeriod                = (uint32)sConfig.GetIntDefault("Anticheat.Movement.AlarmTime", 5000);+    m_MvAntiCheatBan                        = (unsigned char)sConfig.GetIntDefault("Anticheat.Movement.BanType",0);+    m_MvAnticheatBanTime                    = sConfig.GetStringDefault("Anticheat.Movement.BanTime","1m");+    m_MvAnticheatGmLevel                    = (unsigned char)sConfig.GetIntDefault("Anticheat.Movement.GmLevel",0);+    m_MvAnticheatKill                       = sConfig.GetBoolDefault("Anticheat.Movement.Kill",false);+    m_MvAnticheatMaxXYT                     = sConfig.GetFloatDefault("Anticheat.Movement.MaxXYT",0.04f);+    m_MvAnticheatIgnoreAfterTeleport        = (uint16)sConfig.GetIntDefault("Anticheat.Movement.IgnoreSecAfterTeleport",10);+     m_configs[CONFIG_COMPRESSION] = sConfig.GetIntDefault("Compression", 1);     if(m_configs[CONFIG_COMPRESSION] < 1 || m_configs[CONFIG_COMPRESSION] > 9)     {diff --git a/src/game/World.h b/src/game/World.hindex cea5310..11587af 100644--- a/src/game/World.h+++ b/src/game/World.h@@ -489,6 +489,19 @@ class World         static float GetVisibleUnitGreyDistance()       { return m_VisibleUnitGreyDistance;       }         static float GetVisibleObjectGreyDistance()     { return m_VisibleObjectGreyDistance;     } +        //movement anticheat enable flag+        inline bool GetMvAnticheatEnable()             {return m_MvAnticheatEnable;}+        inline bool GetMvAnticheatKick()               {return m_MvAnticheatKick;}+        inline uint32 GetMvAnticheatAlarmCount()       {return m_MvAnticheatAlarmCount;}+        inline uint32 GetMvAnticheatAlarmPeriod()      {return m_MvAnticheatAlarmPeriod;}+        inline unsigned char GetMvAnticheatBan()       {return m_MvAntiCheatBan;}+        inline std::string GetMvAnticheatBanTime()     {return m_MvAnticheatBanTime;}+        inline unsigned char GetMvAnticheatGmLevel()   {return m_MvAnticheatGmLevel;}+        inline bool GetMvAnticheatKill()               {return m_MvAnticheatKill;}+        inline float GetMvAnticheatMaxXYT()            {return m_MvAnticheatMaxXYT;}+        inline uint16 GetMvAnticheatIgnoreAfterTeleport()   {return m_MvAnticheatIgnoreAfterTeleport;}+        +         void ProcessCliCommands();         void QueueCliCommand( CliCommandHolder::Print* zprintf, char const* input ) { cliCmdQueue.add(new CliCommandHolder(input, zprintf)); } @@ -555,6 +568,19 @@ class World         static float m_VisibleUnitGreyDistance;         static float m_VisibleObjectGreyDistance; +        //movement anticheat enable flag+        bool m_MvAnticheatEnable;+        bool m_MvAnticheatKick;+        uint32 m_MvAnticheatAlarmCount;+        uint32 m_MvAnticheatAlarmPeriod;+        unsigned char m_MvAntiCheatBan;+        std::string m_MvAnticheatBanTime;+        unsigned char m_MvAnticheatGmLevel;+        bool m_MvAnticheatKill;+        float m_MvAnticheatMaxXYT;+        uint16 m_MvAnticheatIgnoreAfterTeleport;++         // CLI command holder to be thread safe         ACE_Based::LockedQueue<CliCommandHolder*,ACE_Thread_Mutex> cliCmdQueue;         SqlResultQueue *m_resultQueue;diff --git a/src/game/WorldSession.h b/src/game/WorldSession.hindex a30ea29..6f6d99c 100644--- a/src/game/WorldSession.h+++ b/src/game/WorldSession.h@@ -104,6 +104,10 @@ class MANGOS_DLL_SPEC WorldSession         bool PlayerLoading() const { return m_playerLoading; }         bool PlayerLogout() const { return m_playerLogout; } +        inline bool Anti__CheatOccurred(uint32 CurTime,const char* Reason,float Speed,const char* Op=NULL,+                                float Val1=0.0f,uint32 Val2=0,MovementInfo* MvInfo=NULL);+        bool Anti__ReportCheat(const char* Reason,float Speed,const char* Op=NULL,float Val1=0.0f,uint32 Val2=0,MovementInfo* MvInfo=NULL);+         void SizeError(WorldPacket const& packet, uint32 size) const;          void ReadAddonsInfo(WorldPacket &data);diff --git a/src/mangosd/mangosd.conf.dist.in b/src/mangosd/mangosd.conf.dist.inindex 4b57965..34fb363 100644--- a/src/mangosd/mangosd.conf.dist.in+++ b/src/mangosd/mangosd.conf.dist.in@@ -1282,3 +1282,63 @@ Ra.IP = 0.0.0.0  # Do not perform action on GM if this is enabled LexicsCutterNoActionOnGM = 1++###################################################################################################################+# MOVEMENT ANTICHEAT+#+#    Anticheat.Movement.Enable+#        Enable Movement Anticheat+#        Default: 0 - off+#                 1 - on+#+#    Anticheat.Movement.AlarmCount+#        Count alarms. After AlarmCount is exceeded, actions are taken against the player. (default 5)+#+#    Anticheat.Movement.AlarmTime+#        Reset alarm-count after this milliseconds. (default 5000)+#+#    Anticheat.Movement.Kill+#        Enable Kill cheater+#        Default: 0 - off+#                 1 - on+#+#    Anticheat.Movement.Kick+#        Enable Kick cheater+#        Default: 0 - off+#                 1 - on+#+#    Anticheat.Movement.BanType+#        Enable Ban cheater+#        Default: 0 - off+#                 1 - Ban Account+#                 2 - Ban IP+#                 3 - Ban Account + IP+#+#    Anticheat.Movement.BanTime+#        How long the ban should last.+#        Default: 1 Minute - 1m+#+#    Anticheat.Movement.MaxXYT+#        Max units a player is allowed to travel per millisecond.+#        Default: 0.04 (This is ~400% Speed, 0.007 is walk-speed, 310% is 0.0287)+#+#    Anticheat.Movement.IgnoreSecAfterTeleport+#        After being teleported this number of seconds no cheat is reported.+#        Default: 10 seconds - 10+#+#    Anticheat.Movement.GmLevel+#        Only accounts that are below this gm-level or exact at the same, are reported for cheating.+#        Default: Only normal Players - 0+#+###################################################################################################################++Anticheat.Movement.Enable = 1+Anticheat.Movement.AlarmCount = 5+Anticheat.Movement.AlarmTime = 5000+Anticheat.Movement.Kill = 0+Anticheat.Movement.Kick = 0+Anticheat.Movement.BanType = 0+Anticheat.Movement.BanTime = "1m"+Anticheat.Movement.MaxXYT = 0.04+Anticheat.Movement.IgnoreSecAfterTeleport = 10+Anticheat.Movement.GmLevel = 0