mirror of
https://github.com/luanti-org/luanti.git
synced 2025-07-12 16:58:39 +00:00
Fix anticheat
This commit is contained in:
parent
bc5db9b027
commit
742614180c
5 changed files with 146 additions and 70 deletions
|
@ -934,7 +934,6 @@ PlayerSAO::PlayerSAO(ServerEnvironment *env_, Player *player_, u16 peer_id_,
|
|||
m_peer_id(peer_id_),
|
||||
m_inventory(NULL),
|
||||
m_last_good_position(0,0,0),
|
||||
m_last_good_position_age(0),
|
||||
m_time_from_last_punch(0),
|
||||
m_nocheat_dig_pos(32767, 32767, 32767),
|
||||
m_nocheat_dig_time(0),
|
||||
|
@ -1002,7 +1001,6 @@ void PlayerSAO::addedToEnvironment(u32 dtime_s)
|
|||
m_player->setPlayerSAO(this);
|
||||
m_player->peer_id = m_peer_id;
|
||||
m_last_good_position = m_player->getPosition();
|
||||
m_last_good_position_age = 0.0;
|
||||
}
|
||||
|
||||
// Called before removing from environment
|
||||
|
@ -1106,6 +1104,19 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
|||
m_moved = true;
|
||||
}
|
||||
|
||||
//dstream<<"PlayerSAO::step: dtime: "<<dtime<<std::endl;
|
||||
|
||||
// Set lag pool maximums based on estimated lag
|
||||
const float LAG_POOL_MIN = 5.0;
|
||||
float lag_pool_max = m_env->getMaxLagEstimate() * 2.0;
|
||||
if(lag_pool_max < LAG_POOL_MIN)
|
||||
lag_pool_max = LAG_POOL_MIN;
|
||||
m_dig_pool.setMax(lag_pool_max);
|
||||
m_move_pool.setMax(lag_pool_max);
|
||||
|
||||
// Increment cheat prevention timers
|
||||
m_dig_pool.add(dtime);
|
||||
m_move_pool.add(dtime);
|
||||
m_time_from_last_punch += dtime;
|
||||
m_nocheat_dig_time += dtime;
|
||||
|
||||
|
@ -1115,66 +1126,8 @@ void PlayerSAO::step(float dtime, bool send_recommended)
|
|||
{
|
||||
v3f pos = m_env->getActiveObject(m_attachment_parent_id)->getBasePosition();
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
m_player->setPosition(pos);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_is_singleplayer || g_settings->getBool("disable_anticheat"))
|
||||
{
|
||||
m_last_good_position = m_player->getPosition();
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Check player movements
|
||||
|
||||
NOTE: Actually the server should handle player physics like the
|
||||
client does and compare player's position to what is calculated
|
||||
on our side. This is required when eg. players fly due to an
|
||||
explosion. Altough a node-based alternative might be possible
|
||||
too, and much more lightweight.
|
||||
*/
|
||||
|
||||
float player_max_speed = 0;
|
||||
float player_max_speed_up = 0;
|
||||
if(m_privs.count("fast") != 0){
|
||||
// Fast speed
|
||||
player_max_speed = BS * 20;
|
||||
player_max_speed_up = BS * 20;
|
||||
} else {
|
||||
// Normal speed
|
||||
player_max_speed = BS * 4.0;
|
||||
player_max_speed_up = BS * 4.0;
|
||||
}
|
||||
// Tolerance
|
||||
player_max_speed *= 2.5;
|
||||
player_max_speed_up *= 2.5;
|
||||
|
||||
m_last_good_position_age += dtime;
|
||||
if(m_last_good_position_age >= 1.0){
|
||||
float age = m_last_good_position_age;
|
||||
v3f diff = (m_player->getPosition() - m_last_good_position);
|
||||
float d_vert = diff.Y;
|
||||
diff.Y = 0;
|
||||
float d_horiz = diff.getLength();
|
||||
/*infostream<<m_player->getName()<<"'s horizontal speed is "
|
||||
<<(d_horiz/age)<<std::endl;*/
|
||||
if(d_horiz <= age * player_max_speed &&
|
||||
(d_vert < 0 || d_vert < age * player_max_speed_up)){
|
||||
m_last_good_position = m_player->getPosition();
|
||||
} else {
|
||||
actionstream<<"Player "<<m_player->getName()
|
||||
<<" moved too fast; resetting position"
|
||||
<<std::endl;
|
||||
m_player->setPosition(m_last_good_position);
|
||||
m_moved = true;
|
||||
}
|
||||
m_last_good_position_age = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(send_recommended == false)
|
||||
return;
|
||||
|
@ -1267,7 +1220,6 @@ void PlayerSAO::setPos(v3f pos)
|
|||
m_player->setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
// Force position change on client
|
||||
m_moved = true;
|
||||
}
|
||||
|
@ -1279,7 +1231,6 @@ void PlayerSAO::moveTo(v3f pos, bool continuous)
|
|||
m_player->setPosition(pos);
|
||||
// Movement caused by this command is always valid
|
||||
m_last_good_position = pos;
|
||||
m_last_good_position_age = 0;
|
||||
// Force position change on client
|
||||
m_moved = true;
|
||||
}
|
||||
|
@ -1503,6 +1454,59 @@ std::string PlayerSAO::getPropertyPacket()
|
|||
return gob_cmd_set_properties(m_prop);
|
||||
}
|
||||
|
||||
void PlayerSAO::checkMovementCheat()
|
||||
{
|
||||
if(isAttached() || m_is_singleplayer ||
|
||||
g_settings->getBool("disable_anticheat"))
|
||||
{
|
||||
m_last_good_position = m_player->getPosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
Check player movements
|
||||
|
||||
NOTE: Actually the server should handle player physics like the
|
||||
client does and compare player's position to what is calculated
|
||||
on our side. This is required when eg. players fly due to an
|
||||
explosion. Altough a node-based alternative might be possible
|
||||
too, and much more lightweight.
|
||||
*/
|
||||
|
||||
float player_max_speed = 0;
|
||||
float player_max_speed_up = 0;
|
||||
if(m_privs.count("fast") != 0){
|
||||
// Fast speed
|
||||
player_max_speed = m_player->movement_speed_fast;
|
||||
player_max_speed_up = m_player->movement_speed_fast;
|
||||
} else {
|
||||
// Normal speed
|
||||
player_max_speed = m_player->movement_speed_walk;
|
||||
player_max_speed_up = m_player->movement_speed_walk;
|
||||
}
|
||||
// Tolerance. With the lag pool we shouldn't need it.
|
||||
//player_max_speed *= 2.5;
|
||||
//player_max_speed_up *= 2.5;
|
||||
|
||||
v3f diff = (m_player->getPosition() - m_last_good_position);
|
||||
float d_vert = diff.Y;
|
||||
diff.Y = 0;
|
||||
float d_horiz = diff.getLength();
|
||||
float required_time = d_horiz/player_max_speed;
|
||||
if(d_vert > 0 && d_vert/player_max_speed > required_time)
|
||||
required_time = d_vert/player_max_speed;
|
||||
if(m_move_pool.grab(required_time)){
|
||||
m_last_good_position = m_player->getPosition();
|
||||
} else {
|
||||
actionstream<<"Player "<<m_player->getName()
|
||||
<<" moved too fast; resetting position"
|
||||
<<std::endl;
|
||||
m_player->setPosition(m_last_good_position);
|
||||
m_moved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool PlayerSAO::getCollisionBox(aabb3f *toset) {
|
||||
//update collision box
|
||||
*toset = m_player->getCollisionbox();
|
||||
|
@ -1516,3 +1520,4 @@ bool PlayerSAO::getCollisionBox(aabb3f *toset) {
|
|||
bool PlayerSAO::collideWithObjects(){
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue