diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/server/game/Entities/Player/Player.cpp | 41 | ||||
-rw-r--r-- | src/server/game/Entities/Player/Player.h | 3 | ||||
-rw-r--r-- | src/server/game/World/World.cpp | 3 | ||||
-rw-r--r-- | src/server/game/World/World.h | 1 | ||||
-rw-r--r-- | src/server/worldserver/worldserver.conf.dist | 10 |
5 files changed, 53 insertions, 5 deletions
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e2038e91e89..92c9ac89e60 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -501,7 +501,7 @@ Player::Player(WorldSession* session): Unit(true) m_runes = nullptr; - m_lastFallTime = 0; + m_lastFallTimeClient = 0; m_lastFallZ = 0; m_grantableLevels = 0; @@ -1512,7 +1512,6 @@ void Player::Update(uint32 p_time) //because we don't want player's ghost teleported from graveyard if (IsHasDelayedTeleport() && IsAlive()) TeleportTo(m_teleport_dest, m_teleport_options); - } void Player::setDeathState(DeathState s) @@ -24852,7 +24851,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; } @@ -24860,6 +24877,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("zDiff = %f", z_diff); //Players with low fall distance, Feather Fall or physical immunity (charges used) are ignored @@ -25189,7 +25222,7 @@ void Player::AddKnownCurrency(uint32 itemId) void Player::UpdateFallInformationIfNeed(MovementInfo const& minfo, uint16 opcode) { - if (m_lastFallTime >= minfo.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND) + if (m_lastFallTimeClient >= minfo.fallTime || m_lastFallZ <= minfo.pos.GetPositionZ() || opcode == MSG_MOVE_FALL_LAND) SetFallInformation(minfo.fallTime, minfo.pos.GetPositionZ()); } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index 99e5f37ee7b..fb72eb6af00 100644 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -2586,7 +2586,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]; diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp index 2f09d03893f..d8f5923873a 100644 --- a/src/server/game/World/World.cpp +++ b/src/server/game/World/World.cpp @@ -1349,6 +1349,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); diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h index cdf3703a67a..01c2275fade 100644 --- a/src/server/game/World/World.h +++ b/src/server/game/World/World.h @@ -390,6 +390,7 @@ enum WorldIntConfigs CONFIG_RESPAWN_DYNAMICMINIMUM_CREATURE, CONFIG_RESPAWN_DYNAMICMINIMUM_GAMEOBJECT, CONFIG_RESPAWN_GUIDWARNING_FREQUENCY, + CONFIG_ANTICHEAT_FALL_PUNISHMENT, INT_CONFIG_VALUE_COUNT }; diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist index 83dd87a487e..ff09c324df1 100644 --- a/src/server/worldserver/worldserver.conf.dist +++ b/src/server/worldserver/worldserver.conf.dist @@ -1248,6 +1248,16 @@ BirthdayTime = 1222964635 CacheDataQueries = 1 # +# 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 + +# ################################################################################################### ################################################################################################### |