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