Cross-check client-submitted fall time with server-measured time. When excessive difference is detected, punish player.

Fixes an exploit that could trivialize the Lich King encounter.
This commit is contained in:
Aokromes committed 2017-06-17 11:58:15 +02:00
1 parent a990a4ce08
commit e0e2242b17
5 files changed
+53 -4

No files matched your search

+37 -3
View File
@@ -495,7 +495,7 @@ Player::Player(WorldSession* session): Unit(true)
m_runes = nullptr;
m_lastFallTime = 0;
m_lastFallTimeClient = 0;
m_lastFallZ = 0;
m_grantableLevels = 0;
@@ -25453,7 +25453,25 @@ InventoryResult Player::CanEquipUniqueItem(ItemTemplate const* itemProto, uint8
void Player::SetFallInformation(uint32 time, float z)
{
m_lastFallTime = time;
if (time < m_lastFallTimeClient)
m_fallStartTimeServer = GameTime::GetGameTimeMS() - time;
else if (m_fallStartTimeServer && time < std::max<uint32>(GameTime::GetGameTimeMS() - m_fallStartTimeServer, 2500) - 2500)
{
TC_LOG_WARN("cheat", "Player %s found to be delaying their falling movement.", GetName().c_str());
switch (sWorld->getIntConfig(CONFIG_ANTICHEAT_FALL_PUNISHMENT))
{
case 1: // kill
EnvironmentalDamage(DAMAGE_FALL, GetMaxHealth());
if (!isDead())
Kill(this, false);
break;
case 2: // disconnect
GetSession()->KickPlayer();
break;
}
}
m_lastFallTimeClient = time;
m_lastFallZ = z;
}
@@ -25461,6 +25479,22 @@ void Player::HandleFall(MovementInfo const& movementInfo)
{
// calculate total z distance of the fall
float z_diff = m_lastFallZ - movementInfo.pos.GetPositionZ();
if (m_fallStartTimeServer && movementInfo.fallTime < std::max<uint32>(GameTime::GetGameTimeMS() - m_fallStartTimeServer, 2500) - 2500)
{
TC_LOG_WARN("cheat", "Player %s found to be delaying their falling movement.", GetName().c_str());
switch (sWorld->getIntConfig(CONFIG_ANTICHEAT_FALL_PUNISHMENT))
{
case 1: // kill
z_diff = MAX_HEIGHT;
break;
case 2: // disconnect
GetSession()->KickPlayer();
break;
default:
break;
}
}
m_fallStartTimeServer = 0;
//TC_LOG_DEBUG("misc", "zDiff = %f", z_diff);
//Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored
@@ -25842,7 +25876,7 @@ void Player::AddKnownCurrency(uint32 itemId)
void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode)
{
if (m_lastFallTime >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
if (m_lastFallTimeClient >= minfo.jump.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND)
SetFallInformation(minfo.jump.fallTime, minfo.pos.GetPositionZ());
}
+2 -1
View File
@@ -2841,7 +2841,8 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
MapReference m_mapRef;
uint32 m_lastFallTime;
uint32 m_lastFallTimeClient;
uint32 m_fallStartTimeServer;
float m_lastFallZ;
int32 m_MirrorTimer[MAX_TIMERS];
+3
View File
@@ -1409,6 +1409,9 @@ void World::LoadConfigSettings(bool reload)
// Whether to use LoS from game objects
m_bool_configs[CONFIG_CHECK_GOBJECT_LOS] = sConfigMgr->GetBoolDefault("CheckGameObjectLoS", true);
// What happens with cheaters that delay their fall
m_int_configs[CONFIG_ANTICHEAT_FALL_PUNISHMENT] = sConfigMgr->GetIntDefault("Anticheat.FallDelayed", 1); // 1 - kill
// call ScriptMgr if we're reloading the configuration
if (reload)
sScriptMgr->OnConfigLoad(reload);
+1
View File
@@ -413,6 +413,7 @@ enum WorldIntConfigs
CONFIG_RESPAWN_DYNAMICMINIMUM_CREATURE,
CONFIG_RESPAWN_DYNAMICMINIMUM_GAMEOBJECT,
CONFIG_RESPAWN_GUIDWARNING_FREQUENCY,
CONFIG_ANTICHEAT_FALL_PUNISHMENT,
INT_CONFIG_VALUE_COUNT
};
@@ -1212,6 +1212,16 @@ Account.PasswordChangeSecurity = 0
BirthdayTime = 1222964635
#
# Anticheat.FallDelayed
# Description: Decides what happens with players who show invalid fall behavior.
# Can produce false positives in high latency situations.
# 2 - (Force disconnect from server)
# Default: 1 - (Kill player using fall damage)
# 0 - (Only log to console)
Anticheat.FallDelayed = 1
#
###################################################################################################