rendered paste bodydiff --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