R-Type
Distributed multiplayer game engine in C++
Loading...
Searching...
No Matches
Connection.hpp
Go to the documentation of this file.
1/*
2** EPITECH PROJECT, 2025
3** Created on 09/12/2025.
4** File description:
5** Connection.hpp
6*/
7
8#pragma once
9
10#include <capnp/message.h>
11#include <capnp/serialize.h>
12#include <cstdint>
13#include <string>
14#include <vector>
15#include "schemas/connection.capnp.h"
16
18
24 public:
25 std::string _clientVersion;
26 std::string _playerName;
27 uint64_t _timestamp;
28
30
31 HandshakeRequest(const std::string &version, const std::string &name, uint64_t ts)
32 : _clientVersion(version), _playerName(name), _timestamp(ts) {}
33
34 [[nodiscard]] std::vector<uint8_t> serialize() const {
35 capnp::MallocMessageBuilder message;
36 auto builder = message.initRoot<::HandshakeRequest>();
37 builder.setClientVersion(_clientVersion);
38 builder.setPlayerName(_playerName);
39 builder.setTimestamp(_timestamp);
40
41 auto bytes = capnp::messageToFlatArray(message);
42 auto byteArray = bytes.asBytes();
43 return std::vector<uint8_t>(byteArray.begin(), byteArray.end());
44 }
45
46 static HandshakeRequest deserialize(const std::vector<uint8_t> &data) {
47 // Ensure buffer is word-aligned for Cap'n Proto (undefined behavior if not)
48 KJ_REQUIRE(data.size() % sizeof(capnp::word) == 0,
49 "Serialized data size must be a multiple of capnp::word");
50 auto aligned = kj::heapArray<uint8_t>(data.size());
51 memcpy(aligned.begin(), data.data(), data.size());
52 kj::ArrayPtr<const capnp::word> words(reinterpret_cast<const capnp::word *>(aligned.begin()),
53 data.size() / sizeof(capnp::word));
54 capnp::FlatArrayMessageReader message(words);
55 auto reader = message.getRoot<::HandshakeRequest>();
56
57 return HandshakeRequest(reader.getClientVersion().cStr(), reader.getPlayerName().cStr(),
58 reader.getTimestamp());
59 }
60 };
61
67 public:
68 bool accepted{false};
69 std::string sessionId;
70 std::string serverId;
71 std::string message;
72 std::string serverVersion;
73 uint32_t playerId{0}; // Player ID assigned by server
74 std::string playerName; // Display name (username or guest_XXXX)
75
76 HandshakeResponse() = default;
77
78 [[nodiscard]] std::vector<uint8_t> serialize() const {
79 capnp::MallocMessageBuilder msg;
80 auto builder = msg.initRoot<::HandshakeResponse>();
81 builder.setAccepted(accepted);
82 builder.setSessionId(sessionId);
83 builder.setServerId(serverId);
84 builder.setMessage(message);
85 builder.setServerVersion(serverVersion);
86 builder.setPlayerId(playerId);
87 builder.setPlayerName(playerName);
88
89 auto bytes = capnp::messageToFlatArray(msg);
90 auto byteArray = bytes.asBytes();
91 return std::vector<uint8_t>(byteArray.begin(), byteArray.end());
92 }
93
94 static HandshakeResponse deserialize(const std::vector<uint8_t> &data) {
95 // Ensure buffer is word-aligned for Cap'n Proto (undefined behavior if not)
96 KJ_REQUIRE(data.size() % sizeof(capnp::word) == 0,
97 "Serialized data size must be a multiple of capnp::word");
98 auto aligned = kj::heapArray<uint8_t>(data.size());
99 memcpy(aligned.begin(), data.data(), data.size());
100 kj::ArrayPtr<const capnp::word> words(reinterpret_cast<const capnp::word *>(aligned.begin()),
101 data.size() / sizeof(capnp::word));
102 capnp::FlatArrayMessageReader msg(words);
103 auto reader = msg.getRoot<::HandshakeResponse>();
104
105 HandshakeResponse result;
106 result.accepted = reader.getAccepted();
107 result.sessionId = reader.getSessionId().cStr();
108 result.serverId = reader.getServerId().cStr();
109 result.message = reader.getMessage().cStr();
110 result.serverVersion = reader.getServerVersion().cStr();
111 result.playerId = reader.getPlayerId();
112 result.playerName = reader.getPlayerName().cStr();
113 return result;
114 }
115 };
116
122 public:
123 uint64_t timestamp;
125
127 PingMessage(uint64_t ts, uint32_t seq) : timestamp(ts), sequenceNumber(seq) {}
128
129 [[nodiscard]] std::vector<uint8_t> serialize() const {
130 capnp::MallocMessageBuilder message;
131 auto builder = message.initRoot<::PingMessage>();
132 builder.setTimestamp(timestamp);
133 builder.setSequenceNumber(sequenceNumber);
134
135 auto bytes = capnp::messageToFlatArray(message);
136 auto byteArray = bytes.asBytes();
137 return std::vector<uint8_t>(byteArray.begin(), byteArray.end());
138 }
139
140 static PingMessage deserialize(const std::vector<uint8_t> &data) {
141 // Ensure buffer is word-aligned for Cap'n Proto (undefined behavior if not)
142 KJ_REQUIRE(data.size() % sizeof(capnp::word) == 0,
143 "Serialized data size must be a multiple of capnp::word");
144 auto aligned = kj::heapArray<uint8_t>(data.size());
145 memcpy(aligned.begin(), data.data(), data.size());
146 kj::ArrayPtr<const capnp::word> words(reinterpret_cast<const capnp::word *>(aligned.begin()),
147 data.size() / sizeof(capnp::word));
148 capnp::FlatArrayMessageReader message(words);
149 auto reader = message.getRoot<::PingMessage>();
150
151 return PingMessage(reader.getTimestamp(), reader.getSequenceNumber());
152 }
153 };
154
160 public:
164
166
167 [[nodiscard]] std::vector<uint8_t> serialize() const {
168 capnp::MallocMessageBuilder message;
169 auto builder = message.initRoot<::PongMessage>();
170 builder.setClientTimestamp(clientTimestamp);
171 builder.setServerTimestamp(serverTimestamp);
172 builder.setSequenceNumber(sequenceNumber);
173
174 auto bytes = capnp::messageToFlatArray(message);
175 auto byteArray = bytes.asBytes();
176 return std::vector<uint8_t>(byteArray.begin(), byteArray.end());
177 }
178
179 static PongMessage deserialize(const std::vector<uint8_t> &data) {
180 // Ensure buffer is word-aligned for Cap'n Proto (undefined behavior if not)
181 KJ_REQUIRE(data.size() % sizeof(capnp::word) == 0,
182 "Serialized data size must be a multiple of capnp::word");
183 auto aligned = kj::heapArray<uint8_t>(data.size());
184 memcpy(aligned.begin(), data.data(), data.size());
185 kj::ArrayPtr<const capnp::word> words(reinterpret_cast<const capnp::word *>(aligned.begin()),
186 data.size() / sizeof(capnp::word));
187 capnp::FlatArrayMessageReader message(words);
188 auto reader = message.getRoot<::PongMessage>();
189
190 PongMessage result;
191 result.clientTimestamp = reader.getClientTimestamp();
192 result.serverTimestamp = reader.getServerTimestamp();
193 result.sequenceNumber = reader.getSequenceNumber();
194 return result;
195 }
196 };
197
198} // namespace RType::Messages::Connection
Client initiates connection with server.
static HandshakeRequest deserialize(const std::vector< uint8_t > &data)
HandshakeRequest(const std::string &version, const std::string &name, uint64_t ts)
std::vector< uint8_t > serialize() const
std::vector< uint8_t > serialize() const
static HandshakeResponse deserialize(const std::vector< uint8_t > &data)
Client or server sends ping.
PingMessage(uint64_t ts, uint32_t seq)
static PingMessage deserialize(const std::vector< uint8_t > &data)
std::vector< uint8_t > serialize() const
std::vector< uint8_t > serialize() const
static PongMessage deserialize(const std::vector< uint8_t > &data)