Sanitize player position and speed server-side (#12396)

This commit is contained in:
sfan5 2022-06-07 21:27:05 +02:00 committed by GitHub
parent 3107c98591
commit 3ac5a24b12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 25 additions and 6 deletions

@ -134,13 +134,14 @@ public:
std::vector<CollisionInfo> *collision_info) std::vector<CollisionInfo> *collision_info)
{} {}
const v3f &getSpeed() const v3f getSpeed() const
{ {
return m_speed; return m_speed;
} }
void setSpeed(const v3f &speed) void setSpeed(v3f speed)
{ {
clampToF1000(speed);
m_speed = speed; m_speed = speed;
} }

@ -319,8 +319,14 @@ std::string PlayerSAO::generateUpdatePhysicsOverrideCommand() const
return os.str(); return os.str();
} }
void PlayerSAO::setBasePosition(const v3f &position) void PlayerSAO::setBasePosition(v3f position)
{ {
// It's not entirely clear which parts of the network protocol still use
// v3f1000, but the script API enforces its bound on all float vectors
// (maybe it shouldn't?). For that reason we need to make sure the position
// isn't ever set to values that fail this restriction.
clampToF1000(position);
if (m_player && position != m_base_position) if (m_player && position != m_base_position)
m_player->setDirty(true); m_player->setDirty(true);
@ -344,7 +350,7 @@ void PlayerSAO::setPos(const v3f &pos)
setBasePosition(pos); setBasePosition(pos);
// Movement caused by this command is always valid // Movement caused by this command is always valid
m_last_good_position = pos; m_last_good_position = getBasePosition();
m_move_pool.empty(); m_move_pool.empty();
m_time_from_last_teleport = 0.0; m_time_from_last_teleport = 0.0;
m_env->getGameDef()->SendMovePlayer(m_peer_id); m_env->getGameDef()->SendMovePlayer(m_peer_id);
@ -357,7 +363,7 @@ void PlayerSAO::moveTo(v3f pos, bool continuous)
setBasePosition(pos); setBasePosition(pos);
// Movement caused by this command is always valid // Movement caused by this command is always valid
m_last_good_position = pos; m_last_good_position = getBasePosition();
m_move_pool.empty(); m_move_pool.empty();
m_time_from_last_teleport = 0.0; m_time_from_last_teleport = 0.0;
m_env->getGameDef()->SendMovePlayer(m_peer_id); m_env->getGameDef()->SendMovePlayer(m_peer_id);

@ -87,7 +87,7 @@ public:
std::string getClientInitializationData(u16 protocol_version) override; std::string getClientInitializationData(u16 protocol_version) override;
void getStaticData(std::string *result) const override; void getStaticData(std::string *result) const override;
void step(float dtime, bool send_recommended) override; void step(float dtime, bool send_recommended) override;
void setBasePosition(const v3f &position); void setBasePosition(v3f position);
void setPos(const v3f &pos) override; void setPos(const v3f &pos) override;
void moveTo(v3f pos, bool continuous) override; void moveTo(v3f pos, bool continuous) override;
void setPlayerYaw(const float yaw); void setPlayerYaw(const float yaw);

@ -439,6 +439,18 @@ MAKE_STREAM_WRITE_FXN(video::SColor, ARGB8, 4);
//// More serialization stuff //// More serialization stuff
//// ////
inline void clampToF1000(float &v)
{
v = core::clamp(v, F1000_MIN, F1000_MAX);
}
inline void clampToF1000(v3f &v)
{
clampToF1000(v.X);
clampToF1000(v.Y);
clampToF1000(v.Z);
}
// Creates a string with the length as the first two bytes // Creates a string with the length as the first two bytes
std::string serializeString16(const std::string &plain); std::string serializeString16(const std::string &plain);