RunicVTT Open Source Virtual Tabletop for TTRPG using P2P
Loading...
Searching...
No Matches
NetworkManager Class Reference

#include <NetworkManager.h>

Inheritance diagram for NetworkManager:
Collaboration diagram for NetworkManager:

Public Member Functions

 NetworkManager (flecs::world ecs, std::shared_ptr< IdentityManager > identity_manager)
 
void setup (std::weak_ptr< BoardManager > board_manager, std::weak_ptr< GameTableManager > gametable_manager)
 
 ~NetworkManager ()
 
void startServer (ConnectionType mode, unsigned short port, bool tryUpnp)
 
void startServer (std::string internal_ip_address, unsigned short port)
 
void closeServer ()
 
bool isConnected ()
 
bool isHosting () const
 
bool hasAnyPeer () const
 
int connectedPeerCount () const
 
void allowPort (unsigned int port)
 
void disallowPort (unsigned short port)
 
std::string getNetworkInfo (ConnectionType type)
 
std::string getLocalIPAddress ()
 
std::string getExternalIPAddress ()
 
std::string getLocalTunnelURL ()
 
void parseConnectionString (std::string connection_string, std::string &server, unsigned short &port, std::string &password)
 
unsigned short getPort () const
 
std::string getNetworkPassword () const
 
void setPort (unsigned int port)
 
void setNetworkPassword (const char *password)
 
Role getPeerRole () const
 
void ShowPortForwardingHelpPopup (bool *p_open)
 
rtc::Configuration getRTCConfig () const
 
bool connectToPeer (const std::string &connectionString)
 
bool disconectFromPeers ()
 
bool removePeer (std::string peerId)
 
bool clearPeers () const
 
bool disconnectAllPeers ()
 
std::size_t removeDisconnectedPeers ()
 
void broadcastPeerDisconnect (const std::string &targetId)
 
void onPeerLocalDescription (const std::string &peerId, const rtc::Description &desc)
 
void onPeerLocalCandidate (const std::string &peerId, const rtc::Candidate &cand)
 
std::shared_ptr< PeerLinkensurePeerLink (const std::string &peerId)
 
std::string displayNameForPeer (const std::string &peerId) const
 
std::string getMyUsername () const
 
std::string getMyUniqueId () const
 
const std::string & getMyPeerId () const
 
void setMyPeerId (std::string v)
 
const std::unordered_map< std::string, std::shared_ptr< PeerLink > > & getPeers () const
 
std::shared_ptr< SignalingServergetSignalingServer () const
 
bool tryPopReadyMessage (msg::ReadyMessage &out)
 
bool tryPopRawMessage (msg::InboundRaw &out)
 
void drainEvents ()
 
void drainInboundRaw (int maxPerTick)
 
void decodeRawChatBuffer (const std::string &fromPeer, const std::vector< uint8_t > &b)
 
void decodeRawNotesBuffer (const std::string &fromPeer, const std::vector< uint8_t > &b)
 
void startRawDrainWorker ()
 
void stopRawDrainWorker ()
 
void onPeerChannelOpen (const std::string &peerId, const std::string &label)
 
void bootstrapPeerIfReady (const std::string &peerId)
 
void broadcastGameTable (const flecs::entity &gameTable)
 
void broadcastBoard (const flecs::entity &board)
 
void broadcastFog (uint64_t boardId, const flecs::entity &fog)
 
void broadcastFogUpdate (uint64_t boardId, const flecs::entity &fog)
 
void broadcastFogDelete (uint64_t boardId, const flecs::entity &fog)
 
void sendFogUpdate (uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
 
void sendFogDelete (uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
 
void sendGameTo (const std::string &peerId, const std::vector< unsigned char > &bytes)
 
void broadcastGameFrame (const std::vector< unsigned char > &frame, const std::vector< std::string > &toPeerIds)
 
void sendGameTable (const flecs::entity &gameTable, const std::vector< std::string > &toPeerIds)
 
void sendBoard (const flecs::entity &board, const std::vector< std::string > &toPeerIds)
 
void sendFog (uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
 
bool sendImageChunks (msg::ImageOwnerKind kind, uint64_t id, const std::vector< unsigned char > &img, const std::vector< std::string > &toPeerIds)
 
void setToaster (std::shared_ptr< ImGuiToaster > t)
 
void pushStatusToast (const std::string &msg, ImGuiToaster::Level lvl, float durationSec=5.0f)
 
std::vector< std::string > getConnectedPeerIds () const
 
std::vector< std::string > getConnectedUsernames () const
 
void setGMId (const std::string &id)
 
const std::string & getGMId () const
 
void decodeRawGameBuffer (const std::string &fromPeer, const std::vector< uint8_t > &b)
 
void sendMarkerDelete (uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
 
void broadcastMarkerDelete (uint64_t boardId, const flecs::entity &marker)
 
void broadcastMarker (uint64_t boardId, const flecs::entity &marker)
 
void sendMarker (uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
 
void decodeRawMarkerMoveBuffer (const std::string &fromPeer, const std::vector< uint8_t > &b)
 
void markDraggingLocal (uint64_t markerId, bool dragging)
 
bool isMarkerBeingDragged (uint64_t markerId) const
 
bool amIDragging (uint64_t markerId) const
 
void forceCloseDrag (uint64_t markerId)
 
void broadcastMarkerMove (uint64_t boardId, const flecs::entity &marker)
 
void sendMarkerMove (uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
 
void broadcastMarkerMoveState (uint64_t boardId, const flecs::entity &marker)
 
void sendMarkerMoveState (uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
 
void broadcastMarkerUpdate (uint64_t boardId, const flecs::entity &marker)
 
void sendMarkerUpdate (uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
 
bool shouldApplyMarkerMove (const msg::ReadyMessage &m)
 
bool shouldApplyMarkerMoveStateStart (const msg::ReadyMessage &m)
 
bool shouldApplyMarkerMoveStateFinal (const msg::ReadyMessage &m)
 
void broadcastGridUpdate (uint64_t boardId, const flecs::entity &board)
 
void sendGridUpdate (uint64_t boardId, const flecs::entity &board, const std::vector< std::string > &toPeerIds)
 
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 broadcastUserNameUpdate (const std::vector< uint8_t > &payload)
 
void sendUserNameUpdateTo (const std::string &peerId, const std::vector< uint8_t > &payload)
 
void upsertPeerIdentityWithUnique (const std::string &peerId, const std::string &uniqueId, const std::string &username)
 
bool broadcastChatJson (const msg::Json &j)
 
bool sendChatJsonTo (const std::string &peerId, const msg::Json &j)
 
bool sendChatJsonTo (const std::set< std::string > &peers, const msg::Json &j)
 
std::shared_ptr< IdentityManagergetIdentityManager ()
 
std::string debugIdentitySnapshot () const
 
void clearDragState (uint64_t markerId)
 
void housekeepPeers ()
 
void setCustomHost (const std::string &h)
 
const std::string & getCustomHost () const
 

Public Attributes

MessageQueue< msg::NetEventevents_
 
MessageQueue< msg::InboundRawinboundRaw_
 
std::unordered_map< uint64_t, DragStatedrag_
 

Private Member Functions

std::vector< unsigned char > buildGridUpdateFrame (uint64_t boardId, const Grid &grid)
 
void handleGridUpdate (const std::vector< uint8_t > &b, size_t &off)
 
uint32_t getSendMoveMinPeriodMs () const
 
void handleMarkerMove (const std::vector< uint8_t > &b, size_t &off)
 
void handleMarkerUpdate (const std::vector< uint8_t > &b, size_t &off)
 
void handleMarkerMoveState (const std::vector< uint8_t > &b, size_t &off)
 
std::vector< unsigned char > buildMarkerMoveFrame (uint64_t boardId, const flecs::entity &marker, uint32_t seq)
 
std::vector< unsigned char > buildMarkerMoveStateFrame (uint64_t boardId, const flecs::entity &marker)
 
std::vector< unsigned char > buildMarkerUpdateFrame (uint64_t boardId, const flecs::entity &marker)
 
void handleMarkerDelete (const std::vector< uint8_t > &b, size_t &off)
 
std::vector< unsigned char > buildMarkerDeleteFrame (uint64_t boardId, uint64_t markerId)
 
std::vector< uint8_t > buildCommitMarkerFrame (uint64_t boardId, uint64_t markerId)
 
std::vector< uint8_t > buildCreateMarkerFrame (uint64_t boardId, const flecs::entity &marker, uint64_t imageBytesTotal)
 
void handleMarkerMeta (const std::vector< uint8_t > &b, size_t &off)
 
void handleGameTableSnapshot (const std::vector< uint8_t > &b, size_t &off)
 
void handleBoardMeta (const std::vector< uint8_t > &b, size_t &off)
 
void handleFogCreate (const std::vector< uint8_t > &b, size_t &off)
 
void handleImageChunk (const std::vector< uint8_t > &b, size_t &off)
 
void handleCommitBoard (const std::vector< uint8_t > &b, size_t &off)
 
void handleCommitMarker (const std::vector< uint8_t > &b, size_t &off)
 
void handleUserNameUpdate (const std::vector< uint8_t > &b, size_t &off)
 
void handleFogUpdate (const std::vector< uint8_t > &b, size_t &off)
 
void handleFogDelete (const std::vector< uint8_t > &b, size_t &off)
 
void tryFinalizeImage (msg::ImageOwnerKind kind, uint64_t id)
 
std::vector< uint8_t > buildSnapshotGameTableFrame (uint64_t gameTableId, const std::string &name)
 
std::vector< uint8_t > buildSnapshotBoardFrame (const flecs::entity &board, uint64_t imageBytesTotal)
 
std::vector< uint8_t > buildFogCreateFrame (uint64_t boardId, const flecs::entity &fog)
 
std::vector< uint8_t > buildImageChunkFrame (uint8_t ownerKind, uint64_t id, uint64_t offset, const uint8_t *data, size_t len)
 
std::vector< uint8_t > buildCommitBoardFrame (uint64_t boardId)
 
std::vector< unsigned char > buildFogUpdateFrame (uint64_t boardId, const flecs::entity &fog)
 
std::vector< unsigned char > buildFogDeleteFrame (uint64_t boardId, uint64_t fogId)
 
std::vector< unsigned char > readFileBytes (const std::string &path)
 

Static Private Member Functions

static bool tieBreakWins (const std::string &challengerPeerId, const std::string &currentOwnerPeerId)
 
static bool hasUrlScheme (const std::string &s)
 
static bool ensureRemaining (const std::vector< uint8_t > &b, size_t off, size_t need)
 
static uint64_t nowMs ()
 

Private Attributes

std::string customHost_
 
std::string decodingFromPeer_
 
uint32_t sendMoveMinPeriodMs_ {50}
 
std::unordered_map< uint64_t, PendingImageimagesRx_
 
MessageQueue< msg::ReadyMessageinboundGame_
 
std::atomic< bool > rawWorkerRunning_ {false}
 
std::atomic< bool > rawWorkerStop_ {false}
 
std::thread rawWorker_
 
std::shared_ptr< IdentityManageridentity_manager
 
std::shared_ptr< ImGuiToastertoaster_
 
std::string myPeerId_
 
std::string gmPeerId_
 
flecs::world ecs
 
unsigned int port = 8080
 
char network_password [124] = "\0"
 
std::string external_ip_address = ""
 
std::string local_ip_address = ""
 
Role peer_role
 
rtc::Configuration rtcConfig
 
std::shared_ptr< SignalingServersignalingServer
 
std::shared_ptr< SignalingClientsignalingClient
 
std::unordered_map< std::string, std::shared_ptr< PeerLink > > peers
 
std::weak_ptr< BoardManagerboard_manager
 
std::weak_ptr< GameTableManagergametable_manager
 

Static Private Attributes

static constexpr size_t kChunk = 8 * 1024
 
static constexpr int kPaceEveryN = 48
 
static constexpr int kPaceMillis = 2
 

Detailed Description

Definition at line 66 of file NetworkManager.h.

Constructor & Destructor Documentation

◆ NetworkManager()

NetworkManager::NetworkManager ( flecs::world ecs,
std::shared_ptr< IdentityManager > identity_manager )

Definition at line 14 of file NetworkManager.cpp.

14 :
16{
19 rtc::InitLogger(rtc::LogLevel::Verbose);
21}
std::shared_ptr< IdentityManager > identity_manager
flecs::world ecs
std::string getExternalIPAddress()
std::string getLocalIPAddress()
static void setupTLS()
Here is the call graph for this function:

◆ ~NetworkManager()

NetworkManager::~NetworkManager ( )

Definition at line 47 of file NetworkManager.cpp.

48{
51}
Here is the call graph for this function:

Member Function Documentation

◆ allowPort()

void NetworkManager::allowPort ( unsigned int port)

◆ amIDragging()

bool NetworkManager::amIDragging ( uint64_t markerId) const

Definition at line 1450 of file NetworkManager.cpp.

1451{
1452 auto it = drag_.find(markerId);
1453 if (it == drag_.end())
1454 return false;
1455 const auto& s = it->second;
1456
1457 // If we started the drag locally, trust the local flag.
1458 if (!s.closed && s.locallyDragging)
1459 return true;
1460
1461 // Otherwise fall back to peer-id ownership (remote handoff cases).
1462 return !s.closed && s.ownerPeerId == getMyPeerId();
1463}
const std::string & getMyPeerId() const
std::unordered_map< uint64_t, DragState > drag_
Here is the call graph for this function:

◆ bootstrapPeerIfReady()

void NetworkManager::bootstrapPeerIfReady ( const std::string & peerId)

Definition at line 2550 of file NetworkManager.cpp.

2551{
2552 Logger::instance().log("localtunnel", Logger::Level::Info, "BeginBoostrap");
2553 auto gm = gametable_manager.lock();
2554 auto bm = board_manager.lock();
2555 if (!gm)
2556 {
2557 throw std::exception("[NetworkManager] GametableManager Expired!!");
2558 }
2559 if (!bm)
2560 {
2561 throw std::exception("[NetworkManager] BoardManager Expired!!");
2562 }
2563
2564 auto it = peers.find(peerId);
2565 if (it == peers.end() || !it->second)
2566 return;
2567 auto& link = it->second;
2568 if (link->bootstrapSent())
2569 return; // one-shot per connection
2570 if (gm->active_game_table.is_valid() && gm->active_game_table.has<GameTable>())
2571 {
2572 sendGameTable(gm->active_game_table, {peerId});
2573 Logger::instance().log("localtunnel", Logger::Level::Info, "SentGameTable");
2574 }
2575
2576 if (bm->isBoardActive())
2577 {
2578 auto boardEnt = bm->getActiveBoard();
2579 if (boardEnt.is_valid() && boardEnt.has<Board>())
2580 {
2581 sendBoard(boardEnt, {peerId}); // this sends meta + image chunks + commit
2582 Logger::instance().log("localtunnel", Logger::Level::Info, "SentBoard");
2583 }
2584 }
2585
2586 link->markBootstrapSent();
2587}
static Logger & instance()
Definition Logger.h:39
std::weak_ptr< GameTableManager > gametable_manager
std::unordered_map< std::string, std::shared_ptr< PeerLink > > peers
std::weak_ptr< BoardManager > board_manager
void sendBoard(const flecs::entity &board, const std::vector< std::string > &toPeerIds)
void sendGameTable(const flecs::entity &gameTable, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ broadcastBoard()

void NetworkManager::broadcastBoard ( const flecs::entity & board)

Definition at line 979 of file NetworkManager.cpp.

980{ //{check}--USE THIS METHOD
981 auto ids = getConnectedPeerIds();
982 if (!ids.empty())
983 {
984 sendBoard(board, ids);
985 }
986}
std::vector< std::string > getConnectedPeerIds() const
Here is the call graph for this function:

◆ broadcastChatJson()

bool NetworkManager::broadcastChatJson ( const msg::Json & j)

Definition at line 1074 of file NetworkManager.cpp.

1075{
1076 const std::string text = j.dump(); // UTF-8 JSON
1077 bool any = false;
1078 for (auto& [pid, link] : peers)
1079 {
1080 if (link->sendOn(msg::dc::name::Chat, std::string_view(text)))
1081 any = true;
1082 }
1083 return any;
1084}
constexpr std::string Chat
Definition Message.h:298

◆ broadcastFog()

void NetworkManager::broadcastFog ( uint64_t boardId,
const flecs::entity & fog )

Definition at line 997 of file NetworkManager.cpp.

998{ //{check}--USE THIS METHOD
999 auto ids = getConnectedPeerIds();
1000 if (!ids.empty())
1001 {
1002 sendFog(boardId, fog, ids);
1003 }
1004}
void sendFog(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastFogDelete()

void NetworkManager::broadcastFogDelete ( uint64_t boardId,
const flecs::entity & fog )

Definition at line 1024 of file NetworkManager.cpp.

1025{
1026 auto ids = getConnectedPeerIds();
1027 if (!ids.empty())
1028 sendFogDelete(boardId, fog, ids);
1029}
void sendFogDelete(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastFogUpdate()

void NetworkManager::broadcastFogUpdate ( uint64_t boardId,
const flecs::entity & fog )

Definition at line 1017 of file NetworkManager.cpp.

1018{
1019 auto ids = getConnectedPeerIds();
1020 if (!ids.empty())
1021 sendFogUpdate(boardId, fog, ids);
1022}
void sendFogUpdate(uint64_t boardId, const flecs::entity &fog, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastGameFrame()

void NetworkManager::broadcastGameFrame ( const std::vector< unsigned char > & frame,
const std::vector< std::string > & toPeerIds )

Definition at line 2791 of file NetworkManager.cpp.

2792{
2793 for (auto& pid : toPeerIds)
2794 {
2795 sendGameTo(pid, frame);
2796 }
2797}
void sendGameTo(const std::string &peerId, const std::vector< unsigned char > &bytes)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ broadcastGameTable()

void NetworkManager::broadcastGameTable ( const flecs::entity & gameTable)

Definition at line 970 of file NetworkManager.cpp.

971{ //{check}--USE THIS METHOD
972 auto ids = getConnectedPeerIds();
973 if (!ids.empty())
974 {
975 sendGameTable(gameTable, ids);
976 }
977}
Here is the call graph for this function:

◆ broadcastGridUpdate()

void NetworkManager::broadcastGridUpdate ( uint64_t boardId,
const flecs::entity & board )

Definition at line 1893 of file NetworkManager.cpp.

1894{
1895 auto ids = getConnectedPeerIds();
1896 if (!ids.empty())
1897 sendGridUpdate(boardId, board, ids);
1898}
void sendGridUpdate(uint64_t boardId, const flecs::entity &board, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastMarker()

void NetworkManager::broadcastMarker ( uint64_t boardId,
const flecs::entity & marker )

Definition at line 988 of file NetworkManager.cpp.

989{ //{check}--USE THIS METHOD
990 auto ids = getConnectedPeerIds();
991 if (!ids.empty())
992 {
993 sendMarker(boardId, marker, ids);
994 }
995}
void sendMarker(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastMarkerDelete()

void NetworkManager::broadcastMarkerDelete ( uint64_t boardId,
const flecs::entity & marker )

Definition at line 1010 of file NetworkManager.cpp.

1011{
1012 auto ids = getConnectedPeerIds();
1013 if (!ids.empty())
1014 sendMarkerDelete(boardId, marker, ids);
1015}
void sendMarkerDelete(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastMarkerMove()

void NetworkManager::broadcastMarkerMove ( uint64_t boardId,
const flecs::entity & marker )

Definition at line 1387 of file NetworkManager.cpp.

1388{
1389 auto ids = getConnectedPeerIds();
1390 if (!ids.empty())
1391 sendMarkerMove(boardId, marker, ids);
1392}
void sendMarkerMove(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastMarkerMoveState()

void NetworkManager::broadcastMarkerMoveState ( uint64_t boardId,
const flecs::entity & marker )

Definition at line 1421 of file NetworkManager.cpp.

1422{
1423 auto ids = getConnectedPeerIds();
1424 if (!ids.empty())
1425 sendMarkerMoveState(boardId, marker, ids);
1426}
void sendMarkerMoveState(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastMarkerUpdate()

void NetworkManager::broadcastMarkerUpdate ( uint64_t boardId,
const flecs::entity & marker )

Definition at line 1380 of file NetworkManager.cpp.

1381{
1382 auto ids = getConnectedPeerIds();
1383 if (!ids.empty())
1384 sendMarkerUpdate(boardId, marker, ids);
1385}
void sendMarkerUpdate(uint64_t boardId, const flecs::entity &marker, const std::vector< std::string > &toPeerIds)
Here is the call graph for this function:

◆ broadcastPeerDisconnect()

void NetworkManager::broadcastPeerDisconnect ( const std::string & targetId)

Definition at line 869 of file NetworkManager.cpp.

870{
871 if (!signalingClient)
872 return; // GM might be loopbacked as a client; else send via server
873 auto j = msg::makePeerDisconnect(targetId, /*broadcast*/ true);
874 signalingClient->send(j.dump());
875}
std::shared_ptr< SignalingClient > signalingClient
nlohmann::json makePeerDisconnect(const std::string &targetPeerId, bool broadcast=true)
Definition Message.h:466
Here is the call graph for this function:

◆ broadcastUserNameUpdate()

void NetworkManager::broadcastUserNameUpdate ( const std::vector< uint8_t > & payload)

Definition at line 1048 of file NetworkManager.cpp.

1049{
1050 for (auto& [pid, link] : peers)
1051 {
1052 if (!link)
1053 continue;
1054 sendUserNameUpdateTo(pid, payload);
1055 }
1056}
void sendUserNameUpdateTo(const std::string &peerId, const std::vector< uint8_t > &payload)
Here is the call graph for this function:

◆ buildCommitBoardFrame()

std::vector< unsigned char > NetworkManager::buildCommitBoardFrame ( uint64_t boardId)
private

Definition at line 2766 of file NetworkManager.cpp.

2767{
2768 std::vector<unsigned char> b;
2769 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::CommitBoard));
2770 Serializer::serializeUInt64(b, boardId);
2771 return b;
2772}
static void serializeUInt8(std::vector< unsigned char > &buffer, uint8_t value)
Definition Serializer.h:341
static void serializeUInt64(std::vector< unsigned char > &buffer, uint64_t value)
Definition Serializer.h:331
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildCommitMarkerFrame()

std::vector< unsigned char > NetworkManager::buildCommitMarkerFrame ( uint64_t boardId,
uint64_t markerId )
private

Definition at line 2774 of file NetworkManager.cpp.

2775{
2776 std::vector<unsigned char> b;
2777 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::CommitMarker));
2778 Serializer::serializeUInt64(b, boardId);
2779 Serializer::serializeUInt64(b, markerId);
2780 return b;
2781}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildCreateMarkerFrame()

std::vector< unsigned char > NetworkManager::buildCreateMarkerFrame ( uint64_t boardId,
const flecs::entity & marker,
uint64_t imageBytesTotal )
private

Definition at line 2709 of file NetworkManager.cpp.

2710{
2711 std::vector<unsigned char> b;
2712 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::MarkerCreate));
2713
2714 auto mid = marker.get<Identifier>()->id;
2715 auto pos = *marker.get<Position>();
2716 auto sz = *marker.get<Size>();
2717 auto vis = *marker.get<Visibility>();
2718 auto mov = *marker.get<Moving>();
2719
2720 std::string name = "marker_" + std::to_string(mid);
2721
2722 Serializer::serializeUInt64(b, boardId);
2725
2730
2731 Serializer::serializeUInt64(b, imageBytesTotal);
2732 return b;
2733}
static void serializeSize(std::vector< unsigned char > &buffer, const Size *size)
Definition Serializer.h:416
static void serializeString(std::vector< unsigned char > &buffer, const std::string &str)
Definition Serializer.h:318
static void serializePosition(std::vector< unsigned char > &buffer, const Position *position)
Definition Serializer.h:403
static void serializeMoving(std::vector< unsigned char > &buffer, const Moving *moving)
Definition Serializer.h:442
static void serializeVisibility(std::vector< unsigned char > &buffer, const Visibility *visibility)
Definition Serializer.h:430
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildFogCreateFrame()

std::vector< unsigned char > NetworkManager::buildFogCreateFrame ( uint64_t boardId,
const flecs::entity & fog )
private

Definition at line 2735 of file NetworkManager.cpp.

2736{
2737 std::vector<unsigned char> b;
2738 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::FogCreate));
2739
2740 auto fid = fog.get<Identifier>()->id;
2741 auto pos = *fog.get<Position>();
2742 auto sz = *fog.get<Size>();
2743 auto vis = *fog.get<Visibility>();
2744
2745 Serializer::serializeUInt64(b, boardId);
2750 return b;
2751}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildFogDeleteFrame()

std::vector< unsigned char > NetworkManager::buildFogDeleteFrame ( uint64_t boardId,
uint64_t fogId )
private

Definition at line 2656 of file NetworkManager.cpp.

2657{
2658 std::vector<unsigned char> b;
2659 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::FogDelete));
2660 Serializer::serializeUInt64(b, boardId);
2662 return b;
2663}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildFogUpdateFrame()

std::vector< unsigned char > NetworkManager::buildFogUpdateFrame ( uint64_t boardId,
const flecs::entity & fog )
private

Definition at line 2638 of file NetworkManager.cpp.

2639{
2640 std::vector<unsigned char> b;
2641 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::FogUpdate));
2642 Serializer::serializeUInt64(b, boardId);
2643
2644 const auto id = fog.get<Identifier>()->id;
2645 const auto pos = *fog.get<Position>();
2646 const auto siz = *fog.get<Size>();
2647 const auto vis = *fog.get<Visibility>();
2648
2653 return b;
2654}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildGridUpdateFrame()

std::vector< unsigned char > NetworkManager::buildGridUpdateFrame ( uint64_t boardId,
const Grid & grid )
private

Definition at line 1911 of file NetworkManager.cpp.

1912{
1913 std::vector<unsigned char> b;
1914 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::GridUpdate));
1915 Serializer::serializeUInt64(b, boardId);
1916 Serializer::serializeGrid(b, &grid);
1917 return b;
1918}
static void serializeGrid(std::vector< unsigned char > &buffer, const Grid *grid)
Definition Serializer.h:482
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildImageChunkFrame()

std::vector< unsigned char > NetworkManager::buildImageChunkFrame ( uint8_t ownerKind,
uint64_t id,
uint64_t offset,
const uint8_t * data,
size_t len )
private

Definition at line 2753 of file NetworkManager.cpp.

2754{
2755 std::vector<unsigned char> b;
2756 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::ImageChunk));
2757 Serializer::serializeUInt8(b, ownerKind);
2759 Serializer::serializeUInt64(b, offset);
2760 // len as int32
2761 Serializer::serializeInt(b, static_cast<int>(len));
2762 b.insert(b.end(), data, data + len);
2763 return b;
2764}
static void serializeInt(std::vector< unsigned char > &buffer, int value)
Definition Serializer.h:302
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildMarkerDeleteFrame()

std::vector< unsigned char > NetworkManager::buildMarkerDeleteFrame ( uint64_t boardId,
uint64_t markerId )
private

Definition at line 2628 of file NetworkManager.cpp.

2629{
2630 std::vector<unsigned char> b;
2631 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::MarkerDelete));
2632 Serializer::serializeUInt64(b, boardId);
2633 Serializer::serializeUInt64(b, markerId);
2634 return b;
2635}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildMarkerMoveFrame()

std::vector< unsigned char > NetworkManager::buildMarkerMoveFrame ( uint64_t boardId,
const flecs::entity & marker,
uint32_t seq )
private

Definition at line 1299 of file NetworkManager.cpp.

1300{
1301 std::vector<unsigned char> out;
1302 const auto* id = marker.get<Identifier>();
1303 const auto* pos = marker.get<Position>();
1304 if (!id || !pos)
1305 return out;
1306
1307 // epoch from drag_ state
1308 auto& s = drag_[id->id];
1309 if (s.locallyProposedEpoch == 0 && s.epoch == 0)
1310 {
1311 s.locallyProposedEpoch = s.epoch + 1;
1312 s.epoch = s.locallyProposedEpoch;
1313 }
1314 const uint32_t epoch = (s.locallyProposedEpoch ? s.locallyProposedEpoch : s.epoch);
1315 const uint64_t ts = nowMs();
1316
1317 Serializer::serializeUInt8(out, static_cast<uint8_t>(msg::DCType::MarkerMove));
1318 Serializer::serializeUInt64(out, boardId);
1319 Serializer::serializeUInt64(out, id->id);
1320 Serializer::serializeUInt32(out, epoch);
1324 return out;
1325}
static uint64_t nowMs()
static void serializeUInt32(std::vector< unsigned char > &buffer, uint32_t value)
Definition Serializer.h:336
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildMarkerMoveStateFrame()

std::vector< unsigned char > NetworkManager::buildMarkerMoveStateFrame ( uint64_t boardId,
const flecs::entity & marker )
private

Definition at line 1326 of file NetworkManager.cpp.

1327{
1328 std::vector<unsigned char> out;
1329 const auto* id = marker.get<Identifier>();
1330 const auto* mv = marker.get<Moving>();
1331 if (!id || !mv)
1332 return out;
1333
1334 auto& s = drag_[id->id];
1335 if (s.locallyProposedEpoch == 0 && s.epoch == 0)
1336 {
1337 s.locallyProposedEpoch = s.epoch + 1;
1338 s.epoch = s.locallyProposedEpoch;
1339 }
1340 const uint32_t epoch = (s.locallyProposedEpoch ? s.locallyProposedEpoch : s.epoch);
1341 const uint32_t seq = ++s.localSeq;
1342 const uint64_t ts = nowMs();
1343 s.lastTxMs = ts;
1344
1345 Serializer::serializeUInt8(out, static_cast<uint8_t>(msg::DCType::MarkerMoveState));
1346 Serializer::serializeUInt64(out, boardId);
1347 Serializer::serializeUInt64(out, id->id);
1348 Serializer::serializeUInt32(out, epoch);
1351 Serializer::serializeMoving(out, mv); // isDragging
1352
1353 if (!mv->isDragging && marker.has<Position>())
1354 {
1355 const auto* pos = marker.get<Position>(); // final pos at end
1357 }
1358 return out;
1359}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildMarkerUpdateFrame()

std::vector< unsigned char > NetworkManager::buildMarkerUpdateFrame ( uint64_t boardId,
const flecs::entity & marker )
private

Definition at line 1362 of file NetworkManager.cpp.

1363{
1364 std::vector<unsigned char> b;
1365 Serializer::serializeUInt8(b, static_cast<uint8_t>(msg::DCType::MarkerUpdate));
1366 Serializer::serializeUInt64(b, boardId);
1367
1368 const auto id = marker.get<Identifier>()->id;
1369 const auto siz = *marker.get<Size>();
1370 const auto vis = *marker.get<Visibility>();
1371 const auto mc = *marker.get<MarkerComponent>();
1372
1377 return b;
1378}
static void serializeMarkerComponent(std::vector< unsigned char > &buffer, const MarkerComponent *marker_component)
Definition Serializer.h:284
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildSnapshotBoardFrame()

std::vector< unsigned char > NetworkManager::buildSnapshotBoardFrame ( const flecs::entity & board,
uint64_t imageBytesTotal )
private

Definition at line 2674 of file NetworkManager.cpp.

2675{
2676 std::vector<unsigned char> b;
2678
2679 // Required components
2680 auto id = board.get<Identifier>()->id;
2681 auto bd = *board.get<Board>();
2682 auto pan = *board.get<Panning>();
2683 auto grid = *board.get<Grid>();
2684 auto size = *board.get<Size>();
2685
2687 Serializer::serializeString(b, bd.board_name);
2688
2689 // Panning
2690 Serializer::serializeBool(b, pan.isPanning);
2691
2692 // Grid
2693 Serializer::serializeVec2(b, grid.offset);
2694 Serializer::serializeFloat(b, grid.cell_size);
2695 Serializer::serializeBool(b, grid.is_hex);
2696 Serializer::serializeBool(b, grid.snap_to_grid);
2697 Serializer::serializeBool(b, grid.visible);
2698 Serializer::serializeFloat(b, grid.opacity);
2699
2700 // Size
2701 Serializer::serializeFloat(b, size.width);
2702 Serializer::serializeFloat(b, size.height);
2703
2704 // Image total size in bytes (u64)
2705 Serializer::serializeUInt64(b, imageBytesTotal);
2706 return b;
2707}
static void serializeBool(std::vector< unsigned char > &buffer, bool value)
Definition Serializer.h:312
static void serializeVec2(std::vector< unsigned char > &buffer, const glm::vec2 &vec)
Definition Serializer.h:325
static void serializeFloat(std::vector< unsigned char > &buffer, float value)
Definition Serializer.h:307
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildSnapshotGameTableFrame()

std::vector< unsigned char > NetworkManager::buildSnapshotGameTableFrame ( uint64_t gameTableId,
const std::string & name )
private

Definition at line 2665 of file NetworkManager.cpp.

2666{
2667 std::vector<unsigned char> b;
2669 Serializer::serializeUInt64(b, gameTableId);
2671 return b;
2672}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ buildUserNameUpdate()

void NetworkManager::buildUserNameUpdate ( std::vector< uint8_t > & out,
uint64_t tableId,
const std::string & userUniqueId,
const std::string & oldUsername,
const std::string & newUsername,
bool reboundFlag ) const

Definition at line 1033 of file NetworkManager.cpp.

1039{
1040 out.clear();
1041 Serializer::serializeUInt64(out, tableId);
1042 Serializer::serializeString(out, userUniqueId); // <— uniqueId
1043 Serializer::serializeString(out, oldUsername);
1044 Serializer::serializeString(out, newUsername);
1045 Serializer::serializeUInt8(out, reboundFlag ? 1 : 0);
1046}
Here is the call graph for this function:

◆ clearDragState()

void NetworkManager::clearDragState ( uint64_t markerId)

Definition at line 963 of file NetworkManager.cpp.

964{
965 drag_.erase(markerId);
966}

◆ clearPeers()

bool NetworkManager::clearPeers ( ) const
inline

Definition at line 121 of file NetworkManager.h.

122 {
123 for (auto [id, peer] : peers)
124 {
125 peer->close();
126 }
127 return peers.empty();
128 }

◆ closeServer()

void NetworkManager::closeServer ( )

Definition at line 307 of file NetworkManager.cpp.

308{
309 if (signalingServer.get() != nullptr)
310 {
312 signalingServer->stop();
313 }
314 //stopRawDrainWorker();
316}
std::shared_ptr< SignalingServer > signalingServer
static void stopLocalTunnel()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ connectedPeerCount()

int NetworkManager::connectedPeerCount ( ) const

Definition at line 335 of file NetworkManager.cpp.

336{
337 int n = 0;
338 for (auto& [id, link] : peers)
339 if (link && link->isConnected())
340 ++n;
341 return n;
342}

◆ connectToPeer()

bool NetworkManager::connectToPeer ( const std::string & connectionString)

Definition at line 344 of file NetworkManager.cpp.

345{
346 std::string server;
347 unsigned short port = 0;
348 std::string password;
349 parseConnectionString(connectionString, server, port, password);
350
351 if (!password.empty())
352 setNetworkPassword(password.c_str());
354
355 if (hasUrlScheme(server))
356 {
357 return signalingClient->connectUrl(server); // NEW method (see below)
358 }
359 return signalingClient->connect(server, port); // your old method
360}
@ PLAYER
unsigned int port
void parseConnectionString(std::string connection_string, std::string &server, unsigned short &port, std::string &password)
static bool hasUrlScheme(const std::string &s)
void setNetworkPassword(const char *password)
Here is the call graph for this function:

◆ debugIdentitySnapshot()

std::string NetworkManager::debugIdentitySnapshot ( ) const

Definition at line 906 of file NetworkManager.cpp.

907{
908 std::ostringstream os;
909 os << "[Identity Snapshot]\n";
910
911 os << "self.peerId=" << (getMyPeerId().empty() ? "(none)" : getMyPeerId()) << "\n";
913 {
914 os << "self.uniqueId=" << identity_manager->myUniqueId()
915 << " username=\"" << identity_manager->myUsername() << "\"\n";
916 }
917 // GM (if tracked)
918 if (!getGMId().empty())
919 {
920 os << "gm.uniqueId=" << getGMId()
921 << " username=\"" << (identity_manager ? identity_manager->usernameForUnique(getGMId()) : std::string{}) << "\"\n";
922 }
923
924 os << "\n[Peers]\n";
925 for (const auto& [peerId, link] : peers)
926 {
927 os << "- peerId=" << peerId;
928
929 std::string uid, uname;
931 {
932 if (auto u = identity_manager->uniqueForPeer(peerId))
933 uid = *u;
934 if (!uid.empty())
935 uname = identity_manager->usernameForUnique(uid);
936 }
937
938 if (!uid.empty())
939 os << " uniqueId=" << uid;
940 if (!uname.empty())
941 os << " username=\"" << uname << "\"";
942
943 if (link)
944 os << " link.display=\"" << link->displayName() << "\"";
945
946 os << "\n";
947 }
948
949 // Optionally: dump address-book keys too
951 {
952 os << "\n[Peer→Unique map]\n";
953 // If you don’t expose an accessor, add one that returns a copy or iterate via a friend.
954 for (const auto& pid : getConnectedPeerIds())
955 {
956 if (auto u = identity_manager->uniqueForPeer(pid))
957 os << " " << pid << " -> " << *u << "\n";
958 }
959 }
960
961 return os.str();
962}
const std::string & getGMId() const
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decodeRawChatBuffer()

void NetworkManager::decodeRawChatBuffer ( const std::string & fromPeer,
const std::vector< uint8_t > & b )

Definition at line 2390 of file NetworkManager.cpp.

2392{
2393 // ---- JSON branch ----
2394 auto first_non_ws = std::find_if(b.begin(), b.end(), [](uint8_t c)
2395 { return !std::isspace((unsigned char)c); });
2396 if (first_non_ws != b.end() && *first_non_ws == '{')
2397 {
2398 try
2399 {
2400 std::string s(b.begin(), b.end()); // UTF-8
2401 msg::Json j = msg::Json::parse(s);
2402
2404 r.fromPeerId = fromPeer;
2405
2406 // type
2407 msg::DCType t;
2408 if (!msg::DCTypeFromJson(msg::getString(j, "type"), t))
2409 {
2410 Logger::instance().log("chat", Logger::Level::Warn, "JSON chat: unknown type");
2411 return;
2412 }
2413 r.kind = t;
2414
2415 // common fields
2416 if (j.contains("tableId"))
2417 r.tableId = (uint64_t)j["tableId"].get<uint64_t>();
2418 if (j.contains("groupId"))
2419 r.threadId = (uint64_t)j["groupId"].get<uint64_t>();
2420
2421 switch (t)
2422 {
2425 {
2426 if (j.contains("name"))
2427 r.name = j["name"].get<std::string>();
2428 if (j.contains("participants") && j["participants"].is_array())
2429 {
2430 std::set<std::string> parts;
2431 for (auto& e : j["participants"])
2432 parts.insert(e.get<std::string>());
2433 r.participants = std::move(parts);
2434 }
2435 break;
2436 }
2438 {
2439 // nothing extra
2440 break;
2441 }
2443 {
2444 if (j.contains("ts"))
2445 r.ts = (uint64_t)j["ts"].get<uint64_t>();
2446 if (j.contains("username"))
2447 r.name = j["username"].get<std::string>();
2448 if (j.contains("text"))
2449 r.text = j["text"].get<std::string>();
2450 break;
2451 }
2452 default:
2453 return; // ignore non-chat types here
2454 }
2455
2456 inboundGame_.push(std::move(r));
2457 return; // handled JSON
2458 }
2459 catch (const std::exception& e)
2460 {
2461 Logger::instance().log("chat", Logger::Level::Warn, std::string("JSON parse error: ") + e.what());
2462 // fall through to legacy-binary branch if you still support it
2463 }
2464 }
2465}
void push(T value)
MessageQueue< msg::ReadyMessage > inboundGame_
bool DCTypeFromJson(std::string_view s, DCType &out)
Definition Message.h:322
std::string getString(const Json &j, std::string k, std::string def={})
Definition Message.h:579
DCType
Definition Message.h:31
nlohmann::json Json
Definition Message.h:363
std::string fromPeerId
Definition Message.h:169
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decodeRawGameBuffer()

void NetworkManager::decodeRawGameBuffer ( const std::string & fromPeer,
const std::vector< uint8_t > & b )

Definition at line 1113 of file NetworkManager.cpp.

1114{
1115 decodingFromPeer_ = fromPeer;
1116 size_t off = 0;
1117 while (off < b.size())
1118 {
1119 if (!ensureRemaining(b, off, 1))
1120 break;
1121
1122 auto type = static_cast<msg::DCType>(b[off]);
1123 off += 1;
1124
1125 Logger::instance().log("localtunnel", Logger::Level::Info, msg::DCtypeString(type) + " Received!!");
1126 switch (type)
1127 {
1130 Logger::instance().log("localtunnel", Logger::Level::Info, "Snapshot_GameTable Handled!!");
1131 break;
1132
1134 handleBoardMeta(b, off); // fills imagesRx_
1135 Logger::instance().log("localtunnel", Logger::Level::Info, "Snapshot_Board Handled!!");
1136 break;
1137
1139 handleMarkerMeta(b, off); // fills imagesRx_
1140 //Logger::instance().log("localtunnel", Logger::Level::Info, "MarkerCreate Handled!!");
1141 break;
1142
1144 handleFogCreate(b, off);
1145 //Logger::instance().log("localtunnel", Logger::Level::Info, "FogCreate Handled!!");
1146 break;
1147
1149 handleImageChunk(b, off);
1150 Logger::instance().log("localtunnel", Logger::Level::Info, "ImageChunk Handled!!");
1151 break;
1152
1154 handleCommitBoard(b, off);
1155 Logger::instance().log("localtunnel", Logger::Level::Info, "CommitBoard Handled!!");
1156 break;
1157
1159 handleCommitMarker(b, off);
1160 Logger::instance().log("localtunnel", Logger::Level::Info, "CommitMarker Handled!!");
1161 break;
1162
1164 handleMarkerUpdate(b, off);
1165 Logger::instance().log("localtunnel", Logger::Level::Info, "MarkerUpdate Handled!!");
1166 break;
1167
1169 handleMarkerMoveState(b, off);
1170 Logger::instance().log("localtunnel", Logger::Level::Info, "MarkerUpdate Handled!!");
1171 break;
1172
1174 handleFogUpdate(b, off);
1175 Logger::instance().log("localtunnel", Logger::Level::Info, "FogUpdate Handled!!");
1176 break;
1177
1179 handleMarkerDelete(b, off);
1180 Logger::instance().log("localtunnel", Logger::Level::Info, "MarkerDelete Handled!!");
1181 break;
1182
1184 handleFogDelete(b, off);
1185 Logger::instance().log("localtunnel", Logger::Level::Info, "MarkerDelete FogDelete!!");
1186 break;
1187
1189 handleGridUpdate(b, off);
1190 Logger::instance().log("localtunnel", Logger::Level::Info, "GridUpdate Handled!!");
1191 break;
1192
1194 {
1195 handleUserNameUpdate(b, off);
1196 break;
1197 }
1198 default:
1199 Logger::instance().log("localtunnel", Logger::Level::Warn, "Unkown Message Type not Handled!!");
1200 break;
1201 }
1202 }
1203 decodingFromPeer_.clear();
1204}
void handleFogUpdate(const std::vector< uint8_t > &b, size_t &off)
void handleFogDelete(const std::vector< uint8_t > &b, size_t &off)
std::string decodingFromPeer_
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 handleGridUpdate(const std::vector< uint8_t > &b, size_t &off)
void handleImageChunk(const std::vector< uint8_t > &b, size_t &off)
void handleBoardMeta(const std::vector< uint8_t > &b, size_t &off)
void handleFogCreate(const std::vector< uint8_t > &b, size_t &off)
void handleGameTableSnapshot(const std::vector< uint8_t > &b, size_t &off)
void handleMarkerUpdate(const std::vector< uint8_t > &b, size_t &off)
void handleMarkerMeta(const std::vector< uint8_t > &b, size_t &off)
static bool ensureRemaining(const std::vector< uint8_t > &b, size_t off, size_t need)
void handleMarkerDelete(const std::vector< uint8_t > &b, size_t &off)
std::string DCtypeString(DCType type)
Definition Message.h:61
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decodeRawMarkerMoveBuffer()

void NetworkManager::decodeRawMarkerMoveBuffer ( const std::string & fromPeer,
const std::vector< uint8_t > & b )

Definition at line 1207 of file NetworkManager.cpp.

1208{
1209 decodingFromPeer_ = fromPeer;
1210 size_t off = 0;
1211 while (off < b.size())
1212 {
1213 if (!ensureRemaining(b, off, 1))
1214 break;
1215
1216 auto type = static_cast<msg::DCType>(b[off]);
1217 off += 1;
1218 Logger::instance().log("localtunnel", Logger::Level::Info, msg::DCtypeString(type) + " Received!! MarkerMove");
1219 if (type != msg::DCType::MarkerMove)
1220 {
1221 // If the sender packed something else on this DC, bail
1222 return;
1223 }
1224
1225 handleMarkerMove(b, off); // parses one frame and updates coalescer
1226 Logger::instance().log("localtunnel", Logger::Level::Info, "MarkerMove Handled!!");
1227 }
1228 decodingFromPeer_.clear();
1229}
void handleMarkerMove(const std::vector< uint8_t > &b, size_t &off)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ decodeRawNotesBuffer()

void NetworkManager::decodeRawNotesBuffer ( const std::string & fromPeer,
const std::vector< uint8_t > & b )

Definition at line 2467 of file NetworkManager.cpp.

2468{
2469 size_t off = 0;
2470 while (off < b.size())
2471 {
2472 if (!ensureRemaining(b, off, 1))
2473 break;
2474
2475 auto type = static_cast<msg::DCType>(b[off]);
2476 off += 1;
2477
2478 Logger::instance().log("localtunnel", Logger::Level::Info, msg::DCtypeString(type) + " Received!!");
2479 switch (type)
2480 {
2482 //handleGameTableSnapshot(b, off); // pushes ReadyMessage internally
2483 Logger::instance().log("localtunnel", Logger::Level::Info, "NoteCreate Handled!!");
2484 break;
2485
2487 //handleBoardMeta(b, off); // fills imagesRx_
2488 Logger::instance().log("localtunnel", Logger::Level::Info, "NoteUpdate Handled!!");
2489 break;
2490
2492 //handleMarkerMeta(b, off); // fills imagesRx_
2493 Logger::instance().log("localtunnel", Logger::Level::Info, "NoteDelete Handled!!");
2494 break;
2495 default:
2496 // unknown / out-of-sync: stop this buffer
2497 Logger::instance().log("localtunnel", Logger::Level::Warn, "Unkown Message Type not Handled!! onNotes");
2498 return;
2499 }
2500 }
2501}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ disallowPort()

void NetworkManager::disallowPort ( unsigned short port)

◆ disconectFromPeers()

bool NetworkManager::disconectFromPeers ( )

Definition at line 781 of file NetworkManager.cpp.

782{
783 // Move out to avoid mutation during destruction
784 std::unordered_map<std::string, std::shared_ptr<PeerLink>> moved = std::move(peers);
785 peers.clear();
786
787 for (auto& [pid, link] : moved)
788 {
789 if (!link)
790 continue;
791 try
792 {
793 link->close();
794 }
795 catch (const std::exception& e)
796 {
797 Logger::instance().log("main", Logger::Level::Error, std::string("[disconnectFromPeers] ") + e.what());
798 pushStatusToast("Peer disconnect error", ImGuiToaster::Level::Error, 5.0f);
799 }
800 catch (...)
801 {
802 Logger::instance().log("main", Logger::Level::Error, "[disconnectFromPeers] unknown");
803 pushStatusToast("Peer disconnect error (unknown)", ImGuiToaster::Level::Error, 5.0f);
804 }
805 }
806 moved.clear();
807
808 if (signalingClient)
809 {
810 signalingClient->close();
811 }
812
814 return true;
815}
void pushStatusToast(const std::string &msg, ImGuiToaster::Level lvl, float durationSec=5.0f)
Here is the call graph for this function:

◆ disconnectAllPeers()

bool NetworkManager::disconnectAllPeers ( )

Definition at line 817 of file NetworkManager.cpp.

818{
819 if (signalingServer)
820 {
821 signalingServer->broadcastShutdown();
822 }
823
824 std::unordered_map<std::string, std::shared_ptr<PeerLink>> moved = std::move(peers);
825 peers.clear();
826
827 for (auto& [pid, link] : moved)
828 {
829 if (!link)
830 continue;
831 try
832 {
833 link->close();
834 }
835 catch (const std::exception& e)
836 {
837 Logger::instance().log("main", Logger::Level::Error, std::string("[disconnectAllPeers] ") + e.what());
838 pushStatusToast("Peer disconnect error", ImGuiToaster::Level::Error, 5.0f);
839 }
840 catch (...)
841 {
842 Logger::instance().log("main", Logger::Level::Error, "[disconnectAllPeers] unknown");
843 pushStatusToast("Peer disconnect error (unknown)", ImGuiToaster::Level::Error, 5.0f);
844 }
845 }
846 moved.clear();
847
848 if (signalingServer)
849 {
850 signalingServer->disconnectAllClients();
851 try
852 {
853 signalingServer->stop();
854 }
855 catch (...)
856 {
857 }
858 }
859
860 if (signalingClient)
861 {
862 signalingClient->close();
863 }
864
866 return true;
867}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ displayNameForPeer()

std::string NetworkManager::displayNameForPeer ( const std::string & peerId) const

Definition at line 773 of file NetworkManager.cpp.

774{
775 if (!identity_manager)
776 return peerId;
777 auto u = identity_manager->usernameForPeer(peerId);
778 return u.value_or(peerId);
779}
Here is the caller graph for this function:

◆ drainEvents()

void NetworkManager::drainEvents ( )

Definition at line 2173 of file NetworkManager.cpp.

2174{
2175 msg::NetEvent ev;
2176 while (events_.try_pop(ev))
2177 {
2178 if (ev.type == msg::NetEvent::Type::DcOpen)
2179 {
2180 auto it = peers.find(ev.peerId);
2181 if (it != peers.end() && it->second)
2182 {
2183 it->second->setOpen(ev.label, true);
2184 }
2185 }
2186 else if (ev.type == msg::NetEvent::Type::DcClosed)
2187 {
2188 auto it = peers.find(ev.peerId);
2189 if (it != peers.end() && it->second)
2190 {
2191 it->second->setOpen(ev.label, false);
2192 it->second->markBootstrapReset();
2193 //reconnectPeer(ev.peerId);
2194 }
2195 }
2196 else if (ev.type == msg::NetEvent::Type::PcClosed)
2197 {
2198 auto it = peers.find(ev.peerId);
2199 if (it != peers.end() && it->second)
2200 {
2201 //reconnectPeer(ev.peerId);
2202 }
2203 }
2204 else if (ev.type == msg::NetEvent::Type::PcOpen)
2205 {
2206 pushStatusToast(std::string("[Peer] ") + ev.peerId + " Connected", ImGuiToaster::Level::Good);
2207 }
2208 }
2209
2210 // If GM: check if any peer is now fully open → bootstrap once
2212 {
2213 for (auto& [pid, link] : peers)
2214 {
2215 if (link && link->allRequiredOpen() && !link->bootstrapSent())
2216 {
2217 try
2218 {
2220 }
2221 catch (const std::exception& e)
2222 {
2223 const std::string msg = std::string("Error bootstrapping peer: ") + e.what();
2226 }
2227 catch (...)
2228 {
2229 const char* msg = "Error bootstrapping peer: unknown exception";
2232 }
2233 }
2234 }
2235 }
2236}
@ GAMEMASTER
bool try_pop(T &value)
std::shared_ptr< ImGuiToaster > toaster_
MessageQueue< msg::NetEvent > events_
void bootstrapPeerIfReady(const std::string &peerId)
Definition Message.h:28
Here is the call graph for this function:

◆ drainInboundRaw()

void NetworkManager::drainInboundRaw ( int maxPerTick)

Definition at line 2238 of file NetworkManager.cpp.

2239{
2240 using clock = std::chrono::steady_clock;
2241 int processed = 0;
2242
2244 while (processed < maxPerTick && inboundRaw_.try_pop(r))
2245 {
2246 try
2247 {
2248 if (r.label == msg::dc::name::Game)
2249 {
2250 decodeRawGameBuffer(r.fromPeer, r.bytes);
2251 }
2252 else if (r.label == msg::dc::name::Chat)
2253 {
2254 decodeRawChatBuffer(r.fromPeer, r.bytes);
2255 }
2256 else if (r.label == msg::dc::name::Notes)
2257 {
2258 decodeRawNotesBuffer(r.fromPeer, r.bytes);
2259 }
2260 else if (r.label == msg::dc::name::MarkerMove)
2261 {
2262 decodeRawMarkerMoveBuffer(r.fromPeer, r.bytes); // coalesce into moveLatest_
2263 }
2264 }
2265 catch (...)
2266 {
2267 // swallow/log
2268 }
2269 ++processed;
2270 }
2271}
void decodeRawNotesBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
void decodeRawGameBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
void decodeRawChatBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
void decodeRawMarkerMoveBuffer(const std::string &fromPeer, const std::vector< uint8_t > &b)
MessageQueue< msg::InboundRaw > inboundRaw_
constexpr std::string Game
Definition Message.h:297
constexpr std::string Notes
Definition Message.h:299
constexpr std::string MarkerMove
Definition Message.h:300
Here is the call graph for this function:

◆ ensurePeerLink()

std::shared_ptr< PeerLink > NetworkManager::ensurePeerLink ( const std::string & peerId)

Definition at line 632 of file NetworkManager.cpp.

633{
634 if (auto it = peers.find(peerId); it != peers.end())
635 return it->second;
636 auto link = std::make_shared<PeerLink>(peerId, weak_from_this());
637 peers.emplace(peerId, link);
638 return link;
639}

◆ ensureRemaining()

static bool NetworkManager::ensureRemaining ( const std::vector< uint8_t > & b,
size_t off,
size_t need )
inlinestaticprivate

Definition at line 409 of file NetworkManager.h.

410 {
411 return off + need <= b.size();
412 }
Here is the caller graph for this function:

◆ forceCloseDrag()

void NetworkManager::forceCloseDrag ( uint64_t markerId)

Definition at line 1492 of file NetworkManager.cpp.

1493{
1494 auto it = drag_.find(markerId);
1495 if (it == drag_.end())
1496 return;
1497 auto& s = it->second;
1498 s.closed = true;
1499 s.locallyDragging = false;
1500 s.localSeq = 0;
1501}

◆ getConnectedPeerIds()

std::vector< std::string > NetworkManager::getConnectedPeerIds ( ) const

Definition at line 877 of file NetworkManager.cpp.

878{
879 std::vector<std::string> ids;
880 ids.reserve(peers.size());
881 for (auto& [pid, link] : peers)
882 {
883 if (link && link->isConnected())
884 {
885 ids.push_back(pid);
886 }
887 }
888 return ids;
889}
Here is the caller graph for this function:

◆ getConnectedUsernames()

std::vector< std::string > NetworkManager::getConnectedUsernames ( ) const

Definition at line 891 of file NetworkManager.cpp.

892{
893 std::vector<std::string> user_names;
894 user_names.reserve(peers.size());
895 for (auto& [pid, link] : peers)
896 {
897 if (link && link->isConnected())
898 {
899 user_names.push_back(displayNameForPeer(pid));
900 }
901 }
902 return user_names;
903}
std::string displayNameForPeer(const std::string &peerId) const
Here is the call graph for this function:

◆ getCustomHost()

const std::string & NetworkManager::getCustomHost ( ) const
inline

Definition at line 300 of file NetworkManager.h.

300{ return customHost_; }
std::string customHost_
Here is the caller graph for this function:

◆ getExternalIPAddress()

std::string NetworkManager::getExternalIPAddress ( )

Definition at line 374 of file NetworkManager.cpp.

375{
376 if (external_ip_address == "")
377 {
378 //auto external_ip = UPnPManager::getExternalIPv4Address();
379 std::string external_ip = NetworkUtilities::httpGet(L"loca.lt", L"/mytunnelpassword");
380 external_ip_address = external_ip;
381 return external_ip;
382 }
383 return external_ip_address;
384}
std::string external_ip_address
static std::string httpGet(const std::wstring &host, const std::wstring &path)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getGMId()

const std::string & NetworkManager::getGMId ( ) const
inline

Definition at line 229 of file NetworkManager.h.

230 {
231 return gmPeerId_;
232 }
std::string gmPeerId_
Here is the caller graph for this function:

◆ getIdentityManager()

std::shared_ptr< IdentityManager > NetworkManager::getIdentityManager ( )
inline

Definition at line 288 of file NetworkManager.h.

289 {
290 return identity_manager;
291 }

◆ getLocalIPAddress()

std::string NetworkManager::getLocalIPAddress ( )

Definition at line 363 of file NetworkManager.cpp.

364{
365 if (local_ip_address == "")
366 {
368 local_ip_address = local_ip;
369 return local_ip;
370 }
371 return local_ip_address;
372}
std::string local_ip_address
static std::string getLocalIPv4Address()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getLocalTunnelURL()

std::string NetworkManager::getLocalTunnelURL ( )

Definition at line 414 of file NetworkManager.cpp.

415{
417}
static std::string getLocalTunnelUrl()
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getMyPeerId()

const std::string & NetworkManager::getMyPeerId ( ) const
inline

Definition at line 149 of file NetworkManager.h.

150 {
151 return myPeerId_;
152 }
std::string myPeerId_
Here is the caller graph for this function:

◆ getMyUniqueId()

std::string NetworkManager::getMyUniqueId ( ) const
inline

Definition at line 144 of file NetworkManager.h.

145 {
146 return identity_manager->myUniqueId();
147 }
Here is the caller graph for this function:

◆ getMyUsername()

std::string NetworkManager::getMyUsername ( ) const
inline

Definition at line 140 of file NetworkManager.h.

141 {
142 return identity_manager->myUsername();
143 }
Here is the caller graph for this function:

◆ getNetworkInfo()

std::string NetworkManager::getNetworkInfo ( ConnectionType type)

Definition at line 386 of file NetworkManager.cpp.

387{
388 const auto port = getPort();
389 const auto pwd = getNetworkPassword();
390
391 if (type == ConnectionType::LOCAL)
392 { // LAN (192.168.x.y)
393 const auto ip = getLocalIPAddress();
394 return "runic:" + ip + ":" + std::to_string(port) + "?" + pwd;
395 }
396 else if (type == ConnectionType::EXTERNAL)
397 { // public IP
398 const auto ip = getExternalIPAddress();
399 return "runic:" + ip + ":" + std::to_string(port) + "?" + pwd;
400 }
401 else if (type == ConnectionType::LOCALTUNNEL)
402 {
403 const auto url = getLocalTunnelURL(); // e.g., https://sub.loca.lt
404 return url + "?" + pwd; // no port needed (LT handles it)
405 }
406 else if (type == ConnectionType::CUSTOM)
407 { // public IP
408 const auto customHost = getCustomHost();
409 return "runic:" + customHost + ":" + std::to_string(port) + "?" + pwd;
410 }
411 return {};
412}
unsigned short getPort() const
std::string getLocalTunnelURL()
std::string getNetworkPassword() const
const std::string & getCustomHost() const
Here is the call graph for this function:

◆ getNetworkPassword()

std::string NetworkManager::getNetworkPassword ( ) const
inline

Definition at line 99 of file NetworkManager.h.

100 {
101 return std::string(network_password);
102 };
char network_password[124]
Here is the caller graph for this function:

◆ getPeerRole()

Role NetworkManager::getPeerRole ( ) const
inline

Definition at line 108 of file NetworkManager.h.

109 {
110 return peer_role;
111 }

◆ getPeers()

const std::unordered_map< std::string, std::shared_ptr< PeerLink > > & NetworkManager::getPeers ( ) const
inline

Definition at line 158 of file NetworkManager.h.

159 {
160 return peers;
161 }

◆ getPort()

unsigned short NetworkManager::getPort ( ) const
inline

Definition at line 95 of file NetworkManager.h.

96 {
97 return port;
98 };
Here is the caller graph for this function:

◆ getRTCConfig()

rtc::Configuration NetworkManager::getRTCConfig ( ) const
inline

Definition at line 113 of file NetworkManager.h.

114 {
115 return rtcConfig;
116 }
rtc::Configuration rtcConfig

◆ getSendMoveMinPeriodMs()

uint32_t NetworkManager::getSendMoveMinPeriodMs ( ) const
inlineprivate

Definition at line 312 of file NetworkManager.h.

313 {
315 }
uint32_t sendMoveMinPeriodMs_

◆ getSignalingServer()

std::shared_ptr< SignalingServer > NetworkManager::getSignalingServer ( ) const
inline

Definition at line 162 of file NetworkManager.h.

163 {
164 return signalingServer;
165 }

◆ handleBoardMeta()

void NetworkManager::handleBoardMeta ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1945 of file NetworkManager.cpp.

1946{
1947 msg::BoardMeta bm;
1949 bm.boardName = Serializer::deserializeString(b, off);
1950 bm.pan = Serializer::deserializePanning(b, off);
1951 bm.grid = Serializer::deserializeGrid(b, off);
1952 bm.size = Serializer::deserializeSize(b, off);
1953 uint64_t total = Serializer::deserializeUInt64(b, off); // 0 if no image
1954
1955 auto& p = imagesRx_[bm.boardId];
1957 p.id = bm.boardId;
1958 p.boardId = bm.boardId;
1959 p.boardMeta = bm;
1960 p.total = total;
1961 p.received = 0;
1962 p.buf.clear();
1963 if (total)
1964 p.buf.resize(static_cast<size_t>(total));
1965}
std::unordered_map< uint64_t, PendingImage > imagesRx_
static Size deserializeSize(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:422
static std::string deserializeString(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:388
static Grid deserializeGrid(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:492
static Panning deserializePanning(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:475
static uint64_t deserializeUInt64(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:360
uint64_t boardId
Definition Message.h:158
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleCommitBoard()

void NetworkManager::handleCommitBoard ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2005 of file NetworkManager.cpp.

2006{
2007 uint64_t boardId = Serializer::deserializeUInt64(b, off);
2008
2009 auto it = imagesRx_.find(boardId);
2010 if (it == imagesRx_.end())
2011 {
2012 // Late/meta-less commit? Create a placeholder so tryFinalize can run if chunks arrive later.
2013 PendingImage p;
2015 p.id = boardId;
2016 imagesRx_.emplace(boardId, std::move(p));
2017 it = imagesRx_.find(boardId);
2018 }
2019
2020 it->second.commitRequested = true;
2022}
void tryFinalizeImage(msg::ImageOwnerKind kind, uint64_t id)
msg::ImageOwnerKind kind
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleCommitMarker()

void NetworkManager::handleCommitMarker ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2091 of file NetworkManager.cpp.

2092{
2093 uint64_t boardId = Serializer::deserializeUInt64(b, off);
2094 uint64_t markerId = Serializer::deserializeUInt64(b, off);
2095
2096 auto it = imagesRx_.find(markerId);
2097 if (it == imagesRx_.end())
2098 {
2099 PendingImage p;
2101 p.id = markerId;
2102 p.boardId = boardId;
2103 imagesRx_.emplace(markerId, std::move(p));
2104 it = imagesRx_.find(markerId);
2105 }
2106 else
2107 {
2108 it->second.boardId = boardId; // ensure it's set
2109 }
2110
2111 it->second.commitRequested = true;
2113}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleFogCreate()

void NetworkManager::handleFogCreate ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1993 of file NetworkManager.cpp.

1994{
1997 m.boardId = Serializer::deserializeUInt64(b, off);
1998 m.fogId = Serializer::deserializeUInt64(b, off);
1999 m.pos = Serializer::deserializePosition(b, off);
2000 m.size = Serializer::deserializeSize(b, off);
2001 m.vis = Serializer::deserializeVisibility(b, off);
2002 inboundGame_.push(std::move(m));
2003}
static Visibility deserializeVisibility(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:435
static Position deserializePosition(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:409
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleFogDelete()

void NetworkManager::handleFogDelete ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2164 of file NetworkManager.cpp.

2165{
2168 m.boardId = Serializer::deserializeUInt64(b, off);
2169 m.fogId = Serializer::deserializeUInt64(b, off);
2170 inboundGame_.push(std::move(m));
2171}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleFogUpdate()

void NetworkManager::handleFogUpdate ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2151 of file NetworkManager.cpp.

2152{
2155 m.boardId = Serializer::deserializeUInt64(b, off);
2156 m.fogId = Serializer::deserializeUInt64(b, off);
2157 m.pos = Serializer::deserializePosition(b, off);
2158 m.size = Serializer::deserializeSize(b, off);
2159 m.vis = Serializer::deserializeVisibility(b, off);
2160 m.mov = Serializer::deserializeMoving(b, off); // remove if you don’t use Moving on fog
2161 inboundGame_.push(std::move(m));
2162}
static Moving deserializeMoving(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:447
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleGameTableSnapshot()

void NetworkManager::handleGameTableSnapshot ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1935 of file NetworkManager.cpp.

1936{
1939 m.tableId = Serializer::deserializeUInt64(b, off);
1940 m.name = Serializer::deserializeString(b, off);
1941 inboundGame_.push(std::move(m));
1942}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleGridUpdate()

void NetworkManager::handleGridUpdate ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1920 of file NetworkManager.cpp.

1921{
1922 // type byte already consumed by the caller switch
1923 if (!ensureRemaining(b, off, 8))
1924 return;
1925
1928 m.boardId = Serializer::deserializeUInt64(b, off);
1930 m.grid = g;
1931 inboundGame_.push(std::move(m));
1932}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleImageChunk()

void NetworkManager::handleImageChunk ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2024 of file NetworkManager.cpp.

2025{
2026 if (off + 1 > b.size())
2027 {
2028 Logger::instance().log("localtunnel", Logger::Level::Error, "ImageChunk: underrun(kind)");
2029 return;
2030 }
2031 auto kind = static_cast<msg::ImageOwnerKind>(b[off]);
2032 off += 1;
2033
2034 if (off + 8 + 8 + 4 > b.size())
2035 {
2036 Logger::instance().log("localtunnel", Logger::Level::Error, "ImageChunk: underrun(headers)");
2037 return;
2038 }
2039 uint64_t id = Serializer::deserializeUInt64(b, off);
2040 uint64_t off64 = Serializer::deserializeUInt64(b, off);
2041 int len = Serializer::deserializeInt(b, off);
2042
2043 if (len < 0 || off + static_cast<size_t>(len) > b.size())
2044 {
2045 Logger::instance().log("localtunnel", Logger::Level::Error,
2046 "ImageChunk: invalid len id=" + std::to_string(id) + " len=" + std::to_string(len));
2047 return;
2048 }
2049
2050 auto it = imagesRx_.find(id);
2051 if (it == imagesRx_.end())
2052 {
2053 Logger::instance().log("localtunnel", Logger::Level::Warn,
2054 "ImageChunk: unknown id=" + std::to_string(id));
2055 off += static_cast<size_t>(len);
2056 return;
2057 }
2058
2059 auto& p = it->second;
2060 if (p.kind != kind || p.total == 0)
2061 {
2062 Logger::instance().log("localtunnel", Logger::Level::Warn,
2063 "ImageChunk: kind/total mismatch id=" + std::to_string(id));
2064 off += static_cast<size_t>(len);
2065 return;
2066 }
2067
2068 if (off64 + static_cast<uint64_t>(len) > p.total)
2069 {
2070 Logger::instance().log("localtunnel", Logger::Level::Error,
2071 "ImageChunk: out-of-bounds id=" + std::to_string(id) +
2072 " off=" + std::to_string(off64) + " len=" + std::to_string(len) +
2073 " total=" + std::to_string(p.total));
2074 off += static_cast<size_t>(len);
2075 return;
2076 }
2077
2078 std::memcpy(p.buf.data() + off64, b.data() + off, static_cast<size_t>(len));
2079 off += static_cast<size_t>(len);
2080 p.received += static_cast<uint64_t>(len);
2081
2082 // Occasional progress log (e.g., every ~1MB)
2083 if ((p.received % (1u << 20)) < static_cast<uint64_t>(len))
2084 {
2085 Logger::instance().log("localtunnel", Logger::Level::Info,
2086 "ImageChunk: id=" + std::to_string(id) + " " +
2087 std::to_string(p.received) + "/" + std::to_string(p.total));
2088 }
2089}
static int deserializeInt(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:367
ImageOwnerKind
Definition Message.h:140
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleMarkerDelete()

void NetworkManager::handleMarkerDelete ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2141 of file NetworkManager.cpp.

2142{
2145 m.boardId = Serializer::deserializeUInt64(b, off);
2146 m.markerId = Serializer::deserializeUInt64(b, off);
2147 inboundGame_.push(std::move(m));
2148}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleMarkerMeta()

void NetworkManager::handleMarkerMeta ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1968 of file NetworkManager.cpp.

1969{
1970 msg::MarkerMeta mm;
1972 mm.markerId = Serializer::deserializeUInt64(b, off);
1973 mm.name = Serializer::deserializeString(b, off);
1974 mm.pos = Serializer::deserializePosition(b, off);
1975 mm.size = Serializer::deserializeSize(b, off);
1976 mm.vis = Serializer::deserializeVisibility(b, off);
1977 mm.mov = Serializer::deserializeMoving(b, off);
1978 uint64_t total = Serializer::deserializeUInt64(b, off); // 0 if no image
1979
1980 auto& p = imagesRx_[mm.markerId];
1982 p.id = mm.markerId;
1983 p.boardId = mm.boardId;
1984 p.markerMeta = mm;
1985 p.total = total;
1986 p.received = 0;
1987 p.buf.clear();
1988 if (total)
1989 p.buf.resize(static_cast<size_t>(total));
1990}
uint64_t boardId
Definition Message.h:148
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleMarkerMove()

void NetworkManager::handleMarkerMove ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1231 of file NetworkManager.cpp.

1232{
1233 if (!ensureRemaining(raw, off, 8 + 8 + 4 + 4 + 8 + 8)) // 8 bytes Position (2x int32)
1234 return;
1235
1236 const auto& b = reinterpret_cast<const std::vector<unsigned char>&>(raw);
1237
1240 m.boardId = Serializer::deserializeUInt64(b, off);
1241 m.markerId = Serializer::deserializeUInt64(b, off);
1242 m.dragEpoch = Serializer::deserializeUInt32(b, off);
1243 m.seq = Serializer::deserializeUInt32(b, off);
1244 m.ts = Serializer::deserializeUInt64(b, off);
1246 m.pos = p;
1247 m.mov = Moving{true};
1248
1249 m.fromPeerId = decodingFromPeer_;
1250
1251 inboundGame_.push(std::move(m));
1252}
static uint32_t deserializeUInt32(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:353
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleMarkerMoveState()

void NetworkManager::handleMarkerMoveState ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1269 of file NetworkManager.cpp.

1270{
1271 // Expect (after type):
1272 // [boardId:u64][markerId:u64][epoch:u32][seq:u32][ts:u64][Moving][(Position if final)]
1273 if (!ensureRemaining(raw, off, 8 + 8 + 4 + 4 + 8 + 1))
1274 return;
1275
1276 const auto& b = reinterpret_cast<const std::vector<unsigned char>&>(raw);
1277
1280 m.boardId = Serializer::deserializeUInt64(b, off);
1281 m.markerId = Serializer::deserializeUInt64(b, off);
1282 m.dragEpoch = Serializer::deserializeUInt32(b, off);
1283 m.seq = Serializer::deserializeUInt32(b, off);
1284 m.ts = Serializer::deserializeUInt64(b, off);
1286 m.mov = mv;
1287
1288 if (!mv.isDragging)
1289 {
1290 if (!ensureRemaining(raw, off, 8))
1291 return; // Position (2x int)
1293 m.pos = p;
1294 }
1295 m.fromPeerId = decodingFromPeer_;
1296 inboundGame_.push(std::move(m));
1297}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleMarkerUpdate()

void NetworkManager::handleMarkerUpdate ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 1255 of file NetworkManager.cpp.

1256{
1259
1260 m.boardId = Serializer::deserializeUInt64(b, off);
1261 m.markerId = Serializer::deserializeUInt64(b, off);
1262 m.size = Serializer::deserializeSize(b, off);
1263 m.vis = Serializer::deserializeVisibility(b, off);
1264 m.markerComp = Serializer::deserializeMarkerComponent(b, off);
1265
1266 m.fromPeerId = decodingFromPeer_;
1267 inboundGame_.push(std::move(m));
1268}
static MarkerComponent deserializeMarkerComponent(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:292
Here is the call graph for this function:
Here is the caller graph for this function:

◆ handleUserNameUpdate()

void NetworkManager::handleUserNameUpdate ( const std::vector< uint8_t > & b,
size_t & off )
private

Definition at line 2115 of file NetworkManager.cpp.

2116{
2119 r.fromPeerId = decodingFromPeer_;
2120 r.tableId = Serializer::deserializeUInt64(b, off);
2121
2122 // This is UNIQUE ID now:
2123 const std::string uniqueId = Serializer::deserializeString(b, off);
2124 const std::string oldU = Serializer::deserializeString(b, off);
2125 const std::string newU = Serializer::deserializeString(b, off);
2126 const uint8_t rebound = Serializer::deserializeUInt8(b, off);
2127
2128 // Keep old ReadyMessage fields for upstream handlers (uses userPeerId/name/text in your codebase):
2129 r.userUniqueId = uniqueId; // NOTE: field name is legacy; carries uniqueId now.
2130 r.text = oldU;
2131 r.name = newU;
2132 r.rebound = rebound;
2133
2135 "UserNameUpdate: tbl=" + std::to_string(r.tableId.value_or(0)) +
2136 " uid=" + uniqueId + " old=" + oldU + " new=" + newU);
2137
2138 inboundGame_.push(std::move(r));
2139}
static uint8_t deserializeUInt8(const std::vector< unsigned char > &buffer, size_t &offset)
Definition Serializer.h:346
Here is the call graph for this function:
Here is the caller graph for this function:

◆ hasAnyPeer()

bool NetworkManager::hasAnyPeer ( ) const

Definition at line 331 of file NetworkManager.cpp.

332{
333 return !peers.empty();
334}

◆ hasUrlScheme()

static bool NetworkManager::hasUrlScheme ( const std::string & s)
inlinestaticprivate

Definition at line 402 of file NetworkManager.h.

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 }
Here is the caller graph for this function:

◆ housekeepPeers()

void NetworkManager::housekeepPeers ( )

Definition at line 678 of file NetworkManager.cpp.

679{
680 const uint64_t now = nowMs();
681 const uint64_t kGraceMs = 10'000; // disconnect grace period
682
683 static std::unordered_map<std::string, uint64_t> firstDiscPeerAt;
684 static std::unordered_map<std::string, uint64_t> firstDiscWsAt;
685
686 // ---- PeerLink cleanup ----
687 for (auto it = peers.begin(); it != peers.end();)
688 {
689 const std::string& pid = it->first;
690 auto& link = it->second;
691
692 const bool connected = (link && link->isConnected());
693 if (connected)
694 {
695 firstDiscPeerAt.erase(pid);
696 ++it;
697 continue;
698 }
699
700 uint64_t& t0 = firstDiscPeerAt[pid];
701 if (t0 == 0)
702 t0 = now;
703
704 if (now - t0 >= kGraceMs)
705 {
706 try
707 {
708 if (link)
709 link->close();
710 }
711 catch (...)
712 {
713 }
714 it = peers.erase(it);
715 firstDiscPeerAt.erase(pid);
716 }
717 else
718 {
719 ++it;
720 }
721 }
722
723 // ---- WebSocket cleanup (server side) ----
724 auto wsClients = signalingServer->authClients();
725 for (auto it = wsClients.begin(); it != wsClients.end();)
726 {
727 const std::string& cid = it->first;
728 auto& ws = it->second;
729
730 const bool open = (ws && ws->isOpen()); // if your API is different, change this check
731 if (open)
732 {
733 firstDiscWsAt.erase(cid);
734 ++it;
735 continue;
736 }
737
738 uint64_t& t0 = firstDiscWsAt[cid];
739 if (t0 == 0)
740 t0 = now;
741
742 if (now - t0 >= kGraceMs)
743 {
744 try
745 {
747 }
748 catch (...)
749 {
750 }
751 it = wsClients.erase(it);
752 firstDiscWsAt.erase(cid);
753 }
754 else
755 {
756 ++it;
757 }
758 }
759}
static void safeCloseWebSocket(std::shared_ptr< rtc::WebSocket > &ws)
Here is the call graph for this function:

◆ isConnected()

bool NetworkManager::isConnected ( )

Definition at line 318 of file NetworkManager.cpp.

319{
320 for (auto& [peerId, link] : peers)
321 {
322 if (link && link->isConnected())
323 return true;
324 }
325 return false;
326}

◆ isHosting()

bool NetworkManager::isHosting ( ) const

Definition at line 327 of file NetworkManager.cpp.

328{
329 return signalingServer && signalingServer->isRunning(); // if you expose isRunning()
330}

◆ isMarkerBeingDragged()

bool NetworkManager::isMarkerBeingDragged ( uint64_t markerId) const

Definition at line 1486 of file NetworkManager.cpp.

1487{
1488 auto it = drag_.find(markerId);
1489 return (it != drag_.end() && !it->second.closed);
1490}

◆ markDraggingLocal()

void NetworkManager::markDraggingLocal ( uint64_t markerId,
bool dragging )

Definition at line 1466 of file NetworkManager.cpp.

1467{
1468 auto& s = drag_[markerId];
1469 if (dragging)
1470 {
1471 s.locallyDragging = true;
1472 s.locallyProposedEpoch = (s.closed ? (s.epoch + 1) : s.epoch);
1473 s.localSeq = 0;
1474 s.ownerPeerId = getMyPeerId();
1475 s.epochOpenedMs = nowMs();
1476 s.closed = false;
1477 if (s.locallyProposedEpoch > s.epoch)
1478 s.epoch = s.locallyProposedEpoch;
1479 }
1480 else
1481 {
1482 s.locallyDragging = false; // we close epoch on final frame or forceCloseDrag
1483 }
1484}
Here is the call graph for this function:

◆ nowMs()

static uint64_t NetworkManager::nowMs ( )
inlinestaticprivate

Definition at line 433 of file NetworkManager.h.

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 }
std::chrono::steady_clock Clock
Here is the caller graph for this function:

◆ onPeerChannelOpen()

void NetworkManager::onPeerChannelOpen ( const std::string & peerId,
const std::string & label )

◆ onPeerLocalCandidate()

void NetworkManager::onPeerLocalCandidate ( const std::string & peerId,
const rtc::Candidate & cand )

Definition at line 670 of file NetworkManager.cpp.

671{
672 auto j = msg::makeCandidate("", peerId, cand.candidate());
673 if (signalingClient)
674 signalingClient->send(j.dump());
675}
Json makeCandidate(const std::string &from, const std::string &to, const std::string &cand, const std::string &broadcast=msg::value::False)
Definition Message.h:448
Here is the call graph for this function:

◆ onPeerLocalDescription()

void NetworkManager::onPeerLocalDescription ( const std::string & peerId,
const rtc::Description & desc )

Definition at line 643 of file NetworkManager.cpp.

644{
645 nlohmann::json j;
646 const std::string sdp = std::string(desc);
647
648 // Always pull identity from IdentityManager
649 const std::string username = getMyUsername(); // forwards to IdentityManager
650 const std::string uniqueId = getMyUniqueId(); // forwards to IdentityManager
651
652 if (desc.type() == rtc::Description::Type::Offer)
653 {
654 // server will overwrite "from", so "" is fine
655 j = msg::makeOffer(/*from*/ "", /*to*/ peerId, sdp, username, uniqueId);
656 }
657 else if (desc.type() == rtc::Description::Type::Answer)
658 {
659 j = msg::makeAnswer(/*from*/ "", /*to*/ peerId, sdp, username, uniqueId);
660 }
661 else
662 {
663 return;
664 }
665
666 if (signalingClient)
667 signalingClient->send(j.dump());
668}
std::string getMyUsername() const
std::string getMyUniqueId() const
Json makeOffer(const std::string &from, const std::string &to, const std::string &sdp, const std::string &username, const std::string &uniqueId, const std::string &broadcast=msg::value::False)
Definition Message.h:417
Json makeAnswer(const std::string &from, const std::string &to, const std::string &sdp, const std::string &username, const std::string &uniqueId, const std::string &broadcast=msg::value::False)
Definition Message.h:433
Here is the call graph for this function:

◆ parseConnectionString()

void NetworkManager::parseConnectionString ( std::string connection_string,
std::string & server,
unsigned short & port,
std::string & password )

Definition at line 419 of file NetworkManager.cpp.

420{
421 server.clear();
422 password.clear();
423 port = 0;
424
425 const std::string prefix = "runic:";
426 if (connection_string.rfind(prefix, 0) == 0)
427 connection_string.erase(0, prefix.size());
428
429 // split pass
430 std::string left = connection_string;
431 if (auto q = connection_string.find('?'); q != std::string::npos)
432 {
433 left = connection_string.substr(0, q);
434 password = connection_string.substr(q + 1);
435 }
436
437 if (hasUrlScheme(left))
438 { // URL path
439 server = left;
440 return;
441 }
442
443 // host[:port]
444 if (auto colon = left.find(':'); colon != std::string::npos)
445 {
446 server = left.substr(0, colon);
447 try
448 {
449 port = static_cast<unsigned short>(std::stoi(left.substr(colon + 1)));
450 }
451 catch (...)
452 {
453 port = 0;
454 }
455 }
456 else
457 {
458 server = left; // no port
459 }
460}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pushStatusToast()

void NetworkManager::pushStatusToast ( const std::string & msg,
ImGuiToaster::Level lvl,
float durationSec = 5.0f )
inline

Definition at line 213 of file NetworkManager.h.

214 {
215 if (toaster_)
216 toaster_->Push(lvl, msg, durationSec);
217 }
Here is the caller graph for this function:

◆ readFileBytes()

std::vector< unsigned char > NetworkManager::readFileBytes ( const std::string & path)
inlineprivate

Definition at line 414 of file NetworkManager.h.

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 }
Here is the caller graph for this function:

◆ removeDisconnectedPeers()

std::size_t NetworkManager::removeDisconnectedPeers ( )

Definition at line 551 of file NetworkManager.cpp.

552{
553 std::vector<std::string> toErase;
554 std::vector<std::shared_ptr<PeerLink>> toClose;
555 toErase.reserve(peers.size());
556 toClose.reserve(peers.size());
557
558 // 1) Decide who to remove; DO NOT mutate the map yet.
559 for (auto const& [pid, link] : peers)
560 {
561 const bool shouldRemove = (!link) || link->isClosedOrFailed();
562 if (shouldRemove)
563 {
564 toErase.push_back(pid);
565 if (link)
566 toClose.emplace_back(link);
567 }
568 }
569
570 // 2) Erase all selected entries from the map (no destructors called yet for links we retained).
571 for (auto const& pid : toErase)
572 peers.erase(pid);
573
574 // 3) Close outside the map to avoid re-entrancy/races.
575 for (auto& link : toClose)
576 {
577 try
578 {
579 link->close(); // should be idempotent and NOT call back into NM
580 }
581 catch (const std::exception& e)
582 {
583 Logger::instance().log("main", Logger::Level::Error, std::string("[removeDisconnectedPeers] ") + e.what());
584 //pushStatusToast("Peer close error", ImGuiToaster::Level::Error, 4.0f);
585 }
586 catch (...)
587 {
588 Logger::instance().log("main", Logger::Level::Error, "[removeDisconnectedPeers] unknown exception");
589 //pushStatusToast("Peer close error (unknown)", ImGuiToaster::Level::Error, 4.0f);
590 }
591 }
592
593 return toErase.size();
594}
Here is the call graph for this function:

◆ removePeer()

bool NetworkManager::removePeer ( std::string peerId)

Definition at line 596 of file NetworkManager.cpp.

597{
598 // 1) Find, move the link out, erase entry first.
599 std::shared_ptr<PeerLink> link;
600 if (auto it = peers.find(peerId); it != peers.end())
601 {
602 link = std::move(it->second);
603 peers.erase(it);
604 }
605 else
606 {
607 return false;
608 }
609
610 // 2) Close outside the map.
611 if (link)
612 {
613 try
614 {
615 link->close(); // safe: detach callbacks first, idempotent
616 }
617 catch (const std::exception& e)
618 {
619 Logger::instance().log("main", Logger::Level::Error, std::string("[removePeer] ") + e.what());
620 //pushStatusToast("Peer close error", ImGuiToaster::Level::Error, 4.0f);
621 }
622 catch (...)
623 {
624 Logger::instance().log("main", Logger::Level::Error, "[removePeer] unknown exception");
625 //pushStatusToast("Peer close error (unknown)", ImGuiToaster::Level::Error, 4.0f);
626 }
627 }
628 return true;
629}
Here is the call graph for this function:

◆ sendBoard()

void NetworkManager::sendBoard ( const flecs::entity & board,
const std::vector< std::string > & toPeerIds )

Definition at line 1697 of file NetworkManager.cpp.

1698{
1699 // read board image (from TextureComponent.image_path)
1700 auto tex = board.get<TextureComponent>();
1701 auto image_path = tex->image_path;
1702 Logger::instance().log("localtunnel", Logger::Level::Info, "Board Texture Path: " + image_path);
1703 auto is_file_only = PathManager::isFilenameOnly(tex->image_path);
1704 auto is_path_like = PathManager::isPathLike(tex->image_path);
1705 if (is_file_only || !is_path_like)
1706 {
1707 Logger::instance().log("localtunnel", Logger::Level::Info, "Board Texture Path is FILE ONLY");
1708 auto map_folder = PathManager::getMapsPath();
1709 auto image_path_ = map_folder / tex->image_path;
1710 image_path = image_path_.string();
1711 }
1712 Logger::instance().log("localtunnel", Logger::Level::Info, "Board Texture Path AGAIN: " + image_path);
1713 std::vector<unsigned char> img = tex ? readFileBytes(image_path) : std::vector<unsigned char>{};
1714
1715 // 1) meta
1716 auto meta = buildSnapshotBoardFrame(board, static_cast<uint64_t>(img.size()));
1717 broadcastGameFrame(meta, toPeerIds);
1718
1720 uint64_t bid = board.get<Identifier>()->id;
1721 sendImageChunks(msg::ImageOwnerKind::Board, bid, img, toPeerIds);
1722
1723 // 3) commit
1724 auto commit = buildCommitBoardFrame(bid);
1725 broadcastGameFrame(commit, toPeerIds);
1726
1727 board.children([&](flecs::entity child)
1728 {
1729 if (child.has<MarkerComponent>()) {
1730 uint64_t bid = board.get<Identifier>()->id;
1731 sendMarker(bid, child, toPeerIds);
1732 Logger::instance().log("localtunnel", Logger::Level::Info, "SentMarker");
1733 }
1734 else if (child.has<FogOfWar>()) {
1735 uint64_t bid = board.get<Identifier>()->id;
1736 sendFog(bid, child, toPeerIds);
1737 Logger::instance().log("localtunnel", Logger::Level::Info, "SentFog");
1738 } });
1739}
std::vector< uint8_t > buildCommitBoardFrame(uint64_t boardId)
bool sendImageChunks(msg::ImageOwnerKind kind, uint64_t id, const std::vector< unsigned char > &img, const std::vector< std::string > &toPeerIds)
std::vector< unsigned char > readFileBytes(const std::string &path)
void broadcastGameFrame(const std::vector< unsigned char > &frame, const std::vector< std::string > &toPeerIds)
std::vector< uint8_t > buildSnapshotBoardFrame(const flecs::entity &board, uint64_t imageBytesTotal)
static bool isFilenameOnly(const std::string &s)
static bool isPathLike(const std::string &s)
static fs::path getMapsPath()
Definition PathManager.h:61
std::string image_path
Definition Components.h:47
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendChatJsonTo() [1/2]

bool NetworkManager::sendChatJsonTo ( const std::set< std::string > & peers,
const msg::Json & j )

Definition at line 1095 of file NetworkManager.cpp.

1096{
1097 const std::string text = j.dump();
1098 bool any = false;
1099 for (auto& pid : targets)
1100 {
1101 auto it = peers.find(pid);
1102 if (it == peers.end() || !it->second)
1103 continue;
1104 auto& link = it->second;
1105 if (!link->isConnected())
1106 continue;
1107 if (link->sendOn(msg::dc::name::Chat, std::string_view(text)))
1108 any = true;
1109 }
1110 return any;
1111}

◆ sendChatJsonTo() [2/2]

bool NetworkManager::sendChatJsonTo ( const std::string & peerId,
const msg::Json & j )

Definition at line 1085 of file NetworkManager.cpp.

1086{
1087 auto it = peers.find(peerId);
1088 if (it == peers.end() || !it->second)
1089 return false;
1090 auto& link = it->second;
1091 if (!link->isConnected())
1092 return false;
1093 return link->sendOn(msg::dc::name::Chat, std::string_view(j.dump()));
1094}

◆ sendFog()

void NetworkManager::sendFog ( uint64_t boardId,
const flecs::entity & fog,
const std::vector< std::string > & toPeerIds )

Definition at line 1780 of file NetworkManager.cpp.

1781{
1782 auto frame = buildFogCreateFrame(boardId, fog);
1783 broadcastGameFrame(frame, toPeerIds);
1784}
std::vector< uint8_t > buildFogCreateFrame(uint64_t boardId, const flecs::entity &fog)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendFogDelete()

void NetworkManager::sendFogDelete ( uint64_t boardId,
const flecs::entity & fog,
const std::vector< std::string > & toPeerIds )

Definition at line 1677 of file NetworkManager.cpp.

1679{
1680 if (!fog.is_valid() || !fog.has<Identifier>())
1681 return;
1682
1683 const uint64_t fid = fog.get<Identifier>()->id;
1684 auto frame = buildFogDeleteFrame(boardId, fid);
1685 broadcastGameFrame(frame, toPeerIds);
1686}
std::vector< unsigned char > buildFogDeleteFrame(uint64_t boardId, uint64_t fogId)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendFogUpdate()

void NetworkManager::sendFogUpdate ( uint64_t boardId,
const flecs::entity & fog,
const std::vector< std::string > & toPeerIds )

Definition at line 1667 of file NetworkManager.cpp.

1669{
1670 if (!fog.is_valid() || !fog.has<Identifier>())
1671 return;
1672
1673 auto frame = buildFogUpdateFrame(boardId, fog);
1674 broadcastGameFrame(frame, toPeerIds);
1675}
std::vector< unsigned char > buildFogUpdateFrame(uint64_t boardId, const flecs::entity &fog)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendGameTable()

void NetworkManager::sendGameTable ( const flecs::entity & gameTable,
const std::vector< std::string > & toPeerIds )

Definition at line 1689 of file NetworkManager.cpp.

1690{
1691 auto gtId = gameTable.get<Identifier>()->id;
1692 auto gt = *gameTable.get<GameTable>();
1693 auto frame = buildSnapshotGameTableFrame(gtId, gt.gameTableName);
1694 broadcastGameFrame(frame, toPeerIds);
1695}
std::vector< uint8_t > buildSnapshotGameTableFrame(uint64_t gameTableId, const std::string &name)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendGameTo()

void NetworkManager::sendGameTo ( const std::string & peerId,
const std::vector< unsigned char > & bytes )

Definition at line 2783 of file NetworkManager.cpp.

2784{
2785 auto it = peers.find(peerId);
2786 if (it == peers.end() || !it->second)
2787 return;
2788 it->second->sendGame(bytes);
2789}
Here is the caller graph for this function:

◆ sendGridUpdate()

void NetworkManager::sendGridUpdate ( uint64_t boardId,
const flecs::entity & board,
const std::vector< std::string > & toPeerIds )

Definition at line 1900 of file NetworkManager.cpp.

1902{
1903 if (!board.is_valid() || !board.has<Grid>())
1904 return;
1905
1906 const auto* g = board.get<Grid>();
1907 auto frame = buildGridUpdateFrame(boardId, *g);
1908 broadcastGameFrame(frame, toPeerIds);
1909}
std::vector< unsigned char > buildGridUpdateFrame(uint64_t boardId, const Grid &grid)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendImageChunks()

bool NetworkManager::sendImageChunks ( msg::ImageOwnerKind kind,
uint64_t id,
const std::vector< unsigned char > & img,
const std::vector< std::string > & toPeerIds )

Definition at line 1792 of file NetworkManager.cpp.

1793{
1794 Logger::instance().log("localtunnel", Logger::Level::Info,
1795 std::string("sendImageChunks: kind=") + (kind == msg::ImageOwnerKind::Board ? "Board" : "Marker") +
1796 " id=" + std::to_string(id) + " bytes=" + std::to_string(img.size()));
1797
1798 size_t sent = 0;
1799 int paced = 0;
1800 while (sent < img.size())
1801 {
1802 const size_t chunk = std::min(kChunk, img.size() - sent);
1803 const auto frame = buildImageChunkFrame(static_cast<uint8_t>(kind), id, sent, img.data() + sent, chunk);
1804
1805 // If you have per-peer send that returns bool, check and log
1806 bool allOk = true;
1807 for (auto& pid : toPeerIds)
1808 {
1809 sendGameTo(pid, frame); // if your API is void, keep it; otherwise log ok
1810 }
1811
1812 // Fallback pacing (keeps buffers happy)
1813 if ((++paced % kPaceEveryN) == 0)
1814 std::this_thread::sleep_for(std::chrono::milliseconds(kPaceMillis));
1815
1816 sent += chunk;
1817 }
1818
1819 Logger::instance().log("localtunnel", Logger::Level::Info,
1820 "sendImageChunks: done kind=" + std::string(kind == msg::ImageOwnerKind::Board ? "Board" : "Marker") +
1821 " id=" + std::to_string(id) + " total=" + std::to_string(img.size()));
1822 return true;
1823}
static constexpr int kPaceMillis
static constexpr int kPaceEveryN
std::vector< uint8_t > buildImageChunkFrame(uint8_t ownerKind, uint64_t id, uint64_t offset, const uint8_t *data, size_t len)
static constexpr size_t kChunk
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendMarker()

void NetworkManager::sendMarker ( uint64_t boardId,
const flecs::entity & marker,
const std::vector< std::string > & toPeerIds )

Definition at line 1741 of file NetworkManager.cpp.

1742{
1743 const TextureComponent* tex = marker.get<TextureComponent>();
1744 auto image_path = tex->image_path;
1745 Logger::instance().log("localtunnel", Logger::Level::Info, "Marker Path: " + image_path);
1746 auto is_file_only = PathManager::isFilenameOnly(tex->image_path);
1747 auto is_path_like = PathManager::isPathLike(tex->image_path);
1748 if (is_file_only || !is_path_like)
1749 {
1750 Logger::instance().log("localtunnel", Logger::Level::Info, "Marker Path is FILE ONLY");
1751 auto marker_folder = PathManager::getMarkersPath();
1752 auto image_path_ = marker_folder / tex->image_path;
1753 image_path = image_path_.string();
1754 }
1755 Logger::instance().log("localtunnel", Logger::Level::Info, "Marker Path Again: " + image_path);
1756 std::vector<unsigned char> img = tex ? readFileBytes(image_path) : std::vector<unsigned char>{};
1757 Logger::instance().log("localtunnel", Logger::Level::Info, "Marker Texture Byte Size: " + std::to_string(img.size()));
1758 // 1) meta
1759 auto meta = buildCreateMarkerFrame(boardId, marker, static_cast<uint64_t>(img.size()));
1760 broadcastGameFrame(meta, toPeerIds);
1761
1762 // 2) image chunks (ownerKind=1 for marker)
1763 uint64_t mid = marker.get<Identifier>()->id;
1764 sendImageChunks(msg::ImageOwnerKind::Marker, mid, img, toPeerIds);
1765 //uint64_t off = 0;
1766 //while (off < img.size())
1767 //{
1768 // size_t chunk = std::min<size_t>(kChunk, img.size() - off);
1769 // auto frame = buildImageChunkFrame(/*ownerKind=*/1, mid, off, img.data() + off, chunk);
1770 // Logger::instance().log("localtunnel", Logger::Level::Info, "Marker Texture Byte Size: " + img.size());
1771 // broadcastGameFrame(frame, toPeerIds);
1772 // off += chunk;
1773 //}
1774
1775 // 3) commit
1776 auto commit = buildCommitMarkerFrame(boardId, mid);
1777 broadcastGameFrame(commit, toPeerIds);
1778}
std::vector< uint8_t > buildCommitMarkerFrame(uint64_t boardId, uint64_t markerId)
std::vector< uint8_t > buildCreateMarkerFrame(uint64_t boardId, const flecs::entity &marker, uint64_t imageBytesTotal)
static fs::path getMarkersPath()
Definition PathManager.h:66
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendMarkerDelete()

void NetworkManager::sendMarkerDelete ( uint64_t boardId,
const flecs::entity & marker,
const std::vector< std::string > & toPeerIds )

Definition at line 1656 of file NetworkManager.cpp.

1658{
1659 if (!marker.is_valid() || !marker.has<Identifier>())
1660 return;
1661
1662 const uint64_t mid = marker.get<Identifier>()->id;
1663 auto frame = buildMarkerDeleteFrame(boardId, mid);
1664 broadcastGameFrame(frame, toPeerIds);
1665}
std::vector< unsigned char > buildMarkerDeleteFrame(uint64_t boardId, uint64_t markerId)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendMarkerMove()

void NetworkManager::sendMarkerMove ( uint64_t boardId,
const flecs::entity & marker,
const std::vector< std::string > & toPeerIds )

Definition at line 1393 of file NetworkManager.cpp.

1394{
1395 if (!marker.is_valid() || !marker.has<Identifier>() || !marker.has<Position>())
1396 return;
1397
1398 const uint64_t markerId = marker.get<Identifier>()->id;
1399
1400 // per-drag local seq in DragState
1401 auto& s = drag_[markerId];
1402 if (s.locallyProposedEpoch == 0 && s.epoch == 0)
1403 {
1404 s.locallyProposedEpoch = s.epoch + 1;
1405 s.epoch = s.locallyProposedEpoch;
1406 }
1407 const uint32_t seq = ++s.localSeq;
1408 s.lastTxMs = nowMs();
1409
1410 auto frame = buildMarkerMoveFrame(boardId, marker, seq);
1411 if (frame.empty())
1412 return;
1413
1414 for (auto& pid : toPeerIds)
1415 {
1416 if (auto it = peers.find(pid); it != peers.end() && it->second)
1417 it->second->sendMarkerMove(frame);
1418 }
1419}
std::vector< unsigned char > buildMarkerMoveFrame(uint64_t boardId, const flecs::entity &marker, uint32_t seq)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendMarkerMoveState()

void NetworkManager::sendMarkerMoveState ( uint64_t boardId,
const flecs::entity & marker,
const std::vector< std::string > & toPeerIds )

Definition at line 1428 of file NetworkManager.cpp.

1429{
1430 if (!marker.is_valid() || !marker.has<Identifier>() || !marker.has<Moving>())
1431 return;
1432
1433 auto frame = buildMarkerMoveStateFrame(boardId, marker);
1434 if (frame.empty())
1435 return;
1436
1437 // Reliable: use your game channel
1438 broadcastGameFrame(frame, toPeerIds);
1439}
std::vector< unsigned char > buildMarkerMoveStateFrame(uint64_t boardId, const flecs::entity &marker)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendMarkerUpdate()

void NetworkManager::sendMarkerUpdate ( uint64_t boardId,
const flecs::entity & marker,
const std::vector< std::string > & toPeerIds )

Definition at line 1503 of file NetworkManager.cpp.

1505{
1506 if (!marker.is_valid() || !marker.has<Identifier>())
1507 return;
1508
1509 auto frame = buildMarkerUpdateFrame(boardId, marker);
1510 broadcastGameFrame(frame, toPeerIds);
1511}
std::vector< unsigned char > buildMarkerUpdateFrame(uint64_t boardId, const flecs::entity &marker)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ sendUserNameUpdateTo()

void NetworkManager::sendUserNameUpdateTo ( const std::string & peerId,
const std::vector< uint8_t > & payload )

Definition at line 1058 of file NetworkManager.cpp.

1060{
1061 auto it = peers.find(peerId);
1062 if (it == peers.end() || !it->second)
1063 return;
1064
1065 std::vector<uint8_t> frame;
1066 frame.reserve(1 + payload.size());
1067 frame.push_back((uint8_t)msg::DCType::UserNameUpdate);
1068 frame.insert(frame.end(), payload.begin(), payload.end());
1069
1070 it->second->sendOn(msg::dc::name::Game, frame);
1071}
Here is the caller graph for this function:

◆ setCustomHost()

void NetworkManager::setCustomHost ( const std::string & h)
inline

Definition at line 299 of file NetworkManager.h.

299{ customHost_ = h; }

◆ setGMId()

void NetworkManager::setGMId ( const std::string & id)
inline

Definition at line 225 of file NetworkManager.h.

226 {
227 gmPeerId_ = id;
228 }

◆ setMyPeerId()

void NetworkManager::setMyPeerId ( std::string v)
inline

Definition at line 153 of file NetworkManager.h.

154 {
155 myPeerId_ = std::move(v);
156 }

◆ setNetworkPassword()

void NetworkManager::setNetworkPassword ( const char * password)

Definition at line 462 of file NetworkManager.cpp.

463{
464 strncpy(network_password, password, sizeof(network_password) - 1);
465 network_password[sizeof(network_password) - 1] = '\0';
466}
Here is the caller graph for this function:

◆ setPort()

void NetworkManager::setPort ( unsigned int port)
inline

Definition at line 103 of file NetworkManager.h.

104 {
105 this->port = port;
106 }
Here is the caller graph for this function:

◆ setToaster()

void NetworkManager::setToaster ( std::shared_ptr< ImGuiToaster > t)
inline

Definition at line 208 of file NetworkManager.h.

209 {
210 toaster_ = t;
211 }

◆ setup()

void NetworkManager::setup ( std::weak_ptr< BoardManager > board_manager,
std::weak_ptr< GameTableManager > gametable_manager )

Definition at line 23 of file NetworkManager.cpp.

24{
27
28 signalingClient = std::make_shared<SignalingClient>(weak_from_this());
29 signalingServer = std::make_shared<SignalingServer>(weak_from_this());
30
32 [this]() -> std::string
33 {
35 Logger::instance().log("localtunnel", Logger::Level::Debug, "Starting with runic-" + ip + ":" + std::to_string(port));
36 return NetworkUtilities::startLocalTunnel("runic-" + ip, port);
37 },
38 [this]()
39 {
41 Logger::instance().log("localtunnel", Logger::Level::Info, "Stop requested");
42 });
43 DebugConsole::setIdentityLogger([this]() -> std::string
44 { return debugIdentitySnapshot(); });
45}
static void setLocalTunnelHandlers(std::function< std::string()> startHandler, std::function< void()> stopHandler)
static void setIdentityLogger(std::function< std::string()> identityLogger)
std::string debugIdentitySnapshot() const
static std::string startLocalTunnel(const std::string &subdomainBase, int port)
Here is the call graph for this function:

◆ shouldApplyMarkerMove()

bool NetworkManager::shouldApplyMarkerMove ( const msg::ReadyMessage & m)

Definition at line 1513 of file NetworkManager.cpp.

1514{
1515 if (!m.markerId || !m.dragEpoch)
1516 return false;
1517 auto& s = drag_[*m.markerId];
1518
1519 // Epoch
1520 if (*m.dragEpoch < s.epoch)
1521 return false;
1522 if (*m.dragEpoch > s.epoch)
1523 {
1524 s.epoch = *m.dragEpoch;
1525 s.closed = false;
1526 s.lastSeq = 0;
1527 s.ownerPeerId = m.fromPeerId;
1528 }
1529 else
1530 {
1531 if (s.closed)
1532 return false;
1533 if (!s.ownerPeerId.empty() && s.ownerPeerId != m.fromPeerId)
1534 {
1535 if (!tieBreakWins(m.fromPeerId, s.ownerPeerId))
1536 return false;
1537 s.ownerPeerId = m.fromPeerId;
1538 if (s.locallyDragging)
1539 {
1540 s.locallyDragging = false;
1541 s.localSeq = 0;
1542 }
1543 }
1544 else
1545 {
1546 s.ownerPeerId = m.fromPeerId; // first owner for this epoch
1547 }
1548 }
1549
1550 // Seq
1551 if (m.seq && *m.seq <= s.lastSeq)
1552 return false;
1553 if (m.seq)
1554 s.lastSeq = *m.seq;
1555
1556 // Local echo suppression while we drag
1557 if (s.locallyDragging)
1558 return false;
1559
1560 return true;
1561}
static bool tieBreakWins(const std::string &challengerPeerId, const std::string &currentOwnerPeerId)
Here is the call graph for this function:

◆ shouldApplyMarkerMoveStateFinal()

bool NetworkManager::shouldApplyMarkerMoveStateFinal ( const msg::ReadyMessage & m)

Definition at line 1607 of file NetworkManager.cpp.

1608{
1609 if (!m.markerId || !m.dragEpoch || !m.mov || m.mov->isDragging)
1610 return false;
1611 auto& s = drag_[*m.markerId];
1612
1613 if (*m.dragEpoch < s.epoch)
1614 return false;
1615 if (*m.dragEpoch > s.epoch)
1616 {
1617 s.epoch = *m.dragEpoch;
1618 s.closed = false;
1619 s.lastSeq = 0;
1620 s.ownerPeerId = m.fromPeerId;
1621 }
1622 else
1623 {
1624 if (s.closed)
1625 return false;
1626 if (!s.ownerPeerId.empty() && s.ownerPeerId != m.fromPeerId)
1627 {
1628 if (!tieBreakWins(m.fromPeerId, s.ownerPeerId))
1629 return false;
1630 s.ownerPeerId = m.fromPeerId;
1631 if (s.locallyDragging)
1632 {
1633 s.locallyDragging = false;
1634 s.localSeq = 0;
1635 }
1636 }
1637 else
1638 {
1639 s.ownerPeerId = m.fromPeerId;
1640 }
1641 if (m.seq && *m.seq < s.lastSeq)
1642 return false;
1643 if (m.seq && *m.seq >= s.lastSeq)
1644 s.lastSeq = *m.seq;
1645 }
1646
1647 // finalize epoch
1648 s.closed = true;
1649 s.locallyDragging = false;
1650 s.localSeq = 0;
1651
1652 return true;
1653}
Here is the call graph for this function:

◆ shouldApplyMarkerMoveStateStart()

bool NetworkManager::shouldApplyMarkerMoveStateStart ( const msg::ReadyMessage & m)

Definition at line 1563 of file NetworkManager.cpp.

1564{
1565 if (!m.markerId || !m.dragEpoch || !m.mov || !m.mov->isDragging)
1566 return false;
1567 auto& s = drag_[*m.markerId];
1568
1569 if (*m.dragEpoch < s.epoch)
1570 return false;
1571 if (*m.dragEpoch > s.epoch)
1572 {
1573 s.epoch = *m.dragEpoch;
1574 s.closed = false;
1575 s.lastSeq = 0;
1576 s.ownerPeerId = m.fromPeerId;
1577 }
1578 else
1579 {
1580 if (s.closed)
1581 return false;
1582 if (!s.ownerPeerId.empty() && s.ownerPeerId != m.fromPeerId)
1583 {
1584 if (!tieBreakWins(m.fromPeerId, s.ownerPeerId))
1585 return false;
1586 s.ownerPeerId = m.fromPeerId;
1587 if (s.locallyDragging)
1588 {
1589 s.locallyDragging = false;
1590 s.localSeq = 0;
1591 }
1592 }
1593 else
1594 {
1595 s.ownerPeerId = m.fromPeerId;
1596 }
1597 }
1598
1599 if (m.seq && *m.seq <= s.lastSeq)
1600 return false;
1601 if (m.seq)
1602 s.lastSeq = *m.seq;
1603
1604 return true;
1605}
Here is the call graph for this function:

◆ ShowPortForwardingHelpPopup()

void NetworkManager::ShowPortForwardingHelpPopup ( bool * p_open)

Definition at line 469 of file NetworkManager.cpp.

470{
471 if (*p_open)
472 {
473 ImGui::OpenPopup("Port Forwarding Failed");
474 }
475
476 if (ImGui::BeginPopupModal("Port Forwarding Failed", p_open, ImGuiWindowFlags_AlwaysAutoResize))
477 {
478 ImGui::Text("Automatic port forwarding failed. This is likely because your router does not\n"
479 "support UPnP or it is disabled. You can still host by choosing one of the\n"
480 "following three options:");
481
482 ImGui::Separator();
483
484 if (ImGui::BeginTabBar("PortOptions"))
485 {
486
487 // Tab 1: Enable UPnP
488 if (ImGui::BeginTabItem("Enable UPnP"))
489 {
490 ImGui::Text("This is the easiest solution and will allow automatic port forwarding to work.");
491 ImGui::Spacing();
492 ImGui::BulletText("Access your router's administration page. This is usually done by\n"
493 "typing its IP address (e.g., 192.168.1.1) in your browser.");
494 ImGui::BulletText("Log in with your router's credentials.");
495 ImGui::BulletText("Look for a setting named 'UPnP' or 'Universal Plug and Play' and enable it.");
496 ImGui::BulletText("Save the settings and restart your router if necessary.");
497 ImGui::BulletText("Try hosting again. The application should now automatically forward the port.");
498 ImGui::EndTabItem();
499 }
500
501 // Tab 2: Manual Port Forwarding
502 if (ImGui::BeginTabItem("Manual Port Forwarding"))
503 {
504 ImGui::Text("This method always works but requires you to configure your router manually.");
505 ImGui::Spacing();
506 ImGui::BulletText("Find your local IP address. Open Command Prompt and type 'ipconfig' to find it\n"
507 "(e.g., 192.168.1.100).");
508 ImGui::BulletText("Access your router's administration page.");
509 ImGui::BulletText("Look for a setting named 'Port Forwarding', 'Virtual Server', or 'NAT'.");
510 ImGui::BulletText("Create a new rule with the following details:");
511 ImGui::Indent();
512 ImGui::BulletText("Protocol: TCP");
513 ImGui::BulletText("Internal Port: [Your application's port, e.g., 8080]");
514 ImGui::BulletText("External Port: [The same port]");
515 ImGui::BulletText("Internal IP: [Your local IP from step 1]");
516 ImGui::Unindent();
517 ImGui::BulletText("Save the rule and try hosting again.");
518 ImGui::EndTabItem();
519 }
520
521 // Tab 3: Use a VPN (Hamachi)
522 if (ImGui::BeginTabItem("Use a VPN (Hamachi)"))
523 {
524 ImGui::Text("A VPN creates a virtual local network, bypassing the need for port forwarding.");
525 ImGui::Spacing();
526 ImGui::BulletText("Download and install a VPN client like Hamachi.");
527 ImGui::BulletText("Create a new network within the VPN client.");
528 ImGui::BulletText("Share the network name and password with your friends.");
529 ImGui::BulletText("Instruct your friends to join your network.");
530 ImGui::BulletText("On the host screen, you should be able to see your VPN IP address.\n"
531 "Use this IP to host your session.");
532 ImGui::EndTabItem();
533 }
534
535 ImGui::EndTabBar();
536 }
537
538 if (ImGui::Button("Close"))
539 {
540 *p_open = false;
541 ImGui::CloseCurrentPopup();
542 }
543
544 ImGui::EndPopup();
545 }
546}

◆ startRawDrainWorker()

void NetworkManager::startRawDrainWorker ( )

Definition at line 2502 of file NetworkManager.cpp.

2503{
2504 bool expected = false;
2505 if (!rawWorkerRunning_.compare_exchange_strong(expected, true))
2506 return; // already running
2507
2508 rawWorkerStop_.store(false);
2509 rawWorker_ = std::thread([this]()
2510 {
2511 using clock = std::chrono::steady_clock;
2512 auto lastFlush = clock::now();
2513 for (;;) {
2514 if (rawWorkerStop_.load())
2515 break;
2516
2517 bool didWork = false;
2518
2520 if (inboundRaw_.try_pop(r)) {
2521 try {
2522 if (r.label == msg::dc::name::Game) {
2523 decodeRawGameBuffer(r.fromPeer, r.bytes);
2524 } else if (r.label == msg::dc::name::Chat) {
2525 decodeRawChatBuffer(r.fromPeer, r.bytes);
2526 } else if (r.label == msg::dc::name::Notes) {
2527 decodeRawNotesBuffer(r.fromPeer, r.bytes);
2528 } else if (r.label == msg::dc::name::MarkerMove) {
2529 decodeRawMarkerMoveBuffer(r.fromPeer, r.bytes);
2530 }
2531 } catch (...) {
2532 // swallow
2533 }
2534 didWork = true;
2535 }
2536
2537 } });
2538}
std::atomic< bool > rawWorkerRunning_
std::thread rawWorker_
std::atomic< bool > rawWorkerStop_
Here is the call graph for this function:

◆ startServer() [1/2]

void NetworkManager::startServer ( ConnectionType mode,
unsigned short port,
bool tryUpnp )

Definition at line 123 of file NetworkManager.cpp.

124{
126
127 if (!signalingServer)
128 signalingServer = std::make_shared<SignalingServer>(shared_from_this());
129 if (!signalingClient)
130 signalingClient = std::make_shared<SignalingClient>(shared_from_this());
131
132 // Bind WS to all interfaces (overlay/LAN/etc.)
133 signalingServer->start(port);
134 setPort(port);
135
136 const std::string localIp = getLocalIPAddress();
137
138 // Mode-specific side effects (no client connect here)
139 switch (mode)
140 {
142 {
143 // Expose to the world; GM still connects locally below
144 try {
145 (void)NetworkUtilities::startLocalTunnel("runic-" + localIp, static_cast<int>(port));
146 } catch (...) {
147 pushStatusToast("LocalTunnel failed to start.", ImGuiToaster::Level::Error, 4);
148 }
149 break;
150 }
151
153 {
154 if (tryUpnp)
155 {
156 try
157 {
158 (void)UPnPManager::addPortMapping(localIp, port, port, "TCP", "RunicVTT");
159 }
160 catch (...)
161 {
162 pushStatusToast("UPnP port mapping failed — check router config.", ImGuiToaster::Level::Error, 4);
163 }
164 }
165 // Players will connect via public IP:port; GM still connects locally below
166 break;
167 }
168
171 default:
172 // No special side-effect needed; GM still connects locally below
173 break;
174 }
175
176 // GM always connects locally to the server it just started.
177 signalingClient->connect("127.0.0.1", port);
178
179 pushStatusToast("Signalling Server Started!!", ImGuiToaster::Level::Good, 4);
180 // startRawDrainWorker(); // if/when you want it
181}
void setPort(unsigned int port)
static bool addPortMapping(const std::string &internalIp, unsigned short internalPort, unsigned short externalPort, const std::string &protocol, const std::string &description="", unsigned int duration=0)
Definition UPnPManager.h:60
Here is the call graph for this function:
Here is the caller graph for this function:

◆ startServer() [2/2]

void NetworkManager::startServer ( std::string internal_ip_address,
unsigned short port )

Definition at line 301 of file NetworkManager.cpp.

302{
303 // Old default used LocalTunnel; keep that behavior
304 startServer(ConnectionType::LOCALTUNNEL, port, /*tryUpnp=*/false);
305}
void startServer(ConnectionType mode, unsigned short port, bool tryUpnp)
Here is the call graph for this function:

◆ stopRawDrainWorker()

void NetworkManager::stopRawDrainWorker ( )

Definition at line 2540 of file NetworkManager.cpp.

2541{
2542 if (!rawWorkerRunning_.load())
2543 return;
2544 rawWorkerStop_.store(true);
2545 if (rawWorker_.joinable())
2546 rawWorker_.join();
2547 rawWorkerRunning_.store(false);
2548}

◆ tieBreakWins()

static bool NetworkManager::tieBreakWins ( const std::string & challengerPeerId,
const std::string & currentOwnerPeerId )
inlinestaticprivate

Definition at line 327 of file NetworkManager.h.

328 {
329 return challengerPeerId < currentOwnerPeerId;
330 }
Here is the caller graph for this function:

◆ tryFinalizeImage()

void NetworkManager::tryFinalizeImage ( msg::ImageOwnerKind kind,
uint64_t id )
private

Definition at line 2589 of file NetworkManager.cpp.

2590{
2591 auto it = imagesRx_.find(id);
2592 if (it == imagesRx_.end())
2593 return;
2594 auto& p = it->second;
2595 if (!p.commitRequested || !p.isComplete())
2596 return;
2597
2599 if (kind == msg::ImageOwnerKind::Board)
2600 {
2601 if (!p.boardMeta)
2602 return; // need meta
2604 m.boardId = p.boardMeta->boardId;
2605 m.boardMeta = p.boardMeta;
2606 }
2607 else
2608 {
2609 if (!p.markerMeta)
2610 return; // need meta
2612 m.boardId = p.boardId; // for markers we also stored the boardId
2613 m.markerMeta = p.markerMeta;
2614 }
2615 m.bytes = std::move(p.buf);
2616 inboundGame_.push(std::move(m));
2617
2618 Logger::instance().log("localtunnel", Logger::Level::Info,
2619 std::string("tryFinalizeImage: finalized ") +
2620 (kind == msg::ImageOwnerKind::Board ? "Board" : "Marker") +
2621 " id=" + std::to_string(id));
2622
2623 imagesRx_.erase(it);
2624}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tryPopRawMessage()

bool NetworkManager::tryPopRawMessage ( msg::InboundRaw & out)
inline

Definition at line 172 of file NetworkManager.h.

173 {
174 return inboundRaw_.try_pop(out);
175 }
Here is the call graph for this function:

◆ tryPopReadyMessage()

bool NetworkManager::tryPopReadyMessage ( msg::ReadyMessage & out)
inline

Definition at line 167 of file NetworkManager.h.

168 {
169 return inboundGame_.try_pop(out);
170 }
Here is the call graph for this function:

◆ upsertPeerIdentityWithUnique()

void NetworkManager::upsertPeerIdentityWithUnique ( const std::string & peerId,
const std::string & uniqueId,
const std::string & username )

Definition at line 761 of file NetworkManager.cpp.

764{
765 identity_manager->bindPeer(/*peerId=*/peerId,
766 /*uniqueId=*/uniqueId,
767 /*username=*/username);
768
769 if (auto it = peers.find(peerId); it != peers.end() && it->second)
770 it->second->setDisplayName(username);
771}

Member Data Documentation

◆ board_manager

std::weak_ptr<BoardManager> NetworkManager::board_manager
private

Definition at line 399 of file NetworkManager.h.

◆ customHost_

std::string NetworkManager::customHost_
private

Definition at line 303 of file NetworkManager.h.

◆ decodingFromPeer_

std::string NetworkManager::decodingFromPeer_
private

Definition at line 310 of file NetworkManager.h.

◆ drag_

std::unordered_map<uint64_t , DragState> NetworkManager::drag_

Definition at line 293 of file NetworkManager.h.

◆ ecs

flecs::world NetworkManager::ecs
private

Definition at line 388 of file NetworkManager.h.

◆ events_

MessageQueue<msg::NetEvent> NetworkManager::events_

Definition at line 219 of file NetworkManager.h.

◆ external_ip_address

std::string NetworkManager::external_ip_address = ""
private

Definition at line 391 of file NetworkManager.h.

◆ gametable_manager

std::weak_ptr<GameTableManager> NetworkManager::gametable_manager
private

Definition at line 400 of file NetworkManager.h.

◆ gmPeerId_

std::string NetworkManager::gmPeerId_
private

Definition at line 386 of file NetworkManager.h.

◆ identity_manager

std::shared_ptr<IdentityManager> NetworkManager::identity_manager
private

Definition at line 347 of file NetworkManager.h.

◆ imagesRx_

std::unordered_map<uint64_t, PendingImage> NetworkManager::imagesRx_
private

Definition at line 340 of file NetworkManager.h.

◆ inboundGame_

MessageQueue<msg::ReadyMessage> NetworkManager::inboundGame_
private

Definition at line 341 of file NetworkManager.h.

◆ inboundRaw_

MessageQueue<msg::InboundRaw> NetworkManager::inboundRaw_

Definition at line 220 of file NetworkManager.h.

◆ kChunk

constexpr size_t NetworkManager::kChunk = 8 * 1024
staticconstexprprivate

Definition at line 349 of file NetworkManager.h.

◆ kPaceEveryN

constexpr int NetworkManager::kPaceEveryN = 48
staticconstexprprivate

Definition at line 352 of file NetworkManager.h.

◆ kPaceMillis

constexpr int NetworkManager::kPaceMillis = 2
staticconstexprprivate

Definition at line 353 of file NetworkManager.h.

◆ local_ip_address

std::string NetworkManager::local_ip_address = ""
private

Definition at line 392 of file NetworkManager.h.

◆ myPeerId_

std::string NetworkManager::myPeerId_
private

Definition at line 385 of file NetworkManager.h.

◆ network_password

char NetworkManager::network_password[124] = "\0"
private

Definition at line 390 of file NetworkManager.h.

◆ peer_role

Role NetworkManager::peer_role
private

Definition at line 393 of file NetworkManager.h.

◆ peers

std::unordered_map<std::string, std::shared_ptr<PeerLink> > NetworkManager::peers
private

Definition at line 398 of file NetworkManager.h.

◆ port

unsigned int NetworkManager::port = 8080
private

Definition at line 389 of file NetworkManager.h.

◆ rawWorker_

std::thread NetworkManager::rawWorker_
private

Definition at line 345 of file NetworkManager.h.

◆ rawWorkerRunning_

std::atomic<bool> NetworkManager::rawWorkerRunning_ {false}
private

Definition at line 343 of file NetworkManager.h.

343{false};

◆ rawWorkerStop_

std::atomic<bool> NetworkManager::rawWorkerStop_ {false}
private

Definition at line 344 of file NetworkManager.h.

344{false};

◆ rtcConfig

rtc::Configuration NetworkManager::rtcConfig
private

Definition at line 395 of file NetworkManager.h.

◆ sendMoveMinPeriodMs_

uint32_t NetworkManager::sendMoveMinPeriodMs_ {50}
private

Definition at line 311 of file NetworkManager.h.

311{50}; // pacing target (~20Hz)

◆ signalingClient

std::shared_ptr<SignalingClient> NetworkManager::signalingClient
private

Definition at line 397 of file NetworkManager.h.

◆ signalingServer

std::shared_ptr<SignalingServer> NetworkManager::signalingServer
private

Definition at line 396 of file NetworkManager.h.

◆ toaster_

std::shared_ptr<ImGuiToaster> NetworkManager::toaster_
private

Definition at line 348 of file NetworkManager.h.


The documentation for this class was generated from the following files: