diff --git a/Plugin/Plugin.cpp b/Plugin/Plugin.cpp index 6562166..37d1993 100644 --- a/Plugin/Plugin.cpp +++ b/Plugin/Plugin.cpp @@ -9,6 +9,7 @@ #include "Plugin.h" #include "ClientMetaData.h" #include "RadioUpdate.h" +#include "RadioUpdateCommand.h" #include "json/json.h" #include @@ -34,7 +35,7 @@ static SimpleRadio::Plugin plugin; namespace SimpleRadio { const char* Plugin::NAME = "DCS-SimpleRadio"; - const char* Plugin::VERSION = "1.0.8"; + const char* Plugin::VERSION = "1.0.9"; const char* Plugin::AUTHOR = "Ciribob - GitHub.com/ciribob"; const char* Plugin::DESCRIPTION = "DCS-SimpleRadio "; const char* Plugin::COMMAND_KEYWORD = "sr"; @@ -69,8 +70,9 @@ namespace SimpleRadio //read registry key this->readSettings(); - this->acceptor = thread(&Plugin::UDPListener, this); + + this->udpCommandListener = thread(&Plugin::UDPCommandListener, this); } LPCWSTR Plugin::getConfigPath() @@ -128,6 +130,11 @@ namespace SimpleRadio { this->acceptor.join(); } + + if (this->udpCommandListener.joinable()) + { + this->udpCommandListener.join(); + } } void Plugin::setTeamSpeakFunctions(TS3Functions functions) @@ -776,8 +783,7 @@ namespace SimpleRadio SOCKADDR_IN SenderAddr; int SenderAddrSize = sizeof(SenderAddr); - int ByteReceived = 5; - char ch = 'Y'; + int ByteReceived = 0; char ReceiveBuf[768]; //maximum UDP Packet Size int BufLength = 768; @@ -940,6 +946,108 @@ namespace SimpleRadio // Back to the system } + void Plugin::UDPCommandListener() + { + WSADATA wsaData; + SOCKET ReceivingSocket; + + SOCKADDR_IN SenderAddr; + int SenderAddrSize = sizeof(SenderAddr); + int ByteReceived = 0; + + char ReceiveBuf[768]; //maximum UDP Packet Size + int BufLength = 768; + + struct ip_mreq mreq; + + // Initialize Winsock version 2.2 + if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + { + this->teamspeak.logMessage("WSAStartup failed with error", LogLevel_ERROR, Plugin::NAME, 0); + } + + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_port = htons(5060); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + ReceivingSocket = mksocket(&addr); + + /* use setsockopt() to request that the kernel join a multicast group */ + + if (this->switchToUnicast == false) + { + // store this IP address in sa: + inet_pton(AF_INET, "239.255.50.10", &(mreq.imr_multiaddr.s_addr)); + + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + if (setsockopt(ReceivingSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq)) < 0) { + this->teamspeak.logMessage("Error adding membership for Multicast - Check firewall!", LogLevel_ERROR, Plugin::NAME, 0); + + } + } + + while (this->listening) + { + + if (recvfromTimeOutUDP(ReceivingSocket, 2, 0) > 0) + { + + ByteReceived = recvfrom(ReceivingSocket, ReceiveBuf, BufLength, + 0, (SOCKADDR *)&SenderAddr, &SenderAddrSize); + if (ByteReceived > 0) + { + try + { + ReceiveBuf[ByteReceived - 1] = 0; //add terminator + + //only allow on FC3 aircraft + if (this->myClientData.hasRadio == false) + { + RadioUpdateCommand updateCommand = RadioUpdateCommand::deserialize(ReceiveBuf); + + if (updateCommand.radio >= 0) + { + //reset all the radios + this->teamSpeakControlledClientData.radio[updateCommand.radio].frequency += updateCommand.freq; + } + } + + + + } + catch (...) + { + //ERROR!? + } + + memset(&ReceiveBuf[0], 0, sizeof(ReceiveBuf)); + } + + } + } + + + // When your application is finished receiving datagrams close the socket. + //printf("Server: Finished receiving. Closing the listening socket...\n"); + if (closesocket(ReceivingSocket) != 0) + { + this->teamspeak.logMessage("Closesocket failed!", LogLevel_ERROR, Plugin::NAME, 0); + } + //printf("Server: closesocket() failed! Error code: %ld\n", WSAGetLastError()); + + + // When your application is finished call WSACleanup. + //printf("Server: Cleaning up...\n"); + if (WSACleanup() != 0) + { + //printf("Server: WSACleanup() failed! Error code: %ld\n", WSAGetLastError()); + this->teamspeak.logMessage(" WSACleanup() failed!", LogLevel_ERROR, Plugin::NAME, 0); + } + // Back to the system + } + } /* Unique name identifying this plugin */ diff --git a/Plugin/Plugin.h b/Plugin/Plugin.h index b0284f8..b228e83 100644 --- a/Plugin/Plugin.h +++ b/Plugin/Plugin.h @@ -68,12 +68,16 @@ namespace SimpleRadio SOCKET mksocket(struct sockaddr_in *addr); void UDPListener(); + + void UDPCommandListener(); volatile bool debug; volatile bool listening; std::thread acceptor; + std::thread udpCommandListener; + bool allowNonPlayers; bool switchToUnicast; diff --git a/Plugin/Plugin.vcxproj b/Plugin/Plugin.vcxproj index 34cbcc9..e09777b 100644 --- a/Plugin/Plugin.vcxproj +++ b/Plugin/Plugin.vcxproj @@ -206,6 +206,7 @@ true WIN32;NDEBUG;_WINDOWS;_USRDLL;PLUGIN_EXPORTS;%(PreprocessorDefinitions) $(SolutionDir)DSPFilters\include;%(AdditionalIncludeDirectories) + MultiThreaded Windows @@ -256,6 +257,7 @@ + @@ -267,6 +269,7 @@ + diff --git a/Plugin/Plugin.vcxproj.filters b/Plugin/Plugin.vcxproj.filters index 608abb7..1c9ebdb 100644 --- a/Plugin/Plugin.vcxproj.filters +++ b/Plugin/Plugin.vcxproj.filters @@ -63,6 +63,9 @@ Source Files + + Header Files + @@ -83,6 +86,9 @@ Source Files + + Source Files + diff --git a/Plugin/RadioUpdateCommand.cpp b/Plugin/RadioUpdateCommand.cpp new file mode 100644 index 0000000..2396cae --- /dev/null +++ b/Plugin/RadioUpdateCommand.cpp @@ -0,0 +1,35 @@ +#include "RadioUpdateCommand.h" +#include "json/json.h" + +namespace SimpleRadio +{ + + RadioUpdateCommand::RadioUpdateCommand() + { + } + + + RadioUpdateCommand::~RadioUpdateCommand() + { + } + + const RadioUpdateCommand RadioUpdateCommand::deserialize(const std::string& document) + { + RadioUpdateCommand data; + Json::Reader reader; + Json::Value root; + + bool success = reader.parse(document, root, false); + if (success == true) + { + data.freq = root["freq"].asDouble(); + data.radio = root["radio"].asInt(); + } + else + { + throw std::string("Failed to parse Update Command"); + } + + return data; + } +} \ No newline at end of file diff --git a/Plugin/RadioUpdateCommand.h b/Plugin/RadioUpdateCommand.h new file mode 100644 index 0000000..b9177e0 --- /dev/null +++ b/Plugin/RadioUpdateCommand.h @@ -0,0 +1,17 @@ +#pragma once +#include +namespace SimpleRadio +{ + class RadioUpdateCommand + { + public: + + double freq; + int radio; + + RadioUpdateCommand(); + ~RadioUpdateCommand(); + + static const RadioUpdateCommand deserialize(const std::string& document); + }; +} diff --git a/RadioGui/MainWindow.xaml b/RadioGui/MainWindow.xaml index 37b127a..970ff8e 100644 --- a/RadioGui/MainWindow.xaml +++ b/RadioGui/MainWindow.xaml @@ -7,35 +7,21 @@ mc:Ignorable="d" ResizeMode="CanMinimize" Topmost="True" - - Title="DCS-SimpleRadio" Height="290" Width="120"> + + + Title="DCS-SimpleRadio" Height="325" Width="120"> -