]> git.tdb.fi Git - libs/game.git/commitdiff
Check that clients only do calls on entities they possess
authorMikko Rasa <tdb@tdb.fi>
Sat, 13 Jan 2024 12:30:05 +0000 (14:30 +0200)
committerMikko Rasa <tdb@tdb.fi>
Sat, 13 Jan 2024 12:46:08 +0000 (14:46 +0200)
source/game/networking.cpp
source/game/networking.h
source/game/remotecall.h
source/game/replicator.cpp
source/game/replicator.h

index fb3d977219b944dfed61567597e1f25cb63428f8..1ad4ed1e3fc5a3a285d637bcb1e5801e7f3c525f 100644 (file)
@@ -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)
index 8217bb1e3fead66259126e84fded7c7f5c4f07b4..eb97a26d9da92c85250dcb1442385b34c2c4b797 100644 (file)
@@ -172,6 +172,8 @@ public:
        template<typename P, typename F>
        void send(const P &, F &&);
 
+       bool is_current_sender(std::uint32_t) const;
+
 private:
        void set_state(State);
        void protocol_ready(const Net::Protocol &);
index f79569c4726eaa463568e474899eaa56bee6e34d..b8e64dd192adfd4b90dc7aa4ac62999c901f766c 100644 (file)
@@ -120,7 +120,7 @@ template<typename P, typename E>
        requires std::is_base_of_v<Entity, E> && HasEntityIdField<P>
 void RemoteEntityCallBase<P, E>::call(const P &packet)
 {
-       Handle<Entity> entity = this->replicator->find_entity(packet.entity_id);
+       Handle<Entity> entity = this->replicator->find_entity(packet.entity_id, this->replicator->is_server());
        if(!entity)
                return;  // TODO report the error somehow
 
index fa32249b32aac4b7067608cd184566fb2b00b3ba..8fefb572f2bcfe1ccfa1a2d9d387b0a38def3c99 100644 (file)
@@ -9,6 +9,11 @@ using namespace std;
 
 namespace Msp::Game {
 
+entity_access_denied::entity_access_denied(uint32_t entity_id):
+       runtime_error(lexical_cast<string>(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<Messages::GrantPossession>(*this);
 }
 
-Handle<Entity> Replicator::find_entity(uint32_t id) const
+Handle<Entity> 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);
 }
 
index fdbe8f07b311756b11e0def52fb78b51568e7a22..33850937406d9e0908e1a1d745a4ac4d73c331ed 100644 (file)
@@ -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<Messages::SpawnEntity>,
        private Net::PacketReceiver<Messages::GrantPossession>
 {
@@ -70,7 +77,7 @@ public:
        template<typename P>
        void send(std::uint32_t, const P &);
 
-       Handle<Entity> find_entity(std::uint32_t) const;
+       Handle<Entity> find_entity(std::uint32_t, bool = false) const;
 
        void tick(Time::TimeDelta) override;
        void deferred_tick() override;