summaryrefslogtreecommitdiff
path: root/src/content_sao.cpp
diff options
context:
space:
mode:
authorEkdohibs <nathanael.courant@laposte.net>2017-01-30 07:58:43 +0100
committerparamat <mat.gregory@virginmedia.com>2017-02-01 15:03:57 +0000
commitd873545ac70331a224967493f9296a854d292dd8 (patch)
treec503555b9ac782b30dc84ce014437fd4257f5cf4 /src/content_sao.cpp
parent3e355ab7d5ccdcd77f104eee57237828410b85d7 (diff)
downloadminetest-d873545ac70331a224967493f9296a854d292dd8.tar.gz
minetest-d873545ac70331a224967493f9296a854d292dd8.tar.bz2
minetest-d873545ac70331a224967493f9296a854d292dd8.zip
Fix anticheat resetting client position after the client is teleported
Previously, m_move_pool could accomodate the client moving from the new position to the old one, and the server accepted the client to go back to its old position. However, it couldn't then accomodate the client moving from its old to its new position, and therefore would reset position to the old position. Thus, by emptying m_move_pool after a teleport, the server no longer accepts the client to go back to its old position. A drawback is however that a laggy client *will* trigger a few "moved_too_fast" anticheats before being told about its new position. Don't report player cheated if caused by lag. Fixes #5118
Diffstat (limited to 'src/content_sao.cpp')
-rw-r--r--src/content_sao.cpp19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/content_sao.cpp b/src/content_sao.cpp
index 7a1171eb7..f87977f80 100644
--- a/src/content_sao.cpp
+++ b/src/content_sao.cpp
@@ -785,6 +785,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer
m_inventory(NULL),
m_damage(0),
m_last_good_position(0,0,0),
+ m_time_from_last_teleport(0),
m_time_from_last_punch(0),
m_nocheat_dig_pos(32767, 32767, 32767),
m_nocheat_dig_time(0),
@@ -1000,6 +1001,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
// Increment cheat prevention timers
m_dig_pool.add(dtime);
m_move_pool.add(dtime);
+ m_time_from_last_teleport += dtime;
m_time_from_last_punch += dtime;
m_nocheat_dig_time += dtime;
@@ -1106,6 +1108,8 @@ void PlayerSAO::setPos(const v3f &pos)
setBasePosition(pos);
// Movement caused by this command is always valid
m_last_good_position = pos;
+ m_move_pool.empty();
+ m_time_from_last_teleport = 0.0;
m_env->getGameDef()->SendMovePlayer(m_peer_id);
}
@@ -1117,6 +1121,8 @@ void PlayerSAO::moveTo(v3f pos, bool continuous)
setBasePosition(pos);
// Movement caused by this command is always valid
m_last_good_position = pos;
+ m_move_pool.empty();
+ m_time_from_last_teleport = 0.0;
m_env->getGameDef()->SendMovePlayer(m_peer_id);
}
@@ -1405,11 +1411,16 @@ bool PlayerSAO::checkMovementCheat()
if (m_move_pool.grab(required_time)) {
m_last_good_position = m_base_position;
} else {
- actionstream << "Player " << m_player->getName()
- << " moved too fast; resetting position"
- << std::endl;
+ const float LAG_POOL_MIN = 5.0;
+ float lag_pool_max = m_env->getMaxLagEstimate() * 2.0;
+ lag_pool_max = MYMAX(lag_pool_max, LAG_POOL_MIN);
+ if (m_time_from_last_teleport > lag_pool_max) {
+ actionstream << "Player " << m_player->getName()
+ << " moved too fast; resetting position"
+ << std::endl;
+ cheated = true;
+ }
setBasePosition(m_last_good_position);
- cheated = true;
}
return cheated;
}