]> git.localhorst.tv Git - blank.git/commitdiff
make server aware connected clients' player entity
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 5 Sep 2015 13:45:11 +0000 (15:45 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Sat, 5 Sep 2015 13:45:11 +0000 (15:45 +0200)
src/net/ClientConnection.hpp [new file with mode: 0644]
src/net/Server.hpp
src/net/net.cpp

diff --git a/src/net/ClientConnection.hpp b/src/net/ClientConnection.hpp
new file mode 100644 (file)
index 0000000..acbee6e
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef BLANK_NET_CLIENTCONNECTION_HPP_
+#define BLANK_NET_CLIENTCONNECTION_HPP_
+
+#include "Connection.hpp"
+#include "ConnectionHandler.hpp"
+
+#include <SDL_net.h>
+
+
+namespace blank {
+
+class Entity;
+class Server;
+
+class ClientConnection
+: public ConnectionHandler {
+
+public:
+       explicit ClientConnection(Server &, const IPaddress &);
+       ~ClientConnection();
+
+       bool Matches(const IPaddress &addr) const noexcept { return conn.Matches(addr); }
+
+       void Update(int dt);
+
+       Connection &GetConnection() noexcept { return conn; }
+       bool Disconnected() const noexcept { return conn.Closed(); }
+
+       void AttachPlayer(Entity &);
+       void DetachPlayer();
+
+       void On(const Packet::Login &) override;
+       void On(const Packet::Part &) override;
+
+private:
+       Server &server;
+       Connection conn;
+       Entity *player;
+
+};
+
+}
+
+#endif
index a95cd37bea9aa41c119783538e44e08af423d840..a6d509b6974052855e2272574bf8c13a1db7fa9f 100644 (file)
@@ -7,7 +7,7 @@
 
 namespace blank {
 
-class Connection;
+class ClientConnection;
 class World;
 
 class Server {
@@ -25,21 +25,20 @@ public:
 
        void Update(int dt);
 
-private:
-       void HandlePacket(const UDPpacket &);
+       UDPsocket &GetSocket() noexcept { return serv_sock; }
+       UDPpacket &GetPacket() noexcept { return serv_pack; }
 
-       Connection &GetClient(const IPaddress &);
+       World &GetWorld() noexcept { return world; }
 
-       void OnConnect(Connection &);
-       void OnDisconnect(Connection &);
+private:
+       void HandlePacket(const UDPpacket &);
 
-       void HandleLogin(Connection &client, const UDPpacket &);
-       void HandlePart(Connection &client, const UDPpacket &);
+       ClientConnection &GetClient(const IPaddress &);
 
 private:
        UDPsocket serv_sock;
        UDPpacket serv_pack;
-       std::list<Connection> clients;
+       std::list<ClientConnection> clients;
 
        World &world;
 
index 4d364124253d9e5d5e5668e77a6ec52ef29eb9b0..7f12e63ff3626b4d23f741d6d38cea9304ed7ad6 100644 (file)
@@ -1,4 +1,5 @@
 #include "Client.hpp"
+#include "ClientConnection.hpp"
 #include "Connection.hpp"
 #include "ConnectionHandler.hpp"
 #include "io.hpp"
@@ -101,6 +102,67 @@ uint16_t Client::SendLogin(const string &name) {
 }
 
 
+ClientConnection::ClientConnection(Server &server, const IPaddress &addr)
+: server(server)
+, conn(addr)
+, player(nullptr) {
+       conn.SetHandler(this);
+}
+
+ClientConnection::~ClientConnection() {
+       DetachPlayer();
+}
+
+void ClientConnection::Update(int dt) {
+       conn.Update(dt);
+       if (Disconnected()) {
+               cout << "disconnect from " << conn.Address() << endl;
+       } else if (conn.ShouldPing()) {
+               conn.SendPing(server.GetPacket(), server.GetSocket());
+       }
+}
+
+void ClientConnection::AttachPlayer(Entity &new_player) {
+       DetachPlayer();
+       player = &new_player;
+       player->Ref();
+}
+
+void ClientConnection::DetachPlayer() {
+       if (!player) return;
+       player->Kill();
+       player->UnRef();
+       player = nullptr;
+}
+
+void ClientConnection::On(const Packet::Login &pack) {
+       string name;
+       pack.ReadPlayerName(name);
+
+       Entity *new_player = server.GetWorld().AddPlayer(name);
+
+       if (new_player) {
+               // success!
+               AttachPlayer(*new_player);
+               cout << "accepted login from player \"" << name << '"' << endl;
+               auto response = Packet::Make<Packet::Join>(server.GetPacket());
+               response.WritePlayer(*new_player);
+               response.WriteWorldName(server.GetWorld().Name());
+               conn.Send(server.GetPacket(), server.GetSocket());
+       } else {
+               // aw no :(
+               cout << "rejected login from player \"" << name << '"' << endl;
+               Packet::Make<Packet::Part>(server.GetPacket());
+               conn.Send(server.GetPacket(), server.GetSocket());
+               conn.Close();
+       }
+}
+
+void ClientConnection::On(const Packet::Part &) {
+       conn.Close();
+}
+
+
 Connection::Connection(const IPaddress &addr)
 : handler(nullptr)
 , addr(addr)
@@ -387,85 +449,29 @@ void Server::HandlePacket(const UDPpacket &udp_pack) {
                return;
        }
 
-       Connection &client = GetClient(udp_pack.address);
-       client.Received(udp_pack);
-
-       switch (pack.header.type) {
-               case Packet::Login::TYPE:
-                       HandleLogin(client, udp_pack);
-                       break;
-               case Packet::Part::TYPE:
-                       HandlePart(client, udp_pack);
-                       break;
-               default:
-                       // just drop packets of unknown or unhandled type
-                       break;
-       }
+       ClientConnection &client = GetClient(udp_pack.address);
+       client.GetConnection().Received(udp_pack);
 }
 
-Connection &Server::GetClient(const IPaddress &addr) {
-       for (Connection &client : clients) {
+ClientConnection &Server::GetClient(const IPaddress &addr) {
+       for (ClientConnection &client : clients) {
                if (client.Matches(addr)) {
                        return client;
                }
        }
-       clients.emplace_back(addr);
-       OnConnect(clients.back());
+       clients.emplace_back(*this, addr);
        return clients.back();
 }
 
-void Server::OnConnect(Connection &client) {
-       cout << "new connection from " << client.Address() << endl;
-       // tell it we're alive
-       client.SendPing(serv_pack, serv_sock);
-}
-
 void Server::Update(int dt) {
-       for (list<Connection>::iterator client(clients.begin()), end(clients.end()); client != end;) {
+       for (list<ClientConnection>::iterator client(clients.begin()), end(clients.end()); client != end;) {
                client->Update(dt);
-               if (client->Closed()) {
-                       OnDisconnect(*client);
+               if (client->Disconnected()) {
                        client = clients.erase(client);
                } else {
-                       if (client->ShouldPing()) {
-                               client->SendPing(serv_pack, serv_sock);
-                       }
                        ++client;
                }
        }
 }
 
-void Server::OnDisconnect(Connection &client) {
-       cout << "connection timeout from " << client.Address() << endl;
-}
-
-
-void Server::HandleLogin(Connection &client, const UDPpacket &udp_pack) {
-       auto pack = Packet::As<Packet::Login>(udp_pack);
-
-       string name;
-       pack.ReadPlayerName(name);
-
-       Entity *player = world.AddPlayer(name);
-
-       if (player) {
-               // success!
-               cout << "accepted login from player \"" << name << '"' << endl;
-               auto response = Packet::Make<Packet::Join>(serv_pack);
-               response.WritePlayer(*player);
-               response.WriteWorldName(world.Name());
-               client.Send(serv_pack, serv_sock);
-       } else {
-               // aw no :(
-               cout << "rejected login from player \"" << name << '"' << endl;
-               Packet::Make<Packet::Part>(serv_pack);
-               client.Send(serv_pack, serv_sock);
-               client.Close();
-       }
-}
-
-void Server::HandlePart(Connection &client, const UDPpacket &udp_pack) {
-       client.Close();
-}
-
 }