]> git.localhorst.tv Git - blank.git/blob - src/server/ClientConnection.hpp
group entity updates in as few packets as possible
[blank.git] / src / server / ClientConnection.hpp
1 #ifndef BLANK_SERVER_CLIENTCONNECTION_HPP_
2 #define BLANK_SERVER_CLIENTCONNECTION_HPP_
3
4 #include "ChunkTransmitter.hpp"
5 #include "Server.hpp"
6 #include "../app/IntervalTimer.hpp"
7 #include "../net/Connection.hpp"
8 #include "../net/ConnectionHandler.hpp"
9 #include "../world/EntityState.hpp"
10 #include "../world/Player.hpp"
11
12 #include <deque>
13 #include <list>
14 #include <SDL_net.h>
15 #include <vector>
16
17
18 namespace blank {
19 namespace server {
20
21 class Server;
22
23 class ClientConnection
24 : public ConnectionHandler {
25
26 public:
27         explicit ClientConnection(Server &, const IPaddress &);
28         ~ClientConnection();
29
30         bool Matches(const IPaddress &addr) const noexcept { return conn.Matches(addr); }
31
32         void Update(int dt);
33
34         Connection &GetConnection() noexcept { return conn; }
35         bool Disconnected() const noexcept { return conn.Closed(); }
36
37         /// prepare a packet of given type
38         template<class Type>
39         Type Prepare() const noexcept {
40                 return Packet::Make<Type>(server.GetPacket());
41         }
42         /// send the previously prepared packet
43         std::uint16_t Send();
44         /// send the previously prepared packet of non-default length
45         std::uint16_t Send(std::size_t len);
46
47         void AttachPlayer(const Player &);
48         void DetachPlayer();
49         bool HasPlayer() const noexcept { return player.entity; }
50         Entity &PlayerEntity() noexcept { return *player.entity; }
51         const Entity &PlayerEntity() const noexcept { return *player.entity; }
52         ChunkIndex &PlayerChunks() noexcept { return *player.chunks; }
53         const ChunkIndex &PlayerChunks() const noexcept { return *player.chunks; }
54
55 private:
56         struct SpawnStatus {
57                 // the entity in question
58                 Entity *const entity = nullptr;
59                 // sequence number of the spawn packet or -1 after it's been ack'd
60                 std::int32_t spawn_pack = -1;
61                 // sequence number of the despawn packet or -1 if no despawn has been sent
62                 std::int32_t despawn_pack = -1;
63
64                 explicit SpawnStatus(Entity &);
65                 ~SpawnStatus();
66         };
67
68 private:
69         void OnPacketReceived(std::uint16_t) override;
70         void OnPacketLost(std::uint16_t) override;
71
72         void On(const Packet::Login &) override;
73         void On(const Packet::Part &) override;
74         void On(const Packet::PlayerUpdate &) override;
75
76         bool CanSpawn(const Entity &) const noexcept;
77         bool CanDespawn(const Entity &) const noexcept;
78
79         void SendSpawn(SpawnStatus &);
80         void SendDespawn(SpawnStatus &);
81         void QueueUpdate(SpawnStatus &);
82         void SendUpdates();
83
84         void CheckPlayerFix();
85
86         void CheckChunkQueue();
87
88 private:
89         Server &server;
90         Connection conn;
91         Player player;
92         std::list<SpawnStatus> spawns;
93         unsigned int confirm_wait;
94
95         std::vector<SpawnStatus *> entity_updates;
96
97         EntityState player_update_state;
98         std::uint16_t player_update_pack;
99         IntervalTimer player_update_timer;
100
101         ChunkTransmitter transmitter;
102         std::deque<glm::ivec3> chunk_queue;
103         glm::ivec3 old_base;
104
105 };
106
107 }
108 }
109
110 #endif