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