3#include <unordered_map>
7#include "rtc/configuration.hpp"
11#include <rtc/peerconnection.hpp>
12#include <nlohmann/json.hpp>
56 std::vector<uint8_t>
buf;
94 void parseConnectionString(std::string connection_string, std::string& server,
unsigned short&
port, std::string& password);
123 for (
auto [
id, peer] :
peers)
127 return peers.empty();
136 std::shared_ptr<PeerLink>
ensurePeerLink(
const std::string& peerId);
158 const std::unordered_map<std::string, std::shared_ptr<PeerLink>>&
getPeers()
const
191 void broadcastFog(uint64_t boardId,
const flecs::entity& fog);
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);
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);
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);
236 void sendMarkerDelete(uint64_t boardId,
const flecs::entity& marker,
const std::vector<std::string>& toPeerIds);
239 void sendMarker(uint64_t boardId,
const flecs::entity& marker,
const std::vector<std::string>& toPeerIds);
251 void sendMarkerMove(uint64_t boardId,
const flecs::entity& marker,
const std::vector<std::string>& toPeerIds);
254 void sendMarkerMoveState(uint64_t boardId,
const flecs::entity& marker,
const std::vector<std::string>& toPeerIds);
257 void sendMarkerUpdate(uint64_t boardId,
const flecs::entity& marker,
const std::vector<std::string>& toPeerIds);
265 void sendGridUpdate(uint64_t boardId,
const flecs::entity& board,
const std::vector<std::string>& toPeerIds);
271 const std::string& userUniqueId,
272 const std::string& oldUsername,
273 const std::string& newUsername,
274 bool reboundFlag)
const;
278 const std::vector<uint8_t>& payload);
281 const std::string& uniqueId,
282 const std::string& username);
323 std::vector<unsigned char>
buildMarkerMoveFrame(uint64_t boardId,
const flecs::entity& marker, uint32_t seq);
327 static bool tieBreakWins(
const std::string& challengerPeerId,
const std::string& currentOwnerPeerId)
329 return challengerPeerId < currentOwnerPeerId;
336 std::vector<uint8_t>
buildCreateMarkerFrame(uint64_t boardId,
const flecs::entity& marker, uint64_t imageBytesTotal);
349 static constexpr size_t kChunk = 8 * 1024;
373 std::vector<uint8_t>
buildImageChunkFrame(uint8_t ownerKind, uint64_t
id, uint64_t offset,
const uint8_t* data,
size_t len);
377 std::vector<unsigned char>
buildFogUpdateFrame(uint64_t boardId,
const flecs::entity& fog);
398 std::unordered_map<std::string, std::shared_ptr<PeerLink>>
peers;
404 auto starts = [&](
const char* p)
405 {
return s.rfind(p, 0) == 0; };
406 return starts(
"https://") || starts(
"http://") || starts(
"wss://") || starts(
"ws://");
409 static inline bool ensureRemaining(
const std::vector<uint8_t>& b,
size_t off,
size_t need)
411 return off + need <= b.size();
416 std::ifstream file(path, std::ios::binary);
421 file.seekg(0, std::ios::end);
422 size_t size = file.tellg();
423 file.seekg(0, std::ios::beg);
425 std::vector<unsigned char> buffer(size);
428 file.read(
reinterpret_cast<char*
>(buffer.data()), size);
435 using Clock = std::chrono::steady_clock;
436 using namespace std::chrono;
437 return duration_cast<milliseconds>(Clock::now().time_since_epoch()).count();
std::chrono::steady_clock Clock
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
bool disconnectAllPeers()
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_
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
void clearDragState(uint64_t markerId)
void onPeerChannelOpen(const std::string &peerId, const std::string &label)
bool disconectFromPeers()
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 ¤tOwnerPeerId)
std::shared_ptr< IdentityManager > identity_manager
void startRawDrainWorker()
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)
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)
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)
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)
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)
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 stopRawDrainWorker()
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)
void sendFogDelete(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
void disallowPort(unsigned short port)
char network_password[124]
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::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)
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_
uint32_t locallyProposedEpoch
std::vector< uint8_t > buf
std::optional< msg::BoardMeta > boardMeta
std::optional< msg::MarkerMeta > markerMeta