]> icculus.org git repositories - taylor/freespace2.git/blob - src/network/ptrack.cpp
handle player info and player selection
[taylor/freespace2.git] / src / network / ptrack.cpp
1 /*
2  * Copyright (C) Volition, Inc. 2005.  All rights reserved.
3  * 
4  * All source code herein is the property of Volition, Inc. You may not sell 
5  * or otherwise commercially exploit the source or things you created based on the 
6  * source.
7  *
8 */
9
10 //Pilot tracker client code
11
12 #ifdef PLAT_UNIX
13 #include <arpa/inet.h>
14 #include <netinet/in.h>
15 #include <errno.h>
16 #include <netdb.h>
17 #endif
18
19 #include "pstypes.h"
20 #include "timer.h"
21 #include "multi.h"
22 #include "ptrack.h"
23 #include "psnet.h"
24
25
26 // check structs for size compatibility
27 //SDL_COMPILE_TIME_ASSERT(udp_packet_header, sizeof(udp_packet_header) == 497);
28 #ifndef MAKE_FS1
29 SDL_COMPILE_TIME_ASSERT(vmt_freespace2_struct, sizeof(vmt_freespace2_struct) == 440);
30 #else
31 SDL_COMPILE_TIME_ASSERT(vmt_freespace_struct, sizeof(vmt_freespace_struct) == 468);
32 #endif
33 SDL_COMPILE_TIME_ASSERT(validate_id_request, sizeof(validate_id_request) == 60);
34 SDL_COMPILE_TIME_ASSERT(squad_war_request, sizeof(squad_war_request) == 104);
35 SDL_COMPILE_TIME_ASSERT(squad_war_response, sizeof(squad_war_response) == 256);
36 SDL_COMPILE_TIME_ASSERT(squad_war_result, sizeof(squad_war_result) == 72);
37 SDL_COMPILE_TIME_ASSERT(pilot_request, sizeof(pilot_request) == 32);
38
39
40 //Variables
41
42 #ifdef MAKE_FS1
43 SOCKET  pilotsock;
44 #define PILOTSOCK pilotsock
45 #else
46 #define PILOTSOCK Unreliable_socket
47 #endif
48
49 struct sockaddr_in      ptrackaddr;
50
51
52 int             FSWriteState;
53 int             FSReadState;
54 unsigned int    FSLastSentWrite;
55 unsigned int    FSFirstSentWrite;
56 unsigned int    FSLastSent;
57 unsigned int    FSFirstSent;
58
59 int             SWWriteState;
60 unsigned int SWLastSentWrite;
61 unsigned int SWFirstSentWrite;
62
63
64 udp_packet_header fs_pilot_req, fs_pilot_write, sw_res_write;
65 pilot_request *fs_pr;
66 #ifdef MAKE_FS1
67 vmt_freespace_struct *ReadFSPilot;
68 #else
69 vmt_freespace2_struct *ReadFSPilot;
70 #endif
71
72 // squad war response
73 squad_war_response SquadWarWriteResponse;
74
75
76 static int SerializePilotPacket(const udp_packet_header *uph, ubyte *data)
77 {
78         int packet_size = 0;
79         int i;
80 #ifdef MAKE_FS1
81         char h_pad = 0;
82 #endif
83
84         PXO_ADD_DATA(uph->type);
85 #ifdef MAKE_FS1
86         PXO_ADD_DATA(h_pad);
87 #endif
88         PXO_ADD_USHORT(uph->len);
89         PXO_ADD_UINT(uph->code);
90         PXO_ADD_USHORT(uph->xcode);
91 #ifdef MAKE_FS1
92         PXO_ADD_DATA(h_pad);
93         PXO_ADD_DATA(h_pad);
94 #endif
95         PXO_ADD_UINT(uph->sig);
96         PXO_ADD_UINT(uph->security);
97
98         switch (uph->type) {
99                 // no extra data for this
100                 case UNT_CONTROL:
101                         break;
102
103                 case UNT_PILOT_DATA_WRITE_NEW: {
104                         vmt_stats_struct *fs2 = (vmt_stats_struct *)&uph->data;
105
106                         PXO_ADD_DATA(fs2->tracker_id);
107                         PXO_ADD_DATA(fs2->pilot_name);
108
109                         PXO_ADD_DATA(fs2->pad_a);       // junk, for size/alignment
110
111                         PXO_ADD_INT(fs2->score);
112                         PXO_ADD_INT(fs2->rank);
113
114 #ifdef MAKE_FS1
115                         for (i = 0; i < MAX_FS_MEDALS; i++) {
116                                 PXO_ADD_INT(fs2->medals[i]);
117                         }
118
119                         for (i = 0; i < MAX_FS_SHIP_TYPES; i++) {
120                                 PXO_ADD_INT(fs2->kills[i]);
121                         }
122 #endif
123
124                         PXO_ADD_INT(fs2->assists);
125                         PXO_ADD_INT(fs2->kill_count);
126                         PXO_ADD_INT(fs2->kill_count_ok);
127                         PXO_ADD_UINT(fs2->p_shots_fired);
128                         PXO_ADD_UINT(fs2->s_shots_fired);
129
130                         PXO_ADD_UINT(fs2->p_shots_hit);
131                         PXO_ADD_UINT(fs2->s_shots_hit);
132
133                         PXO_ADD_UINT(fs2->p_bonehead_hits);
134                         PXO_ADD_UINT(fs2->s_bonehead_hits);
135                         PXO_ADD_INT(fs2->bonehead_kills);
136
137                         PXO_ADD_INT(fs2->security);
138                         PXO_ADD_DATA(fs2->virgin_pilot);
139
140                         PXO_ADD_DATA(fs2->pad_b);       // junk, for size/alignment
141
142                         PXO_ADD_UINT(fs2->checksum);
143
144                         PXO_ADD_UINT(fs2->missions_flown);
145                         PXO_ADD_UINT(fs2->flight_time);
146                         PXO_ADD_UINT(fs2->last_flown);
147
148 #ifndef MAKE_FS1
149                         PXO_ADD_USHORT(fs2->num_medals);
150                         PXO_ADD_USHORT(fs2->num_ship_types);
151
152                         for (i = 0; i < MAX_FS2_MEDALS; i++) {
153                                 PXO_ADD_INT(fs2->medals[i]);
154                         }
155
156                         for (i = 0; i < MAX_FS2_SHIP_TYPES; i++) {
157                                 PXO_ADD_USHORT(fs2->kills[i]);
158                         }
159 #endif
160
161                         break;
162                 }
163
164                 case UNT_SW_RESULT_WRITE: {
165                         squad_war_result *sw_result     = (squad_war_result *)&uph->data;
166
167                         PXO_ADD_DATA(sw_result->match_code);
168                         PXO_ADD_DATA(sw_result->result);
169                         PXO_ADD_DATA(sw_result->squad_count1);
170                         PXO_ADD_DATA(sw_result->squad_count2);
171                         PXO_ADD_DATA(sw_result->pad);           // junk, for size/alignment
172
173                         for (i = 0; i < MAX_SQUAD_PLAYERS; i++) {
174                                 PXO_ADD_INT(sw_result->squad_winners[i]);
175                         }
176
177                         for (i = 0; i < MAX_SQUAD_PLAYERS; i++) {
178                                 PXO_ADD_INT(sw_result->squad_losers[i]);
179                         }
180
181                         break;
182                 }
183
184                 case UNT_PILOT_DATA_READ_NEW:
185                 case UNT_PILOT_DATA_READ: {
186                         pilot_request *pr = (pilot_request *)&uph->data;
187
188                         PXO_ADD_DATA(pr->pilot_name);
189                         PXO_ADD_DATA(pr->tracker_id);
190                         PXO_ADD_DATA(pr->pad);          // junk, for size/alignment
191
192                         break;
193                 }
194
195                 // we shouldn't be sending any other packet types
196                 default:
197                         Int3();
198                         break;
199         }
200
201         SDL_assert(packet_size >= (int)PACKED_HEADER_ONLY_SIZE);
202         SDL_assert(packet_size == (int)uph->len);
203
204         return packet_size;
205 }
206
207 static void DeserializePilotPacket(const ubyte *data, const int data_size, udp_packet_header *uph)
208 {
209         int offset = 0;
210         int i;
211 #ifdef MAKE_FS1
212         char h_pad;
213 #endif
214
215         memset(uph, 0, sizeof(udp_packet_header));
216
217         // make sure we received a complete base packet
218         if (data_size < (int)PACKED_HEADER_ONLY_SIZE) {
219                 uph->len = 0;
220                 uph->type = 0xff;
221
222                 return;
223         }
224
225         PXO_GET_DATA(uph->type);
226 #ifdef MAKE_FS1
227         PXO_GET_DATA(h_pad);
228 #endif
229         PXO_GET_USHORT(uph->len);
230         PXO_GET_UINT(uph->code);
231         PXO_GET_USHORT(uph->xcode);
232 #ifdef MAKE_FS1
233         PXO_GET_DATA(h_pad);
234         PXO_GET_DATA(h_pad);
235 #endif
236         PXO_GET_UINT(uph->sig);
237         PXO_GET_UINT(uph->security);
238
239         // sanity check data size to make sure we reveived all of the expected packet
240 #ifndef MAKE_FS1
241         // (the -1 is because psnet2 pops off one byte)
242         if ((int)uph->len-1 > data_size) {
243 #else
244         if ((int)uph->len > data_size) {
245 #endif
246                 uph->len = 0;
247                 uph->type = 0xff;
248
249                 return;
250         }
251
252         switch (uph->type) {
253                 // no extra data for these
254                 case UNT_PILOT_READ_FAILED:
255                 case UNT_PILOT_WRITE_SUCCESS:
256                 case UNT_PILOT_WRITE_FAILED:
257                         break;
258
259                 case UNT_PILOT_DATA_RESPONSE: {
260                         vmt_stats_struct *fs2 = (vmt_stats_struct *)&uph->data;
261
262                         PXO_GET_DATA(fs2->tracker_id);
263                         PXO_GET_DATA(fs2->pilot_name);
264
265                         PXO_GET_DATA(fs2->pad_a);       // junk, for size/alignment
266
267                         PXO_GET_INT(fs2->score);
268                         PXO_GET_INT(fs2->rank);
269
270 #ifdef MAKE_FS1
271                         for (i = 0; i < MAX_FS_MEDALS; i++) {
272                                 PXO_GET_INT(fs2->medals[i]);
273                         }
274
275                         for (i =0; i < MAX_FS_SHIP_TYPES; i++) {
276                                 PXO_GET_INT(fs2->kills[i]);
277                         }
278 #endif
279
280                         PXO_GET_INT(fs2->assists);
281                         PXO_GET_INT(fs2->kill_count);
282                         PXO_GET_INT(fs2->kill_count_ok);
283                         PXO_GET_UINT(fs2->p_shots_fired);
284                         PXO_GET_UINT(fs2->s_shots_fired);
285
286                         PXO_GET_UINT(fs2->p_shots_hit);
287                         PXO_GET_UINT(fs2->s_shots_hit);
288
289                         PXO_GET_UINT(fs2->p_bonehead_hits);
290                         PXO_GET_UINT(fs2->s_bonehead_hits);
291                         PXO_GET_INT(fs2->bonehead_kills);
292
293                         PXO_GET_INT(fs2->security);
294                         PXO_GET_DATA(fs2->virgin_pilot);
295
296                         PXO_GET_DATA(fs2->pad_b);       // junk, for size/alignment
297
298                         PXO_GET_UINT(fs2->checksum);
299
300                         PXO_GET_UINT(fs2->missions_flown);
301                         PXO_GET_UINT(fs2->flight_time);
302                         PXO_GET_UINT(fs2->last_flown);
303
304 #ifndef MAKE_FS1
305                         PXO_GET_USHORT(fs2->num_medals);
306                         PXO_GET_USHORT(fs2->num_ship_types);
307
308                         for (i = 0; i < MAX_FS2_MEDALS; i++) {
309                                 PXO_GET_INT(fs2->medals[i]);
310                         }
311
312                         for (i =0; i < MAX_FS2_SHIP_TYPES; i++) {
313                                 PXO_GET_USHORT(fs2->kills[i]);
314                         }
315 #endif
316
317                         break;
318                 }
319
320                 case UNT_SW_RESULT_RESPONSE: {
321                         squad_war_response *sw_resp = (squad_war_response *)&uph->data;
322
323                         PXO_GET_DATA(sw_resp->reason);
324                         PXO_GET_DATA(sw_resp->accepted);
325
326                         break;
327                 }
328
329                 default:
330                         break;
331         }
332
333         //SDL_assert(offset == data_size);
334 }
335
336
337 int InitPilotTrackerClient()
338 {
339         struct sockaddr_in sockaddr;
340         in_addr_t iaddr;
341
342         FSWriteState = STATE_IDLE;
343         FSReadState = STATE_IDLE;       
344         SWWriteState = STATE_IDLE;
345         
346         ReadFSPilot = NULL;
347
348         fs_pr = (pilot_request *)&fs_pilot_req.data;
349
350 #ifdef MAKE_FS1
351         pilotsock = socket(AF_INET,SOCK_DGRAM,0);
352         
353         if ( pilotsock == (SOCKET)INVALID_SOCKET )
354         {
355                 mprintf(("Unable to open a socket.\n"));
356                 return 0;
357         }
358 #endif
359         
360         memset( &sockaddr, 0, sizeof(struct sockaddr_in) );
361         sockaddr.sin_family = AF_INET; 
362         sockaddr.sin_addr.s_addr = INADDR_ANY; 
363         sockaddr.sin_port = 0;//htons(REGPORT);
364         
365 #ifdef MAKE_FS1
366         if (SOCKET_ERROR==bind(pilotsock, (struct sockaddr*)&sockaddr, sizeof (sockaddr)))
367         {       
368                 mprintf(("Unable to bind a socket.\n"));
369                 mprintf(("WSAGetLastError() returned %d.\n",WSAGetLastError()));
370                 return 0;
371         }
372 #endif
373         
374         // iaddr = inet_addr ( Multi_user_tracker_ip_address ); 
375
376         // first try and resolve by name
377         iaddr = inet_addr( Multi_options_g.user_tracker_ip );
378         if ( iaddr == INADDR_NONE ) {
379                 struct hostent *he;
380                 he = gethostbyname( Multi_options_g.user_tracker_ip );
381                 if(!he)
382                         return 0;
383         /*
384                 {               
385                         // try and resolve by address
386                         unsigned int n_order = inet_addr(Multi_user_tracker_ip_address);
387                         he = gethostbyaddr((char*)&n_order,4,PF_INET);
388
389                         if(!he){
390                                 return 0;
391                         }
392                 }
393         */
394                 iaddr = ((in_addr *)(he->h_addr))->s_addr;
395         }
396         
397         ptrackaddr.sin_addr.s_addr = iaddr;
398         ptrackaddr.sin_family = AF_INET; 
399         ptrackaddr.sin_port = htons(REGPORT);
400         
401         return 1;
402 }
403
404 // Returns:
405 // -3   Error -- Called with NULL, but no request is waiting
406 // -2   Error -- Already sending data (hasn't timed out yet)
407 // -1   Timeout trying to send pilot data
408 // 0    Sending
409 // 1    Data succesfully sent
410 // 2    Send Cancelled (data may still have been written already, we just haven't been ACK'd yet)
411 // 3    Pilot not written (for some reason)
412   
413 // Call with NULL to poll 
414 // Call with -1 to cancel send
415 // Call with valid pointer to a vmt_descent3_struct to initiate send
416 int SendFSPilotData(vmt_stats_struct *fs_pilot)
417 {
418         //First check the network
419         PollPTrackNet();
420
421         if(fs_pilot == NULL)
422         {
423                 if(FSWriteState == STATE_IDLE)
424                 {
425                         return -3;
426                 }
427                 if(FSWriteState == STATE_SENDING_PILOT)
428                 {
429                         return 0;
430                 }
431                 if(FSWriteState == STATE_WROTE_PILOT)
432                 {
433                         //We wrote this pilot, and now we are about to inform the app, so back to idle
434                         FSWriteState = STATE_IDLE;
435                         return 1;
436                 }
437                 if(FSWriteState == STATE_TIMED_OUT)
438                 {
439                         //We gave up on sending this pilot, and now we are about to inform the app, so back to idle
440                         FSWriteState = STATE_IDLE;
441
442                         return -1;
443                 }
444                 if(FSWriteState == STATE_WRITE_PILOT_FAILED)
445                 {
446                         //The tracker said this dude couldn't be written
447                         FSWriteState = STATE_IDLE;
448
449                         return 3;
450                 }
451
452         }
453         else if(fs_pilot == (vmt_stats_struct*)0xffffffff)
454         {
455                 if(FSWriteState == STATE_IDLE)
456                 {
457                         return -3;
458                 }
459                 else
460                 {
461                         //Cancel this baby
462                         FSWriteState = STATE_IDLE;
463
464                         return 2;
465                 }
466
467         }
468         else if(FSWriteState == STATE_IDLE)
469         {
470                 //New request, send out the req, and go for it.
471                 
472                 FSWriteState = STATE_SENDING_PILOT;
473                 
474                 FSLastSentWrite = 0;
475                 FSFirstSentWrite = timer_get_milliseconds();
476
477                 fs_pilot_write.type = UNT_PILOT_DATA_WRITE_NEW;
478 #ifdef MAKE_FS1
479                 fs_pilot_write.code = CMD_GAME_FREESPACE;
480 #else
481                 fs_pilot_write.code = CMD_GAME_FREESPACE2;
482 #endif
483                 fs_pilot_write.len = PACKED_HEADER_ONLY_SIZE+sizeof(vmt_stats_struct);
484                 memcpy(&fs_pilot_write.data,fs_pilot,sizeof(vmt_stats_struct));
485
486                 return 0;       
487         }
488         return -2;
489 }
490
491 // Returns:
492 // -3   Error -- Called with NULL, but no request is waiting
493 // -2   Error -- Already sending data (hasn't timed out yet)
494 // -1   Timeout trying to send pilot data
495 // 0    Sending
496 // 1    Data succesfully sent
497 // 2    Send Cancelled (data may still have been written already, we just haven't been ACK'd yet)
498 // 3    Pilot not written (for some reason)
499   
500 // Call with NULL to poll 
501 // Call with -1 to cancel send
502 // Call with valid pointer to a vmt_descent3_struct to initiate send
503 int SendSWData(squad_war_result *sw_res, squad_war_response *sw_resp)
504 {
505         //First check the network
506         PollPTrackNet();
507
508         if(sw_res == NULL){
509                 if(SWWriteState == STATE_IDLE){
510                         return -3;
511                 }
512                 if(SWWriteState == STATE_SENDING_PILOT){
513                         return 0;
514                 }
515
516                 // fill in the response
517                 if(SWWriteState == STATE_WROTE_PILOT){
518                         // We wrote this pilot, and now we are about to inform the app, so back to idle
519                         SWWriteState = STATE_IDLE;
520                         
521                         if(sw_resp != NULL){
522                                 memcpy(sw_resp, &SquadWarWriteResponse, sizeof(squad_war_response));
523                         }
524                         return 1;
525                 }
526                 // fill in the response
527                 if(SWWriteState == STATE_WRITE_PILOT_FAILED){
528                         // The tracker said this dude couldn't be written               
529                         SWWriteState = STATE_IDLE;
530
531                         if(sw_resp != NULL){
532                                 memcpy(sw_resp, &SquadWarWriteResponse, sizeof(squad_war_response));
533                         }
534                         return 3;
535                 }
536
537                 if(SWWriteState == STATE_TIMED_OUT){
538                         // We gave up on sending this pilot, and now we are about to inform the app, so back to idle
539                         SWWriteState = STATE_IDLE;
540
541                         return -1;
542                 }               
543         } else if(sw_res == (squad_war_result*)0xffffffff){
544                 if(SWWriteState == STATE_IDLE){
545                         return -3;
546                 } else {
547                         // Cancel this baby
548                         SWWriteState = STATE_IDLE;
549
550                         return 2;
551                 }
552         } else if(SWWriteState == STATE_IDLE) {
553                 //New request, send out the req, and go for it.
554                 
555                 SWWriteState = STATE_SENDING_PILOT;
556                 
557                 SWLastSentWrite = 0;
558                 SWFirstSentWrite = timer_get_milliseconds();
559
560                 sw_res_write.len = PACKED_HEADER_ONLY_SIZE+sizeof(squad_war_result);
561                 sw_res_write.type = UNT_SW_RESULT_WRITE;
562 #ifdef MAKE_FS1
563                 sw_res_write.code = CMD_GAME_FREESPACE;
564 #else
565                 sw_res_write.code = CMD_GAME_FREESPACE2;
566 #endif
567                 memcpy(&sw_res_write.data, sw_res, sizeof(squad_war_result));
568
569                 return 0;       
570         }
571         return -2;
572 }
573
574
575 // Returns:
576 // -3   Error -- Called with NULL, but no request is waiting
577 // -2   Error -- Already waiting on data (hasn't timed out yet)
578 // -1   Timeout waiting for pilot data
579 // 0    Waiting for data
580 // 1    Data received
581 // 2    Get Cancelled
582 // 3    Pilot not found
583         
584 // Call with NULL to poll 
585 // Call with -1 to cancel wait
586 // Call with valid pointer to a vmt_descent3_struct to get a response
587 int GetFSPilotData(vmt_stats_struct *fs_pilot, const char *pilot_name, const char *tracker_id, int get_security)
588 {
589         //First check the network
590         PollPTrackNet();
591
592         if(fs_pilot == NULL)
593         {
594                 if(FSReadState == STATE_IDLE)
595                 {
596                         return -3;
597                 }
598                 if(FSReadState == STATE_READING_PILOT)
599                 {
600                         return 0;
601                 }
602                 if(FSReadState == STATE_RECEIVED_PILOT)
603                 {
604                         // We got this pilot, and now we are about to inform the app, so back to idle
605                         FSReadState = STATE_IDLE;
606                         ReadFSPilot = NULL;
607                         return 1;
608                 }
609                 if(FSReadState == STATE_TIMED_OUT)
610                 {
611                         // We gave up on this pilot, and now we are about to inform the app, so back to idle
612                         FSReadState = STATE_IDLE;
613                         ReadFSPilot = NULL;
614                         return -1;
615                 }
616                 if(FSReadState == STATE_PILOT_NOT_FOUND)
617                 {
618                         //The tracker said this dude is not found.
619                         FSReadState = STATE_IDLE;
620                         ReadFSPilot = NULL;
621                         return 3;
622                 }
623
624         }
625         else if(fs_pilot == (vmt_stats_struct*)0xffffffff)
626         {
627                 if(FSReadState == STATE_IDLE)
628                 {
629                         return -3;
630                 }
631                 else
632                 {
633                         //Cancel this baby
634                         FSReadState = STATE_IDLE;
635                         ReadFSPilot = NULL;
636                         return 2;
637                 }
638
639         }
640         else if(FSReadState == STATE_IDLE)
641         {
642                 //New request, send out the req, and go for it.
643                 
644                 FSReadState = STATE_READING_PILOT;
645                 ReadFSPilot = fs_pilot;
646                 FSLastSent = 0;
647                 FSFirstSent = timer_get_milliseconds();
648
649                 fs_pilot_req.len = PACKED_HEADER_ONLY_SIZE+sizeof(pilot_request);
650
651                 if(get_security){
652                         fs_pilot_req.type = UNT_PILOT_DATA_READ_NEW;
653                 } else {
654                         fs_pilot_req.type = UNT_PILOT_DATA_READ;                        
655                 }
656
657 #ifdef MAKE_FS1
658                 fs_pilot_req.code = CMD_GAME_FREESPACE;
659 #else
660                 fs_pilot_req.code = CMD_GAME_FREESPACE2;
661 #endif
662                 SDL_strlcpy(fs_pr->pilot_name, pilot_name, SDL_arraysize(fs_pr->pilot_name));
663                 SDL_strlcpy(fs_pr->tracker_id, tracker_id, SDL_arraysize(fs_pr->tracker_id));
664
665                 return 0;       
666         }
667         return -2;
668
669 }
670
671 // Send an ACK to the server
672 void AckServer(unsigned int sig)
673 {
674         udp_packet_header ack_pack;
675         ubyte packet_data[sizeof(udp_packet_header)];
676         int packet_length = 0;
677
678         ack_pack.type = UNT_CONTROL;
679         ack_pack.sig = sig;
680         ack_pack.code = CMD_CLIENT_RECEIVED;
681         ack_pack.len = PACKED_HEADER_ONLY_SIZE; 
682
683         packet_length = SerializePilotPacket(&ack_pack, packet_data);
684         SDL_assert(packet_length == PACKED_HEADER_ONLY_SIZE);
685         PXO_SENDTO(PILOTSOCK, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
686 }
687
688 void IdlePTrack()
689 {
690         ubyte packet_data[sizeof(udp_packet_header)];
691         int packet_length = 0;
692
693 #ifndef MAKE_FS1
694         PSNET_TOP_LAYER_PROCESS();
695 #endif
696
697         // reading pilot data
698         if(FSReadState == STATE_READING_PILOT){
699                 if((timer_get_milliseconds()-FSFirstSent)>=PILOT_REQ_TIMEOUT){
700                         FSReadState = STATE_TIMED_OUT;
701                 } else if((timer_get_milliseconds()-FSLastSent)>=PILOT_REQ_RESEND_TIME){
702                         //Send 'da packet
703                         packet_length = SerializePilotPacket(&fs_pilot_req, packet_data);
704                         PXO_SENDTO(PILOTSOCK, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
705                         FSLastSent = timer_get_milliseconds();
706                 }
707         }
708
709         // writing pilot data
710         if(FSWriteState == STATE_SENDING_PILOT){
711                 if((timer_get_milliseconds()-FSFirstSentWrite)>=PILOT_REQ_TIMEOUT){
712                         FSWriteState = STATE_TIMED_OUT;
713
714                 } else if((timer_get_milliseconds()-FSLastSentWrite)>=PILOT_REQ_RESEND_TIME){
715                         // Send 'da packet
716                         packet_length = SerializePilotPacket(&fs_pilot_write, packet_data);
717                         PXO_SENDTO(PILOTSOCK, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
718                         FSLastSentWrite = timer_get_milliseconds();
719                 }
720         }
721
722         // writing squad war results
723         if(SWWriteState == STATE_SENDING_PILOT){
724                 if((timer_get_milliseconds()-SWFirstSentWrite) >= PILOT_REQ_TIMEOUT){
725                         SWWriteState = STATE_TIMED_OUT;
726                 } else if((timer_get_milliseconds()-SWLastSentWrite) >= PILOT_REQ_RESEND_TIME){
727                         // Send 'da packet
728                         packet_length = SerializePilotPacket(&sw_res_write, packet_data);
729                         PXO_SENDTO(PILOTSOCK, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
730                         SWLastSentWrite = timer_get_milliseconds();
731                 }
732         }
733 }
734
735 void PollPTrackNet()
736 {
737         fd_set read_fds;                   
738         struct timeval timeout;
739         ubyte packet_data[sizeof(udp_packet_header)];
740
741         IdlePTrack();
742         
743         timeout.tv_sec=0;            
744         timeout.tv_usec=0;
745         
746         FD_ZERO(&read_fds);
747         FD_SET(PILOTSOCK, &read_fds);
748
749         if(PXO_SELECT(PILOTSOCK+1, &read_fds,NULL,NULL,&timeout, PSNET_TYPE_USER_TRACKER)){
750                 int bytesin;
751                 int addrsize;
752                 struct sockaddr_in fromaddr;
753
754                 udp_packet_header inpacket;
755
756                 SDL_zero(inpacket);
757                 addrsize = sizeof(struct sockaddr_in);
758
759                 bytesin = PXO_RECVFROM(PILOTSOCK, (char *)&packet_data, sizeof(udp_packet_header), 0, (struct sockaddr *)&fromaddr, &addrsize, PSNET_TYPE_USER_TRACKER);
760
761                 if (bytesin > 0) {
762                         DeserializePilotPacket(packet_data, bytesin, &inpacket);
763
764 #ifndef MAKE_FS1
765                         // decrease packet size by 1
766                         inpacket.len--;
767 #endif
768 #ifndef NDEBUG
769                 } else {
770                         int wserr=WSAGetLastError();
771                         mprintf(("recvfrom() failure. WSAGetLastError() returned %d\n",wserr));
772 #endif
773                 }
774
775                 //Check to make sure the packets ok
776                 if ( (bytesin > 0) && (bytesin == inpacket.len) ) {
777                         switch(inpacket.type){
778                         case UNT_PILOT_DATA_RESPONSE:
779                                 if(inpacket.code == CMD_GAME_FREESPACE2){
780 #ifdef MAKE_FS1
781                                         Int3();
782 #else
783                                         if(FSReadState == STATE_READING_PILOT){
784                                                 vmt_freespace2_struct *stats;
785                                                 
786                                                 // 9/17/98 MWA.  Compare the tracker id of this packet with the tracker id of
787                                                 // what we are expecting.  Only set our state to something different when
788                                                 // the tracker id's match.  This fixes possible multiple packets for a single pilto
789                                                 // accidentally getting set for the wrong pilot
790
791                                                 stats = (vmt_freespace2_struct *)(&inpacket.data);
792                                                 if ( !SDL_strncasecmp(stats->tracker_id, fs_pr->tracker_id,TRACKER_ID_LEN) ) {
793                                                         //Copy the data
794                                                         memcpy(ReadFSPilot,&inpacket.data,sizeof(vmt_freespace2_struct));
795                                                         //Set the state 
796                                                         FSReadState = STATE_RECEIVED_PILOT;
797                                                 }
798                                         }
799 #endif
800                                 } else if(inpacket.code == CMD_GAME_FREESPACE){
801 #ifndef MAKE_FS1
802                                         Int3();
803 #else
804                                         if(FSReadState == STATE_READING_PILOT){
805                                                 vmt_freespace_struct *stats;
806
807                                                 // 9/17/98 MWA.  Compare the tracker id of this packet with the tracker id of
808                                                 // what we are expecting.  Only set our state to something different when
809                                                 // the tracker id's match.  This fixes possible multiple packets for a single pilto
810                                                 // accidentally getting set for the wrong pilot
811
812                                                 stats = (vmt_freespace_struct *)(&inpacket.data);
813                                                 if ( !SDL_strncasecmp(stats->tracker_id, fs_pr->tracker_id,TRACKER_ID_LEN) ) {
814                                                         //Copy the data
815                                                         memcpy(ReadFSPilot,&inpacket.data,sizeof(vmt_freespace_struct));
816                                                         //Set the state
817                                                         FSReadState = STATE_RECEIVED_PILOT;
818                                                 }
819                                         }
820 #endif
821                                 } else {
822                                         Int3();
823                                 }
824                                 break;
825
826                         case UNT_PILOT_READ_FAILED:
827                                 if(inpacket.code == CMD_GAME_FREESPACE2){
828 #ifdef MAKE_FS1
829                                         Int3();
830 #else
831                                         if(FSReadState == STATE_READING_PILOT){
832                                                 FSReadState = STATE_PILOT_NOT_FOUND;
833                                         }
834 #endif
835                                 } else if(inpacket.code == CMD_GAME_FREESPACE){
836 #ifndef MAKE_FS1
837                                         Int3();
838 #else
839                                         if(FSReadState == STATE_READING_PILOT){
840                                                 FSReadState = STATE_PILOT_NOT_FOUND;
841                                         }
842 #endif
843                                 } else {
844                                         Int3();
845                                 }
846                                 break;
847
848                         case UNT_PILOT_WRITE_SUCCESS:
849                                 if(inpacket.code == CMD_GAME_FREESPACE2){
850 #ifdef MAKE_FS1
851                                         Int3();
852 #else
853                                         if(FSWriteState == STATE_SENDING_PILOT){
854                                                 FSWriteState = STATE_WROTE_PILOT;
855                                         }
856 #endif
857                                 } else if(inpacket.code == CMD_GAME_FREESPACE){
858 #ifndef MAKE_FS1
859                                         Int3();
860 #else
861                                         if(FSWriteState == STATE_SENDING_PILOT){
862                                                 FSWriteState = STATE_WROTE_PILOT;
863                                         }
864 #endif
865                                 } else {
866                                         Int3();
867                                 }
868                                 break;
869
870                         case UNT_PILOT_WRITE_FAILED:
871                                 if(inpacket.code == CMD_GAME_FREESPACE2){
872 #ifdef MAKE_FS1
873                                         Int3();
874 #else
875                                         if(FSWriteState == STATE_SENDING_PILOT){
876                                                 FSWriteState = STATE_WRITE_PILOT_FAILED;
877                                         }
878 #endif
879                                 } else  if(inpacket.code == CMD_GAME_FREESPACE){
880 #ifndef MAKE_FS1
881                                         Int3();
882 #else
883                                         if(FSWriteState == STATE_SENDING_PILOT){
884                                                 FSWriteState = STATE_WRITE_PILOT_FAILED;
885                                         }
886 #endif
887                                 } else {
888                                         Int3();
889                                 }
890                                 break;
891
892                         case UNT_SW_RESULT_RESPONSE:
893                                 if(SWWriteState == STATE_SENDING_PILOT){                                        
894                                         // copy the data
895                                         SDL_assert((bytesin - PACKED_HEADER_ONLY_SIZE) == sizeof(squad_war_response));
896                                         if((bytesin - PACKED_HEADER_ONLY_SIZE) == sizeof(squad_war_response)){
897                                                 memset(&SquadWarWriteResponse, 0, sizeof(squad_war_response));
898                                                 memcpy(&SquadWarWriteResponse, inpacket.data, sizeof(squad_war_response));
899
900                                                 // now check to see if we're good
901                                                 if(SquadWarWriteResponse.accepted){
902                                                         SWWriteState = STATE_WROTE_PILOT;
903                                                 } else {
904                                                         SWWriteState = STATE_WRITE_PILOT_FAILED;
905                                                 }
906                                         } else {
907                                                 SWWriteState = STATE_WRITE_PILOT_FAILED;
908                                         }       
909                                 }
910                                 break;
911
912                         case UNT_CONTROL:
913                                 Int3();
914                                 break;
915
916                         case UNT_CONTROL_VALIDATION:
917                                 Int3();
918                                 break;
919
920                         default:
921                                 break;
922                         }
923                         AckServer(inpacket.sig);
924                 }
925         }
926 }