55#include < winsock2.h>
66#include < ws2tcpip.h>
77#include < objbase.h>
8-
8+ #include < thread>
9+ #include < chrono>
910#include < iostream>
1011#include < stdint.h>
1112
@@ -14,6 +15,7 @@ typedef struct _TARGET_PADS
1415 uint8_t Pid;
1516 PVIGEM_TARGET Pad;
1617 SOCKADDR_IN Addr;
18+ time_t Utime;
1719} TARGET_PADS, * PTARGET_PADS;
1820
1921#define PAD_OUT_SIZE 5
@@ -36,7 +38,6 @@ VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR
3638 packet[2 ] = LargeMotor;
3739 packet[3 ] = SmallMotor;
3840 packet[4 ] = LedNumber;
39-
4041 if (sendto (sock, (const char *)&packet, sizeof (packet), 0 , (struct sockaddr *)&pads[i].Addr , sizeof (pads[i].Addr )) != sizeof (packet))
4142 printf (" Failed to Send Notify message \n " );
4243 break ;
@@ -45,6 +46,28 @@ VOID CALLBACK gamepad_callback(PVIGEM_CLIENT Client, PVIGEM_TARGET Target, UCHAR
4546 }
4647}
4748
49+ void CheckPadUpdateTimeOut () {
50+
51+ while (true )
52+ {
53+ for (int i = 0 ; i < XUSER_MAX_COUNT; i++)
54+ {
55+ if (pads[i].Pad == nullptr )
56+ continue ;
57+
58+ if (time (NULL ) - pads[i].Utime >= 15 )
59+ {
60+ auto pad = pads[i].Pad ;
61+ pads[i].Pad = nullptr ;
62+ vigem_target_remove (client, pad);
63+ vigem_target_x360_unregister_notification (pad);
64+ vigem_target_free (pad);
65+ }
66+ }
67+
68+ std::this_thread::sleep_for (std::chrono::milliseconds (5000 ));
69+ }
70+ }
4871
4972void SetGamepadOnline (SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) {
5073
@@ -55,18 +78,13 @@ void SetGamepadOnline(SOCKADDR_IN ClientAddr, uint8_t Pid, uint8_t Pindex) {
5578 packet[2 ] = 0 ;
5679 packet[3 ] = 0 ;
5780 packet[4 ] = Pindex;
58-
81+
5982 if (sendto (sock, (const char *)&packet, sizeof (packet), 0 , (struct sockaddr *)&ClientAddr, sizeof (ClientAddr)) != sizeof (packet))
6083 printf (" Failed to Send Online message \n " );
6184}
6285
6386
64-
65-
66-
67-
68-
69- int GetPadIndex (uint8_t pid, SOCKADDR_IN ClientAddr)
87+ int GetNewPadIndex (uint8_t pid, SOCKADDR_IN ClientAddr)
7088{
7189 int index = -1 ;
7290 for (int i = 0 ; i < XUSER_MAX_COUNT; i++)
@@ -75,7 +93,25 @@ int GetPadIndex(uint8_t pid, SOCKADDR_IN ClientAddr)
7593 {
7694 index = i;
7795
78- }else if ( pads[i].Pid == pid && pads[i].Addr .sin_addr .S_un .S_addr == ClientAddr.sin_addr .S_un .S_addr )
96+ }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 )
97+ {
98+ index = i;
99+ break ;
100+ }
101+ }
102+ return index;
103+ }
104+
105+
106+ int CheckPadIndex (uint8_t pid, SOCKADDR_IN ClientAddr)
107+ {
108+ int index = -1 ;
109+ for (int i = 0 ; i < XUSER_MAX_COUNT; i++)
110+ {
111+ if (pads[i].Pad == nullptr )
112+ continue ;
113+
114+ 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 )
79115 {
80116 index = i;
81117 break ;
@@ -91,7 +127,7 @@ void ResetGamepad(SOCKADDR_IN ClientAddr)
91127 if (pads[i].Pad == nullptr )
92128 continue ;
93129
94- if (pads[i].Addr .sin_addr .S_un .S_addr == ClientAddr.sin_addr .S_un .S_addr )
130+ 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 )
95131 {
96132 auto pad = pads[i].Pad ;
97133 pads[i].Pad = nullptr ;
@@ -181,31 +217,27 @@ int main(int argc, char* argv[])
181217 }
182218
183219 printf (" Done.\n " );
184-
185220 printf (" Waiting for data...\n " );
186221
222+
223+ std::thread checktimeout (CheckPadUpdateTimeOut);
224+
187225 uint8_t packet[sizeof (XINPUT_STATE) + 1 ];
188226 struct sockaddr_in clientAddr;
189227
190228 while (true )
191229 {
192- if (GetKeyState (VK_ESCAPE) & 0x8000 )
193- break ;
194-
195230 memset (&clientAddr, 0 , sizeof (clientAddr));
196- int addr_len = sizeof (clientAddr);
231+ int addr_len = sizeof (clientAddr);
197232 int bytesReceived = recvfrom (sock, (char *)&packet, sizeof (packet), 0 , (struct sockaddr *)&clientAddr, &addr_len);
198233
199234 if (bytesReceived == 1 && packet[0 ] == (uint8_t )0xFFu )
200235 {
201236 printf (" Reset signal received, controllers will be reset.\n " );
202237 ResetGamepad (clientAddr);
203- }
204- else if (bytesReceived == sizeof (packet) && packet[0 ] >= 0 && packet[0 ] < XUSER_MAX_COUNT)
238+ }else if (bytesReceived == 2 && packet[0 ] == (uint8_t )0xFEu )
205239 {
206- uint8_t pindex = GetPadIndex ((uint8_t )packet[0 ], clientAddr);
207- XINPUT_STATE* state = (XINPUT_STATE*)(packet + 1 );
208-
240+ uint8_t pindex = GetNewPadIndex ((uint8_t )packet[1 ], clientAddr);
209241 if (pindex >= 0 && pindex < XUSER_MAX_COUNT)
210242 {
211243 if (pads[pindex].Pad == nullptr ) {
@@ -217,9 +249,10 @@ int main(int argc, char* argv[])
217249
218250 pads[pindex].Pad = pad;
219251 pads[pindex].Addr = clientAddr;
220- pads[pindex].Pid = (uint8_t )packet[0 ];
252+ pads[pindex].Pid = (uint8_t )packet[1 ];
253+ pads[pindex].Utime = time (NULL );
221254
222- SetGamepadOnline (clientAddr, (uint8_t )packet[0 ], pindex);
255+ SetGamepadOnline (clientAddr, (uint8_t )packet[1 ], pindex);
223256
224257 const auto retval = vigem_target_x360_register_notification (client, pad, &gamepad_callback, nullptr );
225258
@@ -241,10 +274,18 @@ int main(int argc, char* argv[])
241274 }
242275 }
243276
244- if (pads[pindex].Pad != nullptr ) {
245- vigem_target_x360_update (client, pads[pindex].Pad , *reinterpret_cast <XUSB_REPORT*>(&state->Gamepad ));
246- }
247-
277+ if (pads[pindex].Pad != nullptr )
278+ pads[pindex].Utime = time (NULL );
279+ }
280+ }
281+ else if (bytesReceived == sizeof (packet) && packet[0 ] >= 0 && packet[0 ] < XUSER_MAX_COUNT)
282+ {
283+ uint8_t pindex = CheckPadIndex ((uint8_t )packet[0 ], clientAddr);
284+ XINPUT_STATE* state = (XINPUT_STATE*)(packet + 1 );
285+ if (pindex >= 0 && pindex < XUSER_MAX_COUNT && pads[pindex].Pad != nullptr )
286+ {
287+ pads[pindex].Utime = time (NULL );
288+ vigem_target_x360_update (client, pads[pindex].Pad , *reinterpret_cast <XUSB_REPORT*>(&state->Gamepad ));
248289 }
249290 }
250291 }
0 commit comments