From 1bb3655ef7154d5c24238d910d77bdf7606c90ec Mon Sep 17 00:00:00 2001 From: "shaun.qiu" Date: Tue, 31 Jan 2023 16:44:56 +0800 Subject: [PATCH 1/5] Update v1.12 --- NetInput.Capture/NetInput.Capture.cpp | 87 +++++++++--- NetInput.Player/NetInput.Player.cpp | 185 +++++++++++++++++++++----- README.md | 19 +++ 3 files changed, 238 insertions(+), 53 deletions(-) diff --git a/NetInput.Capture/NetInput.Capture.cpp b/NetInput.Capture/NetInput.Capture.cpp index 50bd4f7..b727053 100644 --- a/NetInput.Capture/NetInput.Capture.cpp +++ b/NetInput.Capture/NetInput.Capture.cpp @@ -13,10 +13,56 @@ #include #include + +#define PAD_OUT_SIZE 5 +#define PAD_ONLINE 0x00 +#define PAD_VIBRA 0x01 + SOCKET sock; struct sockaddr_in addr; XINPUT_STATE lastSentInputStates[XUSER_MAX_COUNT]; +void CheckControllerMessage() +{ + while (true) + { + if (GetKeyState(VK_ESCAPE) & 0x8000) + break; + + char packet[PAD_OUT_SIZE]; + int addr_size = sizeof(addr); + int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, &addr_size); + if (bytesReceived == PAD_OUT_SIZE){ + uint8_t i = (uint8_t)packet[1]; + if ((i >= 0) && (i < XUSER_MAX_COUNT)) { + if (packet[0] == PAD_ONLINE) { + XINPUT_VIBRATION Vibration; + + uint8_t pindex = (uint8_t)packet[4]; + Vibration.wLeftMotorSpeed = 0; + Vibration.wRightMotorSpeed = -1; + XInputSetState(i, &Vibration); + + printf("Get Local controller %u as Online controller %u.\n", i,pindex); + std::this_thread::sleep_for(std::chrono::milliseconds(250)); + + Vibration.wLeftMotorSpeed = 0; + Vibration.wRightMotorSpeed = 0; + XInputSetState(i, &Vibration); + + } + else if (packet[0] == PAD_VIBRA) { + XINPUT_VIBRATION Vibration; + Vibration.wLeftMotorSpeed = packet[2] << 8; + Vibration.wRightMotorSpeed = packet[3] << 8; + XInputSetState(i, &Vibration); + } + } + } + } +} + + void SendResetControllers() { uint8_t packet[] = { 0xFFu }; @@ -27,7 +73,7 @@ void SendResetControllers() void PollControllers() { XINPUT_STATE state; - for (uint32_t i = 0u; i < XUSER_MAX_COUNT; i++) + for (uint8_t i = 0u; i < XUSER_MAX_COUNT; i++) { memset(&state, 0, sizeof(XINPUT_STATE)); if (XInputGetState(i, &state) != ERROR_SUCCESS) @@ -46,23 +92,19 @@ void PollControllers() } } -int main() +int main(int argc, char* argv[]) { std::string ip; - - std::ifstream input_file("target.txt"); - if (input_file.is_open()) - { - printf("Reading ip from target.txt.\n"); - ip = std::string((std::istreambuf_iterator(input_file)), std::istreambuf_iterator()); - - if (inet_pton(AF_INET, ip.c_str(), &(addr.sin_addr)) != 1) - { - std::cout << ip << " is not a valid ip, please correct target.txt\n"; - return -1; - } + int port = 4313; + + if (argc > 1) { + ip = argv[1]; } + if (argc > 2) { + sscanf_s(argv[2], "%d", &port); + } + if (ip.empty()) { while (true) @@ -77,7 +119,13 @@ int main() } } - printf("Target is %s.\n", ip.c_str()); + if (inet_pton(AF_INET, ip.c_str(), &(addr.sin_addr)) != 1) + { + std::cout << ip << " is not a valid ip, please try again ! \n"; + return -1; + } + + printf("Target is %s:%d.\n", ip.c_str(),port); CoInitialize(NULL); @@ -99,23 +147,24 @@ int main() } addr.sin_family = AF_INET; - addr.sin_port = htons(4313); + addr.sin_port = htons(port); printf("Sending reset...\n"); SendResetControllers(); printf("Done.\n"); - printf("Waiting for gamepad input, press ESC to exit...\n"); + + std::thread message(CheckControllerMessage); // new thread for vibra notify + memset(lastSentInputStates, 0, sizeof(lastSentInputStates)); while (true) { if (GetKeyState(VK_ESCAPE) & 0x8000) break; - PollControllers(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } - + printf("Wait For Closing...\n"); SendResetControllers(); closesocket(sock); WSACleanup(); diff --git a/NetInput.Player/NetInput.Player.cpp b/NetInput.Player/NetInput.Player.cpp index 923a3a9..8fcc786 100644 --- a/NetInput.Player/NetInput.Player.cpp +++ b/NetInput.Player/NetInput.Player.cpp @@ -9,28 +9,123 @@ #include #include +typedef struct _TARGET_PADS +{ + uint8_t Pid; + PVIGEM_TARGET Pad; + SOCKADDR_IN Addr; +} TARGET_PADS, * PTARGET_PADS; + +#define PAD_OUT_SIZE 5 +#define PAD_ONLINE 0x00 +#define PAD_VIBRA 0x01 + SOCKET sock; -PVIGEM_TARGET pads[XUSER_MAX_COUNT]; +TARGET_PADS pads[XUSER_MAX_COUNT]; PVIGEM_CLIENT client; -void ResetGamepads() +VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData) { + for (int i = 0; i < XUSER_MAX_COUNT; i++) + { + if (Target == pads[i].Pad){ + + char packet[PAD_OUT_SIZE]; + packet[0] = PAD_VIBRA; + packet[1] = pads[i].Pid; + + packet[2] = LargeMotor; + packet[3] = SmallMotor; + packet[4] = LedNumber; + + if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&pads[i].Addr, sizeof(pads[i].Addr)) != sizeof(packet)) + printf("Failed to Send Notify message \n"); + break; + + } + } +} + + +void SetGamepadOnline(SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) { + + char packet[PAD_OUT_SIZE]; + + packet[0] = PAD_ONLINE; + packet[1] = Pid; + packet[2] = 0; + packet[3] = 0; + packet[4] = Pindex; + + if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr)) != sizeof(packet)) + printf("Failed to Send Online message \n"); +} + + + + + + + +int GetPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) { + int index = -1; for (int i = 0; i < XUSER_MAX_COUNT; i++) { - auto pad = pads[i]; - pads[i] = nullptr; + if (pads[i].Pad == nullptr && index < 0 ) + { + index = i; - if (pad == nullptr) - continue; + }else if ( pads[i].Pid == pid && pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr) + { + index = i; + break; + } + } + return index; +} + +void ResetGamepad(SOCKADDR_IN ClientAddr) +{ + for (int i = 0; i < XUSER_MAX_COUNT; i++) + { + if (pads[i].Pad == nullptr) + continue; - vigem_target_remove(client, pad); - vigem_target_free(pad); + if (pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr) + { + auto pad = pads[i].Pad; + pads[i].Pad = nullptr; + vigem_target_remove(client, pad); + vigem_target_x360_unregister_notification(pad); + vigem_target_free(pad); + } } } -int main() +void ResetGamepads() +{ + for (int i = 0; i < XUSER_MAX_COUNT; i++) + { + if (pads[i].Pad == nullptr) + continue; + auto pad = pads[i].Pad; + pads[i].Pad = nullptr; + vigem_target_remove(client, pad); + vigem_target_x360_unregister_notification(pad); + vigem_target_free(pad); + } +} + + +int main(int argc, char* argv[]) { - CoInitialize(NULL); + int port = 4313; + + if (argc > 1) { + sscanf_s(argv[1], "%d", &port); + } + + CoInitialize(NULL); printf("Starting networking...\n"); @@ -51,18 +146,18 @@ int main() struct sockaddr_in addr; addr.sin_family = AF_INET; - addr.sin_port = htons(4313); + addr.sin_port = htons(port); inet_pton(AF_INET, "0.0.0.0", &(addr.sin_addr)); if (bind(sock, (const sockaddr*)&addr, sizeof(addr)) == SOCKET_ERROR) { - printf("Failed to bind to 0.0.0.0:4313."); + printf("Failed to bind to 0.0.0.0:%d.", port); closesocket(sock); WSACleanup(); return -3; } - printf("Done.\n"); + printf("Bind to 0.0.0.0:%d .\n",port); printf("Setting up ViGEmClient...\n"); client = vigem_alloc(); @@ -89,46 +184,68 @@ int main() printf("Waiting for data...\n"); - struct sockaddr_in clientAddr; uint8_t packet[sizeof(XINPUT_STATE) + 1]; + struct sockaddr_in clientAddr; + while (true) { if (GetKeyState(VK_ESCAPE) & 0x8000) break; memset(&clientAddr, 0, sizeof(clientAddr)); - int addrLen = sizeof(clientAddr); - int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&clientAddr, &addrLen); + int addr_len = sizeof(clientAddr); + int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&clientAddr, &addr_len); if (bytesReceived == 1 && packet[0] == (uint8_t)0xFFu) { - printf("Reset signal received, gamepads will be reset.\n"); - ResetGamepads(); + printf("Reset signal received, controllers will be reset.\n"); + ResetGamepad(clientAddr); } else if (bytesReceived == sizeof(packet) && packet[0] >= 0 && packet[0] < XUSER_MAX_COUNT) { - uint32_t i = (uint32_t)packet[0]; + uint8_t pindex = GetPadIndex((uint8_t)packet[0], clientAddr); XINPUT_STATE* state = (XINPUT_STATE*)(packet + 1); - if (pads[i] == nullptr) + if (pindex >= 0 && pindex < XUSER_MAX_COUNT) { - auto pad = vigem_target_x360_alloc(); - const auto targetAddResult = vigem_target_add(client, pad); - if (VIGEM_SUCCESS(targetAddResult)) - { - printf("Connected new gamepad %u.\n", i); - pads[i] = pad; + if (pads[pindex].Pad == nullptr) { + auto pad = vigem_target_x360_alloc(); + const auto targetAddResult = vigem_target_add(client, pad); + if (VIGEM_SUCCESS(targetAddResult)) + { + printf("Connected new controller %u.\n", pindex); + + pads[pindex].Pad = pad; + pads[pindex].Addr = clientAddr; + pads[pindex].Pid = (uint8_t)packet[0]; + + SetGamepadOnline(clientAddr, (uint8_t)packet[0], pindex); + + const auto retval = vigem_target_x360_register_notification(client, pad, &gamepad_callback, nullptr); + + if (VIGEM_SUCCESS(retval)) + { + printf("Register for notification Success! \n"); + + } + else { + printf("Register for notification failed! \n"); + vigem_target_x360_unregister_notification(pad); + } + + } + else + { + vigem_target_free(pad); + printf("Failed to add pad %u with error code 0x%08X.\n", pindex, targetAddResult); + } } - else - { - vigem_target_free(pad); - printf("Failed to add pad %u with error code 0x%08X.\n", i, targetAddResult); + + if (pads[pindex].Pad!= nullptr) { + vigem_target_x360_update(client, pads[pindex].Pad, *reinterpret_cast(&state->Gamepad)); } - } - auto pad = pads[i]; - if (pad != nullptr) - vigem_target_x360_update(client, pad, *reinterpret_cast(&state->Gamepad)); + } } } diff --git a/README.md b/README.md index 7d832ee..f8bc55a 100644 --- a/README.md +++ b/README.md @@ -36,3 +36,22 @@ The Player will see if a gamepad with that index is connected. If not, a new vir ## Requirements - ViGEmBus https://github.com/ViGEm/ViGEmBus/releases + +# Thank usertoroot +# 1.12 By QeeAI + +2023.1.31 + +1. Server : netinput.paly.exe 0-65536 (Default 4313) +2. Client : netinput.capture.exe 192.168.1.31 (for example) 0-65536 (Default 4313) , "target.txt" never use . +3. Support Xbox360/One/XSS Vibration +4. Pads re-Arrays depended By ClientIP and Local XboxId。 + +2023年1月31日 +1. 服务端 增加自定义端口 netinput.paly.exe 4313(0-65536) +2. 客户端 增加自定义IP和端口,取消target.txt的参数文件, netinput.capture.exe 192.168.1.31(自定义) 4313(0-65536) +3. 现在可以完美支持XBOX手柄震动。 +4. 服务端的手柄分组ID现在按IP和本地XBOXID共同决定。 + + + From d1c2bdfbc24e159eb49dfa68267eafd515c782f0 Mon Sep 17 00:00:00 2001 From: "shaun.qiu" Date: Thu, 2 Feb 2023 01:12:14 +0800 Subject: [PATCH 2/5] Update v1.13 --- NetInput.Capture/NetInput.Capture.cpp | 33 ++++++---- NetInput.Player/NetInput.Player.cpp | 95 +++++++++++++++++++-------- README.md | 30 +++++---- 3 files changed, 103 insertions(+), 55 deletions(-) diff --git a/NetInput.Capture/NetInput.Capture.cpp b/NetInput.Capture/NetInput.Capture.cpp index b727053..b490146 100644 --- a/NetInput.Capture/NetInput.Capture.cpp +++ b/NetInput.Capture/NetInput.Capture.cpp @@ -13,7 +13,6 @@ #include #include - #define PAD_OUT_SIZE 5 #define PAD_ONLINE 0x00 #define PAD_VIBRA 0x01 @@ -21,17 +20,16 @@ SOCKET sock; struct sockaddr_in addr; XINPUT_STATE lastSentInputStates[XUSER_MAX_COUNT]; +time_t updatetime[XUSER_MAX_COUNT]; void CheckControllerMessage() -{ +{ while (true) - { - if (GetKeyState(VK_ESCAPE) & 0x8000) - break; - + { char packet[PAD_OUT_SIZE]; int addr_size = sizeof(addr); - int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, &addr_size); + int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, &addr_size); + if (bytesReceived == PAD_OUT_SIZE){ uint8_t i = (uint8_t)packet[1]; if ((i >= 0) && (i < XUSER_MAX_COUNT)) { @@ -77,10 +75,18 @@ void PollControllers() { memset(&state, 0, sizeof(XINPUT_STATE)); if (XInputGetState(i, &state) != ERROR_SUCCESS) - continue; + continue; + + if (time(NULL) - updatetime[i] >= 5) + { + uint8_t packet[] = { 0xFEu ,i }; + if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) + printf("Failed to CheckUpdateTimeOut!\n"); + updatetime[i] = time(NULL); + } if (memcmp(lastSentInputStates + i, &state, sizeof(XINPUT_STATE)) == 0) - continue; + continue; uint8_t packet[sizeof(XINPUT_STATE) + 1]; packet[0] = (uint8_t)i; @@ -152,18 +158,17 @@ int main(int argc, char* argv[]) printf("Sending reset...\n"); SendResetControllers(); printf("Done.\n"); - printf("Waiting for gamepad input, press ESC to exit...\n"); - - std::thread message(CheckControllerMessage); // new thread for vibra notify + printf("Waiting for gamepad input, press Ctrl+C to exit...\n"); + + std::thread message(CheckControllerMessage); // new thread for message memset(lastSentInputStates, 0, sizeof(lastSentInputStates)); while (true) { - if (GetKeyState(VK_ESCAPE) & 0x8000) - break; PollControllers(); std::this_thread::sleep_for(std::chrono::milliseconds(1)); } + printf("Wait For Closing...\n"); SendResetControllers(); closesocket(sock); diff --git a/NetInput.Player/NetInput.Player.cpp b/NetInput.Player/NetInput.Player.cpp index 8fcc786..a4c8e9b 100644 --- a/NetInput.Player/NetInput.Player.cpp +++ b/NetInput.Player/NetInput.Player.cpp @@ -5,7 +5,8 @@ #include #include #include - +#include +#include #include #include @@ -14,6 +15,7 @@ typedef struct _TARGET_PADS uint8_t Pid; PVIGEM_TARGET Pad; SOCKADDR_IN Addr; + time_t Utime; } TARGET_PADS, * PTARGET_PADS; #define PAD_OUT_SIZE 5 @@ -36,7 +38,6 @@ VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR packet[2] = LargeMotor; packet[3] = SmallMotor; packet[4] = LedNumber; - if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&pads[i].Addr, sizeof(pads[i].Addr)) != sizeof(packet)) printf("Failed to Send Notify message \n"); break; @@ -45,6 +46,28 @@ VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR } } +void CheckPadUpdateTimeOut() { + + while (true) + { + for (int i = 0; i < XUSER_MAX_COUNT; i++) + { + if (pads[i].Pad == nullptr) + continue; + + if (time(NULL) - pads[i].Utime >= 15) + { + auto pad = pads[i].Pad; + pads[i].Pad = nullptr; + vigem_target_remove(client, pad); + vigem_target_x360_unregister_notification(pad); + vigem_target_free(pad); + } + } + + std::this_thread::sleep_for(std::chrono::milliseconds(5000)); + } +} void SetGamepadOnline(SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) { @@ -55,18 +78,13 @@ void SetGamepadOnline(SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) { packet[2] = 0; packet[3] = 0; packet[4] = Pindex; - + if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&ClientAddr, sizeof(ClientAddr)) != sizeof(packet)) printf("Failed to Send Online message \n"); } - - - - - -int GetPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) +int GetNewPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) { int index = -1; for (int i = 0; i < XUSER_MAX_COUNT; i++) @@ -75,7 +93,25 @@ int GetPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) { index = i; - }else if ( pads[i].Pid == pid && pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr) + }else if ( pads[i].Pid == pid && pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr && pads[i].Addr.sin_port == ClientAddr.sin_port) + { + index = i; + break; + } + } + return index; +} + + +int CheckPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) +{ + int index = -1; + for (int i = 0; i < XUSER_MAX_COUNT; i++) + { + if (pads[i].Pad == nullptr) + continue; + + if (pads[i].Pid == pid && pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr && pads[i].Addr.sin_port == ClientAddr.sin_port) { index = i; break; @@ -91,7 +127,7 @@ void ResetGamepad(SOCKADDR_IN ClientAddr) if (pads[i].Pad == nullptr) continue; - if (pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr) + if (pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr && pads[i].Addr.sin_port== ClientAddr.sin_port) { auto pad = pads[i].Pad; pads[i].Pad = nullptr; @@ -181,31 +217,27 @@ int main(int argc, char* argv[]) } printf("Done.\n"); - printf("Waiting for data...\n"); + + std::thread checktimeout(CheckPadUpdateTimeOut); + uint8_t packet[sizeof(XINPUT_STATE) + 1]; struct sockaddr_in clientAddr; while (true) { - if (GetKeyState(VK_ESCAPE) & 0x8000) - break; - memset(&clientAddr, 0, sizeof(clientAddr)); - int addr_len = sizeof(clientAddr); + int addr_len = sizeof(clientAddr); int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&clientAddr, &addr_len); if (bytesReceived == 1 && packet[0] == (uint8_t)0xFFu) { printf("Reset signal received, controllers will be reset.\n"); ResetGamepad(clientAddr); - } - else if (bytesReceived == sizeof(packet) && packet[0] >= 0 && packet[0] < XUSER_MAX_COUNT) + }else if (bytesReceived == 2 && packet[0] == (uint8_t)0xFEu) { - uint8_t pindex = GetPadIndex((uint8_t)packet[0], clientAddr); - XINPUT_STATE* state = (XINPUT_STATE*)(packet + 1); - + uint8_t pindex = GetNewPadIndex((uint8_t)packet[1], clientAddr); if (pindex >= 0 && pindex < XUSER_MAX_COUNT) { if (pads[pindex].Pad == nullptr) { @@ -217,9 +249,10 @@ int main(int argc, char* argv[]) pads[pindex].Pad = pad; pads[pindex].Addr = clientAddr; - pads[pindex].Pid = (uint8_t)packet[0]; + pads[pindex].Pid = (uint8_t)packet[1]; + pads[pindex].Utime = time(NULL); - SetGamepadOnline(clientAddr, (uint8_t)packet[0], pindex); + SetGamepadOnline(clientAddr, (uint8_t)packet[1], pindex); const auto retval = vigem_target_x360_register_notification(client, pad, &gamepad_callback, nullptr); @@ -241,10 +274,18 @@ int main(int argc, char* argv[]) } } - if (pads[pindex].Pad!= nullptr) { - vigem_target_x360_update(client, pads[pindex].Pad, *reinterpret_cast(&state->Gamepad)); - } - + if (pads[pindex].Pad != nullptr) + pads[pindex].Utime = time(NULL); + } + } + else if (bytesReceived == sizeof(packet) && packet[0] >= 0 && packet[0] < XUSER_MAX_COUNT) + { + uint8_t pindex = CheckPadIndex((uint8_t)packet[0], clientAddr); + XINPUT_STATE* state = (XINPUT_STATE*)(packet + 1); + if (pindex >= 0 && pindex < XUSER_MAX_COUNT && pads[pindex].Pad != nullptr) + { + pads[pindex].Utime = time(NULL); + vigem_target_x360_update(client, pads[pindex].Pad, *reinterpret_cast(&state->Gamepad)); } } } diff --git a/README.md b/README.md index f8bc55a..864d9b8 100644 --- a/README.md +++ b/README.md @@ -38,20 +38,22 @@ The Player will see if a gamepad with that index is connected. If not, a new vir - ViGEmBus https://github.com/ViGEm/ViGEmBus/releases # Thank usertoroot -# 1.12 By QeeAI - -2023.1.31 - -1. Server : netinput.paly.exe 0-65536 (Default 4313) -2. Client : netinput.capture.exe 192.168.1.31 (for example) 0-65536 (Default 4313) , "target.txt" never use . -3. Support Xbox360/One/XSS Vibration -4. Pads re-Arrays depended By ClientIP and Local XboxId。 - -2023年1月31日 -1. 服务端 增加自定义端口 netinput.paly.exe 4313(0-65536) -2. 客户端 增加自定义IP和端口,取消target.txt的参数文件, netinput.capture.exe 192.168.1.31(自定义) 4313(0-65536) -3. 现在可以完美支持XBOX手柄震动。 -4. 服务端的手柄分组ID现在按IP和本地XBOXID共同决定。 +# 1.13 By QeeAI + +2023.2.2 + +1. Server (Custom Port) : netinput.paly.exe 0-65536 (Default 4313) +2. Client (Custom IPV4/Port) : netinput.capture.exe 192.168.1.31 (for example) 0-65536 (Default 4313) , "target.txt" never use . +3. Support Xbox360/X1S/XSS Vibration +4. GamePads Arrays depended By Client IP ,Port, and Local Xbox controller Index Id 。 +5. Add UDP Client HeartBreak every 5s, TimeOut 15s to break. + +2023年2月2日 +1. 服务端 (自定义端口) : netinput.paly.exe 4313(0-65536) +2. 客户端 (自定义IP和端口) : netinput.capture.exe 192.168.1.31(自定义) 4313(0-65536) , target.txt 不再使用。 +3. 现在可以完美支持Xbox360/X1S/XSS手柄震动。 +4. 服务端的手柄分组现在按IP,端口和本地XBOX手柄序号共同决定。 +5. 增加客户端手柄的心跳连接每5秒1次,超时15秒自动断开。 From ab1b4f5422320fcade8401826f7e98de42d467a9 Mon Sep 17 00:00:00 2001 From: "shaun.qiu" Date: Sat, 4 Feb 2023 22:30:18 +0800 Subject: [PATCH 3/5] GamePads depended By Client Mac Address and Xbox controller Index Id --- NetInput.Capture/NetInput.Capture.cpp | 108 ++++++++++++++++++++----- NetInput.Player/NetInput.Player.cpp | 112 +++++++++++++++++--------- README.md | 12 ++- 3 files changed, 169 insertions(+), 63 deletions(-) diff --git a/NetInput.Capture/NetInput.Capture.cpp b/NetInput.Capture/NetInput.Capture.cpp index b490146..de7eaa3 100644 --- a/NetInput.Capture/NetInput.Capture.cpp +++ b/NetInput.Capture/NetInput.Capture.cpp @@ -12,28 +12,84 @@ #include #include #include +#include +#pragma comment(lib, "Netapi32.lib") -#define PAD_OUT_SIZE 5 -#define PAD_ONLINE 0x00 -#define PAD_VIBRA 0x01 +typedef struct _ASTAT_ +{ + ADAPTER_STATUS adapt; + NAME_BUFFER NameBuff[30]; +} ASTAT, * PASTAT; + + +#define PAD_SERVER_SIZE 5 +#define PAD_CLIENT_SIZE 24 + +#define PAD_ONLINE 0x00u +#define PAD_VIBRA 0x01u +#define PAD_REG 0x03u +#define PAD_STATE 0x04u +#define PAD_RESET 0xFFu SOCKET sock; struct sockaddr_in addr; XINPUT_STATE lastSentInputStates[XUSER_MAX_COUNT]; time_t updatetime[XUSER_MAX_COUNT]; +uint8_t hmac[6]; + +void getMac() +{ + ASTAT Adapter; + NCB Ncb; + UCHAR uRetCode; + LANA_ENUM lenum; + int i = 0; + + memset(&Ncb, 0, sizeof(Ncb)); + Ncb.ncb_command = NCBENUM; + Ncb.ncb_buffer = (UCHAR*)&lenum; + Ncb.ncb_length = sizeof(lenum); + + uRetCode = Netbios(&Ncb); + + for (i = 0; i < lenum.length; i++) + { + memset(&Ncb, 0, sizeof(Ncb)); + Ncb.ncb_command = NCBRESET; + Ncb.ncb_lana_num = lenum.lana[i]; + uRetCode = Netbios(&Ncb); + + memset(&Ncb, 0, sizeof(Ncb)); + Ncb.ncb_command = NCBASTAT; + Ncb.ncb_lana_num = lenum.lana[i]; + strcpy_s((char*)Ncb.ncb_callname, sizeof(Ncb.ncb_callname), "*"); + Ncb.ncb_buffer = (unsigned char*)&Adapter; + Ncb.ncb_length = sizeof(Adapter); + uRetCode = Netbios(&Ncb); + + if (uRetCode == 0) + { + for (int j = 0; j < sizeof(hmac); j++) { + hmac[j] = int(Adapter.adapt.adapter_address[j]); + } + break; + } + } +} + void CheckControllerMessage() { while (true) { - char packet[PAD_OUT_SIZE]; + char packet[PAD_SERVER_SIZE]; int addr_size = sizeof(addr); int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, &addr_size); - if (bytesReceived == PAD_OUT_SIZE){ + if (bytesReceived == PAD_SERVER_SIZE){ uint8_t i = (uint8_t)packet[1]; if ((i >= 0) && (i < XUSER_MAX_COUNT)) { - if (packet[0] == PAD_ONLINE) { + if (packet[0] == (uint8_t)PAD_ONLINE) { XINPUT_VIBRATION Vibration; uint8_t pindex = (uint8_t)packet[4]; @@ -41,7 +97,7 @@ void CheckControllerMessage() Vibration.wRightMotorSpeed = -1; XInputSetState(i, &Vibration); - printf("Get Local controller %u as Online controller %u.\n", i,pindex); + printf("Connected client controller %u to server controller %u.\n", i,pindex); std::this_thread::sleep_for(std::chrono::milliseconds(250)); Vibration.wLeftMotorSpeed = 0; @@ -49,7 +105,7 @@ void CheckControllerMessage() XInputSetState(i, &Vibration); } - else if (packet[0] == PAD_VIBRA) { + else if (packet[0] == (uint8_t)PAD_VIBRA) { XINPUT_VIBRATION Vibration; Vibration.wLeftMotorSpeed = packet[2] << 8; Vibration.wRightMotorSpeed = packet[3] << 8; @@ -63,7 +119,9 @@ void CheckControllerMessage() void SendResetControllers() { - uint8_t packet[] = { 0xFFu }; + uint8_t packet[1+sizeof(hmac)]; + packet[0] = (uint8_t)PAD_RESET; + memcpy(packet + 1, &hmac, sizeof(hmac)); if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) printf("Failed to send reset message.\n"); } @@ -79,22 +137,29 @@ void PollControllers() if (time(NULL) - updatetime[i] >= 5) { - uint8_t packet[] = { 0xFEu ,i }; + uint8_t packet[sizeof(hmac)+2]; + packet[0] = (uint8_t)PAD_REG; + packet[1] = (uint8_t)i; + memcpy(packet + 2, &hmac, sizeof(hmac)); if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) - printf("Failed to CheckUpdateTimeOut!\n"); + printf("Failed to checktimeOut of client controller %u .\n",i); updatetime[i] = time(NULL); } if (memcmp(lastSentInputStates + i, &state, sizeof(XINPUT_STATE)) == 0) continue; - uint8_t packet[sizeof(XINPUT_STATE) + 1]; - packet[0] = (uint8_t)i; - memcpy(packet + 1, &state, sizeof(XINPUT_STATE)); + uint8_t packet[PAD_CLIENT_SIZE]; + + packet[0] = (uint8_t)PAD_STATE; + packet[1] = (uint8_t)i; + + memcpy(packet + 2, &hmac, sizeof(hmac)); + memcpy(packet + sizeof(hmac) + 2, &state, sizeof(XINPUT_STATE)); memcpy(lastSentInputStates + i, &state, sizeof(XINPUT_STATE)); if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) - printf("Failed to send update message of controller %u.\n", i); + printf("Failed to send update message of client controller %u.\n", i); } } @@ -131,12 +196,14 @@ int main(int argc, char* argv[]) return -1; } - printf("Target is %s:%d.\n", ip.c_str(),port); + printf("Connected to server %s:%d.\n", ip.c_str(),port); CoInitialize(NULL); - - printf("Starting networking...\n"); - + + getMac(); + printf("Starting networking at %02X:%02X:%02X:%02X:%02X:%02X ...\n", + hmac[0], hmac[1], hmac[2], hmac[3], hmac[4], hmac[5]); + WSADATA wsaData; int wsaStartupResult = WSAStartup(MAKEWORD(2, 2), &wsaData); if (wsaStartupResult != 0) @@ -155,9 +222,6 @@ int main(int argc, char* argv[]) addr.sin_family = AF_INET; addr.sin_port = htons(port); - printf("Sending reset...\n"); - SendResetControllers(); - printf("Done.\n"); printf("Waiting for gamepad input, press Ctrl+C to exit...\n"); std::thread message(CheckControllerMessage); // new thread for message diff --git a/NetInput.Player/NetInput.Player.cpp b/NetInput.Player/NetInput.Player.cpp index a4c8e9b..1470256 100644 --- a/NetInput.Player/NetInput.Player.cpp +++ b/NetInput.Player/NetInput.Player.cpp @@ -16,11 +16,19 @@ typedef struct _TARGET_PADS PVIGEM_TARGET Pad; SOCKADDR_IN Addr; time_t Utime; + uint8_t hMac[6]; } TARGET_PADS, * PTARGET_PADS; -#define PAD_OUT_SIZE 5 -#define PAD_ONLINE 0x00 -#define PAD_VIBRA 0x01 +#define PAD_SERVER_SIZE 5 +#define PAD_CLIENT_SIZE 24 +#define MAC_SIZE 6 + + +#define PAD_ONLINE 0x00u +#define PAD_VIBRA 0x01u +#define PAD_REG 0x03u +#define PAD_STATE 0x04u +#define PAD_RESET 0xFFu SOCKET sock; TARGET_PADS pads[XUSER_MAX_COUNT]; @@ -29,17 +37,18 @@ PVIGEM_CLIENT client; VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData) { for (int i = 0; i < XUSER_MAX_COUNT; i++) { - if (Target == pads[i].Pad){ + if (Target == pads[i].Pad) { - char packet[PAD_OUT_SIZE]; - packet[0] = PAD_VIBRA; + char packet[PAD_SERVER_SIZE]; + packet[0] = PAD_VIBRA; packet[1] = pads[i].Pid; - + packet[2] = LargeMotor; packet[3] = SmallMotor; packet[4] = LedNumber; - if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&pads[i].Addr, sizeof(pads[i].Addr)) != sizeof(packet)) - printf("Failed to Send Notify message \n"); + + if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&pads[i].Addr, sizeof(pads[i].Addr)) != sizeof(packet)) + printf("Failed to Send Notify message \n"); break; } @@ -48,8 +57,8 @@ VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR void CheckPadUpdateTimeOut() { - while (true) - { + while (true) + { for (int i = 0; i < XUSER_MAX_COUNT; i++) { if (pads[i].Pad == nullptr) @@ -57,6 +66,7 @@ void CheckPadUpdateTimeOut() { if (time(NULL) - pads[i].Utime >= 15) { + printf("Server controller %d unregistered. \n", pads[i].Pid); auto pad = pads[i].Pad; pads[i].Pad = nullptr; vigem_target_remove(client, pad); @@ -66,12 +76,12 @@ void CheckPadUpdateTimeOut() { } std::this_thread::sleep_for(std::chrono::milliseconds(5000)); - } + } } void SetGamepadOnline(SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) { - char packet[PAD_OUT_SIZE]; + char packet[PAD_SERVER_SIZE]; packet[0] = PAD_ONLINE; packet[1] = Pid; @@ -83,8 +93,20 @@ void SetGamepadOnline(SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) { printf("Failed to Send Online message \n"); } +bool CheckMac(uint8_t iMac[], uint8_t hMac[]) { + + for (int i = 0; i < MAC_SIZE; i++) { + if (iMac[i] != hMac[i]) { + return false; + } + } + return true; +} -int GetNewPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) + + + +int GetNewPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr,uint8_t hMac[]) { int index = -1; for (int i = 0; i < XUSER_MAX_COUNT; i++) @@ -93,8 +115,10 @@ int GetNewPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) { index = i; - }else if ( pads[i].Pid == pid && pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr && pads[i].Addr.sin_port == ClientAddr.sin_port) + }else if ( pads[i].Pid == pid && CheckMac(pads[i].hMac,hMac)) { + if (pads[i].Addr.sin_port!= ClientAddr.sin_port || pads[i].Addr.sin_addr.S_un.S_addr != ClientAddr.sin_addr.S_un.S_addr) + pads[i].Addr = ClientAddr; index = i; break; } @@ -103,7 +127,7 @@ int GetNewPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) } -int CheckPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) +int CheckPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr, uint8_t hMac[]) { int index = -1; for (int i = 0; i < XUSER_MAX_COUNT; i++) @@ -111,8 +135,10 @@ int CheckPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) if (pads[i].Pad == nullptr) continue; - if (pads[i].Pid == pid && pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr && pads[i].Addr.sin_port == ClientAddr.sin_port) + if (pads[i].Pid == pid && CheckMac(pads[i].hMac, hMac)) { + if (pads[i].Addr.sin_port != ClientAddr.sin_port || pads[i].Addr.sin_addr.S_un.S_addr != ClientAddr.sin_addr.S_un.S_addr) + pads[i].Addr = ClientAddr; index = i; break; } @@ -120,17 +146,17 @@ int CheckPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr) return index; } -void ResetGamepad(SOCKADDR_IN ClientAddr) +void ResetGamepad(SOCKADDR_IN ClientAddr, uint8_t hMac[]) { for (int i = 0; i < XUSER_MAX_COUNT; i++) { if (pads[i].Pad == nullptr) continue; - - if (pads[i].Addr.sin_addr.S_un.S_addr == ClientAddr.sin_addr.S_un.S_addr && pads[i].Addr.sin_port== ClientAddr.sin_port) + if (CheckMac(pads[i].hMac, hMac)) { - auto pad = pads[i].Pad; - pads[i].Pad = nullptr; + printf("Server controller %d unregistered. \n", pads[i].Pid); + auto pad = pads[i].Pad; + pads[i].Pad = nullptr; vigem_target_remove(client, pad); vigem_target_x360_unregister_notification(pad); vigem_target_free(pad); @@ -146,6 +172,7 @@ void ResetGamepads() continue; auto pad = pads[i].Pad; pads[i].Pad = nullptr; + vigem_target_remove(client, pad); vigem_target_x360_unregister_notification(pad); vigem_target_free(pad); @@ -163,7 +190,7 @@ int main(int argc, char* argv[]) CoInitialize(NULL); - printf("Starting networking...\n"); + printf("Starting networking ...\n"); WSADATA wsaData; int wsaStartupResult = WSAStartup(MAKEWORD(2, 2), &wsaData); @@ -216,13 +243,11 @@ int main(int argc, char* argv[]) return -5; } - printf("Done.\n"); printf("Waiting for data...\n"); - std::thread checktimeout(CheckPadUpdateTimeOut); - uint8_t packet[sizeof(XINPUT_STATE) + 1]; + uint8_t packet[PAD_CLIENT_SIZE]; struct sockaddr_in clientAddr; while (true) @@ -231,13 +256,20 @@ int main(int argc, char* argv[]) int addr_len = sizeof(clientAddr); int bytesReceived = recvfrom(sock, (char*)&packet, sizeof(packet), 0, (struct sockaddr*)&clientAddr, &addr_len); - if (bytesReceived == 1 && packet[0] == (uint8_t)0xFFu) + if (bytesReceived >2 && packet[0] == (uint8_t)PAD_RESET) { printf("Reset signal received, controllers will be reset.\n"); - ResetGamepad(clientAddr); - }else if (bytesReceived == 2 && packet[0] == (uint8_t)0xFEu) + uint8_t hMac[MAC_SIZE]; + memcpy(hMac, packet + 1, sizeof(hMac)); + ResetGamepad(clientAddr, hMac); + + }else if (bytesReceived > 2 && packet[0] == (uint8_t)PAD_REG) { - uint8_t pindex = GetNewPadIndex((uint8_t)packet[1], clientAddr); + uint8_t hMac[MAC_SIZE]; + uint8_t Pid = (uint8_t)packet[1]; + memcpy(hMac, packet+2, sizeof(hMac)); + uint8_t pindex = GetNewPadIndex(Pid, clientAddr,hMac); + if (pindex >= 0 && pindex < XUSER_MAX_COUNT) { if (pads[pindex].Pad == nullptr) { @@ -245,24 +277,25 @@ int main(int argc, char* argv[]) const auto targetAddResult = vigem_target_add(client, pad); if (VIGEM_SUCCESS(targetAddResult)) { - printf("Connected new controller %u.\n", pindex); + printf("Connected server controller %u from client controller %u.\n", pindex, pads[pindex].Pid); pads[pindex].Pad = pad; pads[pindex].Addr = clientAddr; - pads[pindex].Pid = (uint8_t)packet[1]; + pads[pindex].Pid = Pid; pads[pindex].Utime = time(NULL); + memcpy(pads[pindex].hMac,&hMac, sizeof(hMac)); - SetGamepadOnline(clientAddr, (uint8_t)packet[1], pindex); + SetGamepadOnline(clientAddr,Pid, pindex); const auto retval = vigem_target_x360_register_notification(client, pad, &gamepad_callback, nullptr); if (VIGEM_SUCCESS(retval)) { - printf("Register for notification Success! \n"); + printf("Server controller %d register for notification Success! \n", pads[pindex].Pid); } else { - printf("Register for notification failed! \n"); + printf("Server controller %d register for notification failed! \n", pads[pindex].Pid); vigem_target_x360_unregister_notification(pad); } @@ -278,10 +311,13 @@ int main(int argc, char* argv[]) pads[pindex].Utime = time(NULL); } } - else if (bytesReceived == sizeof(packet) && packet[0] >= 0 && packet[0] < XUSER_MAX_COUNT) + else if (bytesReceived > 2 && packet[0] == (uint8_t)PAD_STATE && packet[1] >= 0 && packet[1] < XUSER_MAX_COUNT) { - uint8_t pindex = CheckPadIndex((uint8_t)packet[0], clientAddr); - XINPUT_STATE* state = (XINPUT_STATE*)(packet + 1); + uint8_t hMac[MAC_SIZE]; + uint8_t Pid = (uint8_t)packet[1]; + memcpy(hMac, packet + 2, sizeof(hMac)); + uint8_t pindex = CheckPadIndex(Pid, clientAddr, hMac); + XINPUT_STATE* state = (XINPUT_STATE*)(packet + MAC_SIZE + 2); if (pindex >= 0 && pindex < XUSER_MAX_COUNT && pads[pindex].Pad != nullptr) { pads[pindex].Utime = time(NULL); diff --git a/README.md b/README.md index 864d9b8..f492773 100644 --- a/README.md +++ b/README.md @@ -41,12 +41,11 @@ The Player will see if a gamepad with that index is connected. If not, a new vir # 1.13 By QeeAI 2023.2.2 - 1. Server (Custom Port) : netinput.paly.exe 0-65536 (Default 4313) 2. Client (Custom IPV4/Port) : netinput.capture.exe 192.168.1.31 (for example) 0-65536 (Default 4313) , "target.txt" never use . 3. Support Xbox360/X1S/XSS Vibration -4. GamePads Arrays depended By Client IP ,Port, and Local Xbox controller Index Id 。 -5. Add UDP Client HeartBreak every 5s, TimeOut 15s to break. +4. GamePads depended By Client IP ,Port, and Local Xbox controller Index Id 。 +5. Added UDP Client HeartBreak every 5s, TimeOut 15s to break. 2023年2月2日 1. 服务端 (自定义端口) : netinput.paly.exe 4313(0-65536) @@ -57,3 +56,10 @@ The Player will see if a gamepad with that index is connected. If not, a new vir +# 1.14 By QeeAI + +2023.2.4 +GamePads depended By Client Mac Address and Xbox controller Index Id now. + +2023年2月4日 +服务端的手柄分组现在按客户端MAC地址和XBOX手柄序号共同决定。 \ No newline at end of file From 1fadff140b65751580f0fd09867df807788e3a07 Mon Sep 17 00:00:00 2001 From: "shaun.qiu" Date: Sun, 5 Feb 2023 14:36:06 +0800 Subject: [PATCH 4/5] Added check valid for client mac address. --- NetInput.Capture/NetInput.Capture.cpp | 40 +++++++++++++++++++-------- NetInput.Player/NetInput.Player.cpp | 21 ++++++++++---- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/NetInput.Capture/NetInput.Capture.cpp b/NetInput.Capture/NetInput.Capture.cpp index de7eaa3..94345a9 100644 --- a/NetInput.Capture/NetInput.Capture.cpp +++ b/NetInput.Capture/NetInput.Capture.cpp @@ -24,6 +24,7 @@ typedef struct _ASTAT_ #define PAD_SERVER_SIZE 5 #define PAD_CLIENT_SIZE 24 +#define MAC_SIZE 6 #define PAD_ONLINE 0x00u #define PAD_VIBRA 0x01u @@ -35,9 +36,19 @@ SOCKET sock; struct sockaddr_in addr; XINPUT_STATE lastSentInputStates[XUSER_MAX_COUNT]; time_t updatetime[XUSER_MAX_COUNT]; -uint8_t hmac[6]; +uint8_t hmac[MAC_SIZE]; -void getMac() +bool checkvalidmac(uint8_t hMac[]) +{ + for (int i = 0; i < MAC_SIZE; i++) { + if (hMac[i] > 0x00u && hMac[i] < uint8_t(0xFFu)) + return true; + } + return false; +} + + +bool getMac() { ASTAT Adapter; NCB Ncb; @@ -69,12 +80,15 @@ void getMac() if (uRetCode == 0) { - for (int j = 0; j < sizeof(hmac); j++) { + for (int j = 0; j < MAC_SIZE; j++) { hmac[j] = int(Adapter.adapt.adapter_address[j]); } - break; + + if (checkvalidmac(hmac)) + return true; } } + return false; } @@ -119,9 +133,9 @@ void CheckControllerMessage() void SendResetControllers() { - uint8_t packet[1+sizeof(hmac)]; + uint8_t packet[1+ MAC_SIZE]; packet[0] = (uint8_t)PAD_RESET; - memcpy(packet + 1, &hmac, sizeof(hmac)); + memcpy(packet + 1, &hmac, MAC_SIZE); if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) printf("Failed to send reset message.\n"); } @@ -137,10 +151,10 @@ void PollControllers() if (time(NULL) - updatetime[i] >= 5) { - uint8_t packet[sizeof(hmac)+2]; + uint8_t packet[MAC_SIZE+2]; packet[0] = (uint8_t)PAD_REG; packet[1] = (uint8_t)i; - memcpy(packet + 2, &hmac, sizeof(hmac)); + memcpy(packet + 2, &hmac, MAC_SIZE); if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) printf("Failed to checktimeOut of client controller %u .\n",i); updatetime[i] = time(NULL); @@ -154,8 +168,8 @@ void PollControllers() packet[0] = (uint8_t)PAD_STATE; packet[1] = (uint8_t)i; - memcpy(packet + 2, &hmac, sizeof(hmac)); - memcpy(packet + sizeof(hmac) + 2, &state, sizeof(XINPUT_STATE)); + memcpy(packet + 2, &hmac, MAC_SIZE); + memcpy(packet + MAC_SIZE + 2, &state, sizeof(XINPUT_STATE)); memcpy(lastSentInputStates + i, &state, sizeof(XINPUT_STATE)); if (sendto(sock, (const char*)&packet, sizeof(packet), 0, (struct sockaddr*)&addr, sizeof(addr)) != sizeof(packet)) @@ -196,11 +210,15 @@ int main(int argc, char* argv[]) return -1; } + if (!getMac()) { + printf("Failed to get mac address .\n"); + return -1; + } + printf("Connected to server %s:%d.\n", ip.c_str(),port); CoInitialize(NULL); - getMac(); printf("Starting networking at %02X:%02X:%02X:%02X:%02X:%02X ...\n", hmac[0], hmac[1], hmac[2], hmac[3], hmac[4], hmac[5]); diff --git a/NetInput.Player/NetInput.Player.cpp b/NetInput.Player/NetInput.Player.cpp index 1470256..bc7fe40 100644 --- a/NetInput.Player/NetInput.Player.cpp +++ b/NetInput.Player/NetInput.Player.cpp @@ -34,6 +34,15 @@ SOCKET sock; TARGET_PADS pads[XUSER_MAX_COUNT]; PVIGEM_CLIENT client; +bool checkvalidmac(uint8_t hMac[]) +{ + for (int i = 0; i < MAC_SIZE; i++) { + if (hMac[i] > uint8_t(0x00u) && hMac[i] < uint8_t(0xFFu)) + return true; + } + return false; +} + VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR LargeMotor, UCHAR SmallMotor, UCHAR LedNumber, LPVOID UserData) { for (int i = 0; i < XUSER_MAX_COUNT; i++) { @@ -260,17 +269,17 @@ int main(int argc, char* argv[]) { printf("Reset signal received, controllers will be reset.\n"); uint8_t hMac[MAC_SIZE]; - memcpy(hMac, packet + 1, sizeof(hMac)); + memcpy(hMac, packet + 1, MAC_SIZE); ResetGamepad(clientAddr, hMac); }else if (bytesReceived > 2 && packet[0] == (uint8_t)PAD_REG) { uint8_t hMac[MAC_SIZE]; uint8_t Pid = (uint8_t)packet[1]; - memcpy(hMac, packet+2, sizeof(hMac)); + memcpy(hMac, packet+2, MAC_SIZE); uint8_t pindex = GetNewPadIndex(Pid, clientAddr,hMac); - if (pindex >= 0 && pindex < XUSER_MAX_COUNT) + if (pindex >= 0 && pindex < XUSER_MAX_COUNT && checkvalidmac(hMac)) { if (pads[pindex].Pad == nullptr) { auto pad = vigem_target_x360_alloc(); @@ -283,7 +292,7 @@ int main(int argc, char* argv[]) pads[pindex].Addr = clientAddr; pads[pindex].Pid = Pid; pads[pindex].Utime = time(NULL); - memcpy(pads[pindex].hMac,&hMac, sizeof(hMac)); + memcpy(pads[pindex].hMac,&hMac, MAC_SIZE); SetGamepadOnline(clientAddr,Pid, pindex); @@ -315,10 +324,10 @@ int main(int argc, char* argv[]) { uint8_t hMac[MAC_SIZE]; uint8_t Pid = (uint8_t)packet[1]; - memcpy(hMac, packet + 2, sizeof(hMac)); + memcpy(hMac, packet + 2, MAC_SIZE); uint8_t pindex = CheckPadIndex(Pid, clientAddr, hMac); XINPUT_STATE* state = (XINPUT_STATE*)(packet + MAC_SIZE + 2); - if (pindex >= 0 && pindex < XUSER_MAX_COUNT && pads[pindex].Pad != nullptr) + if (pindex >= 0 && pindex < XUSER_MAX_COUNT && pads[pindex].Pad != nullptr && checkvalidmac(hMac)) { pads[pindex].Utime = time(NULL); vigem_target_x360_update(client, pads[pindex].Pad, *reinterpret_cast(&state->Gamepad)); From 408d0b0e3b85e81fe327a4fb2ee23c9533a7adc6 Mon Sep 17 00:00:00 2001 From: "shaun.qiu" Date: Sun, 5 Feb 2023 14:39:21 +0800 Subject: [PATCH 5/5] Added check valid for client mac address. --- README.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f492773..316ee8d 100644 --- a/README.md +++ b/README.md @@ -55,11 +55,17 @@ The Player will see if a gamepad with that index is connected. If not, a new vir 5. 增加客户端手柄的心跳连接每5秒1次,超时15秒自动断开。 - # 1.14 By QeeAI - -2023.2.4 +2023.2.4 GamePads depended By Client Mac Address and Xbox controller Index Id now. 2023年2月4日 -服务端的手柄分组现在按客户端MAC地址和XBOX手柄序号共同决定。 \ No newline at end of file +服务端的手柄分组现在按客户端MAC地址和XBOX手柄序号共同决定。 + + +# 1.15 By QeeAI +2023.2.5 +Added check valid for client mac address. + +2023年2月5日 +增加客户端MAC地址的有效性校验。 \ No newline at end of file