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