From f11f2d09071add4c549efb79df61a90aece24bcc Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sat, 13 Jan 2024 14:30:05 +0200 Subject: [PATCH] Check that clients only do calls on entities they possess --- source/game/networking.cpp | 9 +++++++++ source/game/networking.h | 2 ++ source/game/remotecall.h | 2 +- source/game/replicator.cpp | 13 ++++++++++++- source/game/replicator.h | 9 ++++++++- 5 files changed, 32 insertions(+), 3 deletions(-) diff --git a/source/game/networking.cpp b/source/game/networking.cpp index fb3d977..1ad4ed1 100644 --- a/source/game/networking.cpp +++ b/source/game/networking.cpp @@ -173,6 +173,15 @@ Networking::Player &Networking::create_player(const string &name, uint32_t id) return player; } +bool Networking::is_current_sender(uint32_t player_id) const +{ + auto i = lower_bound_member(players, player_id, &Player::id); + if(i==players.end() || i->id!=player_id) + return false; + + return i->owner==current_sender; +} + void Networking::set_state(State s) { if(s==state) diff --git a/source/game/networking.h b/source/game/networking.h index 8217bb1..eb97a26 100644 --- a/source/game/networking.h +++ b/source/game/networking.h @@ -172,6 +172,8 @@ public: template void send(const P &, F &&); + bool is_current_sender(std::uint32_t) const; + private: void set_state(State); void protocol_ready(const Net::Protocol &); diff --git a/source/game/remotecall.h b/source/game/remotecall.h index f79569c..b8e64dd 100644 --- a/source/game/remotecall.h +++ b/source/game/remotecall.h @@ -120,7 +120,7 @@ template requires std::is_base_of_v && HasEntityIdField

void RemoteEntityCallBase::call(const P &packet) { - Handle entity = this->replicator->find_entity(packet.entity_id); + Handle entity = this->replicator->find_entity(packet.entity_id, this->replicator->is_server()); if(!entity) return; // TODO report the error somehow diff --git a/source/game/replicator.cpp b/source/game/replicator.cpp index fa32249..8fefb57 100644 --- a/source/game/replicator.cpp +++ b/source/game/replicator.cpp @@ -9,6 +9,11 @@ using namespace std; namespace Msp::Game { +entity_access_denied::entity_access_denied(uint32_t entity_id): + runtime_error(lexical_cast(entity_id)) +{ } + + Replicator::Replicator(Stage &s, Networking &n): System(s), event_source(stage.get_event_bus()), @@ -54,9 +59,15 @@ void Replicator::set_protocol(const Net::Protocol &p) add_receiver(*this); } -Handle Replicator::find_entity(uint32_t id) const +Handle Replicator::find_entity(uint32_t id, bool check_access) const { auto i = find_if(entities, [id](const ReplicatedEntity &e){ return e.zygote->get_entity_id()==id; }); + if(check_access) + { + uint32_t possessor = (i->possessed ? i->possessed->get_player_id() : 0); + if(!possessor || !networking.is_current_sender(possessor)) + throw entity_access_denied(id); + } return (i!=entities.end() ? i->entity : nullptr); } diff --git a/source/game/replicator.h b/source/game/replicator.h index fdbe8f0..3385093 100644 --- a/source/game/replicator.h +++ b/source/game/replicator.h @@ -16,6 +16,13 @@ class Possessed; class Spawner; class Transform; +class entity_access_denied: public std::runtime_error +{ +public: + entity_access_denied(std::uint32_t); +}; + + class MSPGAME_API Replicator: public System, private Net::PacketReceiver, private Net::PacketReceiver { @@ -70,7 +77,7 @@ public: template void send(std::uint32_t, const P &); - Handle find_entity(std::uint32_t) const; + Handle find_entity(std::uint32_t, bool = false) const; void tick(Time::TimeDelta) override; void deferred_tick() override; -- 2.45.2