]> git.tdb.fi Git - libs/game.git/commitdiff
Track the sender of the current packet
authorMikko Rasa <tdb@tdb.fi>
Thu, 11 Jan 2024 17:11:25 +0000 (19:11 +0200)
committerMikko Rasa <tdb@tdb.fi>
Thu, 11 Jan 2024 17:12:34 +0000 (19:12 +0200)
source/game/networking.cpp
source/game/networking.h

index 9c2894f8c8d271a5da20c170db38eaa3526e3fe4..7228a827dd672322eef259593b6a729d532033c6 100644 (file)
@@ -1,4 +1,5 @@
 #include "networking.h"
+#include <msp/core/raii.h>
 #include <msp/net/inet6.h>
 #include <msp/net/resolve.h>
 #include "director.h"
@@ -89,20 +90,16 @@ unsigned Networking::get_next_protocol_id()
        return next_id++;
 }
 
-void Networking::set_protocol(unsigned id, unique_ptr<Net::Protocol> net_proto)
+void Networking::set_receiver(unsigned id, Net::DynamicReceiver *recv)
 {
-       if(protocols.size()<=id)
-               protocols.resize(id+1);
-
-       Protocol &proto = protocols[id];
-       proto.protocol = move(net_proto);
+       protocols[id].receiver = recv;
        if(state==SERVER)
        {
                for(const auto &c: clients)
-                       c->get_communicator().add_protocol(*proto.protocol, proto.receiver);
+                       c->update_receiver(id);
        }
        else if(state==CONNECTING || state==CONNECTED)
-               connection->get_communicator().add_protocol(*proto.protocol, proto.receiver);
+               connection->update_receiver(id);
 }
 
 uint16_t Networking::intern_string(const string &value)
@@ -210,6 +207,16 @@ void Networking::stage_activated(const Events::StageActivated &event)
 }
 
 
+void Networking::ProxyReceiver::receive(unsigned i, const Variant &p)
+{
+       if(receiver)
+       {
+               SetForScope set_sender(networking.current_sender, &connection);
+               receiver->receive(i, p);
+       }
+}
+
+
 Networking::Connection::Connection(Networking &n, unique_ptr<Net::StreamSocket> s):
        networking(n),
        socket(move(s)),
@@ -230,6 +237,20 @@ void Networking::Connection::error(const exception &)
        stale = true;
 }
 
+void Networking::Connection::update_receiver(unsigned id)
+{
+       if(id>=receivers.size())
+               receivers.resize(id+1);
+
+       unique_ptr<ProxyReceiver> &proxy_ptr = receivers[id];
+       if(!proxy_ptr)
+       {
+               proxy_ptr = make_unique<ProxyReceiver>(networking, *this);
+               communicator.add_protocol(*networking.protocols[id].protocol, *proxy_ptr);
+       }
+       proxy_ptr->set_receiver(networking.protocols[id].receiver);
+}
+
 
 Networking::ServerConnection::ServerConnection(Networking &n, const Net::SockAddr &addr):
        Connection(n, make_unique<Net::StreamSocket>(addr.get_family()))
@@ -298,8 +319,14 @@ Networking::ClientConnection::ClientConnection(Networking &n, unique_ptr<Net::St
 {
        communicator.signal_protocol_ready.connect(sigc::mem_fun(this, &ClientConnection::protocol_ready));
        communicator.add_protocol(networking.core_protocol, *this);
-       for(Protocol &p: networking.protocols)
-               communicator.add_protocol(*p.protocol, p.receiver);
+       receivers.resize(networking.protocols.size());
+       for(size_t i=0; i<networking.protocols.size(); ++i)
+               if(Net::Protocol *proto = networking.protocols[i].protocol.get())
+               {
+                       ProxyReceiver *recv_ptr = (receivers[i] = make_unique<ProxyReceiver>(networking, *this)).get();
+                       recv_ptr->set_receiver(networking.protocols[i].receiver);
+                       communicator.add_protocol(*proto, *recv_ptr);
+               }
 }
 
 void Networking::ClientConnection::protocol_ready(const Net::Protocol &p)
index c12f39f2dbb5172aae4f79a6117939814d469b30..f3d8e82e9fec0594ee4b94f0b47f286e754a1fc9 100644 (file)
@@ -30,20 +30,26 @@ public:
                Events::NetworkPlayerDeparted, Events::ServerStageActivated>;
 
 private:
-       class SwitchableReceiver: public Net::DynamicReceiver
+       class Connection;
+
+       class ProxyReceiver: public Net::DynamicReceiver
        {
        private:
+               Networking &networking;
+               Connection &connection;
                Net::DynamicReceiver *receiver = nullptr;
 
        public:
+               ProxyReceiver(Networking &n, Connection &c): networking(n), connection(c) { }
+
                void set_receiver(Net::DynamicReceiver *r) { receiver = r; }
-               void receive(unsigned i, const Variant &p) override { if(receiver) receiver->receive(i, p); }
+               void receive(unsigned, const Variant &) override;
        };
 
        struct Protocol
        {
                std::unique_ptr<Net::Protocol> protocol;
-               SwitchableReceiver receiver;
+               Net::DynamicReceiver *receiver = nullptr;
        };
 
        class Connection
@@ -52,6 +58,7 @@ private:
                Networking &networking;
                std::unique_ptr<Net::StreamSocket> socket;
                Net::Communicator communicator;
+               std::vector<std::unique_ptr<ProxyReceiver>> receivers;
                bool stale = false;
 
                Connection(Networking &, std::unique_ptr<Net::StreamSocket>);
@@ -61,6 +68,7 @@ private:
 
        public:
                Net::Communicator &get_communicator() { return communicator; }
+               void update_receiver(unsigned);
                bool is_stale() const { return stale; }
        };
 
@@ -123,6 +131,7 @@ private:
        std::vector<Player> players;
        unsigned next_player_id = 1;
        std::vector<std::string> strings;
+       Connection *current_sender = nullptr;
 
 public:
        Networking(Director &);
@@ -140,7 +149,7 @@ public:
 private:
        static unsigned get_next_protocol_id();
 
-       void set_protocol(unsigned, std::unique_ptr<Net::Protocol>);
+       void set_receiver(unsigned, Net::DynamicReceiver *);
 
 public:
        std::uint16_t intern_string(const std::string &);
@@ -170,11 +179,14 @@ template<typename P>
 const Net::Protocol &Networking::set_receiver(Net::DynamicReceiver *r)
 {
        static unsigned id = get_next_protocol_id();
-       if(id>=protocols.size() || !protocols[id].protocol)
-               set_protocol(id, std::make_unique<P>());
-
-       protocols[id].receiver.set_receiver(r);
-       return *protocols[id].protocol.get();
+       if(id>=protocols.size())
+               protocols.resize(id+1);
+       Protocol &proto = protocols[id];
+       if(!proto.protocol)
+               proto.protocol = std::make_unique<P>();
+
+       set_receiver(id, r);
+       return *proto.protocol.get();
 }
 
 template<typename P>