From 7c6bd9e76adccf503f3f7c485247b410f159de13 Mon Sep 17 00:00:00 2001 From: benaclejames Date: Thu, 11 Aug 2022 02:03:41 +0100 Subject: [PATCH] More cleanup, added recv loop and destructor to socket. Added incoming data parser to osc --- CMakeLists.txt | 1 + obsc.cpp | 50 ++++------------------------------------------- osc_message.cpp | 18 +++++++++++++++-- osc_message.h | 2 ++ socket_helper.cpp | 22 +++++++++++++++------ socket_helper.h | 5 ++++- 6 files changed, 43 insertions(+), 55 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 250e2e1..95d7668 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,5 @@ # OBSC/CMakeLists.txt +cmake_minimum_required(VERSION 3.23) project(OBSC) diff --git a/obsc.cpp b/obsc.cpp index 8fe9fa7..ae13cab 100644 --- a/obsc.cpp +++ b/obsc.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include "stored.h" #include "socket_helper.h" @@ -11,40 +10,6 @@ OBS_DECLARE_MODULE() socket_helper* sockets; stored stored; -std::thread* osc_thread; - -int create_osc_bool_message(char* message, const char* address, bool value) { - int len = strlen(address)+1; - int paddedLen = len + 4 - len % 4; - memcpy(message, address, paddedLen); - - message[paddedLen++] = ','; - message[paddedLen++] = value ? 'T' : 'F'; - message[paddedLen++] = '\0'; - message[paddedLen++] = '\0'; - - return paddedLen; -} - -int create_osc_int_message(char* message, const char* address, int value) { - int len = strlen(address)+1; - int paddedLen = len + 4 - len % 4; - memcpy(message, address, paddedLen); - - message[paddedLen++] = ','; - message[paddedLen++] = 'i'; - message[paddedLen++] = '\0'; - message[paddedLen++] = '\0'; - - // Convert value from big endian to little endian and copy to message - char* valuePtr = (char*)&value; - message[paddedLen++] = valuePtr[3]; - message[paddedLen++] = valuePtr[2]; - message[paddedLen++] = valuePtr[1]; - message[paddedLen++] = valuePtr[0]; - - return paddedLen; -} void update_osc() { @@ -75,28 +40,21 @@ void frontend_cb(enum obs_frontend_event event, void *priv_data) break; case OBS_FRONTEND_EVENT_EXIT: - osc_thread->detach(); - delete osc_thread; + delete sockets; break; } } -void periodic_update_loop() -{ - while (true) - { - std::this_thread::sleep_for(std::chrono::seconds(5)); +void on_update_recv(osc_message message) { + if (strcmp(message.address, "/avatar/change") == 0) update_osc(); - } } bool obs_module_load() { - sockets = new socket_helper("127.0.0.1", 9001, 9000); + sockets = new socket_helper("127.0.0.1", 9001, 9000, on_update_recv); obs_frontend_add_event_callback(frontend_cb, nullptr); - // Start the osc update loop on a separate thread - osc_thread = new std::thread(periodic_update_loop); return true; } \ No newline at end of file diff --git a/osc_message.cpp b/osc_message.cpp index 680382a..a7fa252 100644 --- a/osc_message.cpp +++ b/osc_message.cpp @@ -1,6 +1,6 @@ #include "osc_message.h" -osc_message::osc_message(char* address, char type) +osc_message::osc_message(char* address, char type) : address(address), type(type) { int len = strlen(address)+1; writerIndex = quantize(len, 4); @@ -14,7 +14,21 @@ osc_message::osc_message(char* address, char type) osc_message::osc_message(char* data, int size) { - + // Read the address string + int len = strlen(data)+1; + address = new char[len]; + memcpy(address, data, len); + + // Offset the writerIndex by the address length quantized to 4 bytes + writerIndex = quantize(len, 4); + + // Ensure the next 2 bytes are a comma and the type + if (data[writerIndex++] != ',') { + throw "Invalid OSC message"; + } + + type = data[writerIndex++]; + writerIndex += 2; } osc_float_message::osc_float_message(char* address, float value): osc_message(address, 'f') diff --git a/osc_message.h b/osc_message.h index 5481f38..01ff8eb 100644 --- a/osc_message.h +++ b/osc_message.h @@ -21,6 +21,8 @@ class osc_message public: osc_message(char* data, int size); + char* address; + char type; int writerIndex; char message[256]; }; diff --git a/socket_helper.cpp b/socket_helper.cpp index 4d014a9..09cb7ab 100644 --- a/socket_helper.cpp +++ b/socket_helper.cpp @@ -1,4 +1,5 @@ #include "socket_helper.h" +#include "osc_message.h" #include @@ -12,18 +13,16 @@ void socket_helper::recv_loop() struct sockaddr_in SenderAddr; int SenderAddrSize = sizeof (SenderAddr); - printf("Receiving datagrams on %s\n", "127.0.0.1"); + blog(LOG_INFO,"Receiving datagrams"); while (true) { bytes_received = recvfrom(inSock, serverBuf, serverBufLen, 0 /* no flags*/, (SOCKADDR *) & SenderAddr, &SenderAddrSize); - if (bytes_received == SOCKET_ERROR) { - printf("recvfrom failed with error %d\n", WSAGetLastError()); - } - printf("recv bytes"); + osc_message msg = osc_message(serverBuf, bytes_received); + onMsgRecv(msg); } } -socket_helper::socket_helper(std::string ip, int inPort, int outPort) +socket_helper::socket_helper(std::string ip, int inPort, int outPort, void(*onMsgRecv)(osc_message)) : onMsgRecv(onMsgRecv) { WSAStartup(MAKEWORD(2,2), &data); @@ -37,8 +36,19 @@ socket_helper::socket_helper(std::string ip, int inPort, int outPort) inAddr.sin_port = htons(inPort); InetPton(AF_INET, ip.c_str(), &inAddr.sin_addr.s_addr); + inSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if(bind(inSock, (SOCKADDR*)&inAddr, sizeof(inAddr))) blog(LOG_ERROR, "[OBSC] Failed to bind in socket"); recvThread = new std::thread(&socket_helper::recv_loop, this); } + +socket_helper::~socket_helper() { + recvThread->detach(); + delete recvThread; + + closesocket(inSock); + closesocket(outSock); + WSACleanup(); +} diff --git a/socket_helper.h b/socket_helper.h index 8bb1e7f..6c5550b 100644 --- a/socket_helper.h +++ b/socket_helper.h @@ -3,6 +3,7 @@ #include #include #include +#include "osc_message.h" #pragma comment(lib,"WS2_32") @@ -12,10 +13,12 @@ class socket_helper SOCKADDR_IN outAddr, inAddr; SOCKET inSock, outSock; std::thread* recvThread; + void (*onMsgRecv)(osc_message); void recv_loop(); public: - socket_helper(std::string ip, int inPort, int outPort); + socket_helper(std::string ip, int inPort, int outPort, void(*onMsgRecv)(osc_message)); + ~socket_helper(); void send(char* data, int size) {