Skip to content

Instantly share code, notes, and snippets.

@asymingt
Created February 6, 2023 04:50
Show Gist options
  • Save asymingt/3440ce86c6f06e9761da2e6d02ea8793 to your computer and use it in GitHub Desktop.
Save asymingt/3440ce86c6f06e9761da2e6d02ea8793 to your computer and use it in GitHub Desktop.
Tracy muxer WIP: Native version
#include <common/TracyProtocol.hpp>
#include <common/TracyVersion.hpp>
#include <common/TracySocket.hpp>
#include <chrono>
#include <iostream>
#include <string>
#include <memory>
#include <cstdlib>
#include <cstring>
#include <unordered_map>
struct ClientData {
int64_t time;
uint32_t protocolVersion;
int32_t activeTime;
uint16_t port;
uint64_t pid;
std::string procName;
std::string address;
};
int main(int argc, char* argv[]) {
std::cout << "Starting listener..." << std::endl;
const auto timestamp_ms = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch() ).count();
static std::unique_ptr<tracy::UdpListen> broadcastListen =
std::make_unique<tracy::UdpListen>();
if (!broadcastListen->Listen(8086)) {
broadcastListen.reset();
return 1;
}
std::unordered_map<uint64_t, ClientData> clients;
tracy::IpAddress addr;
size_t len;
for (;;) {
auto msg = broadcastListen->Read(len, addr, 0);
if (!msg) continue;
if (len > sizeof(tracy::BroadcastMessage)) continue;
uint16_t broadcastVersion;
memcpy(&broadcastVersion, msg, sizeof(uint16_t));
if (broadcastVersion <= tracy::BroadcastVersion) {
uint32_t protoVer;
char procname[tracy::WelcomeMessageProgramNameSize];
int32_t activeTime;
uint16_t listenPort;
uint64_t pid;
switch (broadcastVersion) {
case 3: {
tracy::BroadcastMessage bm;
memcpy(&bm, msg, len);
protoVer = bm.protocolVersion;
strcpy(procname, bm.programName);
activeTime = bm.activeTime;
listenPort = bm.listenPort;
pid = bm.pid;
break;
}
case 2: {
if (len > sizeof(tracy::BroadcastMessage_v2)) continue;
tracy::BroadcastMessage_v2 bm;
memcpy(&bm, msg, len);
protoVer = bm.protocolVersion;
strcpy(procname, bm.programName);
activeTime = bm.activeTime;
listenPort = bm.listenPort;
pid = 0;
break;
}
case 1: {
if (len > sizeof(tracy::BroadcastMessage_v1)) continue;
tracy::BroadcastMessage_v1 bm;
memcpy(&bm, msg, len);
protoVer = bm.protocolVersion;
strcpy(procname, bm.programName);
activeTime = bm.activeTime;
listenPort = bm.listenPort;
pid = 0;
break;
}
case 0: {
if (len > sizeof(tracy::BroadcastMessage_v0)) continue;
tracy::BroadcastMessage_v0 bm;
memcpy(&bm, msg, len);
protoVer = bm.protocolVersion;
strcpy(procname, bm.programName);
activeTime = bm.activeTime;
listenPort = 8086;
pid = 0;
break;
}
default:
std::cout << "Bad broadcast version. Skipping client." << std::endl;
continue;
}
std::cout << "Adding client with procName " << procname << std::endl;
auto address = addr.GetText();
const auto ipNumerical = addr.GetNumber();
const auto clientId = uint64_t(ipNumerical) | (uint64_t(listenPort) << 32);
auto it = clients.find(clientId);
if (activeTime >= 0) {
if (it == clients.end()) {
clients.emplace(
clientId, ClientData{
timestamp_ms, protoVer, activeTime, listenPort, pid, procname, addr.GetText()});
} else {
it->second.time = timestamp_ms;
it->second.activeTime = activeTime;
it->second.port = listenPort;
it->second.pid = pid;
it->second.protocolVersion = protoVer;
if (strcmp(it->second.procName.c_str(), procname) != 0)
it->second.procName = procname;
}
} else if (it != clients.end()) {
clients.erase(it);
}
}
// Collect from the clients
// collect_from_clients(clients);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment