RunicVTT Open Source Virtual Tabletop for TTRPG using P2P
Loading...
Searching...
No Matches
NetworkManager.h
Go to the documentation of this file.
1#pragma once
2#include <string>
3#include <unordered_map>
4#include <memory>
5#include "PeerLink.h"
6#include "flecs.h"
7#include "rtc/configuration.hpp"
8#include "imgui.h"
9#include <regex>
10#include <vector>
11#include <rtc/peerconnection.hpp>
12#include <nlohmann/json.hpp>
13#include <future>
14#include <iostream>
15#include "MessageQueue.h"
16#include "Components.h"
17#include "Message.h"
18#include <fstream>
19#include "ImGuiToaster.h"
20#include "PathManager.h"
21#include "Logger.h"
22#include "IdentityManager.h"
23
25{
26 uint32_t epoch{0};
27 bool closed{true};
28 uint32_t lastSeq{0};
29 std::string ownerPeerId;
30 bool locallyDragging{false};
32 uint32_t localSeq{0};
33 uint64_t lastTxMs{0};
34 uint64_t epochOpenedMs{0};
35};
36
37// Forward declare
38class SignalingServer;
39class SignalingClient;
40class BoardManager;
42
44{
46 uint64_t id = 0; // boardId when kind=Board, markerId when kind=Marker
47 uint64_t boardId = 0; // only used when kind=Marker; for Board can be same as id or 0
48 std::string name; // optional filename/path hint
49
50 // optional meta to finalize on commit:
51 std::optional<msg::MarkerMeta> markerMeta;
52 std::optional<msg::BoardMeta> boardMeta;
53
54 uint64_t total = 0;
55 uint64_t received = 0;
56 std::vector<uint8_t> buf;
57
58 bool commitRequested = false;
59
60 bool isComplete() const
61 {
62 return total == received && total > 0;
63 }
64};
65
66class NetworkManager : public std::enable_shared_from_this<NetworkManager>
67{
68public:
69 NetworkManager(flecs::world ecs, std::shared_ptr<IdentityManager> identity_manager);
70
71 void setup(std::weak_ptr<BoardManager> board_manager, std::weak_ptr<GameTableManager> gametable_manager);
72
74
75 void startServer(ConnectionType mode, unsigned short port, bool tryUpnp);
76 void startServer(std::string internal_ip_address, unsigned short port);
77 void closeServer();
78
79 // if not, call this from main thread; otherwise add a mutex)
80 bool isConnected();
81 bool isHosting() const;
82 bool hasAnyPeer() const;
83 int connectedPeerCount() const;
84
85 void allowPort(unsigned int port);
86 void disallowPort(unsigned short port);
87
88 // Utility methods
89 std::string getNetworkInfo(ConnectionType type); // Get network info (IP and port) (server utility)
90 std::string getLocalIPAddress(); // Get local IP address (server utility)
91 std::string getExternalIPAddress(); // Get external IP address (server utility)
92 std::string getLocalTunnelURL(); // Get Local Tunnel URL
93
94 void parseConnectionString(std::string connection_string, std::string& server, unsigned short& port, std::string& password);
95 unsigned short getPort() const
96 {
97 return port;
98 };
99 std::string getNetworkPassword() const
100 {
101 return std::string(network_password);
102 };
103 void setPort(unsigned int port)
104 {
105 this->port = port;
106 }
107 void setNetworkPassword(const char* password);
109 {
110 return peer_role;
111 }
112 void ShowPortForwardingHelpPopup(bool* p_open);
113 rtc::Configuration getRTCConfig() const
114 {
115 return rtcConfig;
116 }
117
118 bool connectToPeer(const std::string& connectionString);
119 bool disconectFromPeers();
120 bool removePeer(std::string peerId);
121 bool clearPeers() const
122 {
123 for (auto [id, peer] : peers)
124 {
125 peer->close();
126 }
127 return peers.empty();
128 }
129 bool disconnectAllPeers();
130 std::size_t removeDisconnectedPeers();
131 void broadcastPeerDisconnect(const std::string& targetId);
132 /*bool reconnectPeer(const std::string& peerId);*/
133
134 void onPeerLocalDescription(const std::string& peerId, const rtc::Description& desc);
135 void onPeerLocalCandidate(const std::string& peerId, const rtc::Candidate& cand);
136 std::shared_ptr<PeerLink> ensurePeerLink(const std::string& peerId);
137
138 std::string displayNameForPeer(const std::string& peerId) const;
139
140 std::string getMyUsername() const
141 {
142 return identity_manager->myUsername();
143 }
144 std::string getMyUniqueId() const
145 {
146 return identity_manager->myUniqueId();
147 }
148
149 const std::string& getMyPeerId() const
150 {
151 return myPeerId_;
152 }
153 void setMyPeerId(std::string v)
154 {
155 myPeerId_ = std::move(v);
156 }
157
158 const std::unordered_map<std::string, std::shared_ptr<PeerLink>>& getPeers() const
159 {
160 return peers;
161 }
162 std::shared_ptr<SignalingServer> getSignalingServer() const
163 {
164 return signalingServer;
165 }
166
168 {
169 return inboundGame_.try_pop(out);
170 }
171
173 {
174 return inboundRaw_.try_pop(out);
175 }
176
177 void drainEvents();
178 void drainInboundRaw(int maxPerTick);
179
180 void decodeRawChatBuffer(const std::string& fromPeer, const std::vector<uint8_t>& b);
181 void decodeRawNotesBuffer(const std::string& fromPeer, const std::vector<uint8_t>& b);
182
183 void startRawDrainWorker();
184 void stopRawDrainWorker();
185
186 void onPeerChannelOpen(const std::string& peerId, const std::string& label);
187 void bootstrapPeerIfReady(const std::string& peerId);
188
189 void broadcastGameTable(const flecs::entity& gameTable);
190 void broadcastBoard(const flecs::entity& board);
191 void broadcastFog(uint64_t boardId, const flecs::entity& fog);
192
193 void broadcastFogUpdate(uint64_t boardId, const flecs::entity& fog);
194 void broadcastFogDelete(uint64_t boardId, const flecs::entity& fog);
195
196 void sendFogUpdate(uint64_t boardId, const flecs::entity& fog, const std::vector<std::string>& toPeerIds);
197 void sendFogDelete(uint64_t boardId, const flecs::entity& fog, const std::vector<std::string>& toPeerIds);
198
199 void sendGameTo(const std::string& peerId, const std::vector<unsigned char>& bytes);
200 void broadcastGameFrame(const std::vector<unsigned char>& frame, const std::vector<std::string>& toPeerIds);
201
202 void sendGameTable(const flecs::entity& gameTable, const std::vector<std::string>& toPeerIds);
203 void sendBoard(const flecs::entity& board, const std::vector<std::string>& toPeerIds);
204 void sendFog(uint64_t boardId, const flecs::entity& fog, const std::vector<std::string>& toPeerIds);
205
206 bool sendImageChunks(msg::ImageOwnerKind kind, uint64_t id, const std::vector<unsigned char>& img, const std::vector<std::string>& toPeerIds);
207
208 void setToaster(std::shared_ptr<ImGuiToaster> t)
209 {
210 toaster_ = t;
211 }
212 // Unified push (replaces your old pushStatusToast)
213 void pushStatusToast(const std::string& msg, ImGuiToaster::Level lvl, float durationSec = 5.0f)
214 {
215 if (toaster_)
216 toaster_->Push(lvl, msg, durationSec);
217 }
218
219 MessageQueue<msg::NetEvent> events_;
220 MessageQueue<msg::InboundRaw> inboundRaw_;
221 std::vector<std::string> getConnectedPeerIds() const;
222 std::vector<std::string> getConnectedUsernames() const;
223
224 // GM identity
225 void setGMId(const std::string& id)
226 {
227 gmPeerId_ = id;
228 }
229 const std::string& getGMId() const
230 {
231 return gmPeerId_;
232 }
233
234 void decodeRawGameBuffer(const std::string& fromPeer, const std::vector<uint8_t>& b);
235
236 void sendMarkerDelete(uint64_t boardId, const flecs::entity& marker, const std::vector<std::string>& toPeerIds);
237 void broadcastMarkerDelete(uint64_t boardId, const flecs::entity& marker);
238 void broadcastMarker(uint64_t boardId, const flecs::entity& marker);
239 void sendMarker(uint64_t boardId, const flecs::entity& marker, const std::vector<std::string>& toPeerIds);
240 //PUBLIC MARKER STUFF--------------------------------------------------------------------------------
241
242 //END STABLE
243 void decodeRawMarkerMoveBuffer(const std::string& fromPeer, const std::vector<uint8_t>& b);
244
245 void markDraggingLocal(uint64_t markerId, bool dragging);
246 bool isMarkerBeingDragged(uint64_t markerId) const;
247 bool amIDragging(uint64_t markerId) const;
248 void forceCloseDrag(uint64_t markerId);
249
250 void broadcastMarkerMove(uint64_t boardId, const flecs::entity& marker);
251 void sendMarkerMove(uint64_t boardId, const flecs::entity& marker, const std::vector<std::string>& toPeerIds);
252
253 void broadcastMarkerMoveState(uint64_t boardId, const flecs::entity& marker);
254 void sendMarkerMoveState(uint64_t boardId, const flecs::entity& marker, const std::vector<std::string>& toPeerIds);
255
256 void broadcastMarkerUpdate(uint64_t boardId, const flecs::entity& marker);
257 void sendMarkerUpdate(uint64_t boardId, const flecs::entity& marker, const std::vector<std::string>& toPeerIds);
258
259 bool shouldApplyMarkerMove(const msg::ReadyMessage& m); // DCType::MarkerMove
260 bool shouldApplyMarkerMoveStateStart(const msg::ReadyMessage& m); // DCType::MarkerMoveState + mov.isDragging==true
261 bool shouldApplyMarkerMoveStateFinal(const msg::ReadyMessage& m); // DCType::MarkerMoveState + mov.isDragging==false
262
263 // send/broadcast
264 void broadcastGridUpdate(uint64_t boardId, const flecs::entity& board);
265 void sendGridUpdate(uint64_t boardId, const flecs::entity& board, const std::vector<std::string>& toPeerIds);
266
267 //PUBLIC END MARKER STUFF----------------------------------------------------------------------------
268
269 void buildUserNameUpdate(std::vector<uint8_t>& out,
270 uint64_t tableId,
271 const std::string& userUniqueId,
272 const std::string& oldUsername,
273 const std::string& newUsername,
274 bool reboundFlag) const;
275
276 void broadcastUserNameUpdate(const std::vector<uint8_t>& payload); // send on Game DC to all
277 void sendUserNameUpdateTo(const std::string& peerId, // direct (rare)
278 const std::vector<uint8_t>& payload);
279
280 void upsertPeerIdentityWithUnique(const std::string& peerId,
281 const std::string& uniqueId,
282 const std::string& username);
283
284 // NetworkManager.h (public)
285 bool broadcastChatJson(const msg::Json& j);
286 bool sendChatJsonTo(const std::string& peerId, const msg::Json& j);
287 bool sendChatJsonTo(const std::set<std::string>& peers, const msg::Json& j);
288 std::shared_ptr<IdentityManager> getIdentityManager()
289 {
290 return identity_manager;
291 }
292
293 std::unordered_map<uint64_t /*markerId*/, DragState> drag_;
294 // NetworkManager.h
295 std::string debugIdentitySnapshot() const;
296 void clearDragState(uint64_t markerId);
297 void housekeepPeers();
298 // public:
299 void setCustomHost(const std::string& h) { customHost_ = h; }
300 const std::string& getCustomHost() const { return customHost_; }
301
302private:
303 std::string customHost_; // empty = unset
304 // build
305 std::vector<unsigned char> buildGridUpdateFrame(uint64_t boardId, const Grid& grid);
306 // handle
307 void handleGridUpdate(const std::vector<uint8_t>& b, size_t& off);
308
309 //MARKER STUFF--------------------------------------------------------------------------------
310 std::string decodingFromPeer_;
311 uint32_t sendMoveMinPeriodMs_{50}; // pacing target (~20Hz)
312 uint32_t getSendMoveMinPeriodMs() const
313 {
315 }
316
317 // MarkerUpdate
318 void handleMarkerMove(const std::vector<uint8_t>& b, size_t& off);
319 void handleMarkerUpdate(const std::vector<uint8_t>& b, size_t& off);
320 void handleMarkerMoveState(const std::vector<uint8_t>& b, size_t& off);
321
322 // ---- MARKER UPDATE/DELETE ----
323 std::vector<unsigned char> buildMarkerMoveFrame(uint64_t boardId, const flecs::entity& marker, uint32_t seq);
324 std::vector<unsigned char> buildMarkerMoveStateFrame(uint64_t boardId, const flecs::entity& marker);
325 std::vector<unsigned char> buildMarkerUpdateFrame(uint64_t boardId, const flecs::entity& marker);
326
327 static bool tieBreakWins(const std::string& challengerPeerId, const std::string& currentOwnerPeerId) //NEEDS REVISITING
328 {
329 return challengerPeerId < currentOwnerPeerId;
330 }
331
332 //STABLE
333 void handleMarkerDelete(const std::vector<uint8_t>& b, size_t& off);
334 std::vector<unsigned char> buildMarkerDeleteFrame(uint64_t boardId, uint64_t markerId);
335 std::vector<uint8_t> buildCommitMarkerFrame(uint64_t boardId, uint64_t markerId);
336 std::vector<uint8_t> buildCreateMarkerFrame(uint64_t boardId, const flecs::entity& marker, uint64_t imageBytesTotal);
337 void handleMarkerMeta(const std::vector<uint8_t>& b, size_t& off);
338 //END MARKER STUFF----------------------------------------------------------------------------
339
340 std::unordered_map<uint64_t, PendingImage> imagesRx_;
341 MessageQueue<msg::ReadyMessage> inboundGame_;
342 // optional background raw-drain worker
343 std::atomic<bool> rawWorkerRunning_{false};
344 std::atomic<bool> rawWorkerStop_{false};
345 std::thread rawWorker_;
346 // NetworkManager.h
347 std::shared_ptr<IdentityManager> identity_manager;
348 std::shared_ptr<ImGuiToaster> toaster_;
349 static constexpr size_t kChunk = 8 * 1024; // 8KB chunk
350 //static constexpr size_t kHighWater = 2 * 1024 * 1024; // 2 MB queued
351 //static constexpr size_t kLowWater = 512 * 1024; // 512 KB before resuming
352 static constexpr int kPaceEveryN = 48; // crude pacing step
353 static constexpr int kPaceMillis = 2;
354
355 void handleGameTableSnapshot(const std::vector<uint8_t>& b, size_t& off);
356 void handleBoardMeta(const std::vector<uint8_t>& b, size_t& off);
357 void handleFogCreate(const std::vector<uint8_t>& b, size_t& off);
358 void handleImageChunk(const std::vector<uint8_t>& b, size_t& off);
359 void handleCommitBoard(const std::vector<uint8_t>& b, size_t& off);
360 void handleCommitMarker(const std::vector<uint8_t>& b, size_t& off);
361
362 void handleUserNameUpdate(const std::vector<uint8_t>& b, size_t& off);
363
364 // FogUpdate
365 void handleFogUpdate(const std::vector<uint8_t>& b, size_t& off);
366 void handleFogDelete(const std::vector<uint8_t>& b, size_t& off);
367
368 void tryFinalizeImage(msg::ImageOwnerKind kind, uint64_t id);
369 // frame builders
370 std::vector<uint8_t> buildSnapshotGameTableFrame(uint64_t gameTableId, const std::string& name);
371 std::vector<uint8_t> buildSnapshotBoardFrame(const flecs::entity& board, uint64_t imageBytesTotal);
372 std::vector<uint8_t> buildFogCreateFrame(uint64_t boardId, const flecs::entity& fog);
373 std::vector<uint8_t> buildImageChunkFrame(uint8_t ownerKind, uint64_t id, uint64_t offset, const uint8_t* data, size_t len);
374 std::vector<uint8_t> buildCommitBoardFrame(uint64_t boardId);
375
376 // ---- FOG UPDATE/DELETE ----
377 std::vector<unsigned char> buildFogUpdateFrame(uint64_t boardId, const flecs::entity& fog);
378 std::vector<unsigned char> buildFogDeleteFrame(uint64_t boardId, uint64_t fogId);
379
380 // Helpers used by reconnectPeer (thin wrappers around what you already have)
381 /*std::shared_ptr<PeerLink> replaceWithFreshLink_(const std::string& peerId);
382 void createOfferAndSend_(const std::string& peerId, const std::shared_ptr<PeerLink>& link);
383 void createChannelsIfOfferer_(const std::shared_ptr<PeerLink>& link);*/
384
385 std::string myPeerId_;
386 std::string gmPeerId_;
387
388 flecs::world ecs;
389 unsigned int port = 8080;
390 char network_password[124] = "\0";
391 std::string external_ip_address = "";
392 std::string local_ip_address = "";
394
395 rtc::Configuration rtcConfig;
396 std::shared_ptr<SignalingServer> signalingServer;
397 std::shared_ptr<SignalingClient> signalingClient;
398 std::unordered_map<std::string, std::shared_ptr<PeerLink>> peers;
399 std::weak_ptr<BoardManager> board_manager;
400 std::weak_ptr<GameTableManager> gametable_manager;
401
402 static bool hasUrlScheme(const std::string& s)
403 {
404 auto starts = [&](const char* p)
405 { return s.rfind(p, 0) == 0; };
406 return starts("https://") || starts("http://") || starts("wss://") || starts("ws://");
407 }
408
409 static inline bool ensureRemaining(const std::vector<uint8_t>& b, size_t off, size_t need)
410 {
411 return off + need <= b.size();
412 }
413
414 inline std::vector<unsigned char> readFileBytes(const std::string& path)
415 {
416 std::ifstream file(path, std::ios::binary);
417 if (!file)
418 {
419 return {}; // return empty if file not found
420 }
421 file.seekg(0, std::ios::end);
422 size_t size = file.tellg();
423 file.seekg(0, std::ios::beg);
424
425 std::vector<unsigned char> buffer(size);
426 if (size > 0)
427 {
428 file.read(reinterpret_cast<char*>(buffer.data()), size);
429 }
430 return buffer;
431 }
432
433 static uint64_t nowMs()
434 {
435 using Clock = std::chrono::steady_clock;
436 using namespace std::chrono;
437 return duration_cast<milliseconds>(Clock::now().time_since_epoch()).count();
438 }
439};
ConnectionType
Definition Message.h:20
Role
Definition Message.h:13
std::chrono::steady_clock Clock
bool try_pop(T &value)
void markDraggingLocal(uint64_t markerId, bool dragging)
bool shouldApplyMarkerMoveStateFinal(const msg::ReadyMessage &m)
void handleFogUpdate(const std::vector< uint8_t > &b, size_t &off)
unsigned short getPort() const
void onPeerLocalCandidate(const std::string &peerId, const rtc::Candidate &cand)
uint32_t sendMoveMinPeriodMs_
std::vector< uint8_t > buildFogCreateFrame(uint64_t boardId, const flecs::entity &fog)
std::string local_ip_address
void setup(std::weak_ptr< BoardManager > board_manager, std::weak_ptr< GameTableManager > gametable_manager)
bool isMarkerBeingDragged(uint64_t markerId) const
void handleFogDelete(const std::vector< uint8_t > &b, size_t &off)
const std::string & getGMId() const
std::shared_ptr< ImGuiToaster > toaster_
std::string gmPeerId_
bool removePeer(std::string peerId)
void broadcastMarker(uint64_t boardId, const flecs::entity &marker)
std::string getLocalTunnelURL()
void startServer(ConnectionType mode, unsigned short port, bool tryUpnp)
const std::string & getMyPeerId() const
static uint64_t nowMs()
void clearDragState(uint64_t markerId)
void onPeerChannelOpen(const std::string &peerId, const std::string &label)
std::vector< std::string > getConnectedPeerIds() const
std::vector< unsigned char > buildFogUpdateFrame(uint64_t boardId, const flecs::entity &fog)
std::vector< uint8_t > buildCommitBoardFrame(uint64_t boardId)
std::string getNetworkInfo(ConnectionType type)
bool shouldApplyMarkerMoveStateStart(const msg::ReadyMessage &m)
bool tryPopReadyMessage(msg::ReadyMessage &out)
void broadcastGameTable(const flecs::entity &gameTable)
void setMyPeerId(std::string v)
void buildUserNameUpdate(std::vector< uint8_t > &out, uint64_t tableId, const std::string &userUniqueId, const std::string &oldUsername, const std::string &newUsername, bool reboundFlag) const
void broadcastMarkerMove(uint64_t boardId, const flecs::entity &marker)
std::unordered_map< uint64_t, PendingImage > imagesRx_
std::string external_ip_address
void broadcastMarkerUpdate(uint64_t boardId, const flecs::entity &marker)
void sendMarkerMove(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
static bool tieBreakWins(const std::string &challengerPeerId, const std::string &currentOwnerPeerId)
std::shared_ptr< IdentityManager > identity_manager
uint32_t getSendMoveMinPeriodMs() const
std::shared_ptr< SignalingClient > signalingClient
void setCustomHost(const std::string &h)
rtc::Configuration getRTCConfig() const
bool broadcastChatJson(const msg::Json &j)
void sendFogUpdate(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
std::string decodingFromPeer_
void forceCloseDrag(uint64_t markerId)
void sendMarkerUpdate(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
void broadcastMarkerDelete(uint64_t boardId, const flecs::entity &marker)
std::string customHost_
bool tryPopRawMessage(msg::InboundRaw &out)
void decodeRawNotesBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
std::shared_ptr< PeerLink > ensurePeerLink(const std::string &peerId)
unsigned int port
void broadcastPeerDisconnect(const std::string &targetId)
std::weak_ptr< GameTableManager > gametable_manager
void pushStatusToast(const std::string &msg, ImGuiToaster::Level lvl, float durationSec=5.0f)
std::unordered_map< uint64_t, DragState > drag_
void upsertPeerIdentityWithUnique(const std::string &peerId, const std::string &uniqueId, const std::string &username)
void ShowPortForwardingHelpPopup(bool *p_open)
void handleCommitMarker(const std::vector< uint8_t > &b, size_t &off)
void handleCommitBoard(const std::vector< uint8_t > &b, size_t &off)
void handleMarkerMoveState(const std::vector< uint8_t > &b, size_t &off)
void handleUserNameUpdate(const std::vector< uint8_t > &b, size_t &off)
void sendMarkerMoveState(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
std::string getMyUsername() const
void broadcastMarkerMoveState(uint64_t boardId, const flecs::entity &marker)
void decodeRawGameBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
std::string myPeerId_
void setGMId(const std::string &id)
void handleGridUpdate(const std::vector< uint8_t > &b, size_t &off)
std::vector< uint8_t > buildCommitMarkerFrame(uint64_t boardId, uint64_t markerId)
void setPort(unsigned int port)
const std::unordered_map< std::string, std::shared_ptr< PeerLink > > & getPeers() const
std::unordered_map< std::string, std::shared_ptr< PeerLink > > peers
std::vector< unsigned char > buildGridUpdateFrame(uint64_t boardId, const Grid &grid)
void handleImageChunk(const std::vector< uint8_t > &b, size_t &off)
void setToaster(std::shared_ptr< ImGuiToaster > t)
void onPeerLocalDescription(const std::string &peerId, const rtc::Description &desc)
bool shouldApplyMarkerMove(const msg::ReadyMessage &m)
NetworkManager(flecs::world ecs, std::shared_ptr< IdentityManager > identity_manager)
void broadcastFogDelete(uint64_t boardId, const flecs::entity &fog)
bool hasAnyPeer() const
void broadcastBoard(const flecs::entity &board)
std::string displayNameForPeer(const std::string &peerId) const
static constexpr int kPaceMillis
void handleBoardMeta(const std::vector< uint8_t > &b, size_t &off)
void handleFogCreate(const std::vector< uint8_t > &b, size_t &off)
void sendMarker(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
flecs::world ecs
bool amIDragging(uint64_t markerId) const
void sendGameTo(const std::string &peerId, const std::vector< unsigned char > &bytes)
void parseConnectionString(std::string connection_string, std::string &server, unsigned short &port, std::string &password)
void decodeRawChatBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
void broadcastFogUpdate(uint64_t boardId, const flecs::entity &fog)
void handleGameTableSnapshot(const std::vector< uint8_t > &b, size_t &off)
std::string debugIdentitySnapshot() const
std::weak_ptr< BoardManager > board_manager
std::atomic< bool > rawWorkerRunning_
static constexpr int kPaceEveryN
void sendBoard(const flecs::entity &board, const std::vector< std::string > &toPeerIds)
void sendGridUpdate(uint64_t boardId, const flecs::entity &board, const std::vector< std::string > &toPeerIds)
bool isHosting() const
void sendFogDelete(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
void disallowPort(unsigned short port)
char network_password[124]
Role getPeerRole() const
void broadcastUserNameUpdate(const std::vector< uint8_t > &payload)
void allowPort(unsigned int port)
bool sendImageChunks(msg::ImageOwnerKind kind, uint64_t id, const std::vector< unsigned char > &img, const std::vector< std::string > &toPeerIds)
std::string getNetworkPassword() const
std::vector< unsigned char > buildMarkerMoveFrame(uint64_t boardId, const flecs::entity &marker, uint32_t seq)
MessageQueue< msg::ReadyMessage > inboundGame_
std::vector< uint8_t > buildCreateMarkerFrame(uint64_t boardId, const flecs::entity &marker, uint64_t imageBytesTotal)
std::vector< std::string > getConnectedUsernames() const
void tryFinalizeImage(msg::ImageOwnerKind kind, uint64_t id)
int connectedPeerCount() const
std::shared_ptr< SignalingServer > signalingServer
std::shared_ptr< IdentityManager > getIdentityManager()
rtc::Configuration rtcConfig
std::string getExternalIPAddress()
std::vector< unsigned char > readFileBytes(const std::string &path)
MessageQueue< msg::NetEvent > events_
void bootstrapPeerIfReady(const std::string &peerId)
bool connectToPeer(const std::string &connectionString)
void handleMarkerUpdate(const std::vector< uint8_t > &b, size_t &off)
std::vector< unsigned char > buildMarkerDeleteFrame(uint64_t boardId, uint64_t markerId)
std::string getLocalIPAddress()
static bool hasUrlScheme(const std::string &s)
void broadcastFog(uint64_t boardId, const flecs::entity &fog)
std::shared_ptr< SignalingServer > getSignalingServer() const
void sendFog(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
std::thread rawWorker_
std::vector< unsigned char > buildMarkerUpdateFrame(uint64_t boardId, const flecs::entity &marker)
std::string getMyUniqueId() const
const std::string & getCustomHost() const
std::size_t removeDisconnectedPeers()
void setNetworkPassword(const char *password)
void drainInboundRaw(int maxPerTick)
std::vector< uint8_t > buildSnapshotGameTableFrame(uint64_t gameTableId, const std::string &name)
std::atomic< bool > rawWorkerStop_
void handleMarkerMeta(const std::vector< uint8_t > &b, size_t &off)
std::vector< uint8_t > buildImageChunkFrame(uint8_t ownerKind, uint64_t id, uint64_t offset, const uint8_t *data, size_t len)
bool clearPeers() const
void sendUserNameUpdateTo(const std::string &peerId, const std::vector< uint8_t > &payload)
void decodeRawMarkerMoveBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
std::vector< unsigned char > buildFogDeleteFrame(uint64_t boardId, uint64_t fogId)
std::vector< unsigned char > buildMarkerMoveStateFrame(uint64_t boardId, const flecs::entity &marker)
void sendGameTable(const flecs::entity &gameTable, const std::vector< std::string > &toPeerIds)
void broadcastGridUpdate(uint64_t boardId, const flecs::entity &board)
void broadcastGameFrame(const std::vector< unsigned char > &frame, const std::vector< std::string > &toPeerIds)
bool sendChatJsonTo(const std::string &peerId, const msg::Json &j)
static bool ensureRemaining(const std::vector< uint8_t > &b, size_t off, size_t need)
static constexpr size_t kChunk
std::vector< uint8_t > buildSnapshotBoardFrame(const flecs::entity &board, uint64_t imageBytesTotal)
void sendMarkerDelete(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
void handleMarkerDelete(const std::vector< uint8_t > &b, size_t &off)
void handleMarkerMove(const std::vector< uint8_t > &b, size_t &off)
MessageQueue< msg::InboundRaw > inboundRaw_
Definition Message.h:28
ImageOwnerKind
Definition Message.h:140
nlohmann::json Json
Definition Message.h:363
std::string ownerPeerId
uint32_t locallyProposedEpoch
uint32_t lastSeq
uint32_t epoch
uint64_t epochOpenedMs
uint32_t localSeq
uint64_t lastTxMs
bool locallyDragging
std::vector< uint8_t > buf
std::optional< msg::BoardMeta > boardMeta
std::optional< msg::MarkerMeta > markerMeta
uint64_t boardId
uint64_t received
msg::ImageOwnerKind kind
std::string name
bool isComplete() const