2 * Copyright (C) Volition, Inc. 2005. All rights reserved.
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
10 //Pilot tracker client code
13 #include <arpa/inet.h>
14 #include <netinet/in.h>
26 // check structs for size compatibility
27 SDL_COMPILE_TIME_ASSERT(udp_packet_header, sizeof(udp_packet_header) == 497);
29 SDL_COMPILE_TIME_ASSERT(vmt_freespace2_struct, sizeof(vmt_freespace2_struct) == 440);
31 SDL_COMPILE_TIME_ASSERT(vmt_freespace_struct, sizeof(vmt_freespace_struct) == 468);
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);
44 struct sockaddr_in ptrackaddr;
49 unsigned int FSLastSentWrite;
50 unsigned int FSFirstSentWrite;
51 unsigned int FSLastSent;
52 unsigned int FSFirstSent;
55 unsigned int SWLastSentWrite;
56 unsigned int SWFirstSentWrite;
59 udp_packet_header fs_pilot_req, fs_pilot_write, sw_res_write;
62 vmt_freespace_struct *ReadFSPilot;
64 vmt_freespace2_struct *ReadFSPilot;
68 squad_war_response SquadWarWriteResponse;
71 static int SerializePilotPacket(const udp_packet_header *uph, ubyte *data)
76 PXO_ADD_DATA(uph->type);
77 PXO_ADD_USHORT(uph->len);
78 PXO_ADD_UINT(uph->code);
79 PXO_ADD_USHORT(uph->xcode);
80 PXO_ADD_UINT(uph->sig);
81 PXO_ADD_UINT(uph->security);
84 // no extra data for this
88 case UNT_PILOT_DATA_WRITE_NEW: {
89 vmt_stats_struct *fs2 = (vmt_stats_struct *)&uph->data;
91 PXO_ADD_DATA(fs2->tracker_id);
92 PXO_ADD_DATA(fs2->pilot_name);
94 PXO_ADD_DATA(fs2->pad_a); // junk, for size/alignment
96 PXO_ADD_INT(fs2->score);
97 PXO_ADD_INT(fs2->rank);
100 for (i = 0; i < MAX_FS_MEDALS; i++) {
101 PXO_ADD_INT(fs2->medals[i]);
104 for (i = 0; i < MAX_FS_SHIP_TYPES; i++) {
105 PXO_ADD_INT(fs2->kills[i]);
109 PXO_ADD_INT(fs2->assists);
110 PXO_ADD_INT(fs2->kill_count);
111 PXO_ADD_INT(fs2->kill_count_ok);
112 PXO_ADD_UINT(fs2->p_shots_fired);
113 PXO_ADD_UINT(fs2->s_shots_fired);
115 PXO_ADD_UINT(fs2->p_shots_hit);
116 PXO_ADD_UINT(fs2->s_shots_hit);
118 PXO_ADD_UINT(fs2->p_bonehead_hits);
119 PXO_ADD_UINT(fs2->s_bonehead_hits);
120 PXO_ADD_INT(fs2->bonehead_kills);
122 PXO_ADD_INT(fs2->security);
123 PXO_ADD_DATA(fs2->virgin_pilot);
125 PXO_ADD_DATA(fs2->pad_b); // junk, for size/alignment
127 PXO_ADD_UINT(fs2->checksum);
129 PXO_ADD_UINT(fs2->missions_flown);
130 PXO_ADD_UINT(fs2->flight_time);
131 PXO_ADD_UINT(fs2->last_flown);
134 PXO_ADD_USHORT(fs2->num_medals);
135 PXO_ADD_USHORT(fs2->num_ship_types);
137 for (i = 0; i < MAX_FS2_MEDALS; i++) {
138 PXO_ADD_INT(fs2->medals[i]);
141 for (i = 0; i < MAX_FS2_SHIP_TYPES; i++) {
142 PXO_ADD_USHORT(fs2->kills[i]);
149 case UNT_SW_RESULT_WRITE: {
150 squad_war_result *sw_result = (squad_war_result *)&uph->data;
152 PXO_ADD_DATA(sw_result->match_code);
153 PXO_ADD_DATA(sw_result->result);
154 PXO_ADD_DATA(sw_result->squad_count1);
155 PXO_ADD_DATA(sw_result->squad_count2);
156 PXO_ADD_DATA(sw_result->pad); // junk, for size/alignment
158 for (i = 0; i < MAX_SQUAD_PLAYERS; i++) {
159 PXO_ADD_INT(sw_result->squad_winners[i]);
162 for (i = 0; i < MAX_SQUAD_PLAYERS; i++) {
163 PXO_ADD_INT(sw_result->squad_losers[i]);
169 case UNT_PILOT_DATA_READ_NEW:
170 case UNT_PILOT_DATA_READ: {
171 pilot_request *pr = (pilot_request *)&uph->data;
173 PXO_ADD_DATA(pr->pilot_name);
174 PXO_ADD_DATA(pr->tracker_id);
175 PXO_ADD_DATA(pr->pad); // junk, for size/alignment
180 // we shouldn't be sending any other packet types
186 SDL_assert(packet_size >= (int)PACKED_HEADER_ONLY_SIZE);
187 SDL_assert(packet_size == (int)uph->len);
192 static void DeserializePilotPacket(const ubyte *data, const int data_size, udp_packet_header *uph)
197 memset(uph, 0, sizeof(udp_packet_header));
199 // make sure we received a complete base packet
200 if (data_size < (int)PACKED_HEADER_ONLY_SIZE) {
207 PXO_GET_DATA(uph->type);
208 PXO_GET_USHORT(uph->len);
209 PXO_GET_UINT(uph->code);
210 PXO_GET_USHORT(uph->xcode);
211 PXO_GET_UINT(uph->sig);
212 PXO_GET_UINT(uph->security);
214 // sanity check data size to make sure we reveived all of the expected packet
215 // (not exactly sure what -1 is for, but that's how it is later)
216 if ((int)uph->len-1 > data_size) {
224 // no extra data for these
225 case UNT_PILOT_READ_FAILED:
226 case UNT_PILOT_WRITE_SUCCESS:
227 case UNT_PILOT_WRITE_FAILED:
230 case UNT_PILOT_DATA_RESPONSE: {
231 vmt_stats_struct *fs2 = (vmt_stats_struct *)&uph->data;
233 PXO_GET_DATA(fs2->tracker_id);
234 PXO_GET_DATA(fs2->pilot_name);
236 PXO_GET_DATA(fs2->pad_a); // junk, for size/alignment
238 PXO_GET_INT(fs2->score);
239 PXO_GET_INT(fs2->rank);
242 for (i = 0; i < MAX_FS_MEDALS; i++) {
243 PXO_GET_INT(fs2->medals[i]);
246 for (i =0; i < MAX_FS_SHIP_TYPES; i++) {
247 PXO_GET_INT(fs2->kills[i]);
251 PXO_GET_INT(fs2->assists);
252 PXO_GET_INT(fs2->kill_count);
253 PXO_GET_INT(fs2->kill_count_ok);
254 PXO_GET_UINT(fs2->p_shots_fired);
255 PXO_GET_UINT(fs2->s_shots_fired);
257 PXO_GET_UINT(fs2->p_shots_hit);
258 PXO_GET_UINT(fs2->s_shots_hit);
260 PXO_GET_UINT(fs2->p_bonehead_hits);
261 PXO_GET_UINT(fs2->s_bonehead_hits);
262 PXO_GET_INT(fs2->bonehead_kills);
264 PXO_GET_INT(fs2->security);
265 PXO_GET_DATA(fs2->virgin_pilot);
267 PXO_GET_DATA(fs2->pad_b); // junk, for size/alignment
269 PXO_GET_UINT(fs2->checksum);
271 PXO_GET_UINT(fs2->missions_flown);
272 PXO_GET_UINT(fs2->flight_time);
273 PXO_GET_UINT(fs2->last_flown);
276 PXO_GET_USHORT(fs2->num_medals);
277 PXO_GET_USHORT(fs2->num_ship_types);
279 for (i = 0; i < MAX_FS2_MEDALS; i++) {
280 PXO_GET_INT(fs2->medals[i]);
283 for (i =0; i < MAX_FS2_SHIP_TYPES; i++) {
284 PXO_GET_USHORT(fs2->kills[i]);
291 case UNT_SW_RESULT_RESPONSE: {
292 squad_war_response *sw_resp = (squad_war_response *)&uph->data;
294 PXO_GET_DATA(sw_resp->reason);
295 PXO_GET_DATA(sw_resp->accepted);
304 //SDL_assert(offset == data_size);
308 int InitPilotTrackerClient()
310 struct sockaddr_in sockaddr;
313 FSWriteState = STATE_IDLE;
314 FSReadState = STATE_IDLE;
315 SWWriteState = STATE_IDLE;
319 fs_pr = (pilot_request *)&fs_pilot_req.data;
322 pilotsock = socket(AF_INET,SOCK_DGRAM,0);
324 if ( pilotsock == INVALID_SOCKET )
326 printf("Unable to open a socket.\n");
331 memset( &sockaddr, 0, sizeof(struct sockaddr_in) );
332 sockaddr.sin_family = AF_INET;
333 sockaddr.sin_addr.s_addr = INADDR_ANY;
334 sockaddr.sin_port = 0;//htons(REGPORT);
337 if (SOCKET_ERROR==bind(pilotsock, (struct sockaddr*)&sockaddr, sizeof (sockaddr)))
339 printf("Unable to bind a socket.\n");
340 printf("WSAGetLastError() returned %d.\n",WSAGetLastError());
345 // iaddr = inet_addr ( Multi_user_tracker_ip_address );
347 // first try and resolve by name
348 iaddr = inet_addr( Multi_options_g.user_tracker_ip );
349 if ( iaddr == INADDR_NONE ) {
351 he = gethostbyname( Multi_options_g.user_tracker_ip );
356 // try and resolve by address
357 unsigned int n_order = inet_addr(Multi_user_tracker_ip_address);
358 he = gethostbyaddr((char*)&n_order,4,PF_INET);
365 iaddr = ((in_addr *)(he->h_addr))->s_addr;
368 ptrackaddr.sin_addr.s_addr = iaddr;
369 ptrackaddr.sin_family = AF_INET;
370 ptrackaddr.sin_port = htons(REGPORT);
376 // -3 Error -- Called with NULL, but no request is waiting
377 // -2 Error -- Already sending data (hasn't timed out yet)
378 // -1 Timeout trying to send pilot data
380 // 1 Data succesfully sent
381 // 2 Send Cancelled (data may still have been written already, we just haven't been ACK'd yet)
382 // 3 Pilot not written (for some reason)
384 // Call with NULL to poll
385 // Call with -1 to cancel send
386 // Call with valid pointer to a vmt_descent3_struct to initiate send
387 int SendFSPilotData(vmt_stats_struct *fs_pilot)
389 //First check the network
394 if(FSWriteState == STATE_IDLE)
398 if(FSWriteState == STATE_SENDING_PILOT)
402 if(FSWriteState == STATE_WROTE_PILOT)
404 //We wrote this pilot, and now we are about to inform the app, so back to idle
405 FSWriteState = STATE_IDLE;
408 if(FSWriteState == STATE_TIMED_OUT)
410 //We gave up on sending this pilot, and now we are about to inform the app, so back to idle
411 FSWriteState = STATE_IDLE;
415 if(FSWriteState == STATE_WRITE_PILOT_FAILED)
417 //The tracker said this dude couldn't be written
418 FSWriteState = STATE_IDLE;
424 else if(fs_pilot == (vmt_stats_struct*)0xffffffff)
426 if(FSWriteState == STATE_IDLE)
433 FSWriteState = STATE_IDLE;
439 else if(FSWriteState == STATE_IDLE)
441 //New request, send out the req, and go for it.
443 FSWriteState = STATE_SENDING_PILOT;
446 FSFirstSentWrite = timer_get_milliseconds();
448 fs_pilot_write.type = UNT_PILOT_DATA_WRITE_NEW;
450 fs_pilot_write.code = CMD_GAME_FREESPACE;
452 fs_pilot_write.code = CMD_GAME_FREESPACE2;
454 fs_pilot_write.len = PACKED_HEADER_ONLY_SIZE+sizeof(vmt_stats_struct);
455 memcpy(&fs_pilot_write.data,fs_pilot,sizeof(vmt_stats_struct));
463 // -3 Error -- Called with NULL, but no request is waiting
464 // -2 Error -- Already sending data (hasn't timed out yet)
465 // -1 Timeout trying to send pilot data
467 // 1 Data succesfully sent
468 // 2 Send Cancelled (data may still have been written already, we just haven't been ACK'd yet)
469 // 3 Pilot not written (for some reason)
471 // Call with NULL to poll
472 // Call with -1 to cancel send
473 // Call with valid pointer to a vmt_descent3_struct to initiate send
474 int SendSWData(squad_war_result *sw_res, squad_war_response *sw_resp)
476 //First check the network
480 if(SWWriteState == STATE_IDLE){
483 if(SWWriteState == STATE_SENDING_PILOT){
487 // fill in the response
488 if(SWWriteState == STATE_WROTE_PILOT){
489 // We wrote this pilot, and now we are about to inform the app, so back to idle
490 SWWriteState = STATE_IDLE;
493 memcpy(sw_resp, &SquadWarWriteResponse, sizeof(squad_war_response));
497 // fill in the response
498 if(SWWriteState == STATE_WRITE_PILOT_FAILED){
499 // The tracker said this dude couldn't be written
500 SWWriteState = STATE_IDLE;
503 memcpy(sw_resp, &SquadWarWriteResponse, sizeof(squad_war_response));
508 if(SWWriteState == STATE_TIMED_OUT){
509 // We gave up on sending this pilot, and now we are about to inform the app, so back to idle
510 SWWriteState = STATE_IDLE;
514 } else if(sw_res == (squad_war_result*)0xffffffff){
515 if(SWWriteState == STATE_IDLE){
519 SWWriteState = STATE_IDLE;
523 } else if(SWWriteState == STATE_IDLE) {
524 //New request, send out the req, and go for it.
526 SWWriteState = STATE_SENDING_PILOT;
529 SWFirstSentWrite = timer_get_milliseconds();
531 sw_res_write.len = PACKED_HEADER_ONLY_SIZE+sizeof(squad_war_result);
532 sw_res_write.type = UNT_SW_RESULT_WRITE;
534 sw_res_write.code = CMD_GAME_FREESPACE;
536 sw_res_write.code = CMD_GAME_FREESPACE2;
538 memcpy(&sw_res_write.data, sw_res, sizeof(squad_war_result));
547 // -3 Error -- Called with NULL, but no request is waiting
548 // -2 Error -- Already waiting on data (hasn't timed out yet)
549 // -1 Timeout waiting for pilot data
550 // 0 Waiting for data
555 // Call with NULL to poll
556 // Call with -1 to cancel wait
557 // Call with valid pointer to a vmt_descent3_struct to get a response
558 int GetFSPilotData(vmt_stats_struct *fs_pilot, const char *pilot_name, const char *tracker_id, int get_security)
560 //First check the network
565 if(FSReadState == STATE_IDLE)
569 if(FSReadState == STATE_READING_PILOT)
573 if(FSReadState == STATE_RECEIVED_PILOT)
575 // We got this pilot, and now we are about to inform the app, so back to idle
576 FSReadState = STATE_IDLE;
580 if(FSReadState == STATE_TIMED_OUT)
582 // We gave up on this pilot, and now we are about to inform the app, so back to idle
583 FSReadState = STATE_IDLE;
587 if(FSReadState == STATE_PILOT_NOT_FOUND)
589 //The tracker said this dude is not found.
590 FSReadState = STATE_IDLE;
596 else if(fs_pilot == (vmt_stats_struct*)0xffffffff)
598 if(FSReadState == STATE_IDLE)
605 FSReadState = STATE_IDLE;
611 else if(FSReadState == STATE_IDLE)
613 //New request, send out the req, and go for it.
615 FSReadState = STATE_READING_PILOT;
616 ReadFSPilot = fs_pilot;
618 FSFirstSent = timer_get_milliseconds();
620 fs_pilot_req.len = PACKED_HEADER_ONLY_SIZE+sizeof(pilot_request);
623 fs_pilot_req.type = UNT_PILOT_DATA_READ_NEW;
625 fs_pilot_req.type = UNT_PILOT_DATA_READ;
629 fs_pilot_req.code = CMD_GAME_FREESPACE;
631 fs_pilot_req.code = CMD_GAME_FREESPACE2;
633 SDL_strlcpy(fs_pr->pilot_name, pilot_name, SDL_arraysize(fs_pr->pilot_name));
634 SDL_strlcpy(fs_pr->tracker_id, tracker_id, SDL_arraysize(fs_pr->tracker_id));
642 // Send an ACK to the server
643 void AckServer(unsigned int sig)
645 udp_packet_header ack_pack;
646 ubyte packet_data[sizeof(udp_packet_header)];
647 int packet_length = 0;
649 ack_pack.type = UNT_CONTROL;
651 ack_pack.code = CMD_CLIENT_RECEIVED;
652 ack_pack.len = PACKED_HEADER_ONLY_SIZE;
654 packet_length = SerializePilotPacket(&ack_pack, packet_data);
655 SDL_assert(packet_length == PACKED_HEADER_ONLY_SIZE);
656 SENDTO(Unreliable_socket, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
661 ubyte packet_data[sizeof(udp_packet_header)];
662 int packet_length = 0;
664 PSNET_TOP_LAYER_PROCESS();
666 // reading pilot data
667 if(FSReadState == STATE_READING_PILOT){
668 if((timer_get_milliseconds()-FSFirstSent)>=PILOT_REQ_TIMEOUT){
669 FSReadState = STATE_TIMED_OUT;
670 } else if((timer_get_milliseconds()-FSLastSent)>=PILOT_REQ_RESEND_TIME){
672 packet_length = SerializePilotPacket(&fs_pilot_req, packet_data);
673 SENDTO(Unreliable_socket, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
674 FSLastSent = timer_get_milliseconds();
678 // writing pilot data
679 if(FSWriteState == STATE_SENDING_PILOT){
680 if((timer_get_milliseconds()-FSFirstSentWrite)>=PILOT_REQ_TIMEOUT){
681 FSWriteState = STATE_TIMED_OUT;
683 } else if((timer_get_milliseconds()-FSLastSentWrite)>=PILOT_REQ_RESEND_TIME){
685 packet_length = SerializePilotPacket(&fs_pilot_write, packet_data);
686 SENDTO(Unreliable_socket, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
687 FSLastSentWrite = timer_get_milliseconds();
691 // writing squad war results
692 if(SWWriteState == STATE_SENDING_PILOT){
693 if((timer_get_milliseconds()-SWFirstSentWrite) >= PILOT_REQ_TIMEOUT){
694 SWWriteState = STATE_TIMED_OUT;
695 } else if((timer_get_milliseconds()-SWLastSentWrite) >= PILOT_REQ_RESEND_TIME){
697 packet_length = SerializePilotPacket(&sw_res_write, packet_data);
698 SENDTO(Unreliable_socket, (char *)&packet_data, packet_length, 0, (struct sockaddr *)&ptrackaddr, sizeof(struct sockaddr_in), PSNET_TYPE_USER_TRACKER);
699 SWLastSentWrite = timer_get_milliseconds();
707 struct timeval timeout;
708 ubyte packet_data[sizeof(udp_packet_header)];
716 FD_SET(Unreliable_socket, &read_fds);
718 if(SELECT(Unreliable_socket+1, &read_fds,NULL,NULL,&timeout, PSNET_TYPE_USER_TRACKER)){
721 struct sockaddr_in fromaddr;
723 udp_packet_header inpacket;
726 addrsize = sizeof(struct sockaddr_in);
728 bytesin = RECVFROM(Unreliable_socket, (char *)&packet_data, sizeof(udp_packet_header), 0, (struct sockaddr *)&fromaddr, &addrsize, PSNET_TYPE_USER_TRACKER);
731 DeserializePilotPacket(packet_data, bytesin, &inpacket);
733 // decrease packet size by 1
737 int wserr=WSAGetLastError();
738 mprintf(("recvfrom() failure. WSAGetLastError() returned %d\n",wserr));
742 //Check to make sure the packets ok
743 if ( (bytesin > 0) && (bytesin == inpacket.len) ) {
744 switch(inpacket.type){
745 case UNT_PILOT_DATA_RESPONSE:
746 if(inpacket.code == CMD_GAME_FREESPACE2){
750 if(FSReadState == STATE_READING_PILOT){
751 vmt_freespace2_struct *stats;
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
758 stats = (vmt_freespace2_struct *)(&inpacket.data);
759 if ( !SDL_strncasecmp(stats->tracker_id, fs_pr->tracker_id,TRACKER_ID_LEN) ) {
761 memcpy(ReadFSPilot,&inpacket.data,sizeof(vmt_freespace2_struct));
763 FSReadState = STATE_RECEIVED_PILOT;
767 } else if(inpacket.code == CMD_GAME_FREESPACE){
771 if(FSReadState == STATE_READING_PILOT){
772 vmt_freespace_struct *stats;
774 // 9/17/98 MWA. Compare the tracker id of this packet with the tracker id of
775 // what we are expecting. Only set our state to something different when
776 // the tracker id's match. This fixes possible multiple packets for a single pilto
777 // accidentally getting set for the wrong pilot
779 stats = (vmt_freespace_struct *)(&inpacket.data);
780 if ( !SDL_strncasecmp(stats->tracker_id, fs_pr->tracker_id,TRACKER_ID_LEN) ) {
782 memcpy(ReadFSPilot,&inpacket.data,sizeof(vmt_freespace_struct));
784 FSReadState = STATE_RECEIVED_PILOT;
793 case UNT_PILOT_READ_FAILED:
794 if(inpacket.code == CMD_GAME_FREESPACE2){
798 if(FSReadState == STATE_READING_PILOT){
799 FSReadState = STATE_PILOT_NOT_FOUND;
802 } else if(inpacket.code == CMD_GAME_FREESPACE){
806 if(FSReadState == STATE_READING_PILOT){
807 FSReadState = STATE_PILOT_NOT_FOUND;
815 case UNT_PILOT_WRITE_SUCCESS:
816 if(inpacket.code == CMD_GAME_FREESPACE2){
820 if(FSWriteState == STATE_SENDING_PILOT){
821 FSWriteState = STATE_WROTE_PILOT;
824 } else if(inpacket.code == CMD_GAME_FREESPACE){
828 if(FSWriteState == STATE_SENDING_PILOT){
829 FSWriteState = STATE_WROTE_PILOT;
837 case UNT_PILOT_WRITE_FAILED:
838 if(inpacket.code == CMD_GAME_FREESPACE2){
842 if(FSWriteState == STATE_SENDING_PILOT){
843 FSWriteState = STATE_WRITE_PILOT_FAILED;
846 } else if(inpacket.code == CMD_GAME_FREESPACE){
850 if(FSWriteState == STATE_SENDING_PILOT){
851 FSWriteState = STATE_WRITE_PILOT_FAILED;
859 case UNT_SW_RESULT_RESPONSE:
860 if(SWWriteState == STATE_SENDING_PILOT){
862 SDL_assert((bytesin - PACKED_HEADER_ONLY_SIZE) == sizeof(squad_war_response));
863 if((bytesin - PACKED_HEADER_ONLY_SIZE) == sizeof(squad_war_response)){
864 memset(&SquadWarWriteResponse, 0, sizeof(squad_war_response));
865 memcpy(&SquadWarWriteResponse, inpacket.data, sizeof(squad_war_response));
867 // now check to see if we're good
868 if(SquadWarWriteResponse.accepted){
869 SWWriteState = STATE_WROTE_PILOT;
871 SWWriteState = STATE_WRITE_PILOT_FAILED;
874 SWWriteState = STATE_WRITE_PILOT_FAILED;
883 case UNT_CONTROL_VALIDATION:
890 AckServer(inpacket.sig);