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