Skip to content

Commit d873545

Browse files
Ekdohibsparamat
authored andcommittedFeb 1, 2017
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
1 parent 3e355ab commit d873545

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed
 

Diff for: ‎src/content_sao.cpp

+15-4
Original file line numberDiff line numberDiff line change
@@ -785,6 +785,7 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, u16 peer_id_, bool is_singleplayer
785785
m_inventory(NULL),
786786
m_damage(0),
787787
m_last_good_position(0,0,0),
788+
m_time_from_last_teleport(0),
788789
m_time_from_last_punch(0),
789790
m_nocheat_dig_pos(32767, 32767, 32767),
790791
m_nocheat_dig_time(0),
@@ -1000,6 +1001,7 @@ void PlayerSAO::step(float dtime, bool send_recommended)
10001001
// Increment cheat prevention timers
10011002
m_dig_pool.add(dtime);
10021003
m_move_pool.add(dtime);
1004+
m_time_from_last_teleport += dtime;
10031005
m_time_from_last_punch += dtime;
10041006
m_nocheat_dig_time += dtime;
10051007

@@ -1106,6 +1108,8 @@ void PlayerSAO::setPos(const v3f &pos)
11061108
setBasePosition(pos);
11071109
// Movement caused by this command is always valid
11081110
m_last_good_position = pos;
1111+
m_move_pool.empty();
1112+
m_time_from_last_teleport = 0.0;
11091113
m_env->getGameDef()->SendMovePlayer(m_peer_id);
11101114
}
11111115

@@ -1117,6 +1121,8 @@ void PlayerSAO::moveTo(v3f pos, bool continuous)
11171121
setBasePosition(pos);
11181122
// Movement caused by this command is always valid
11191123
m_last_good_position = pos;
1124+
m_move_pool.empty();
1125+
m_time_from_last_teleport = 0.0;
11201126
m_env->getGameDef()->SendMovePlayer(m_peer_id);
11211127
}
11221128

@@ -1405,11 +1411,16 @@ bool PlayerSAO::checkMovementCheat()
14051411
if (m_move_pool.grab(required_time)) {
14061412
m_last_good_position = m_base_position;
14071413
} else {
1408-
actionstream << "Player " << m_player->getName()
1409-
<< " moved too fast; resetting position"
1410-
<< std::endl;
1414+
const float LAG_POOL_MIN = 5.0;
1415+
float lag_pool_max = m_env->getMaxLagEstimate() * 2.0;
1416+
lag_pool_max = MYMAX(lag_pool_max, LAG_POOL_MIN);
1417+
if (m_time_from_last_teleport > lag_pool_max) {
1418+
actionstream << "Player " << m_player->getName()
1419+
<< " moved too fast; resetting position"
1420+
<< std::endl;
1421+
cheated = true;
1422+
}
14111423
setBasePosition(m_last_good_position);
1412-
cheated = true;
14131424
}
14141425
return cheated;
14151426
}

Diff for: ‎src/content_sao.h

+9
Original file line numberDiff line numberDiff line change
@@ -157,18 +157,26 @@ class LagPool
157157
public:
158158
LagPool(): m_pool(15), m_max(15)
159159
{}
160+
160161
void setMax(float new_max)
161162
{
162163
m_max = new_max;
163164
if(m_pool > new_max)
164165
m_pool = new_max;
165166
}
167+
166168
void add(float dtime)
167169
{
168170
m_pool -= dtime;
169171
if(m_pool < 0)
170172
m_pool = 0;
171173
}
174+
175+
void empty()
176+
{
177+
m_pool = m_max;
178+
}
179+
172180
bool grab(float dtime)
173181
{
174182
if(dtime <= 0)
@@ -358,6 +366,7 @@ class PlayerSAO : public UnitSAO
358366
LagPool m_dig_pool;
359367
LagPool m_move_pool;
360368
v3f m_last_good_position;
369+
float m_time_from_last_teleport;
361370
float m_time_from_last_punch;
362371
v3s16 m_nocheat_dig_pos;
363372
float m_nocheat_dig_time;

0 commit comments

Comments
 (0)
Please sign in to comment.