From 742614180cbbe598694a48bd9eb6f7b97a762243 Mon Sep 17 00:00:00 2001 From: Perttu Ahola Date: Sat, 3 Aug 2013 23:16:37 +0300 Subject: Fix anticheat --- src/content_sao.cpp | 129 +++++++++++++++++++++++++++------------------------- 1 file changed, 67 insertions(+), 62 deletions(-) (limited to 'src/content_sao.cpp') diff --git a/src/content_sao.cpp b/src/content_sao.cpp index 90c4fa69c..8d46d4237 100644 --- a/src/content_sao.cpp +++ b/src/content_sao.cpp @@ -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: "<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<getName()<<"'s horizontal speed is " - <<(d_horiz/age)<getPosition(); - } else { - actionstream<<"Player "<getName() - <<" moved too fast; resetting position" - <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 "<getName() + <<" moved too fast; resetting position" + <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; } + -- cgit v1.2.3