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