Index: src/game/MovementHandler.cpp
===================================================================
--- src/game/MovementHandler.cpp (revision 4609)
+++ src/game/MovementHandler.cpp (working copy)
@@ -27,6 +27,7 @@
#include "MapManager.h"
#include "Transports.h"
#include "BattleGroundMgr.h"
+#include "NameTables.h"
void WorldSession::HandleMoveWorldportAckOpcode( WorldPacket & recv_data )
{
@@ -124,6 +125,8 @@
float s_angle;
float j_unk1, j_sinAngle, j_cosAngle, j_xyspeed;
float u_unk1;
+ uint32 m_flags = GetPlayer()->GetMovementFlags();
+ uint16 opcode = recv_data.GetOpcode();
recv_data >> flags >> time;
recv_data >> x >> y >> z >> orientation;
@@ -174,52 +177,63 @@
if (flags & MOVEMENTFLAG_ONTRANSPORT)
{
// if we boarded a transport, add us to it
- if (!GetPlayer()->m_transport)
+ if ((GetPlayer()->m_transportGUID == 0) && (t_GUID !=0))
{
- // unmount before boarding
- _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
+ if (!GetPlayer()->m_transport)
+ {
+ // unmount before boarding
+ _player->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED);
- for (MapManager::TransportSet::iterator iter = MapManager::Instance().m_Transports.begin(); iter != MapManager::Instance().m_Transports.end(); ++iter)
- {
- if ((*iter)->GetGUID() == t_GUID)
+ 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() == t_GUID)
+ {
+ GetPlayer()->m_transport = (*iter);
+ (*iter)->AddPassenger(GetPlayer());
+ break;
+ }
}
}
+ GetPlayer()->m_transportGUID = t_GUID;
}
- GetPlayer()->m_transX = t_x;
- GetPlayer()->m_transY = t_y;
- GetPlayer()->m_transZ = t_z;
- GetPlayer()->m_transO = t_o;
- GetPlayer()->m_transTime = t_time;
+ if (t_GUID !=0)
+ {
+ GetPlayer()->m_transX = t_x;
+ GetPlayer()->m_transY = t_y;
+ GetPlayer()->m_transZ = t_z;
+ GetPlayer()->m_transO = t_o;
+ GetPlayer()->m_transTime = t_time;
+ }
}
- else if (GetPlayer()->m_transport) // if we were on a transport, leave
+ else if (GetPlayer()->m_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;
+ }
GetPlayer()->m_transX = 0.0f;
GetPlayer()->m_transY = 0.0f;
GetPlayer()->m_transZ = 0.0f;
GetPlayer()->m_transO = 0.0f;
GetPlayer()->m_transTime = 0;
+ GetPlayer()->m_transportGUID = 0;
}
- if (GetPlayer()->HasMovementFlags(MOVEMENTFLAG_FALLING) && !(flags & MOVEMENTFLAG_FALLING))
+ if (opcode == MSG_MOVE_FALL_LAND)
{
Player *target = GetPlayer();
+ uint32 safefallTime = (GetPlayer()->HasAuraType(SPELL_AURA_SAFE_FALL)) ? 17000 : 0; // -17 modifier to fall damage at safe fall aura (from wowwiki.com)
+ //sLog.outBasic("Fall time: %d; SafeTime: %d",fallTime, safefallTime);
+ fallTime = (fallTime > safefallTime) ? (fallTime - safefallTime) : 0;
if (fallTime > 1100 && !target->isDead() && !target->isGameMaster() &&
!target->HasAuraType(SPELL_AURA_HOVER) && !target->HasAuraType(SPELL_AURA_FEATHER_FALL))
{
- Map *map = MapManager::Instance().GetMap(target->GetMapId(), target);
- float posz = map->GetWaterLevel(x,y);
float fallperc = float(fallTime)*10/11000;
uint32 damage = (uint32)(((fallperc*fallperc -1) / 9 * target->GetMaxHealth())*sWorld.getRate(RATE_DAMAGE_FALL));
if (damage > 0 && damage < 2* target->GetMaxHealth())
target->EnvironmentalDamage(target->GetGUID(),DAMAGE_FALL, damage);
- DEBUG_LOG("!! z=%f, pz=%f FallTime=%d posz=%f damage=%d" , z, target->GetPositionZ(),fallTime, posz, damage);
}
//handle fall and logout at the sametime
@@ -238,16 +252,117 @@
if(((flags & MOVEMENTFLAG_SWIMMING) != 0) != GetPlayer()->IsInWater())
GetPlayer()->SetInWater( !GetPlayer()->IsInWater() );
/*----------------------*/
+ // ---- anti-cheat features -->>>
+ bool kicked = true;
+ if ((GetPlayer()->m_transportGUID == 0) && !GetPlayer()->isTaxi() && sWorld.GetEnableMovementAnticheat())
+ {
+ UnitMoveType move_type;
+
+ if (flags & MOVEMENTFLAG_FLYING) move_type = flags & MOVEMENTFLAG_BACKWARD ? MOVE_FLYBACK : MOVE_FLY;
+ else if (flags & MOVEMENTFLAG_SWIMMING) move_type = flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIMBACK : MOVE_SWIM;
+ else if (flags & MOVEMENTFLAG_WALK) move_type = MOVE_WALK;
+ else move_type = flags & MOVEMENTFLAG_BACKWARD ? MOVE_SWIMBACK : MOVE_RUN;
+ //hmm... in first time after login player has MOVE_SWIMBACK instead MOVE_WALKBACK
+ float c_speed = 0;
+ float cur_speed = GetPlayer()->GetSpeed(move_type);
+ float delta_x = GetPlayer()->GetPositionX() - x;
+ float delta_y = GetPlayer()->GetPositionY() - y;
+ float delta_z = GetPlayer()->GetPositionZ() - z;
+ float delta = delta_x * delta_x + delta_y * delta_y;
+ float tg_z = -99999; //tangens
+ float delta_t = time - GetPlayer()->m_lastmovetime;
+ if (delta_t > 0) {
+ GetPlayer()->m_lastmovetime = time;
+ } else {delta_t = 0;}
+ delta_t = (delta_t < 1500) ? delta_t/1000 : 1.5;
+ if (!(flags & (MOVEMENTFLAG_FLYING | MOVEMENTFLAG_SWIMMING)))
+ tg_z = (delta !=0) ? delta_z*delta_z / delta : -99999;
+
+ if (cur_speed < GetPlayer()->m_lastspeed)
+ {
+ c_speed = GetPlayer()->m_lastspeed;
+ if (GetPlayer()->m_lastspeed_changetime == 0 )
+ GetPlayer()->m_lastspeed_changetime = time + (uint32)floor(((GetPlayer()->m_lastspeed / cur_speed) * 1000));
+ } else c_speed = cur_speed;
+
+ c_speed = c_speed * delta_t;
+ c_speed = c_speed * c_speed + 1.5;
+
+ //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(),time,fallTime,x,y,z,orientation,flags, LookupName(opcode,g_worldOpcodeNames),move_type_name[move_type]);
+ //sLog.outBasic("%f",tg_z);
+
+ if ((delta > c_speed) && (delta_z < 1))
+ {
+ //sLog.outError("Ahhaaa.... %s is speed cheater!!! delta=%f c_speed=%f | cur_speed=%f last_speed=%f time=%f (%f %f %f %d)[%s]",GetPlayer()->GetName(),delta, c_speed, cur_speed, GetPlayer()->m_lastspeed,delta_t,GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId(),LookupName(opcode,g_worldOpcodeNames));
+ kicked = false;
+ }
+ if ((delta>4900.0f) && !(delta < c_speed))
+ {
+ //sLog.outError("Ahhaaa.... %s is teleport cheater!!! delta=%f c_speed=%f | cur_speed=%f last_speed=%f time=%f (%f %f %f %d)",GetPlayer()->GetName(),delta, c_speed, cur_speed, GetPlayer()->m_lastspeed,delta_t,GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId());
+ kicked = false;
+ }
+
+ if (time>GetPlayer()->m_lastspeed_changetime)
+ {
+ GetPlayer()->m_lastspeed = cur_speed; // store current speed
+ if (GetPlayer()->m_lastspeed_changetime != 0) GetPlayer()->m_lastspeed_changetime = 0;
+ }
+
+ if ((tg_z > 1.55f) && (delta_z < -2.6f))
+ {
+ // sLog.outError("Ahhaaa.... %s is mountain cheater!!! tg_z=%f (%f %f %f %d)",GetPlayer()->GetName(),tg_z, GetPlayer()->GetPositionX(),GetPlayer()->GetPositionY(),GetPlayer()->GetPositionZ(), GetPlayer()->GetMapId());
+ kicked = false;
+ }
+ if (((flags & (MOVEMENTFLAG_CAN_FLY | MOVEMENTFLAG_FLYING)) != 0) && !GetPlayer()->isGameMaster() && !(GetPlayer()->HasAuraType(SPELL_AURA_MOD_SPEED_MOUNTED_FLIGHT) | GetPlayer()->HasAuraType(SPELL_AURA_FLY)))
+ {
+ // sLog.outError("Ahhaaa.... %s is fly cheater!!! SPELL_AURA_FLY=[%X]| SPELL_AURA_MOD_SPEED_MOUNTED_FLIGHT=[%X]", GetPlayer()->GetName(), GetPlayer()->HasAuraType(SPELL_AURA_FLY), GetPlayer()->HasAuraType(SPELL_AURA_MOD_SPEED_MOUNTED_FLIGHT));
+ kicked = false;
+ }
+ if (((flags & MOVEMENTFLAG_WATERWALKING) != 0) && !GetPlayer()->isGameMaster() && !(GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK) | GetPlayer()->HasAuraType(SPELL_AURA_GHOST)))
+ {
+ // sLog.outError("Ahhaaa.... %s is water-walk cheater!!! SPELL_AURA_WATER_WALK=[%X]", GetPlayer()->GetName(), GetPlayer()->HasAuraType(SPELL_AURA_WATER_WALK));
+ kicked = false;
+ }
+ } else if (flags & MOVEMENTFLAG_ONTRANSPORT)
+ {
+ float trans_rad = t_x*t_x + t_y*t_y + t_z*t_z;
+ if (trans_rad > 3600.0f) // transport radius = 60 yards //cheater with on_transport_flag
+ {
+ if (GetPlayer()->m_transport)
+ {
+ GetPlayer()->m_transport->RemovePassenger(GetPlayer());
+ GetPlayer()->m_transport = NULL;
+ }
+ GetPlayer()->m_transX = 0.0f;
+ GetPlayer()->m_transY = 0.0f;
+ GetPlayer()->m_transZ = 0.0f;
+ GetPlayer()->m_transO = 0.0f;
+ GetPlayer()->m_transTime = 0;
+ GetPlayer()->m_transportGUID = 0;
+ }
+ }
+ // <<---- anti-cheat features
+
/* process position-change */
- recv_data.put<uint32>(4, getMSTime());
- WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
- data.append(GetPlayer()->GetPackGUID());
- data.append(recv_data.contents(), recv_data.size());
- GetPlayer()->SendMessageToSet(&data, false);
+ if (kicked)
+ {
+ recv_data.put<uint32>(4, getMSTime());
+ WorldPacket data(recv_data.GetOpcode(), (GetPlayer()->GetPackGUID().size()+recv_data.size()));
+ data.append(GetPlayer()->GetPackGUID());
+ data.append(recv_data.contents(), recv_data.size());
+ GetPlayer()->SendMessageToSet(&data, false);
- GetPlayer()->SetPosition(x, y, z, orientation);
- GetPlayer()->SetMovementFlags(flags);
+ GetPlayer()->SetPosition(x, y, z, orientation);
+ GetPlayer()->SetMovementFlags(flags);
+ } else {
+ WorldPacket data;
+ 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)
@@ -394,12 +509,6 @@
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;
@@ -418,8 +527,10 @@
if(GetPlayer()->GetGUID()!=guid)
return;
- // check code
- */
+ GetPlayer()->SetPosition(x, y, z, orientation);
+ GetPlayer()->SetMovementFlags(flags);
+ GetPlayer()->m_lastspeed = hspeed;
+ GetPlayer()->m_lastspeed_changetime = time+1500;
}
void WorldSession::HandleMoveHoverAck( WorldPacket & recv_data )
Index: src/game/Player.cpp
===================================================================
--- src/game/Player.cpp (revision 4609)
+++ src/game/Player.cpp (working copy)
@@ -198,6 +198,10 @@
m_rest_bonus=0;
rest_type=REST_TYPE_NO;
////////////////////Rest System/////////////////////
+ m_lastmovetime = 0;
+ m_transportGUID = 0;
+ m_lastspeed = 7; //RUN
+ m_lastspeed_changetime = 0;
m_mailsLoaded = false;
m_mailsUpdated = false;
Index: src/game/Player.h
===================================================================
--- src/game/Player.h (revision 4609)
+++ src/game/Player.h (working copy)
@@ -1885,7 +1885,10 @@
float m_rest_bonus;
RestType rest_type;
////////////////////Rest System/////////////////////
-
+ uint32 m_lastmovetime;
+ uint64 m_transportGUID;
+ float m_lastspeed;
+ uint32 m_lastspeed_changetime;
// Transports
float m_transX;
float m_transY;
Index: src/game/TaxiHandler.cpp
===================================================================
--- src/game/TaxiHandler.cpp (revision 4609)
+++ src/game/TaxiHandler.cpp (working copy)
@@ -140,6 +140,7 @@
GetPlayer()->Mount( MountId, true );
FlightPathMovementGenerator *flight = new FlightPathMovementGenerator(path);
+ GetPlayer()->GetMotionMaster()->Clear(true);
GetPlayer()->GetMotionMaster()->Mutate(flight);
Path &pathnodes = flight->GetPath();
@@ -232,6 +233,13 @@
uint32 path, cost;
sLog.outDebug( "WORLD: Received CMSG_MOVE_SPLINE_DONE" );
+ uint32 flags, time;
+ float x, y, z, orientation;
+ recvPacket >> flags >> time;
+ recvPacket >> x >> y >> z >> orientation;
+ GetPlayer()->SetPosition(x, y, z, orientation);
+ GetPlayer()->SetMovementFlags(flags);
+ GetPlayer()->m_lastmovetime = time;
sourcenode = GetPlayer()->GetTaxiSource();
if ( sourcenode > 0 ) // if more destinations to go
Index: src/game/World.cpp
===================================================================
--- src/game/World.cpp (revision 4609)
+++ src/game/World.cpp (working copy)
@@ -441,7 +441,10 @@
sLog.outError("Visibility.Distance.InFlight can't be greater %f",MAX_VISIBILITY_DISTANCE-m_VisibleObjectGreyDistance);
m_MaxVisibleDistanceInFlight = MAX_VISIBILITY_DISTANCE - m_VisibleObjectGreyDistance;
}
-
+ // movement anticheat
+ m_EnableMovementAnticheat = sConfig.GetIntDefault("Anticheat.Movement",1);
+ if (m_EnableMovementAnticheat !=0)
+ m_EnableMovementAnticheat = 1;
///- Read the "Data" directory from the config file
m_dataPath = sConfig.GetStringDefault("DataDir","./");
if((m_dataPath.at(m_dataPath.length()-1)!='/') && (m_dataPath.at(m_dataPath.length()-1)!='\\'))
Index: src/game/World.h
===================================================================
--- src/game/World.h (revision 4609)
+++ src/game/World.h (working copy)
@@ -340,7 +340,8 @@
static float GetMaxVisibleDistanceInFlight() { return m_MaxVisibleDistanceInFlight; }
static float GetVisibleUnitGreyDistance() { return m_VisibleUnitGreyDistance; }
static float GetVisibleObjectGreyDistance() { return m_VisibleObjectGreyDistance; }
-
+ //movement anticheat enable flag
+ uint32 GetEnableMovementAnticheat() {return m_EnableMovementAnticheat;}
void ProcessCliCommands();
void QueueCliCommand(CliCommandHolder* command) { cliCmdQueue.add(command); }
@@ -397,7 +398,8 @@
static float m_MaxVisibleDistanceInFlight;
static float m_VisibleUnitGreyDistance;
static float m_VisibleObjectGreyDistance;
-
+ //movement anticheat enable flag
+ uint32 m_EnableMovementAnticheat;
// CLI command holder to be thread safe
ZThread::LockedQueue<CliCommandHolder*, ZThread::FastMutex> cliCmdQueue;
SqlResultQueue *m_resultQueue;
Index: src/mangosd/mangosd.conf.in
===================================================================
--- src/mangosd/mangosd.conf.in (revision 4609)
+++ src/mangosd/mangosd.conf.in (working copy)
@@ -451,6 +451,11 @@
# List of ids with delimiter ','
vmap.ignoreSpellIds = "7720"
+#Enable movement anticheat features
+#Default: 1 (enable)
+# 0 (disable)
+Anticheat.Movement = 1
+
# Subseqent kills of the same player decrease the amount of honor gained.
# Maximum number of times a user may kill another player in one day and get honor for it.
# Default: 10
|