1 /* Socket.c
2 *
3 * Kevin P. Smith 1/29/89 UDP stuff v1.0 by Andy McFadden Feb-Apr 1992
4 *
5 * UDP protocol v1.0
6 *
7 * Routines to allow connection to the xtrek server.
8 */
9 #include "config.h"
10 #include "copyright2.h"
11
12 #include <stdio.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <unistd.h>
16 #include <time.h>
17 #include <sys/types.h>
18 #include <sys/socket.h>
19 #include <sys/time.h>
20 #include INC_SYS_SELECT
21 #include INC_MACHINE_ENDIAN
22 #include INC_NETINET_IN
23 #include INC_NETINET_TCP
24 #include <netdb.h>
25 #include <arpa/inet.h>
26 #include <math.h>
27 #include <errno.h>
28 #include "Wlib.h"
29 #include "defs.h"
30 #include "struct.h"
31 #include "data.h"
32 #include "packets.h"
33 #include "ltd_stats.h"
34 #include "wtext.h"
35 #include "playerlist.h"
36
37 #include "badversion.h"
38 #include "defaults.h"
39 #include "dmessage.h"
40 #include "getship.h"
41 #include "local.h"
42 #include "map.h"
43 #include "netstat.h"
44 #include "newwin.h"
45 #include "reserved.h"
46 #include "playback.h"
47 #include "rotate.h"
48 #include "redraw.h"
49 #include "short.h"
50 #include "stats.h"
51 #include "udpopt.h"
52 #include "warning.h"
53
54 #include "socket.h"
55
56 #define statsFile stderr /* use stderr for stats output for now */
57 int gather_stats = 0;
58
59 #ifdef WIN32 /* socket garbage in case *
60 * the client is not running
61 *
62 * * on NT */
63 #define read(f,b,l) recv(f,b,l,0)
64 #define write(f,b,l) send(f,b,l,0)
65 #define close(s) closesocket(s)
66 #endif
67
68 #if 0
69 #define INCLUDE_SCAN /* include Amdahl scanning beams */
70 #endif
71 #define INCLUDE_VISTRACT /* include visible tractor beams */
72
73 #define NETSTAT
74
75 #ifdef GATEWAY
76 /* (these values are now defined in "main.c":) char *gw_mach =
77 * "charon"; |client gateway; strcmp(serverName) int gw_serv_port =
78 * 5000; |what to tell the server to use int gw_port = 5001;
79 * |where we will contact gw int gw_local_port = 5100; |where we
80 * expect gw to contact us
81 *
82 * The client binds to "5100" and sends "5000" to the server (TCP). The server
83 * sees that and sends a UDP packet to gw on port udp5000, which passes it
84 * through to port udp5100 on the client. The client-gw gets the server's
85 * host and port from recvfrom. (The client can't use the same method since
86 * these sockets are one-way only, so it connect()s to gw_port (udp5001) on
87 * the gateway machine regardless of what the server sends.)
88 *
89 * So all we need in .gwrc is: udp 5000 5001 tde.uts 5100
90 *
91 * assuming the client is on tde.uts. Note that a UDP declaration will work for
92 * ANY server, but you need one per player, and the client has to have the
93 * port numbers in advance.
94 *
95 * If we're using a standard server, we're set. If we're running through a
96 * gatewayed server, we have to do some unpleasant work on the server side... */
97 #endif
98
99 void handleMessage(struct mesg_spacket *packet);
100 void handlePlyrInfo(struct plyr_info_spacket *packet);
101 void handleKills(struct kills_spacket *packet);
102 void handlePlayer(struct player_spacket *packet);
103 void handleTorpInfo(struct torp_info_spacket *packet);
104 void handleTorp(struct torp_spacket *packet);
105 void handlePhaser(struct phaser_spacket *packet);
106 void handlePlasmaInfo(struct plasma_info_spacket *packet);
107 void handlePlasma(struct plasma_spacket *packet);
108 void handleWarning(struct warning_spacket *packet);
109 void handleMotd(struct motd_spacket *packet);
110 void handleSelf(struct you_spacket *packet);
111 void handleQueue(struct queue_spacket *packet);
112 void handleStatus(struct status_spacket *packet);
113 void handlePlanet(struct planet_spacket *packet);
114 void handlePickok(struct pickok_spacket *packet);
115 void handleLogin(struct login_spacket *packet);
116 void handleFlags(struct flags_spacket *packet);
117 void handleMask(struct mask_spacket *packet);
118 void handlePStatus(struct pstatus_spacket *packet);
119 void handleBadVersion(struct badversion_spacket *packet);
120 void handleHostile(struct hostile_spacket *packet);
121 void handleStats(struct stats_spacket *packet);
122 void handlePlyrLogin(struct plyr_login_spacket *packet, int sock);
123 void handleReserved(struct reserved_spacket *packet, int sock);
124 void handlePlanetLoc(struct planet_loc_spacket *packet);
125
126 #ifdef HANDLE_SCAN
127 void handleScan(struct scan_spacket *packet);
128
129 #endif
130
131 void handleUdpReply(struct udp_reply_spacket *packet);
132 void handleSequence(struct sequence_spacket *packet);
133
134 #ifdef RSA
135 void handleRSAKey(struct rsa_key_spacket *packet);
136 extern void rsa_black_box(unsigned char *, unsigned char *, unsigned char *, unsigned char *);
137 #else
138 void handleRSAKey(void *packet);
139 #endif
140
141 void handleShipCap(struct ship_cap_spacket *packet);
142 static void handleGeneric32(struct generic_32_spacket *packet);
143 extern void handlePing(struct ping_spacket *packet); /* ping.c */
144 extern void terminate(int error);
145
146 #ifdef SHORT_PACKETS
147 extern void handleShortReply(struct shortreply_spacket *packet);
148 extern void handleSMessage(struct mesg_s_spacket *packet);
149 extern void handleSWarning(struct warning_s_spacket *packet);
150 extern void handleSelfShort(struct youshort_spacket *packet);
151 extern void handleSelfShip(struct youss_spacket *packet);
152 extern void handleVPlayer(unsigned char *sbuf);
153 extern void handleVTorp(unsigned char *sbuf);
154 extern void handleVTorpInfo(unsigned char *sbuf);
155 extern void handleVPlanet(unsigned char *sbuf);
156
157 /* S_P2 */
158 extern void handleVPhaser(unsigned char *sbuf);
159 extern void handleVKills(unsigned char *sbuf);
160 extern void handle_s_Stats(struct stats_s_spacket *packet);
161
162 #endif /* SHORT_PACKETS */
163
164 #ifdef FEATURE_PACKETS
165 extern void handleFeature(struct feature_cpacket *packet);
166
167 #endif
168 void handleRank (struct rank_spacket *packet);
169 void handleLtd (struct ltd_spacket *packet);
170
171 static void pickSocket(int old);
172 static int connUdpConn(void);
173 static int openUdpConn(void);
174 static int recvUdpConn(void);
175 static int doRead(int asock);
176
177 char *strcpyp_return(register char *s1, register char *s2, register int length);
178
179 void
dummy(void)180 dummy(void)
181 {
182 }
183
184 #ifdef SHORT_PACKETS
185 unsigned char numofbits[256] =
186 {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1,
187 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1,
188 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
189 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1,
190 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
191 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
192 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
193 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1,
194 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2,
195 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2,
196 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
197 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2,
198 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3,
199 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 3,
200 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4,
201 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
202
203 static int vtsize[9] =
204 {4, 8, 8, 12, 12, 16, 20, 20, 24}; /* How big is the torppacket
205
206 *
207 *
208 */
209 int vtisize[9] =
210 {4, 7, 9, 11, 13, 16, 18, 20, 22}; /* 4 byte Header + torpdata */
211
212 /* S_P2 */
213 int shortversion = SHORTVERSION; /* Which version do we use? */
214
215 #endif /* SHORT_PACKETS */
216
217 #ifdef PACKET_LOG
218 void Log_Packet(char type, int act_size);
219 void Log_OPacket(int tpe, int size);
220 void print_opacket(char *packet, int size);
221 void print_packet(char *packet, int size);
222 #endif
223
224 struct packet_handler handlers[] =
225 {
226 {0, NULL}, /* record 0 */
227 {sizeof(struct mesg_spacket), handleMessage}, /* SP_MESSAGE */
228 {sizeof(struct plyr_info_spacket), handlePlyrInfo}, /* SP_PLAYER_INFO */
229 {sizeof(struct kills_spacket), handleKills}, /* SP_KILLS */
230 {sizeof(struct player_spacket), handlePlayer}, /* SP_PLAYER */
231 {sizeof(struct torp_info_spacket), handleTorpInfo}, /* SP_TORP_INFO */
232 {sizeof(struct torp_spacket), handleTorp}, /* SP_TORP */
233 {sizeof(struct phaser_spacket), handlePhaser}, /* SP_PHASER */
234 {sizeof(struct plasma_info_spacket), handlePlasmaInfo}, /* SP_PLASMA_INFO
235 *
236 */
237 {sizeof(struct plasma_spacket), handlePlasma}, /* SP_PLASMA */
238 {sizeof(struct warning_spacket), handleWarning}, /* SP_WARNING */
239 {sizeof(struct motd_spacket), handleMotd}, /* SP_MOTD */
240 {sizeof(struct you_spacket), handleSelf}, /* SP_YOU */
241 {sizeof(struct queue_spacket), handleQueue}, /* SP_QUEUE */
242 {sizeof(struct status_spacket), handleStatus}, /* SP_STATUS */
243 {sizeof(struct planet_spacket), handlePlanet}, /* SP_PLANET */
244 {sizeof(struct pickok_spacket), handlePickok}, /* SP_PICKOK */
245 {sizeof(struct login_spacket), handleLogin}, /* SP_LOGIN */
246 {sizeof(struct flags_spacket), handleFlags}, /* SP_FLAGS */
247 {sizeof(struct mask_spacket), handleMask}, /* SP_MASK */
248 {sizeof(struct pstatus_spacket), handlePStatus}, /* SP_PSTATUS */
249 {sizeof(struct badversion_spacket), handleBadVersion}, /* SP_BADVERSION
250 *
251 */
252 {sizeof(struct hostile_spacket), handleHostile}, /* SP_HOSTILE */
253 {sizeof(struct stats_spacket), handleStats}, /* SP_STATS */
254 {sizeof(struct plyr_login_spacket), handlePlyrLogin}, /* SP_PL_LOGIN
255 *
256 */
257 {sizeof(struct reserved_spacket), handleReserved}, /* SP_RESERVED */
258 {sizeof(struct planet_loc_spacket), handlePlanetLoc}, /* SP_PLANET_LOC
259 *
260 */
261
262 #ifdef HANDLE_SCAN
263 {sizeof(struct scan_spacket), handleScan} /* SP_SCAN (ATM) */
264 #else
265 {0, dummy}, /* won't be called */
266 #endif
267
268 {sizeof(struct udp_reply_spacket), handleUdpReply}, /* SP_UDP_STAT */
269 {sizeof(struct sequence_spacket), handleSequence}, /* SP_SEQUENCE */
270 {sizeof(struct sc_sequence_spacket), handleSequence}, /* SP_SC_SEQUENCE
271 *
272 */
273
274 #ifdef RSA
275 {sizeof(struct rsa_key_spacket), handleRSAKey}, /* SP_RSA_KEY */
276 #else
277 {0, dummy}, /* #31, and dummy won't */
278 #endif
279
280 {sizeof(struct generic_32_spacket), handleGeneric32}, /* SP_GENERIC_32 */
281 {0, dummy}, /* 33 */
282 {0, dummy}, /* 34 */
283 {0, dummy}, /* 35 */
284 {0, dummy}, /* 36 */
285 {0, dummy}, /* 37 */
286 {0, dummy}, /* 38 */
287 {sizeof(struct ship_cap_spacket), handleShipCap}, /* SP_SHIP_CAP */
288
289 #ifdef SHORT_PACKETS
290 {sizeof(struct shortreply_spacket), handleShortReply}, /* SP_S_REPLY
291 *
292 */
293 {-1, handleSMessage}, /* SP_S_MESSAGE */
294 {-1 /* sizeof(struct *
295 * warning_s_spacket) */ , handleSWarning},
296 /* SP_S_WARNING */
297 {sizeof(struct youshort_spacket), handleSelfShort}, /* SP_S_YOU */
298 {sizeof(struct youss_spacket), handleSelfShip}, /* SP_S_YOU_SS */
299 {-1, /* variable */ handleVPlayer}, /* SP_S_PLAYER */
300 #else
301 {0, dummy}, /* 40 */
302 {0, dummy}, /* 41 */
303 {0, dummy}, /* 42 */
304 {0, dummy}, /* 43 */
305 {0, dummy}, /* 44 */
306 {0, dummy}, /* 45 */
307 #endif
308 {sizeof(struct ping_spacket), handlePing}, /* SP_PING */
309
310 #ifdef SHORT_PACKETS
311 {-1, /* variable */ handleVTorp}, /* SP_S_TORP */
312 {-1, handleVTorpInfo}, /* SP_S_TORP_INFO */
313 {20, handleVTorp}, /* SP_S_8_TORP */
314 {-1, handleVPlanet}, /* SP_S_PLANET */
315 #else
316 {0, dummy}, /* 47 */
317 {0, dummy}, /* 48 */
318 {0, dummy}, /* 49 */
319 {0, dummy}, /* 50 */
320 #endif
321
322 {0, dummy}, /* 51 */
323 {0, dummy}, /* 52 */
324 {0, dummy}, /* 53 */
325 {0, dummy}, /* 54 */
326 {0, dummy}, /* 55 */
327
328 #ifdef SHORT_PACKETS /* S_P2 */
329 {0, dummy}, /* SP_S_SEQUENCE not yet * *
330 * implemented */
331 {-1, handleVPhaser}, /* SP_S_PHASER */
332 {-1, handleVKills}, /* SP_S_KILLS */
333 {sizeof(struct stats_s_spacket), handle_s_Stats}, /* SP_S_STATS */
334 #else
335 {0, dummy}, /* 56 */
336 {0, dummy}, /* 57 */
337 {0, dummy}, /* 58 */
338 {0, dummy}, /* 59 */
339 #endif
340
341 #ifdef FEATURE_PACKETS
342 {sizeof(struct feature_cpacket), handleFeature}, /* SP_FEATURE; 60 */
343 #endif
344 {sizeof(struct rank_spacket), handleRank}, /* SP_RANK; 61 */
345 {sizeof(struct ltd_spacket), handleLtd}, /* SP_LTD; 62 */
346
347 };
348
349 int sizes[] =
350 {
351 0, /* record 0 */
352 sizeof(struct mesg_cpacket), /* CP_MESSAGE */
353 sizeof(struct speed_cpacket), /* CP_SPEED */
354 sizeof(struct dir_cpacket), /* CP_DIRECTION */
355 sizeof(struct phaser_cpacket), /* CP_PHASER */
356 sizeof(struct plasma_cpacket), /* CP_PLASMA */
357 sizeof(struct torp_cpacket), /* CP_TORP */
358 sizeof(struct quit_cpacket), /* CP_QUIT */
359 sizeof(struct login_cpacket), /* CP_LOGIN */
360 sizeof(struct outfit_cpacket), /* CP_OUTFIT */
361 sizeof(struct war_cpacket), /* CP_WAR */
362 sizeof(struct practr_cpacket), /* CP_PRACTR */
363 sizeof(struct shield_cpacket), /* CP_SHIELD */
364 sizeof(struct repair_cpacket), /* CP_REPAIR */
365 sizeof(struct orbit_cpacket), /* CP_ORBIT */
366 sizeof(struct planlock_cpacket), /* CP_PLANLOCK */
367 sizeof(struct playlock_cpacket), /* CP_PLAYLOCK */
368 sizeof(struct bomb_cpacket), /* CP_BOMB */
369 sizeof(struct beam_cpacket), /* CP_BEAM */
370 sizeof(struct cloak_cpacket), /* CP_CLOAK */
371 sizeof(struct det_torps_cpacket), /* CP_DET_TORPS */
372 sizeof(struct det_mytorp_cpacket), /* CP_DET_MYTORP */
373 sizeof(struct copilot_cpacket), /* CP_COPILOT */
374 sizeof(struct refit_cpacket), /* CP_REFIT */
375 sizeof(struct tractor_cpacket), /* CP_TRACTOR */
376 sizeof(struct repress_cpacket), /* CP_REPRESS */
377 sizeof(struct coup_cpacket), /* CP_COUP */
378 sizeof(struct socket_cpacket), /* CP_SOCKET */
379 sizeof(struct options_cpacket), /* CP_OPTIONS */
380 sizeof(struct bye_cpacket), /* CP_BYE */
381 sizeof(struct dockperm_cpacket), /* CP_DOCKPERM */
382 sizeof(struct updates_cpacket), /* CP_UPDATES */
383 sizeof(struct resetstats_cpacket), /* CP_RESETSTATS */
384 sizeof(struct reserved_cpacket), /* CP_RESERVED */
385
386 #ifdef INCLUDE_SCAN
387 sizeof(struct scan_cpacket), /* CP_SCAN (ATM) */
388 #else
389 0,
390 #endif
391 sizeof(struct udp_req_cpacket), /* CP_UDP_REQ */
392 sizeof(struct sequence_cpacket), /* CP_SEQUENCE */
393
394 #ifdef RSA
395 sizeof(struct rsa_key_cpacket), /* CP_RSA_KEY */
396 #else
397 0, /* 37 */
398 #endif
399
400 0, /* 38 */
401 0, /* 39 */
402 0, /* 40 */
403 0, /* 41 */
404
405 #ifdef PING
406 sizeof(struct ping_cpacket), /* CP_PING_RESPONSE */
407 #else
408 0,
409 #endif
410
411 #ifdef SHORT_PACKETS
412 sizeof(struct shortreq_cpacket), /* CP_S_REQ */
413 sizeof(struct threshold_cpacket), /* CP_S_THRS */
414 -1, /* CP_S_MESSAGE */
415 #else
416 0, /* 43 */
417 0, /* 44 */
418 0, /* 45 */
419 #endif
420
421 0, /* 46 */
422 0, /* 47 */
423 0, /* 48 */
424 0, /* 49 */
425 0, /* 50 */
426 0, /* 51 */
427 0, /* 52 */
428 0, /* 53 */
429 0, /* 54 */
430 0, /* 55 */
431 0, /* 56 */
432 0, /* 57 */
433 0, /* 58 */
434 0, /* 59 */
435
436 #ifdef FEATURE_PACKETS
437 sizeof(struct feature_cpacket), /* CP_FEATURE; 60 */
438 #endif
439
440 };
441
442 #define NUM_PACKETS (sizeof(handlers) / sizeof(handlers[0]) - 1)
443 #define NUM_SIZES (sizeof(sizes) / sizeof(sizes[0]) - 1)
444
445
446 #ifdef PACKET_LOG
447 /* stuff useful for logging server packets to see how much bandwidth netrek
448 * is really using */
449 int log_packets = 0; /* whether or not to be
450 * logging packets */
451 int packet_log[NUM_PACKETS]; /* number of packets logged */
452 int outpacket_log[NUM_SIZES];
453 int ALL_BYTES = 0; /* To log all bytes */
454 #endif /* PACKET_LOG */
455
456 int serverDead = 0;
457
458 #define BUFSIZE 1024
459 char buf[BUFSIZE];
460
461 static int udpLocalPort = 0;
462 static int udpServerPort = 0;
463 static LONG serveraddr = 0;
464 static LONG sequence = 0;
465 static int drop_flag = 0;
466 static int chan = -1; /* tells sequence checker *
467
468 *
469 * * where packet is from */
470 static short fSpeed, fDirection, fShield, fOrbit, fRepair, fBeamup, fBeamdown,
471 fCloak, fBomb, fDockperm, fPhaser, fPlasma, fPlayLock, fPlanLock,
472 fTractor, fRepress;
473
474 /* internal prototypes */
475 static void dotimers(void);
476
477 /* print the SP_S_TORP* packets. */
478 /* sbuf = pointer to packet buff */
479 /* type=1 print SP_S_TORP */
480 /* type=2 print SP_S_8_TORP */
481 /* type=3 print SP_S_TORP_INFO */
print_sp_s_torp(char * sbuf,int type)482 void print_sp_s_torp(char *sbuf, int type)
483 {
484 unsigned char which, *data, infobitset, *infodata;
485 unsigned char bitset;
486 int dx, dy;
487 int shiftvar;
488 int i;
489 char status, war;
490 register int shift = 0; /* How many torps are
491 * * extracted (for shifting) */
492
493 if ( (type == 1) || (type == 2) )
494 {
495 /* now we must find the data ... :-) */
496 if (sbuf[0] == SP_S_8_TORP)
497 { /* MAX packet */
498 bitset = 0xff;
499 which = sbuf[1];
500 data = (unsigned char *) &sbuf[2];
501 }
502 else
503 { /* Normal Packet */
504 bitset = sbuf[1];
505 which = sbuf[2];
506 data = (unsigned char *) &sbuf[3];
507 }
508 fprintf(stderr, " bitset=0x%0X, which=%d, ", bitset, which);
509 #ifdef CORRUPTED_PACKETS
510 /* we probably should do something clever here - jmn */
511 #endif
512
513 for (shift = 0, i = 0; i < 8; i++, bitset >>= 1)
514 {
515 if (bitset & 01)
516 {
517 dx = (*data >> shift);
518 data++;
519 shiftvar = (unsigned char) *data; /* to silence gcc */
520 shiftvar <<= (8 - shift);
521 dx |= (shiftvar & 511);
522 shift++;
523 dy = (*data >> shift);
524 data++;
525 shiftvar = (unsigned char) *data; /* to silence gcc */
526 shiftvar <<= (8 - shift);
527 dy |= (shiftvar & 511);
528 shift++;
529 if (shift == 8)
530 {
531 shift = 0;
532 data++;
533 }
534 fprintf(stderr, "dx=%d, dy=%d, ",dx, dy);
535 }
536 }
537 }
538 else if (type == 3)
539 {
540 /* now we must find the data ... :-) */
541 bitset = sbuf[1];
542 which = sbuf[2];
543 infobitset = sbuf[3];
544 /* Where is the data ? */
545 data = (unsigned char *) &sbuf[4];
546
547 fprintf(stderr, " bitset=0x%0X, which=%d, infobitset=0x%0X, ",
548 bitset, which, infobitset);
549
550 infodata = (unsigned char *) &sbuf[vtisize[numofbits[(unsigned char) sbuf[1]]]];
551
552 for (shift = 0, i = 0; i < 8; bitset >>= 1, infobitset >>= 1, i++)
553 {
554 if (bitset & 01)
555 {
556 dx = (*data >> shift);
557 data++;
558 shiftvar = (unsigned char) *data; /* to silence gcc */
559 shiftvar <<= (8 - shift);
560 dx |= (shiftvar & 511);
561 shift++;
562 dy = (*data >> shift);
563 data++;
564 shiftvar = (unsigned char) *data; /* to silence gcc */
565 shiftvar <<= (8 - shift);
566 dy |= (shiftvar & 511);
567 shift++;
568 if (shift == 8)
569 {
570 shift = 0;
571 data++;
572 }
573 fprintf(stderr, "dx=%d, dy=%d, ",dx, dy);
574 }
575
576 /* Now the TorpInfo */
577 if (infobitset & 01)
578 {
579 war = (unsigned char) *infodata & 15 /* 0x0f */ ;
580 status = ((unsigned char) *infodata & 0xf0) >> 4;
581 infodata++;
582 fprintf(stderr, "war=0x%0X, status=0x%0X, ", war, status);
583 } /* if */
584
585 } /* for */
586
587 }
588 }
589
590 /* reset all the "force command" variables */
resetForce(void)591 static void resetForce(void)
592 {
593 fSpeed = fDirection = fShield = fOrbit = fRepair = fBeamup = fBeamdown =
594 fCloak = fBomb = fDockperm = fPhaser = fPlasma = fPlayLock = fPlanLock =
595 fTractor = fRepress = -1;
596 }
597
598 /* If something we want to happen hasn't yet, send it again.
599 *
600 * The low byte is the request, the high byte is a max count. When the max
601 * count reaches zero, the client stops trying. Checking is done with a
602 * macro for speed & clarity. */
603 #define FCHECK_FLAGS(flag, force, const) { \
604 if (force > 0) { \
605 if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) { \
606 speedReq.type = const; \
607 speedReq.speed = (force & 0xff); \
608 sendServerPacket((struct player_spacket *) &speedReq); \
609 V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff)); \
610 force -= 0x100; \
611 if (force < 0x100) force = -1; /* give up */ \
612 } else \
613 force = -1; \
614 } \
615 }
616 #define FCHECK_VAL(value, force, const) { \
617 if (force > 0) { \
618 if ((value) != (force & 0xff)) { \
619 speedReq.type = const; \
620 speedReq.speed = (force & 0xff); \
621 sendServerPacket((struct player_spacket *) &speedReq); \
622 V_UDPDIAG(("Forced %d:%d\n", const, force & 0xff)); \
623 force -= 0x100; \
624 if (force < 0x100) force = -1; /* give up */ \
625 } else \
626 force = -1; \
627 } \
628 }
629 #define FCHECK_TRACT(flag, force, const) { \
630 if (force > 0) { \
631 if (((me->p_flags & flag) && 1) ^ ((force & 0xff) && 1)) { \
632 tractorReq.type = const; \
633 tractorReq.state = ((force & 0xff) >= 0x40); \
634 tractorReq.pnum = (force & 0xff) & (~0x40); \
635 sendServerPacket((struct player_spacket *)&tractorReq); \
636 V_UDPDIAG(("Forced %d:%d/%d\n", const, \
637 tractorReq.state, tractorReq.pnum)); \
638 force -= 0x100; \
639 if (force < 0x100) force = -1; /* give up */ \
640 } else \
641 force = -1; \
642 } \
643 }
644
checkForce(void)645 void checkForce(void)
646 {
647 struct speed_cpacket speedReq;
648 struct tractor_cpacket tractorReq;
649
650 FCHECK_VAL(me->p_speed, fSpeed, CP_SPEED); /* almost always repeats */
651
652 #ifdef nodef /* not needed */
653 FCHECK_VAL(me->p_dir, fDirection, CP_DIRECTION); /* (ditto) */
654 #endif
655
656 FCHECK_FLAGS(PFSHIELD, fShield, CP_SHIELD);
657 FCHECK_FLAGS(PFORBIT, fOrbit, CP_ORBIT);
658 FCHECK_FLAGS(PFREPAIR, fRepair, CP_REPAIR);
659 FCHECK_FLAGS(PFBEAMUP, fBeamup, CP_BEAM);
660 FCHECK_FLAGS(PFBEAMDOWN, fBeamdown, CP_BEAM);
661 FCHECK_FLAGS(PFCLOAK, fCloak, CP_CLOAK);
662 FCHECK_FLAGS(PFBOMB, fBomb, CP_BOMB);
663 FCHECK_FLAGS(PFDOCKOK, fDockperm, CP_DOCKPERM);
664 FCHECK_VAL(phasers[me->p_no].ph_status, fPhaser, CP_PHASER); /* bug: dir 0
665 *
666 */
667 FCHECK_VAL(plasmatorps[me->p_no].pt_status, fPlasma, CP_PLASMA); /* (ditto)
668 *
669 */
670 FCHECK_FLAGS(PFPLOCK, fPlayLock, CP_PLAYLOCK);
671 FCHECK_FLAGS(PFPLLOCK, fPlanLock, CP_PLANLOCK);
672
673 FCHECK_TRACT(PFTRACT, fTractor, CP_TRACTOR);
674 FCHECK_TRACT(PFPRESS, fRepress, CP_REPRESS);
675 }
676
connectToServer(int port)677 void connectToServer(int port)
678 {
679 int s;
680 struct sockaddr_in addr;
681 struct sockaddr_in naddr;
682 socklen_t len;
683 fd_set readfds;
684 struct timeval timeout;
685 struct hostent *hp;
686 int optval;
687
688 serverDead = 0;
689 if (sock != -1)
690 {
691 shutdown(sock, 2);
692 close(sock);
693 sock = -1;
694 }
695
696 #ifdef nodef
697 sleep(3); /* I think this is necessary
698 * * * for some unknown
699 * reason */
700 #endif
701
702 printf("Waiting for connection (port %d). \n", port);
703
704 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
705 {
706 printf("I can't create a socket\n");
707 terminate(2);
708 }
709
710 /* allow local address resuse */
711 optval = 1;
712 if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *) &optval, sizeof(int))
713 < 0)
714 {
715 perror("setsockopt");
716 }
717
718 addr.sin_family = AF_INET;
719 addr.sin_addr.s_addr = INADDR_ANY;
720 addr.sin_port = htons(port);
721
722 if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
723 {
724
725 #ifdef nodef
726 sleep(10);
727 if (bind(s, &addr, sizeof(addr)) < 0)
728 {
729 sleep(10);
730 if (bind(s, &addr, sizeof(addr)) < 0)
731 {
732 printf("I can't bind to port!\n");
733 terminate(3);
734 }
735 }
736 #endif
737
738 perror("bind"); /* NEW */
739 terminate(1);
740 }
741 if (listen(s, 1) < 0)
742 perror("listen");
743
744 len = sizeof(naddr);
745
746 tryagain:
747 timeout.tv_sec = 240; /* four minutes */
748 timeout.tv_usec = 0;
749 FD_ZERO(&readfds);
750 FD_SET(s, &readfds);
751
752 if (s >= max_fd)
753 max_fd = s + 1;
754
755 if (SELECT(max_fd, &readfds, NULL, NULL, &timeout) == 0)
756 {
757 printf("Well, I think the server died!\n");
758 terminate(0);
759 }
760
761 sock = accept(s, (struct sockaddr *) &naddr, &len);
762
763 if (sock == -1)
764 {
765 goto tryagain;
766 }
767
768 if (sock >= max_fd)
769 max_fd = sock + 1;
770
771 printf("Got connection.\n");
772
773 close(s);
774 pickSocket(port); /* new socket != port */
775
776
777 /* This is necessary; it tries to determine who the caller is, and set * *
778 * "serverName" and "serveraddr" appropriately. */
779 len = sizeof(struct sockaddr_in);
780
781 if (getpeername(sock, (struct sockaddr *) &addr, &len) < 0)
782 {
783 perror("unable to get peername");
784 serverName = "nowhere";
785 printf("Connection from server\n");
786 }
787 else
788 {
789 serveraddr = addr.sin_addr.s_addr;
790 hp = gethostbyaddr((char *) &addr.sin_addr.s_addr, sizeof(LONG), AF_INET);
791 if (hp != NULL)
792 {
793 serverName = (char *) malloc(strlen(hp->h_name) + 1);
794 strcpy(serverName, hp->h_name);
795 printf("Connection from server %s (%s)\n", serverName, inet_ntoa(addr.sin_addr));
796 }
797 else
798 {
799 serverName = (char *) malloc(strlen(inet_ntoa(addr.sin_addr)) + 1);
800 strcpy(serverName, inet_ntoa(addr.sin_addr));
801 printf("Connection from server %s\n", serverName);
802 }
803 }
804
805 }
806
807
set_tcp_opts(int s)808 static void set_tcp_opts(int s)
809 {
810 int optval = 1;
811 struct protoent *ent;
812
813 ent = getprotobyname("TCP");
814 if (!ent)
815 {
816 fprintf(stderr, "TCP protocol not found.\n");
817 return;
818 }
819 if (setsockopt(s, ent->p_proto, TCP_NODELAY, &optval, sizeof(int)) < 0)
820 perror("setsockopt");
821 }
822
823 #ifdef nodef
set_udp_opts(int s)824 static void set_udp_opts(int s)
825 {
826 int optval = BUFSIZ;
827 struct protoent *ent;
828
829 ent = getprotobyname("UDP");
830 if (!ent)
831 {
832 fprintf(stderr, "UDP protocol not found.\n");
833 return;
834 }
835 if (setsockopt(s, ent->p_proto, SO_RCVBUF, &optval, sizeof(int)) < 0)
836 perror("setsockopt");
837 }
838 #endif
839
callServer(int port,char * server)840 void callServer(int port, char *server)
841 {
842 int s;
843 struct sockaddr_in addr;
844 struct hostent *hp;
845
846 serverDead = 0;
847
848 fprintf(stderr, "connecting to %s on port %d\n", server, port);
849
850 if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0)
851 {
852 perror("failed in socket");
853 terminate(1);
854 }
855 set_tcp_opts(s);
856 addr.sin_family = AF_INET;
857 addr.sin_port = htons(port);
858
859 if ((addr.sin_addr.s_addr = inet_addr(server)) == -1)
860 {
861 if ((hp = gethostbyname(server)) == NULL)
862 {
863 printf("unable to resolve hostname %s\n", server);
864 terminate(1);
865 }
866 else
867 {
868 addr.sin_addr.s_addr = *(LONG *) hp->h_addr;
869 }
870 }
871 serveraddr = addr.sin_addr.s_addr;
872
873 if (connect(s, (struct sockaddr *) &addr, sizeof(addr)) < 0)
874 {
875 perror("failed in connect");
876 fprintf(stderr, "connection failed\n");
877 terminate(1);
878 }
879 fprintf(stderr, "connected\n");
880
881 sock = s;
882
883 if (sock >= max_fd)
884 max_fd = sock + 1;
885
886 #ifdef TREKHOPD
887 /* We use a different scheme from gw: we tell the server who we want to * *
888 * connect to and what our local UDP port is; it picks its own UDP ports *
889 * * and tells us what they are. This is MUCH more flexible and avoids a *
890 * * number of problems, and may come in handy if the blessed scheme
891 * changes. * * It's also slightly more work. */
892 {
893 extern int port_req, use_trekhopd, serv_port;
894 extern char *host_req;
895 struct mesg_cpacket msg;
896 struct mesg_spacket reply;
897 int n, count, *ip;
898 char *buf;
899
900 if (use_trekhopd)
901 {
902 msg.type = SP_MESSAGE;
903 msg.group = msg.indiv = msg.pad1 = 0;
904 ip = (int *) msg.mesg;
905 *(ip++) = htons(port_req);
906 *(ip++) = htons(gw_local_port);
907 STRNCPY(msg.mesg + 8, login, 8);
908 strcpy(msg.mesg + 16, host_req);
909 if (gwrite(s, &msg, sizeof(struct mesg_cpacket)) < 0)
910 {
911 fprintf(stderr, "trekhopd init failure\n");
912 terminate(1);
913 }
914 printf("--- trekhopd request sent, awaiting reply\n");
915 /* now block waiting for reply */
916 count = sizeof(struct mesg_spacket);
917
918 for (buf = (char *) &reply; count; buf += n, count -= n)
919 {
920 if ((n = read(s, buf, count)) <= 0)
921 {
922 perror("trekhopd read");
923 terminate(1);
924 }
925 }
926
927 if (reply.type != SP_MESSAGE)
928 {
929 fprintf(stderr, "Got bogus reply from trekhopd (%d)\n",
930 reply.type);
931 terminate(1);
932 }
933 ip = (int *) reply.mesg;
934 gw_serv_port = ntohl(*ip++);
935 gw_port = ntohl(*ip++);
936 serv_port = ntohl(*ip++);
937 printf("--- trekhopd reply received\n");
938
939 /* printf("ports = %d/%d, %d\n", gw_serv_port, gw_port, serv_port); */
940 }
941 }
942 #endif /* TREKHOPD */
943
944 pickSocket(port); /* new socket != port */
945 }
946
isServerDead(void)947 int isServerDead(void)
948 {
949 return serverDead;
950 }
951
socketPauseCommon(int wake_on_user_input)952 void socketPauseCommon(int wake_on_user_input)
953 {
954 struct timeval timeout;
955 fd_set readfds;
956 int retval;
957
958 timeout.tv_sec = 1;
959 timeout.tv_usec = 0;
960
961 FD_ZERO(&readfds);
962 FD_SET(sock, &readfds);
963 if (udpSock >= 0) /* new */
964 FD_SET(udpSock, &readfds);
965 #ifndef HAVE_WIN32
966 if (wake_on_user_input)
967 FD_SET(W_Socket(), &readfds);
968 #endif
969
970 retval = SELECT(max_fd, &readfds, 0, 0, &timeout);
971 if (retval < 0) perror("select"); /* FIXME: EBADF on kill of ntserv during outfit */
972 }
973
socketPauseNoUser(void)974 void socketPauseNoUser(void)
975 {
976 socketPauseCommon(0);
977 }
978
socketPause(void)979 void socketPause(void)
980 {
981 socketPauseCommon(1);
982 }
983
readFromServer(fd_set * readfds)984 int readFromServer(fd_set *readfds)
985 {
986 int retval = 0;
987
988 if (serverDead)
989 return 0;
990
991 if (!readfds)
992 {
993 struct timeval timeout;
994 int rs;
995 fd_set mask;
996
997 readfds = &mask;
998
999 FD_ZERO(readfds);
1000 FD_SET(sock, readfds);
1001 if (udpSock >= 0)
1002 FD_SET(udpSock, readfds);
1003 timeout.tv_sec = 0;
1004 timeout.tv_usec = 0;
1005 if ((rs = SELECT(max_fd, readfds, 0, 0, &timeout)) == 0)
1006 {
1007 dotimers();
1008 return 0;
1009 }
1010 if (rs < 0) {
1011 if (errno == EINTR) return 0;
1012 perror("select");
1013 sleep(1);
1014 }
1015 }
1016 if (udpSock >= 0 && FD_ISSET(udpSock, readfds))
1017 {
1018 /* WAS V_ */
1019 UDPDIAG(("Activity on UDP socket\n"));
1020 chan = udpSock;
1021 if (commStatus == STAT_VERIFY_UDP)
1022 {
1023 sequence = 0; /* reset sequence #s */
1024 resetForce();
1025
1026 printUdpInfo();
1027 UDPDIAG(("UDP connection established.\n"));
1028
1029 commMode = COMM_UDP;
1030 commStatus = STAT_CONNECTED;
1031 commSwitchTimeout = 0;
1032 if (udpClientRecv != MODE_SIMPLE)
1033 sendUdpReq(COMM_MODE + udpClientRecv);
1034 if (udpWin)
1035 {
1036 udprefresh(UDP_CURRENT);
1037 udprefresh(UDP_STATUS);
1038 }
1039 }
1040 retval += doRead(udpSock);
1041 }
1042
1043 /* Read info from the xtrek server */
1044 if (FD_ISSET(sock, readfds))
1045 {
1046 chan = sock;
1047 if (commMode == COMM_TCP)
1048 drop_flag = 0; /* just in case */
1049 /* Bug fix for unnecessary redraws with UDP on - reported by TP */
1050 // if (commMode == COMM_UDP)
1051 // doRead (sock);
1052 // else
1053 retval += doRead (sock);
1054 }
1055
1056 dotimers();
1057 return retval != 0; /* convert to 1/0 */
1058 }
1059
dotimers(void)1060 static void dotimers(void)
1061 {
1062 /* if switching comm mode, decrement timeout counter */
1063 if (commSwitchTimeout > 0)
1064 {
1065 if (!(--commSwitchTimeout))
1066 {
1067 /* timed out; could be initial request to non-UDP server (which * *
1068 * won't be answered), or the verify packet got lost en route to *
1069 * * the server. Could also be a request for TCP which timed out *
1070 * * (weird), in which case we just reset anyway. */
1071 commModeReq = commMode = COMM_TCP;
1072 commStatus = STAT_CONNECTED;
1073 if (udpSock >= 0)
1074 closeUdpConn();
1075 if (udpWin)
1076 {
1077 udprefresh(UDP_CURRENT);
1078 udprefresh(UDP_STATUS);
1079 }
1080 warning("Timed out waiting for UDP response from server");
1081 UDPDIAG(("Timed out waiting for UDP response from server\n"));
1082 }
1083 }
1084 /* if we're in a UDP "force" mode, check to see if we need to do something */
1085 if (udpClientSend > 1 && commMode == COMM_UDP)
1086 checkForce();
1087 }
1088
1089 int
getvpsize(char * bufptr)1090 getvpsize(char *bufptr)
1091 {
1092 int size;
1093
1094 switch (*bufptr)
1095 {
1096 case SP_S_MESSAGE:
1097 size = ((unsigned char) bufptr[4]); /* IMPORTANT Changed */
1098 break;
1099 case SP_S_WARNING:
1100 if ((unsigned char) bufptr[1] == STEXTE_STRING ||
1101 (unsigned char) bufptr[1] == SHORT_WARNING)
1102 {
1103 size = ((unsigned char) bufptr[3]);
1104 }
1105 else
1106 size = 4; /* Normal Packet */
1107 break;
1108 case SP_S_PLAYER:
1109 if ((unsigned char) bufptr[1] & (unsigned char) 128)
1110 { /* Small +extended Header */
1111 size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4;
1112 }
1113 else if ((unsigned char) bufptr[1] & 64)
1114 { /* Small Header */
1115 if (shortversion >= SHORTVERSION) /* S_P2 */
1116 size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4 + (bufptr[2] * 4);
1117 else
1118 size = ((unsigned char) (bufptr[1] & 0x3f) * 4) + 4;
1119 }
1120 else
1121 { /* Big Header */
1122 size = ((unsigned char) bufptr[1] * 4 + 12);
1123 }
1124 break;
1125 case SP_S_TORP:
1126 size = vtsize[numofbits[(unsigned char) bufptr[1]]];
1127 break;
1128 case SP_S_TORP_INFO:
1129 size = (vtisize[numofbits[(unsigned char) bufptr[1]]]
1130 + numofbits[(unsigned char) bufptr[3]]);
1131 break;
1132 case SP_S_PLANET:
1133 size = ((unsigned char) bufptr[1] * VPLANET_SIZE) + 2;
1134 break;
1135 case SP_S_PHASER: /* S_P2 */
1136 switch ((unsigned char) bufptr[1] & 0x0f)
1137 {
1138 case PHFREE:
1139 case PHHIT:
1140 case PHMISS:
1141 size = 4;
1142 break;
1143 case PHHIT2:
1144 size = 8;
1145 break;
1146 default:
1147 size = sizeof(struct phaser_s_spacket);
1148
1149 break;
1150 }
1151 break;
1152 case SP_S_KILLS: /* S_P2 */
1153 size = ((unsigned char) bufptr[1] * 2) + 2;
1154 break;
1155 default:
1156 fprintf(stderr, "Unknown variable packet\n");
1157 /* terminate(1); */
1158 return -1;
1159 break;
1160 }
1161 if ((size % 4) != 0)
1162 {
1163 size += (4 - (size % 4));
1164 }
1165
1166 return size;
1167 }
1168
doRead(int asock)1169 static int doRead(int asock)
1170 {
1171 struct timeval timeout;
1172 fd_set readfds;
1173 char *bufptr;
1174 int size;
1175 int count;
1176 int temp;
1177
1178 timeout.tv_sec = 0;
1179 timeout.tv_usec = 0;
1180
1181 count = read(asock, buf, BUFSIZE);
1182
1183 #ifdef NETSTAT
1184 if (netstat &&
1185 (asock == udpSock ||
1186 commMode != COMM_UDP ||
1187 udpClientRecv == MODE_TCP))
1188 {
1189 ns_record_update(count);
1190 }
1191 #endif
1192
1193 if (debug)
1194 printf("read %d bytes from %s socket\n",
1195 count, asock == udpSock ? "UDP" : "TCP");
1196
1197 if (count <= 0)
1198 {
1199 if (asock == udpSock)
1200 {
1201
1202 #ifndef WIN32
1203 if (errno == ECONNREFUSED)
1204 #else
1205 if (WSAGetLastError() == WSAECONNREFUSED)
1206 #endif
1207
1208 {
1209 struct sockaddr_in addr;
1210
1211 UDPDIAG(("asock=%d, sock=%d, udpSock=%d, errno=%d\n",
1212 asock, sock, udpSock, errno));
1213 UDPDIAG(("count=%d\n", count));
1214 UDPDIAG(("Hiccup(%d)! Reconnecting\n", errno));
1215 addr.sin_addr.s_addr = serveraddr;
1216 addr.sin_port = htons(udpServerPort);
1217 addr.sin_family = AF_INET;
1218 if (connect(udpSock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
1219 {
1220 perror("connect");
1221 UDPDIAG(("Unable to reconnect\n"));
1222 /* and fall through to disconnect */
1223 }
1224 else
1225 {
1226 UDPDIAG(("Reconnect successful\n"));
1227 return 0;
1228 }
1229 }
1230 UDPDIAG(("*** UDP disconnected (res=%d, err=%d)\n",
1231 count, errno));
1232 warning("UDP link severed");
1233 printUdpInfo();
1234 closeUdpConn();
1235 commMode = commModeReq = COMM_TCP;
1236 commStatus = STAT_CONNECTED;
1237 if (udpWin)
1238 {
1239 udprefresh(UDP_STATUS);
1240 udprefresh(UDP_CURRENT);
1241 }
1242 return 0;
1243 }
1244 printf("server disconnected\n");
1245 close(asock);
1246 serverDead = 1;
1247 return 0;
1248 }
1249 bufptr = buf;
1250 while (bufptr < buf + count)
1251 {
1252 /* this goto label for a bug w/ short packets */
1253 computesize:
1254 if (*bufptr < 1 ||
1255 *bufptr > NUM_PACKETS ||
1256 handlers[(unsigned char) *bufptr].size == 0) {
1257 int i;
1258
1259 fprintf(stderr, "netrek protocol stream alignment failure, "
1260 "next byte %d (0x%02x)\n", *bufptr, *bufptr);
1261
1262 fprintf(stderr, "protocol buffer dump, bytes %d, [bufptr] at %d :\n",
1263 count, (int) (bufptr - buf));
1264 for (i = 0; i < count; i++) {
1265 if (i == (bufptr - buf)) {
1266 fprintf(stderr, "[%02x]", (unsigned int) buf[i] & 0xff);
1267 } else {
1268 fprintf(stderr, " %02x ", (unsigned int) buf[i] & 0xff);
1269 }
1270 }
1271 fprintf(stderr, "\n");
1272 return 0;
1273 }
1274 size = handlers[(unsigned char) *bufptr].size;
1275
1276 #ifdef SHORT_PACKETS
1277 if (size == -1)
1278 { /* variable packet */
1279 size = getvpsize(bufptr);
1280 if (size <= 0)
1281 {
1282 fprintf(stderr, "Bad short-packet size value (%d)\n", size);
1283 return 0;
1284 }
1285
1286 if (debug)
1287 printf("read variable packet size %d, type %d\n",
1288 size, *bufptr);
1289 }
1290 #endif /* SHORT_PACKETS */
1291
1292 if (size == 0)
1293 fprintf(stderr, "Variable packet has 0 length! type=%d Trying to read more!\n", *bufptr);
1294 /* read broke in the middle of a packet, wait until we get the rest */
1295 while (size > count + (buf - bufptr) || size == 0)
1296 {
1297 /* We wait for up to ten seconds for rest of packet. If we don't *
1298 * * get it, we assume the server died. */
1299 timeout.tv_sec = 20;
1300 timeout.tv_usec = 0;
1301 FD_ZERO(&readfds);
1302 FD_SET(asock, &readfds);
1303 /* readfds=1<<asock; */
1304 if ((temp = SELECT(max_fd, &readfds, 0, 0, &timeout)) == 0)
1305 {
1306 printf("Packet fragment. Server must be dead\n");
1307 serverDead = 1;
1308 close(sock);
1309 return 0;
1310 }
1311
1312 /* 88=largest short packet, messages */
1313 if (size == 0)
1314 {
1315 temp = read(asock, buf + count, 88);
1316 }
1317 else
1318 temp = read(asock, buf + count, size - (count + (buf - bufptr)));
1319 count += temp;
1320 if (temp <= 0)
1321 {
1322 printf("2) Got read() of %d. Server is dead\n", temp);
1323 serverDead = 1;
1324 close(sock);
1325 return 0;
1326 }
1327 /* go back to the size computation, hopefully with the rest of the */
1328 /* aborted packet in the buffer. */
1329 if (size == 0)
1330 goto computesize;
1331 }
1332 if (handlers[(unsigned char) *bufptr].handler != NULL)
1333 {
1334 if (asock != udpSock ||
1335 (!drop_flag || *bufptr == SP_SEQUENCE || *bufptr == SP_SC_SEQUENCE))
1336 {
1337 if (debug)
1338 printf("read packet %d\n", *bufptr);
1339
1340 #ifdef RECORDGAME
1341 if (recordFile != NULL && ckRecordPacket(*bufptr))
1342 {
1343 if (fwrite(bufptr, size, 1, recordFile) != 1)
1344 {
1345 perror("write: (recordFile)");
1346 fclose(recordFile);
1347 recordFile = NULL;
1348 }
1349 }
1350 #endif
1351
1352 #ifdef PACKET_LOG
1353 if (log_packets)
1354 {
1355 Log_Packet((char) (*bufptr), size);
1356 print_packet(bufptr,size);
1357 }
1358 #endif
1359
1360 if (asock == udpSock)
1361 packets_received++;
1362
1363 (*(handlers[(unsigned char) *bufptr].handler)) (bufptr
1364
1365 #ifdef CORRUPTED_PACKETS
1366 ,asock
1367 #endif
1368
1369 );
1370 }
1371 else
1372 {
1373 if (debug)
1374 {
1375 if (drop_flag)
1376 printf("%d bytes dropped.\n", size);
1377 }
1378 UDPDIAG(("Ignored type %d\n", *bufptr));
1379 }
1380 }
1381 else
1382 {
1383 printf("Handler for packet %d not installed...\n", *bufptr);
1384 }
1385
1386 bufptr += size;
1387
1388 #ifdef nodef
1389 if (bufptr > buf + BUFSIZ)
1390 {
1391 MCOPY(buf + BUFSIZ, buf, BUFSIZ);
1392 if (count == BUFSIZ * 2)
1393 {
1394 FD_ZERO(&readfds);
1395 FD_SET(asock, &readfds);
1396 /* readfds = 1<<asock; */
1397 if ((temp = SELECT(max_fd, &readfds, 0, 0, &timeout)) > 0)
1398 {
1399 temp = read(asock, buf + BUFSIZ, BUFSIZ);
1400 count = BUFSIZ + temp;
1401 if (temp <= 0)
1402 {
1403 printf("3) Got read() of %d. Server is dead\n", temp);
1404 serverDead = 1;
1405 close(sock);
1406 return 0;
1407 }
1408 }
1409 else
1410 {
1411 count = BUFSIZ;
1412 }
1413 }
1414 else
1415 {
1416 count -= BUFSIZ;
1417 }
1418 bufptr -= BUFSIZ;
1419 }
1420 #endif
1421 }
1422 return 1;
1423 }
1424
handleTorp(struct torp_spacket * packet)1425 void handleTorp(struct torp_spacket *packet)
1426 {
1427 struct torp *thetorp;
1428
1429 #ifdef CORRUPTED_PACKETS
1430 if (ntohs(packet->tnum) >= MAXPLAYER * MAXTORP)
1431 {
1432 fprintf(stderr, "handleTorp: bad index %d\n", ntohs(packet->tnum));
1433 return;
1434 }
1435 #endif
1436
1437 weaponUpdate = 1;
1438 thetorp = &torps[ntohs(packet->tnum)];
1439
1440 thetorp->t_x = ntohl(packet->x);
1441 thetorp->t_y = ntohl(packet->y);
1442 thetorp->t_dir = packet->dir;
1443 thetorp->t_updateFuse = MAX(2, TORP_UPDATE_FUSE * server_ups / 5);
1444
1445
1446 #ifdef ROTATERACE
1447 if (rotate)
1448 {
1449 rotate_coord(&thetorp->t_x, &thetorp->t_y, rotate_deg,
1450 GWIDTH / 2, GWIDTH / 2);
1451 rotate_dir(&thetorp->t_dir, rotate_deg);
1452 }
1453 #endif
1454
1455 if (gather_stats) {
1456 /*STATS_SP_TORP:DIR,TNUM,X,Y*/
1457 fprintf(statsFile, "\nSTATS_SP_TORP:\t");
1458 fprintf(statsFile, "%d\t%u\t%u\t%u",
1459 ((struct torp_spacket *) packet)->dir,
1460 ntohs(((struct torp_spacket *) packet)->tnum),
1461 ntohl(((struct torp_spacket *) packet)->x),
1462 ntohl(((struct torp_spacket *) packet)->y));
1463 }
1464 }
1465
handleTorpInfo(struct torp_info_spacket * packet)1466 void handleTorpInfo(struct torp_info_spacket *packet)
1467 {
1468 struct torp *thetorp;
1469
1470 #ifdef CORRUPTED_PACKETS
1471 if (ntohs(packet->tnum) >= MAXPLAYER * MAXTORP)
1472 {
1473 fprintf(stderr, "handleTorpInfo: bad index %d\n", ntohs(packet->tnum));
1474 return;
1475 }
1476 #endif
1477
1478 weaponUpdate = 1;
1479 thetorp = &torps[ntohs(packet->tnum)];
1480 thetorp->t_updateFuse = MAX(2, TORP_UPDATE_FUSE * server_ups / 5);
1481
1482 if (packet->status == TEXPLODE && thetorp->t_status == TFREE)
1483 {
1484 /* FAT: redundant explosion; don't update p_ntorp */
1485 /* printf("texplode ignored\n"); */
1486 return;
1487 }
1488
1489 if (packet->status && thetorp->t_status == TFREE)
1490 {
1491 players[thetorp->t_owner].p_ntorp++;
1492
1493 #ifdef nodef
1494 if (players[thetorp->t_owner].p_status == PEXPLODE)
1495 fprintf(stderr, "TORP STARTED WHEN PLAYER EXPLODED\n");
1496 #endif
1497
1498 /* BORG TEST */
1499
1500 #ifdef BD
1501 if (bd)
1502 bd_new_torp(ntohs(packet->tnum), thetorp);
1503 #endif
1504 }
1505 if (packet->status == TFREE && thetorp->t_status)
1506 {
1507 players[thetorp->t_owner].p_ntorp--;
1508 }
1509 thetorp->t_war = packet->war;
1510
1511 if (packet->status != thetorp->t_status)
1512 {
1513 /* FAT: prevent explosion reset */
1514 thetorp->t_status = packet->status;
1515 if (thetorp->t_status == TEXPLODE)
1516 {
1517 thetorp->t_fuse = NUMDETFRAMES * server_ups / 5;
1518 }
1519 }
1520 if (gather_stats) {
1521 /*STATS_SP_TORP_INFO:WAR\tSTATUS\tTNUM*/
1522 fprintf(statsFile, "\nSTATS_SP_TORP_INFO:\t");
1523 fprintf(statsFile, "%d\t%d\t%u",
1524 ((struct torp_info_spacket *) packet)->war,
1525 ((struct torp_info_spacket *) packet)->status,
1526 ntohs(((struct torp_info_spacket *) packet)->tnum));
1527 }
1528 }
1529
handleStatus(struct status_spacket * packet)1530 void handleStatus(struct status_spacket *packet)
1531 {
1532 status->tourn = packet->tourn;
1533 status->armsbomb = ntohl(packet->armsbomb);
1534 status->planets = ntohl(packet->planets);
1535 status->kills = ntohl(packet->kills);
1536 status->losses = ntohl(packet->losses);
1537 status->time = ntohl(packet->time);
1538 status->timeprod = ntohl(packet->timeprod);
1539
1540 if (debug)
1541 {
1542 printf("SERVER STATS:\n");
1543 printf("time: %d\n", status->time / (60 * 60 * 10));
1544 printf("kills: %d\n", status->kills);
1545 printf("losses: %d\n", status->losses);
1546 printf("planets: %d\n", status->planets);
1547 printf("armsbomb: %d\n", status->armsbomb);
1548 }
1549
1550 if (gather_stats) {
1551 /*STATS_SP_STATUS:\tTOURN\tARMSBOMB\tPLANETS\tKILLS\tLOSSES\tTIME\tTIMEPROD*/
1552 fprintf(statsFile, "\nSTATS_SP_STATUS:\t");
1553 fprintf(statsFile, "\t%d\t%u\t%u\t%u\t%u\t%u\t%u",
1554 ((struct status_spacket *) packet)->tourn,
1555 ntohl(((struct status_spacket *) packet)->armsbomb),
1556 ntohl(((struct status_spacket *) packet)->planets),
1557 ntohl(((struct status_spacket *) packet)->kills),
1558 ntohl(((struct status_spacket *) packet)->losses),
1559 ntohl(((struct status_spacket *) packet)->time),
1560 ntohl(((struct status_spacket *) packet)->timeprod));
1561 }
1562 }
1563
become(struct player * pl)1564 void become(struct player *pl)
1565 {
1566 int p_no;
1567
1568 p_no = pl->p_no;
1569 memcpy(&pl->p_ship, &me->p_ship, sizeof(struct ship));
1570 memcpy(&pl->p_stats, &me->p_stats, sizeof(struct stats));
1571 memcpy(pl, me, sizeof(struct player));
1572 pl->p_no = p_no;
1573 me->p_status = PFREE;
1574 }
1575
handleSelf(struct you_spacket * packet)1576 void handleSelf(struct you_spacket *packet) /* SP_YOU */
1577 {
1578 struct player* pl;
1579 static int seen = 0;
1580
1581 pl = &players[(unsigned char) packet->pnum];
1582
1583 #ifdef CORRUPTED_PACKETS
1584 if (packet->pnum < 0 || packet->pnum >= MAXPLAYER)
1585 {
1586 fprintf(stderr, "handleSelf: bad index %d\n", packet->pnum);
1587 return;
1588 }
1589 #endif
1590 if (seen && packet->pnum != me->p_no) become(pl);
1591 seen++;
1592
1593 if (!F_many_self)
1594 {
1595 me = (ghoststart ? &players[ghost_pno] : pl);
1596 myship = &(me->p_ship);
1597 mystats = &(me->p_stats);
1598 }
1599
1600 #ifdef PLIST2
1601 if (pl->p_hostile != packet->hostile)
1602 {
1603 pl->p_hostile = packet->hostile;
1604 PlistNoteHostile(packet->pnum);
1605 }
1606 #else
1607 pl->p_hostile = packet->hostile;
1608 #endif
1609
1610 pl->p_swar = packet->swar;
1611 pl->p_armies = packet->armies;
1612
1613 #ifdef nodef
1614 if (((pl->p_flags & PFGREEN) && (ntohl(packet->flags) & PFRED)) ||
1615 ((pl->p_flags & PFRED) && (ntohl(packet->flags) & PFGREEN)))
1616 printf("green/red transition\n");
1617 #endif
1618
1619 pl->p_flags = ntohl(packet->flags);
1620 if (pl->p_flags & PFPLOCK)
1621 {
1622 redrawPlayer[pl->p_playerl] = 1;
1623 }
1624 pl->p_damage = ntohl(packet->damage);
1625 pl->p_shield = ntohl(packet->shield);
1626 pl->p_fuel = ntohl(packet->fuel);
1627 pl->p_etemp = ntohs(packet->etemp);
1628 pl->p_wtemp = ntohs(packet->wtemp);
1629 pl->p_whydead = ntohs(packet->whydead);
1630 pl->p_whodead = ntohs(packet->whodead);
1631
1632 #ifdef INCLUDE_VISTRACT
1633 if (packet->tractor & 0x40) {
1634 pl->p_tractor = (short) packet->tractor & (~0x40); /* ATM - visible
1635 * tractors */
1636 }
1637
1638 #ifdef nodef /* tmp */
1639 else
1640 pl->p_tractor = -1;
1641 #endif /* nodef */
1642
1643 #endif
1644 }
1645
1646
handlePlayer(struct player_spacket * packet)1647 void handlePlayer(struct player_spacket *packet)
1648 {
1649 register struct player *pl;
1650 int x, y;
1651
1652 #ifdef CORRUPTED_PACKETS
1653 if (packet->pnum >= MAXPLAYER)
1654 {
1655 fprintf(stderr, "handlePlayer: bad index %d\n", packet->pnum);
1656 return;
1657 }
1658 #endif
1659
1660
1661 pl = &players[(unsigned char) packet->pnum];
1662
1663 pl->p_dir = packet->dir;
1664 pl->p_speed = packet->speed;
1665 PlistNoteSpeed(packet->pnum);
1666
1667 if (F_cloak_maxwarp && pl != me)
1668 {
1669 if (pl->p_speed == 0xf)
1670 pl->p_flags |= PFCLOAK;
1671 else if (pl->p_flags & PFCLOAK)
1672 pl->p_flags &= ~PFCLOAK;
1673 }
1674 x = ntohl(packet->x);
1675 y = ntohl(packet->y);
1676
1677 #ifdef WARP_DEAD
1678 if (F_dead_warp && pl->p_speed == 14 && x == -10000 && y == -10000 && (pl->p_status != PEXPLODE))
1679 {
1680 pl->p_status = PEXPLODE;
1681 x = pl->p_x;
1682 y = pl->p_y;
1683 if (pl->p_dir > DEADPACKETS)
1684 pl->p_explode = EX_FRAMES;
1685 else
1686 pl->p_explode = 0;
1687 redrawPlayer[packet->pnum] = 1;
1688 PlistNoteUpdate(packet->pnum);
1689 }
1690 #endif
1691
1692 pl->p_x = x;
1693 pl->p_y = y;
1694
1695 redrawPlayer[(unsigned char) packet->pnum] = 1;
1696
1697 if (me == pl)
1698 {
1699 extern int my_x, my_y; /* From short.c */
1700
1701 my_x = x;
1702 my_y = y;
1703 }
1704
1705
1706 #ifdef ROTATERACE
1707 if (rotate)
1708 {
1709 rotate_coord(&pl->p_x, &pl->p_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
1710 rotate_dir(&pl->p_dir, rotate_deg);
1711 }
1712 #endif
1713
1714 if (gather_stats) {
1715 /* SP_PLAYER:PNUN,DIR,SPEED,X,Y */
1716 fprintf(statsFile, "\nSTATS_SP_PLAYER:\t");
1717 fprintf(statsFile, "%d\t%u\t%d\t%d\t%d",
1718 ((struct player_spacket *) packet)->pnum,
1719 ((struct player_spacket *) packet)->dir,
1720 ((struct player_spacket *) packet)->speed,
1721 ntohl(((struct player_spacket *) packet)->x),
1722 ntohl(((struct player_spacket *) packet)->y));
1723 }
1724 }
1725
1726
handleWarning(struct warning_spacket * packet)1727 void handleWarning(struct warning_spacket *packet)
1728 {
1729 packet->mesg[sizeof(packet->mesg) - 1] = '\0'; /* guarantee null * *
1730 * termination */
1731 warning(packet->mesg);
1732 }
1733
sendShortPacket(char type,char state)1734 void sendShortPacket(char type, char state)
1735 {
1736 struct speed_cpacket speedReq;
1737
1738 bzero(&speedReq, sizeof(speedReq));
1739 speedReq.type = type;
1740 speedReq.speed = state;
1741 sendServerPacket((struct player_spacket *) &speedReq);
1742
1743 /* if we're sending in UDP mode, be prepared to force it */
1744 if (commMode == COMM_UDP && udpClientSend >= 2)
1745 {
1746 switch (type)
1747 {
1748 case CP_SPEED:
1749 fSpeed = state | 0x100;
1750 break;
1751 case CP_DIRECTION:
1752 fDirection = state | 0x100;
1753 break;
1754 case CP_SHIELD:
1755 fShield = state | 0xa00;
1756 break;
1757 case CP_ORBIT:
1758 fOrbit = state | 0xa00;
1759 break;
1760 case CP_REPAIR:
1761 fRepair = state | 0xa00;
1762 break;
1763 case CP_CLOAK:
1764 fCloak = state | 0xa00;
1765 break;
1766 case CP_BOMB:
1767 fBomb = state | 0xa00;
1768 break;
1769 case CP_DOCKPERM:
1770 fDockperm = state | 0xa00;
1771 break;
1772 case CP_PLAYLOCK:
1773 fPlayLock = state | 0xa00;
1774 break;
1775 case CP_PLANLOCK:
1776 fPlanLock = state | 0xa00;
1777 break;
1778 case CP_BEAM:
1779 if (state == 1)
1780 fBeamup = 1 | 0x500;
1781 else
1782 fBeamdown = 2 | 0x500;
1783 break;
1784 }
1785
1786 /* force weapons too? */
1787 if (udpClientSend >= 3)
1788 {
1789 switch (type)
1790 {
1791 case CP_PHASER:
1792 fPhaser = state | 0x100;
1793 break;
1794 case CP_PLASMA:
1795 fPlasma = state | 0x100;
1796 break;
1797 }
1798 }
1799 }
1800 }
1801
sendServerPacket(void * buffer)1802 void sendServerPacket(void *buffer)
1803 {
1804 int size;
1805 struct player_spacket *packet = (struct player_spacket *) buffer;
1806
1807 if (serverDead)
1808 return;
1809 if (packet->type < 1 ||
1810 packet->type > NUM_SIZES ||
1811 sizes[(unsigned char) packet->type] == 0)
1812 {
1813 printf("Attempt to send strange packet %d!\n", packet->type);
1814 return;
1815 }
1816 size = sizes[(unsigned char) packet->type];
1817
1818 #ifdef PACKET_LOG
1819 if (log_packets)
1820 {
1821 Log_OPacket(packet->type, size);
1822 print_opacket((char *) packet,size);
1823 }
1824 #endif
1825
1826 if (commMode == COMM_UDP)
1827 {
1828 /* for now, just sent everything via TCP */
1829 }
1830 if (commMode == COMM_TCP || !udpClientSend)
1831 {
1832 /* special case for verify packet */
1833 if (packet->type == CP_UDP_REQ)
1834 {
1835 if (((struct udp_req_cpacket *) packet)->request == COMM_VERIFY)
1836 goto send_udp;
1837 }
1838 /* business as usual (or player has turned off UDP transmission) */
1839 if (gwrite(sock, (char *) packet, size) != size)
1840 {
1841 printf("gwrite failed. Server must be dead\n");
1842 serverDead = 1;
1843 }
1844 }
1845 else
1846 {
1847 /* UDP stuff */
1848 switch (packet->type)
1849 {
1850 case CP_SPEED:
1851 case CP_DIRECTION:
1852 case CP_PHASER:
1853 case CP_PLASMA:
1854 case CP_TORP:
1855 case CP_QUIT:
1856 case CP_PRACTR:
1857 case CP_SHIELD:
1858 case CP_REPAIR:
1859 case CP_ORBIT:
1860 case CP_PLANLOCK:
1861 case CP_PLAYLOCK:
1862 case CP_BOMB:
1863 case CP_BEAM:
1864 case CP_CLOAK:
1865 case CP_DET_TORPS:
1866 case CP_DET_MYTORP:
1867 case CP_REFIT:
1868 case CP_TRACTOR:
1869 case CP_REPRESS:
1870 case CP_COUP:
1871 case CP_DOCKPERM:
1872
1873 #ifdef INCLUDE_SCAN
1874 case CP_SCAN:
1875 #endif
1876
1877 case CP_PING_RESPONSE:
1878 /* non-critical stuff, use UDP */
1879 send_udp:
1880 packets_sent++;
1881
1882 V_UDPDIAG(("Sent %d on UDP port\n", packet->type));
1883 if (gwrite(udpSock, (char *) packet, size) != size)
1884 {
1885 UDPDIAG(("gwrite on UDP failed. Closing UDP connection\n"));
1886 warning("UDP link severed");
1887 /* serverDead=1; */
1888 commModeReq = commMode = COMM_TCP;
1889 commStatus = STAT_CONNECTED;
1890 commSwitchTimeout = 0;
1891 if (udpWin)
1892 {
1893 udprefresh(UDP_STATUS);
1894 udprefresh(UDP_CURRENT);
1895 }
1896 if (udpSock >= 0)
1897 closeUdpConn();
1898 }
1899 break;
1900
1901 default:
1902 /* critical stuff, use TCP */
1903 if (gwrite(sock, (char *) packet, size) != size)
1904 {
1905 printf("gwrite failed. Server must be dead\n");
1906 serverDead = 1;
1907 }
1908 }
1909 }
1910 }
1911
handlePlanet(struct planet_spacket * packet)1912 void handlePlanet(struct planet_spacket *packet)
1913 {
1914 struct planet *plan;
1915
1916 /* FAT: prevent excessive redraw */
1917 int redraw = 0;
1918
1919 #ifdef CORRUPTED_PACKETS
1920 if (packet->pnum >= MAXPLANETS)
1921 {
1922 fprintf(stderr, "handlePlanet: bad index %d\n", packet->pnum);
1923 return;
1924 }
1925 #endif
1926
1927 plan = &planets[(unsigned char) packet->pnum];
1928
1929 #ifdef nodef
1930 monpoprate(plan, packet);
1931 #endif
1932
1933 if (plan->pl_owner != packet->owner)
1934 redraw = 1;
1935 plan->pl_owner = packet->owner;
1936 if (plan->pl_owner < FED || plan->pl_owner > ORI)
1937 plan->pl_owner = NOBODY;
1938 if (plan->pl_info != packet->info)
1939 redraw = 1;
1940 plan->pl_info = packet->info;
1941 /* Redraw the planet because it was updated by server */
1942
1943 if (plan->pl_flags != (int) ntohs(packet->flags))
1944 redraw = 1;
1945 plan->pl_flags = (int) ntohs(packet->flags);
1946
1947 if (plan->pl_armies != ntohl(packet->armies))
1948 {
1949 /* don't redraw when armies change unless it crosses the '4' army
1950 * limit. Keeps people from watching for planet 'flicker' when
1951 * players are beaming */
1952 int planetarmies = ntohl(packet->armies);
1953
1954 if ((plan->pl_armies < 5 && planetarmies > 4) ||
1955 (plan->pl_armies > 4 && planetarmies < 5))
1956 redraw = 1;
1957 }
1958 plan->pl_armies = ntohl(packet->armies);
1959
1960 #ifndef RECORDGAME
1961 if (plan->pl_info == 0)
1962 {
1963 plan->pl_owner = NOBODY;
1964 }
1965 #endif
1966
1967 if (redraw)
1968 {
1969 plan->pl_flags |= PLREDRAW;
1970 }
1971 }
1972
handlePhaser(struct phaser_spacket * packet)1973 void handlePhaser(struct phaser_spacket *packet)
1974 {
1975 struct phaser *phas;
1976
1977 #ifdef CORRUPTED_PACKETS
1978 if (packet->pnum >= MAXPLAYER)
1979 {
1980 fprintf(stderr, "handlePhaser: bad index %d\n", packet->pnum);
1981 return;
1982 }
1983 if (packet->status == PHHIT &&
1984 (ntohl(packet->target) < 0 || ntohl(packet->target) >= MAXPLAYER))
1985 {
1986 fprintf(stderr, "handlePhaser: bad target %d\n", ntohl(packet->target));
1987 return;
1988 }
1989 #endif
1990
1991 weaponUpdate = 1;
1992 phas = &phasers[(unsigned char) packet->pnum];
1993 phas->ph_status = packet->status;
1994 phas->ph_dir = packet->dir;
1995 phas->ph_x = ntohl(packet->x);
1996 phas->ph_y = ntohl(packet->y);
1997 phas->ph_target = ntohl(packet->target);
1998 phas->ph_fuse = 0;
1999 #ifdef SOUND
2000 phas->sound_phaser = 1;
2001 #endif
2002 phas->ph_updateFuse = PHASER_UPDATE_FUSE * server_ups / 10;
2003
2004 #ifdef ROTATERACE
2005 if (rotate)
2006 {
2007 rotate_coord(&phas->ph_x, &phas->ph_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
2008 rotate_dir(&phas->ph_dir, rotate_deg);
2009 }
2010 #endif
2011
2012 if (gather_stats) {
2013 /* not getting any data?*/
2014 /*STATS_SP_PHASER:\tpnum\tstats\tdir\tx\ty\ttarget*/
2015 fprintf(statsFile, "\nSTATS_SP_PHASER\t");
2016 fprintf(statsFile, "%d\t%d\t%u\t%d\t%d\t%d",
2017 ((struct phaser_spacket *) packet)->pnum,
2018 ((struct phaser_spacket *) packet)->status,
2019 ((struct phaser_spacket *) packet)->dir,
2020 ntohl(((struct phaser_spacket *) packet)->x),
2021 ntohl(((struct phaser_spacket *) packet)->y),
2022 ntohl(((struct phaser_spacket *) packet)->target));
2023 }
2024 }
2025
handleMessage(struct mesg_spacket * packet)2026 void handleMessage(struct mesg_spacket *packet)
2027 {
2028 if (packet->m_from >= MAXPLAYER)
2029 packet->m_from = 255;
2030
2031 #ifdef CORRUPTED_PACKETS
2032 packet->mesg[sizeof(packet->mesg) - 1] = '\0';
2033 #endif
2034
2035 /* printf("flags: 0x%x\n", packet->m_flags);
2036 * printf("from: %d\n", packet->m_from);
2037 * printf("recpt: %d\n", packet->m_recpt);
2038 * printf("mesg: %s\n", packet->mesg);
2039 */
2040
2041 dmessage(packet->mesg, packet->m_flags, packet->m_from, packet->m_recpt);
2042
2043 if (gather_stats) {
2044 /*STATS_SP_MESSAGE:\tFLAGS\tRECPT\tFROM\tMESG*/
2045 fprintf(statsFile, "\nSTATS_SP_MESSAGE:\t");
2046 fprintf(statsFile, "0x%0X\t%d\t%d\t%s",
2047 ((struct mesg_spacket *) packet)->m_flags,
2048 ((struct mesg_spacket *) packet)->m_recpt,
2049 ((struct mesg_spacket *) packet)->m_from,
2050 ((struct mesg_spacket *) packet)->mesg);
2051 }
2052 }
2053
handleQueue(struct queue_spacket * packet)2054 void handleQueue(struct queue_spacket *packet)
2055 {
2056 queuePos = ntohs(packet->pos);
2057 }
2058
sendTeamReq(int team,int ship)2059 void sendTeamReq(int team, int ship)
2060 {
2061 struct outfit_cpacket outfitReq;
2062
2063 bzero(&outfitReq, sizeof(outfitReq));
2064 outfitReq.type = CP_OUTFIT;
2065 outfitReq.team = team;
2066 outfitReq.ship = ship;
2067 sendServerPacket(&outfitReq);
2068 }
2069
handlePickok(struct pickok_spacket * packet)2070 void handlePickok(struct pickok_spacket *packet)
2071 {
2072 pickOk = packet->state;
2073 }
2074
sendLoginReq(char * name,char * pass,char * login,char query)2075 void sendLoginReq(char *name, char *pass, char *login, char query)
2076 {
2077 struct login_cpacket packet;
2078
2079 bzero(&packet, sizeof(packet));
2080 strcpy(packet.name, name);
2081 strcpy(packet.password, pass);
2082 if (strlen(login) > 15)
2083 login[15] = 0;
2084 strcpy(packet.login, login);
2085 packet.type = CP_LOGIN;
2086 packet.query = query;
2087 sendServerPacket((struct player_spacket *) &packet);
2088 }
2089
handleLogin(struct login_spacket * packet)2090 void handleLogin(struct login_spacket *packet)
2091 {
2092 loginAccept = packet->accept;
2093 if (packet->accept)
2094 {
2095 /* no longer needed .. we have it in xtrekrc bcopy(packet->keymap,
2096 * mystats->st_keymap, 96); */
2097 mystats->st_flags = ntohl(packet->flags);
2098
2099 #ifdef nodef
2100 namemode = (me->p_stats.st_flags / ST_NAMEMODE) & 1;
2101 keeppeace = (me->p_stats.st_flags / ST_KEEPPEACE) & 1;
2102 showlocal = (me->p_stats.st_flags / ST_SHOWLOCAL) & 3;
2103 showgalactic = (me->p_stats.st_flags / ST_SHOWGLOBAL) & 3;
2104 #endif
2105 }
2106 }
2107
sendTractorReq(char state,char pnum)2108 void sendTractorReq(char state, char pnum)
2109 {
2110 struct tractor_cpacket tractorReq;
2111
2112 memset(&tractorReq, 0, sizeof(struct tractor_cpacket));
2113 tractorReq.type = CP_TRACTOR;
2114 tractorReq.state = state;
2115 tractorReq.pnum = pnum;
2116 sendServerPacket((struct player_spacket *) &tractorReq);
2117
2118 if (state)
2119 fTractor = pnum | 0x40;
2120 else
2121 fTractor = 0;
2122 }
2123
sendRepressReq(char state,char pnum)2124 void sendRepressReq(char state, char pnum)
2125 {
2126 struct repress_cpacket repressReq;
2127
2128 memset(&repressReq, 0, sizeof(struct repress_cpacket));
2129 repressReq.type = CP_REPRESS;
2130 repressReq.state = state;
2131 repressReq.pnum = pnum;
2132 sendServerPacket((struct player_spacket *) &repressReq);
2133
2134 if (state)
2135 fRepress = pnum | 0x40;
2136 else
2137 fRepress = 0;
2138 }
2139
sendDetMineReq(short int torp)2140 void sendDetMineReq(short int torp)
2141 {
2142 struct det_mytorp_cpacket detReq;
2143
2144 memset(&detReq, 0, sizeof(struct det_mytorp_cpacket));
2145 detReq.type = CP_DET_MYTORP;
2146 detReq.tnum = htons(torp);
2147 sendServerPacket((struct player_spacket *) &detReq);
2148 }
2149
handlePlasmaInfo(struct plasma_info_spacket * packet)2150 void handlePlasmaInfo(struct plasma_info_spacket *packet)
2151 {
2152 struct plasmatorp *thetorp;
2153
2154 #ifdef CORRUPTED_PACKETS
2155 if (ntohs(packet->pnum) >= MAXPLAYER * MAXPLASMA)
2156 {
2157 fprintf(stderr, "handlePlasmaInfo: bad index %d\n", packet->pnum);
2158 return;
2159 }
2160 #endif
2161
2162 weaponUpdate = 1;
2163 thetorp = &plasmatorps[ntohs(packet->pnum)];
2164 thetorp->pt_updateFuse = MAX(2, PLASMA_UPDATE_FUSE * server_ups / 5);
2165 if (packet->status == PTEXPLODE && thetorp->pt_status == PTFREE)
2166 {
2167 /* FAT: redundant explosion; don't update p_nplasmatorp */
2168 return;
2169 }
2170 if (!thetorp->pt_status && packet->status)
2171 {
2172 players[thetorp->pt_owner].p_nplasmatorp++;
2173 }
2174 if (thetorp->pt_status && !packet->status)
2175 {
2176 players[thetorp->pt_owner].p_nplasmatorp--;
2177 }
2178 thetorp->pt_war = packet->war;
2179 if (thetorp->pt_status != packet->status)
2180 {
2181 /* FAT: prevent explosion timer from being reset */
2182 thetorp->pt_status = packet->status;
2183 if (thetorp->pt_status == PTEXPLODE)
2184 {
2185 thetorp->pt_fuse = NUMDETFRAMES * server_ups / 5;
2186 }
2187 }
2188
2189 if (gather_stats) {
2190 /*STATS_SP_PLASMA_INFO:\tWAR\tSTATUS\tPNUM*/
2191 fprintf(statsFile, "\nSTATS_SP_PLASMA_INFO:\t");
2192 fprintf(statsFile, "%d\t%d\t%u",
2193 ((struct plasma_info_spacket *) packet)->war,
2194 ((struct plasma_info_spacket *) packet)->status,
2195 ntohs(((struct plasma_info_spacket *) packet)->pnum));
2196 }
2197 }
2198
handlePlasma(struct plasma_spacket * packet)2199 void handlePlasma(struct plasma_spacket *packet)
2200 {
2201 struct plasmatorp *thetorp;
2202
2203 #ifdef CORRUPTED_PACKETS
2204 if (ntohs(packet->pnum) >= MAXPLAYER * MAXPLASMA)
2205 {
2206 fprintf(stderr, "handlePlasma: bad index %d\n", packet->pnum);
2207 return;
2208 }
2209 #endif
2210
2211 weaponUpdate = 1;
2212 thetorp = &plasmatorps[ntohs(packet->pnum)];
2213 thetorp->pt_x = ntohl(packet->x);
2214 thetorp->pt_y = ntohl(packet->y);
2215 thetorp->pt_updateFuse = MAX(2, PLASMA_UPDATE_FUSE * server_ups / 5);
2216
2217 #ifdef ROTATERACE
2218 if (rotate)
2219 {
2220 rotate_coord(&thetorp->pt_x, &thetorp->pt_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
2221 }
2222 #endif
2223
2224 if (gather_stats) {
2225 /*STATS_SP_PLASMA:\tPNUM\tX\tY*/
2226 fprintf(statsFile, "\nSTATS_SP_PLASMA:\t%u\t%d\t%d",
2227 ntohs(((struct plasma_spacket *) packet)->pnum),
2228 ntohl(((struct plasma_spacket *) packet)->x),
2229 ntohl(((struct plasma_spacket *) packet)->y));
2230 }
2231 }
2232
handleFlags(struct flags_spacket * packet)2233 void handleFlags(struct flags_spacket *packet)
2234 {
2235 struct player* pl;
2236
2237 pl = &players[(unsigned char) packet->pnum];
2238
2239 #ifdef CORRUPTED_PACKETS
2240 if (packet->pnum >= MAXPLAYER)
2241 {
2242 fprintf(stderr, "handleFlags: bad index %d\n", packet->pnum);
2243 return;
2244 }
2245 #endif
2246
2247 if (pl->p_flags != ntohl(packet->flags)
2248
2249 #ifdef INCLUDE_VISTRACT
2250 || pl->p_tractor != ((short) packet->tractor & (~0x40))
2251 #endif
2252
2253 )
2254 {
2255 /* FAT: prevent redundant player update */
2256 redrawPlayer[(unsigned char) packet->pnum] = 1;
2257 }
2258 else
2259 return;
2260
2261 pl->p_flags = ntohl(packet->flags);
2262
2263 #ifdef INCLUDE_VISTRACT
2264 if (packet->tractor & 0x40) {
2265 pl->p_tractor =
2266 (short) packet->tractor & (~0x40); /* ATM visible tractors */
2267 } else
2268 #endif /* INCLUDE_VISTRACT */
2269
2270 pl->p_tractor = -1;
2271 }
2272
handleKills(struct kills_spacket * packet)2273 void handleKills(struct kills_spacket *packet)
2274 {
2275
2276 #ifdef CORRUPTED_PACKETS
2277 if (packet->pnum >= MAXPLAYER)
2278 {
2279 fprintf(stderr, "handleKills: bad index %d\n", packet->pnum);
2280 return;
2281 }
2282 #endif
2283
2284 if (players[(unsigned char) packet->pnum].p_kills !=
2285 ntohl(packet->kills) / 100.0)
2286 {
2287 players[(unsigned char) packet->pnum].p_kills =
2288 ntohl(packet->kills) / 100.0;
2289 /* FAT: prevent redundant player update */
2290 PlistNoteUpdate((unsigned char) packet->pnum);
2291
2292 #ifdef ARMY_SLIDER
2293 if (me == &players[(unsigned char) packet->pnum])
2294 {
2295 calibrate_stats();
2296 redrawStats();
2297 }
2298 #endif /* ARMY_SLIDER */
2299 }
2300
2301 if (gather_stats) {
2302 /*STATS_SP_KILLS:\tPNUM\tKILLS*/
2303 fprintf(statsFile, "\nSTATS_SP_KILLS:\t");
2304 fprintf(statsFile, "%d\t%u",
2305 ((struct kills_spacket *) packet)->pnum,
2306 ntohl(((struct kills_spacket *) packet)->kills));
2307 }
2308 }
2309
handlePStatus(struct pstatus_spacket * packet)2310 void handlePStatus(struct pstatus_spacket *packet)
2311 {
2312 register struct player *j;
2313
2314 #ifdef CORRUPTED_PACKETS
2315 if (packet->pnum >= MAXPLAYER)
2316 {
2317 fprintf(stderr, "handlePStatus: bad index %d\n", packet->pnum);
2318 return;
2319 }
2320 #endif
2321
2322 j = &players[(unsigned char) packet->pnum];
2323
2324 if (packet->status == j->p_status)
2325 return;
2326
2327 if (packet->status == PEXPLODE)
2328 {
2329 j->p_explode = 0;
2330 }
2331
2332 /* Ignore DEAD status. Instead, we treat it as PEXPLODE. This gives us time
2333 * * * to animate all the frames necessary for the explosions at our own
2334 * pace. */
2335 else if (packet->status == PDEAD)
2336 {
2337 packet->status = PEXPLODE;
2338
2339 if (j->p_status == PEXPLODE) /* Prevent redundant updates
2340 *
2341 */
2342 return;
2343 }
2344
2345 /* guarantees we won't miss the kill message since this is TCP */
2346 else if (packet->status == PALIVE && j->p_status != PALIVE)
2347 j->p_kills = 0.;
2348
2349 /* update the player list, especially if this signals a new arrival */
2350 PlistNoteUpdate((unsigned char) packet->pnum);
2351 if (j->p_status == PFREE || packet->status == PFREE)
2352 PlistNoteArrive(packet->pnum);
2353
2354 j->p_status = packet->status;
2355 redrawPlayer[(unsigned char) packet->pnum] = 1;
2356 }
2357
handleMotd(struct motd_spacket * packet)2358 void handleMotd(struct motd_spacket *packet)
2359 {
2360 packet->line[sizeof(packet->line) - 1] = '\0';
2361 newMotdLine(packet->line);
2362 }
2363
sendMessage(char * mes,int group,int indiv)2364 void sendMessage(char *mes, int group, int indiv)
2365 {
2366 struct mesg_cpacket mesPacket;
2367
2368 bzero(&mesPacket, sizeof(mesPacket));
2369 #ifdef SHORT_PACKETS
2370 if (recv_short)
2371 {
2372 int size;
2373
2374 size = strlen(mes);
2375 size += 5; /* 1 for '\0', 4 * *
2376 * packetheader */
2377 if ((size % 4) != 0)
2378 size += (4 - (size % 4));
2379 mesPacket.pad1 = (char) size;
2380 sizes[CP_S_MESSAGE] = size;
2381 mesPacket.type = CP_S_MESSAGE;
2382 }
2383 else
2384 #endif
2385
2386 mesPacket.type = CP_MESSAGE;
2387 mesPacket.group = group;
2388 mesPacket.indiv = indiv;
2389 STRNCPY(mesPacket.mesg, mes, 80);
2390 sendServerPacket((struct player_spacket *) &mesPacket);
2391 }
2392
2393
handleMask(struct mask_spacket * packet)2394 void handleMask(struct mask_spacket *packet)
2395 {
2396 motd_refresh();
2397 tournMask = packet->mask;
2398 }
2399
sendOptionsPacket(void)2400 void sendOptionsPacket(void)
2401 {
2402 struct options_cpacket optPacket;
2403
2404 bzero(&optPacket, sizeof(optPacket));
2405 optPacket.type = CP_OPTIONS;
2406 optPacket.flags =
2407 htonl(ST_MAPMODE + /* always on */
2408 ST_NAMEMODE * namemode +
2409 ST_SHOWSHIELDS + /* always on */
2410 ST_KEEPPEACE * keeppeace +
2411 ST_SHOWLOCAL * showlocal +
2412 ST_SHOWGLOBAL * showgalactic);
2413 MCOPY(mystats->st_keymap, optPacket.keymap, 96);
2414 sendServerPacket((struct player_spacket *) &optPacket);
2415 }
2416
pickSocket(int old)2417 static void pickSocket(int old)
2418 {
2419 int newsocket;
2420 struct socket_cpacket sockPack;
2421
2422 /* If baseLocalPort is defined we want to start from that */
2423 if(baseLocalPort)
2424 newsocket = baseLocalPort;
2425 else
2426 newsocket = (getpid() & 32767);
2427 while (newsocket < 2048 || newsocket == old)
2428 {
2429 if(baseLocalPort)
2430 newsocket++;
2431 else
2432 newsocket = (newsocket + 10687) & 32767;
2433 }
2434 bzero(&sockPack,sizeof(sockPack));
2435 sockPack.type = CP_SOCKET;
2436 sockPack.socket = htonl(newsocket);
2437 sockPack.version = (char) SOCKVERSION;
2438 sockPack.udp_version = (char) UDPVERSION;
2439 sendServerPacket((struct player_spacket *) &sockPack);
2440 /* Did we get new socket # sent? */
2441 if (serverDead)
2442 return;
2443 nextSocket = newsocket;
2444 }
2445
2446 static void
handleBadVersionSorry(char * reason)2447 handleBadVersionSorry (char *reason)
2448 {
2449 printf("%s\nTry again later.\n", reason);
2450 }
2451
handleBadVersion(struct badversion_spacket * packet)2452 void handleBadVersion(struct badversion_spacket *packet)
2453 {
2454 int badversion = packet->why;
2455
2456 if (badversion >= 0 && badversion <= MAXBADVERSION) {
2457 handleBadVersionSorry(badversion_long_strings[badversion]);
2458 }
2459 terminate(EXIT_BADVERSION_BASE+badversion);
2460 }
2461
gwrite(int fd,char * buf,register int bytes)2462 int gwrite(int fd, char *buf, register int bytes)
2463 {
2464 LONG orig = bytes;
2465 register LONG n;
2466
2467 while (bytes)
2468 {
2469 n = write(fd, buf, bytes);
2470 if (n < 0)
2471 {
2472 if (fd == udpSock)
2473 {
2474 fprintf(stderr, "Tried to write %d, %d\n", fd, bytes);
2475 perror("write");
2476 printUdpInfo();
2477 }
2478 return -1;
2479 }
2480 bytes -= n;
2481 buf += n;
2482 }
2483 return orig;
2484 }
2485
handleHostile(struct hostile_spacket * packet)2486 void handleHostile(struct hostile_spacket *packet)
2487 {
2488 int p_no = packet->pnum;
2489 struct player *pl;
2490
2491 #ifdef CORRUPTED_PACKETS
2492 if (p_no < 0 || p_no >= MAXPLAYER)
2493 {
2494 fprintf(stderr, "handleHostile: bad index %d\n", p_no);
2495 return;
2496 }
2497 #endif
2498
2499 pl = &players[p_no];
2500 if (pl->p_swar != packet->war ||
2501 pl->p_hostile != packet->hostile)
2502 {
2503 /* FAT: prevent redundant player update & redraw */
2504 pl->p_swar = packet->war;
2505 pl->p_hostile = packet->hostile;
2506 PlistNoteHostile(p_no);
2507 redrawPlayer[p_no] = 1;
2508 }
2509 }
2510
handlePlyrLogin(struct plyr_login_spacket * packet,int sock)2511 void handlePlyrLogin(struct plyr_login_spacket *packet, int sock)
2512 {
2513 int p_no = packet->pnum;
2514 struct player *pl;
2515
2516 #ifdef CORRUPTED_PACKETS
2517 if (sock == udpSock)
2518 {
2519 fprintf(stderr, "garbage packet discarded.\n");
2520 return;
2521 }
2522 if (packet->pnum < 0 || packet->pnum >= MAXPLAYER)
2523 {
2524 fprintf(stderr, "handlePlyrLogin: bad index %d\n", p_no);
2525 return;
2526 }
2527 packet->name[sizeof(packet->name) - 1] = '\0';
2528 packet->monitor[sizeof(packet->monitor) - 1] = '\0';
2529 packet->login[sizeof(packet->login) - 1] = '\0';
2530 #endif
2531
2532 pl = &players[p_no];
2533
2534 if (identityBlind) {
2535 strcpy(pl->p_name, "");
2536 strcpy(pl->p_monitor, "");
2537 strcpy(pl->p_login, "");
2538 pl->p_stats.st_rank = 0;
2539 } else {
2540 strcpy(pl->p_name, packet->name);
2541 strcpyp_return(pl->p_monitor, packet->monitor, sizeof(pl->p_monitor));
2542 strcpy(pl->p_login, packet->login);
2543 pl->p_stats.st_rank = packet->rank;
2544 }
2545
2546 if (p_no == me->p_no)
2547 {
2548 /* This is me. Set some stats */
2549 if (lastRank == -1)
2550 {
2551 if (loggedIn)
2552 {
2553 lastRank = packet->rank;
2554 }
2555 }
2556 else
2557 {
2558 if (lastRank != packet->rank)
2559 {
2560 lastRank = packet->rank;
2561 promoted = 1;
2562 }
2563 }
2564 }
2565
2566 PlistNoteUpdate(p_no);
2567
2568 if (gather_stats) {
2569 /* STATS_SP_PLAYER:PNUN,RANK,NAME,MONITOR,LOGIN */
2570 fprintf(statsFile, "\nSTATS_SP_PL_LOGIN:\t");
2571 fprintf(statsFile, "%d\t%d\t%s\t%s\t%s",
2572 ((struct plyr_login_spacket *) packet)->pnum,
2573 ((struct plyr_login_spacket *) packet)->rank,
2574 ((struct plyr_login_spacket *) packet)->name,
2575 ((struct plyr_login_spacket *) packet)->monitor,
2576 ((struct plyr_login_spacket *) packet)->login);
2577 }
2578 }
2579
handleStats(struct stats_spacket * packet)2580 void handleStats(struct stats_spacket *packet)
2581 {
2582 int p_no = packet->pnum;
2583 struct player *pl;
2584
2585 #ifdef CORRUPTED_PACKETS
2586 if (p_no < 0 || p_no >= MAXPLAYER)
2587 {
2588 fprintf(stderr, "handleStats: bad index %d\n", p_no);
2589 return;
2590 }
2591 #endif
2592
2593 pl = &players[p_no];
2594
2595 pl->p_stats.st_tkills = ntohl(packet->tkills);
2596 pl->p_stats.st_tlosses = ntohl(packet->tlosses);
2597 pl->p_stats.st_kills = ntohl(packet->kills);
2598 pl->p_stats.st_losses = ntohl(packet->losses);
2599 pl->p_stats.st_tticks = ntohl(packet->tticks);
2600 pl->p_stats.st_tplanets = ntohl(packet->tplanets);
2601 pl->p_stats.st_tarmsbomb = ntohl(packet->tarmies);
2602 pl->p_stats.st_sbkills = ntohl(packet->sbkills);
2603 pl->p_stats.st_sblosses = ntohl(packet->sblosses);
2604 pl->p_stats.st_armsbomb = ntohl(packet->armies);
2605 pl->p_stats.st_planets = ntohl(packet->planets);
2606
2607 if ((pl->p_ship.s_type == STARBASE) && (SBhours))
2608 {
2609 pl->p_stats.st_sbticks = ntohl(packet->maxkills);
2610 }
2611 else
2612 {
2613 pl->p_stats.st_maxkills = ntohl(packet->maxkills) / 100.0;
2614 }
2615 pl->p_stats.st_sbmaxkills = ntohl(packet->sbmaxkills) / 100.0;
2616
2617 /* For some reason, we get updates for freed players. When this
2618 happens, don't bother to update the player list. */
2619 if (pl->p_status != PFREE)
2620 PlistNoteUpdate(p_no);
2621 }
2622
handlePlyrInfo(struct plyr_info_spacket * packet)2623 void handlePlyrInfo(struct plyr_info_spacket *packet)
2624 {
2625 int p_no = packet->pnum;
2626 struct player *pl;
2627 static int lastship = -1;
2628
2629 #ifdef CORRUPTED_PACKETS
2630 if (p_no < 0 || p_no >= MAXPLAYER)
2631 {
2632 fprintf(stderr, "handlePlyrInfo: bad index %d\n", p_no);
2633 return;
2634 }
2635 if (packet->team > ALLTEAM)
2636 {
2637 fprintf(stderr, "handlePlyrInfo: bad team %d\n", packet->team);
2638 return;
2639 }
2640 #endif
2641
2642 pl = &players[p_no];
2643
2644 PlistNoteUpdate(p_no);
2645 if ((pl->p_team != packet->team) || /* Check 0 system default */
2646 ((pl->p_team == 0) && (pl->p_mapchars[0] != teamlet[0])))
2647 {
2648 pl->p_team = packet->team;
2649 pl->p_mapchars[0] = teamlet[pl->p_team];
2650 PlistNoteArrive(p_no);
2651
2652 if (pl == me)
2653 redrawall = 1; /* Update the map if I * *
2654 * change teams */
2655 }
2656
2657 getship(&pl->p_ship, packet->shiptype);
2658 pl->p_mapchars[1] = shipnos[pl->p_no];
2659
2660
2661 if (me == pl && lastship != me->p_ship.s_type)
2662 {
2663 redrawTstats();
2664 calibrate_stats();
2665 redrawStats(); /* TSH */
2666 }
2667 redrawPlayer[p_no] = 1;
2668
2669 if (gather_stats) {
2670 /*STATS_SP_PLAYER_INFO:\tPNUM\tSHIPTYPE\tTEAM*/
2671 fprintf(statsFile, "\nSTATS_SP_PLAYER_INFO:\t");
2672 fprintf(statsFile, "%d\t%d\t%d",
2673 ((struct plyr_info_spacket *) packet)->pnum,
2674 ((struct plyr_info_spacket *) packet)->shiptype,
2675 ((struct plyr_info_spacket *) packet)->team);
2676 }
2677 }
2678
sendUpdatePacket(LONG speed)2679 void sendUpdatePacket(LONG speed)
2680 {
2681 struct updates_cpacket packet;
2682
2683 packet.type = CP_UPDATES;
2684 timerDelay = speed;
2685 packet.usecs = htonl(speed);
2686 sendServerPacket((struct player_spacket *) &packet);
2687 }
2688
handlePlanetLoc(struct planet_loc_spacket * packet)2689 void handlePlanetLoc(struct planet_loc_spacket *packet)
2690 {
2691 int pl_no = packet->pnum;
2692 struct planet *pl;
2693
2694 #ifdef CORRUPTED_PACKETS
2695 if (pl_no < 0 || pl_no >= MAXPLANETS)
2696 {
2697 fprintf(stderr, "handlePlanetLoc: bad index\n");
2698 return;
2699 }
2700 #endif
2701
2702 pl = &planets[pl_no];
2703 pl_update[pl_no].plu_x = pl->pl_x;
2704 pl_update[pl_no].plu_y = pl->pl_y;
2705
2706 if (pl_update[pl_no].plu_update != -1)
2707 {
2708 pl_update[pl_no].plu_update = 1;
2709 }
2710 else
2711 pl_update[pl_no].plu_update = 0;
2712
2713 pl->pl_x = ntohl(packet->x);
2714 pl->pl_y = ntohl(packet->y);
2715 strcpy(pl->pl_name, packet->name);
2716 pl->pl_namelen = strlen(packet->name);
2717 pl->pl_flags |= (PLREDRAW | PLCLEAR);
2718 reinitPlanets = 1;
2719
2720 #ifdef ROTATERACE
2721 if (rotate)
2722 {
2723 rotate_coord(&pl->pl_x, &pl->pl_y, rotate_deg, GWIDTH / 2, GWIDTH / 2);
2724 }
2725 #endif
2726
2727 if (gather_stats) {
2728 /*STATS_SP_PLANET_LOC:\tPNUM\tX\tY\tNAME*/
2729 fprintf(statsFile, "\nSTATS_SP_PLANET_LOC:\t");
2730 fprintf(statsFile, "%d\t%d\t%d\t%s",
2731 ((struct planet_loc_spacket *) packet)->pnum,
2732 ntohl(((struct planet_loc_spacket *) packet)->x),
2733 ntohl(((struct planet_loc_spacket *) packet)->y),
2734 ((struct planet_loc_spacket *) packet)->name);
2735 }
2736 }
2737
2738
handleReserved(struct reserved_spacket * packet,int sock)2739 void handleReserved(struct reserved_spacket *packet, int sock)
2740 {
2741 struct reserved_cpacket response;
2742
2743 bzero(&response, sizeof(response));
2744 #ifdef CORRUPTED_PACKETS
2745 if (sock == udpSock)
2746 {
2747 fprintf(stderr, "garbage Reserved packet discarded.\n");
2748 return;
2749 }
2750 #endif
2751
2752 #if !defined(BORG)
2753
2754 #ifndef RSA
2755 encryptReservedPacket(packet, &response, serverName, me->p_no);
2756 sendServerPacket((struct player_spacket *) &response);
2757 #else
2758
2759 if (RSA_Client)
2760 { /* can use -o option for old
2761 * * * blessing */
2762 /* client sends back a 'reserved' packet just saying RSA_VERSION info */
2763 /* theoretically, the server then sends off a rsa_key_spacket * for the
2764 * * * client to then respond to */
2765 warning(RSA_VERSION);
2766 STRNCPY(response.resp, RSA_VERSION, RESERVED_SIZE);
2767 MCOPY(packet->data, response.data, RESERVED_SIZE);
2768 response.type = CP_RESERVED;
2769
2770 #ifdef DEBUG
2771 printf("Sending RSA reserved response\n");
2772 #endif
2773 }
2774 else
2775 {
2776 /* If server gods don't like NEWMACRO/SMARTMACRO they better install *
2777 * * RSA... */
2778 UseNewMacro = 1;
2779 UseSmartMacro = 1;
2780 encryptReservedPacket(packet, &response, serverName, me->p_no);
2781 }
2782
2783 sendServerPacket((struct player_spacket *) &response);
2784 #endif /* RSA */
2785
2786 #endif /* defined(BORG) */
2787 }
2788
handleShipCap(struct ship_cap_spacket * packet)2789 void handleShipCap(struct ship_cap_spacket *packet)
2790 {
2791 unsigned short stype;
2792
2793 stype = ntohs(packet->s_type);
2794 shipvals[stype].s_torpspeed = ntohs(packet->s_torpspeed);
2795 shipvals[stype].s_maxshield = ntohl(packet->s_maxshield);
2796 shipvals[stype].s_maxdamage = ntohl(packet->s_maxdamage);
2797 shipvals[stype].s_maxegntemp = ntohl(packet->s_maxegntemp);
2798 shipvals[stype].s_maxwpntemp = ntohl(packet->s_maxwpntemp);
2799 shipvals[stype].s_maxarmies = ntohs(packet->s_maxarmies);
2800 shipvals[stype].s_maxfuel = ntohl(packet->s_maxfuel);
2801 shipvals[stype].s_maxspeed = ntohl(packet->s_maxspeed);
2802 shipvals[stype].s_width = ntohs(packet->s_width);
2803 shipvals[stype].s_height = ntohs(packet->s_height);
2804 shipvals[stype].s_phaserdamage = ntohs(packet->s_phaserrange);
2805 getship(myship, myship->s_type);
2806 }
2807
2808 static void
handleGeneric32_a(struct generic_32_spacket_a * packet)2809 handleGeneric32_a (struct generic_32_spacket_a *packet)
2810 {
2811 me->p_repair_time = packet->repair_time;
2812 me->pl_orbit = packet->pl_orbit;
2813 }
2814
2815 static void
handleGeneric32_b(struct generic_32_spacket_b * packet)2816 handleGeneric32_b (struct generic_32_spacket_b *packet)
2817 {
2818 int rate;
2819 static int unsafe = GU_UNSAFE;
2820 static int idling = 0;
2821 static int saved_ups = 0;
2822
2823 me->p_repair_time = ntohs(packet->repair_time);
2824 me->pl_orbit = packet->pl_orbit;
2825 context->gameup = ntohs(packet->gameup);
2826 context->tournament_teams = packet->tournament_teams;
2827 context->tournament_age = packet->tournament_age;
2828 context->tournament_age_units = packet->tournament_age_units;
2829 context->tournament_remain = packet->tournament_remain;
2830 context->tournament_remain_units = packet->tournament_remain_units;
2831 context->starbase_remain = packet->starbase_remain;
2832 context->team_remain = packet->team_remain;
2833
2834 /* to maintain update rate when safe-idle, set updatespersec.idle: -1 */
2835
2836 rate = intDefault("updatespersec.idle", 1);
2837 if ((unsafe ^ context->gameup) & GU_UNSAFE) {
2838 unsafe = context->gameup;
2839 if (context->gameup & GU_UNSAFE) {
2840 if (idling) {
2841 if (rate < 0) {
2842 warning("Safe idle stop.");
2843 } else {
2844 sendUpdatePacket(1000000 / saved_ups);
2845 warning("Safe idle stop, normal update rate resumed.");
2846 }
2847 if (context->tournament_age_units == 's' &&
2848 context->tournament_age < 5 &&
2849 booleanDefault("game-begin-while-idle-beep", 1)) W_Beep();
2850 idling = 0;
2851 }
2852 } else {
2853 if (!(context->gameup & GU_UNSAFE)) {
2854 if (!idling) {
2855 if (rate < 0) {
2856 warning("Safe idle start.");
2857 } else {
2858 saved_ups = client_ups;
2859 sendUpdatePacket(1000000 / rate);
2860 idling++;
2861 warning("Safe idle start, update rate reduced.");
2862 }
2863 }
2864 }
2865 }
2866 }
2867 }
2868
2869 static void
handleGeneric32(struct generic_32_spacket * packet)2870 handleGeneric32 (struct generic_32_spacket *packet)
2871 {
2872 switch (packet->version) {
2873 case 0x60+GENERIC_32_VERSION_A:
2874 handleGeneric32_a((struct generic_32_spacket_a *) packet);
2875 break;
2876 case 0x60+GENERIC_32_VERSION_B:
2877 handleGeneric32_b((struct generic_32_spacket_b *) packet);
2878 break;
2879 }
2880 }
2881
2882 void
handleRank(struct rank_spacket * packet)2883 handleRank (struct rank_spacket *packet)
2884 {
2885 int i = packet->rnum;
2886 int j = packet->rmax + 1;
2887
2888 if (i < 0 || j < 0 || i > j) return;
2889 if (j > nranks) {
2890 ranks = (struct rank *) realloc(ranks, j * sizeof(struct rank));
2891 memset(&ranks[nranks], 0, (j - nranks) * sizeof(struct rank));
2892 }
2893 nranks = j;
2894 W_ChangeBorder(rankw, gColor);
2895 packet->name[15] = 0;
2896 ranks[i].name = strdup(packet->name);
2897 packet->cname[7] = 0;
2898 ranks[i].cname = strdup(packet->cname);
2899 ranks[i].hours = (float) (ntohl (packet->hours) / 100.0);
2900 ranks[i].ratings = (float) (ntohl (packet->ratings) / 100.0);
2901 ranks[i].offense = (float) (ntohl (packet->offense) / 100.0);
2902 }
2903
dump_prefix(const char * abbr,const char * name)2904 static void dump_prefix(const char *abbr, const char *name) {
2905 fprintf(stderr, "%-10s %-30s ", abbr, name);
2906 }
2907
2908 #define dump_stat(STAT) { \
2909 fprintf(stderr, " %8u\n", (unsigned int) ltd.STAT); \
2910 }
2911
2912 #define dump_max(STAT) { \
2913 fprintf(stderr, " %8u\n", (unsigned int) ltd.STAT); \
2914 }
2915
2916 void
handleLtd(struct ltd_spacket * packet)2917 handleLtd (struct ltd_spacket *packet)
2918 {
2919 if (packet->version != LTD_VERSION) return;
2920
2921 struct ltd_stats ltd;
2922
2923 ltd.kills.total = ntohl(packet->kt);
2924 ltd.kills.max = (double)(ntohl(packet->kmax)) / 100.0;
2925 ltd.kills.first = ntohl(packet->k1);
2926 ltd.kills.first_potential = ntohl(packet->k1p);
2927 ltd.kills.first_converted = ntohl(packet->k1c);
2928 ltd.kills.second = ntohl(packet->k2);
2929 ltd.kills.second_potential = ntohl(packet->k2p);
2930 ltd.kills.second_converted = ntohl(packet->k2c);
2931 ltd.kills.phasered = ntohl(packet->kbp);
2932 ltd.kills.torped = ntohl(packet->kbt);
2933 ltd.kills.plasmaed = ntohl(packet->kbs);
2934 ltd.deaths.total = ntohl(packet->dt);
2935 ltd.deaths.potential = ntohl(packet->dpc);
2936 ltd.deaths.converted = ntohl(packet->dcc);
2937 ltd.deaths.dooshed = ntohl(packet->ddc);
2938 ltd.deaths.phasered = ntohl(packet->dbp);
2939 ltd.deaths.torped = ntohl(packet->dbt);
2940 ltd.deaths.plasmaed = ntohl(packet->dbs);
2941 ltd.deaths.acc = ntohl(packet->acc);
2942 ltd.planets.taken = ntohl(packet->ptt);
2943 ltd.planets.destroyed = ntohl(packet->pdt);
2944 ltd.bomb.planets = ntohl(packet->bpt);
2945 ltd.bomb.planets_8 = ntohl(packet->bp8);
2946 ltd.bomb.planets_core = ntohl(packet->bpc);
2947 ltd.bomb.armies = ntohl(packet->bat);
2948 ltd.bomb.armies_8 = ntohl(packet->ba8);
2949 ltd.bomb.armies_core = ntohl(packet->bac);
2950 ltd.ogged.armies = ntohl(packet->oat);
2951 ltd.ogged.dooshed = ntohl(packet->odc);
2952 ltd.ogged.converted = ntohl(packet->occ);
2953 ltd.ogged.potential = ntohl(packet->opc);
2954 ltd.ogged.bigger_ship = ntohl(packet->ogc);
2955 ltd.ogged.same_ship = ntohl(packet->oec);
2956 ltd.ogged.smaller_ship = ntohl(packet->olc);
2957 ltd.ogged.sb_armies = ntohl(packet->osba);
2958 ltd.ogged.friendly = ntohl(packet->ofc);
2959 ltd.ogged.friendly_armies = ntohl(packet->ofa);
2960 ltd.armies.total = ntohl(packet->at);
2961 ltd.armies.attack = ntohl(packet->aa);
2962 ltd.armies.reinforce = ntohl(packet->ar);
2963 ltd.armies.ferries = ntohl(packet->af);
2964 ltd.armies.killed = ntohl(packet->ak);
2965 ltd.carries.total = ntohl(packet->ct);
2966 ltd.carries.partial = ntohl(packet->cp);
2967 ltd.carries.completed = ntohl(packet->cc);
2968 ltd.carries.attack = ntohl(packet->ca);
2969 ltd.carries.reinforce = ntohl(packet->cr);
2970 ltd.carries.ferries = ntohl(packet->cf);
2971 ltd.ticks.total = ntohl(packet->tt);
2972 ltd.ticks.yellow = ntohl(packet->tyel);
2973 ltd.ticks.red = ntohl(packet->tred);
2974 ltd.ticks.zone[0] = ntohl(packet->tz0);
2975 ltd.ticks.zone[1] = ntohl(packet->tz1);
2976 ltd.ticks.zone[2] = ntohl(packet->tz2);
2977 ltd.ticks.zone[3] = ntohl(packet->tz3);
2978 ltd.ticks.zone[4] = ntohl(packet->tz4);
2979 ltd.ticks.zone[5] = ntohl(packet->tz5);
2980 ltd.ticks.zone[6] = ntohl(packet->tz6);
2981 ltd.ticks.zone[7] = ntohl(packet->tz7);
2982 ltd.ticks.potential = ntohl(packet->tpc);
2983 ltd.ticks.carrier = ntohl(packet->tcc);
2984 ltd.ticks.repair = ntohl(packet->tr);
2985 ltd.damage_repaired = ntohl(packet->dr);
2986 ltd.weapons.phaser.fired = ntohl(packet->wpf);
2987 ltd.weapons.phaser.hit = ntohl(packet->wph);
2988 ltd.weapons.phaser.damage.inflicted = ntohl(packet->wpdi);
2989 ltd.weapons.phaser.damage.taken = ntohl(packet->wpdt);
2990 ltd.weapons.torps.fired = ntohl(packet->wtf);
2991 ltd.weapons.torps.hit = ntohl(packet->wth);
2992 ltd.weapons.torps.detted = ntohl(packet->wtd);
2993 ltd.weapons.torps.selfdetted = ntohl(packet->wts);
2994 ltd.weapons.torps.wall = ntohl(packet->wtw);
2995 ltd.weapons.torps.damage.inflicted = ntohl(packet->wtdi);
2996 ltd.weapons.torps.damage.taken = ntohl(packet->wtdt);
2997 ltd.weapons.plasma.fired = ntohl(packet->wsf);
2998 ltd.weapons.plasma.hit = ntohl(packet->wsh);
2999 ltd.weapons.plasma.phasered = ntohl(packet->wsp);
3000 ltd.weapons.plasma.wall = ntohl(packet->wsw);
3001 ltd.weapons.plasma.damage.inflicted = ntohl(packet->wsdi);
3002 ltd.weapons.plasma.damage.taken = ntohl(packet->wsdt);
3003
3004 return;
3005
3006 fprintf(stderr, "SP_LTD test output begins\n");
3007 dump_prefix("kt", "kills total"); dump_stat(kills.total);
3008 dump_prefix("kmax", "kills max"); dump_max(kills.max);
3009 dump_prefix("k1", "kills first"); dump_stat(kills.first);
3010 dump_prefix("k1p", "kills first potential"); dump_stat(kills.first_potential);
3011 dump_prefix("k1c", "kills first converted"); dump_stat(kills.first_converted);
3012 dump_prefix("k2", "kills second"); dump_stat(kills.second);
3013 dump_prefix("k2p", "kills second potential"); dump_stat(kills.second_potential);
3014 dump_prefix("k2c", "kills second converted"); dump_stat(kills.second_converted);
3015 dump_prefix("kbp", "kills by phaser"); dump_stat(kills.phasered);
3016 dump_prefix("kbt", "kills by torp"); dump_stat(kills.torped);
3017 dump_prefix("kbs", "kills by smack"); dump_stat(kills.plasmaed);
3018 dump_prefix("dt", "deaths total"); dump_stat(deaths.total);
3019 dump_prefix("dpc", "deaths as potential carrier"); dump_stat(deaths.potential);
3020 dump_prefix("dcc", "deaths as converted carrier"); dump_stat(deaths.converted);
3021 dump_prefix("ddc", "deaths as dooshed carrier"); dump_stat(deaths.dooshed);
3022 dump_prefix("dbp", "deaths by phaser"); dump_stat(deaths.phasered);
3023 dump_prefix("dbt", "deaths by torp"); dump_stat(deaths.torped);
3024 dump_prefix("dbs", "deaths by smack"); dump_stat(deaths.plasmaed);
3025 dump_prefix("acc", "actual carriers created"); dump_stat(deaths.acc);
3026 dump_prefix("ptt", "planets taken total"); dump_stat(planets.taken);
3027 dump_prefix("pdt", "planets destroyed total"); dump_stat(planets.destroyed);
3028 dump_prefix("bpt", "bombed planets total"); dump_stat(bomb.planets);
3029 dump_prefix("bp8", "bombed planets <=8"); dump_stat(bomb.planets_8);
3030 dump_prefix("bpc", "bombed planets core"); dump_stat(bomb.planets_core);
3031 dump_prefix("bat", "bombed armies total"); dump_stat(bomb.armies);
3032 dump_prefix("ba8", "bombed_armies <= 8"); dump_stat(bomb.armies_8);
3033 dump_prefix("bac", "bombed armies core"); dump_stat(bomb.armies_core);
3034 dump_prefix("oat", "ogged armies total"); dump_stat(ogged.armies);
3035 dump_prefix("odc", "ogged dooshed carrier"); dump_stat(ogged.dooshed);
3036 dump_prefix("occ", "ogged converted carrier"); dump_stat(ogged.converted);
3037 dump_prefix("opc", "ogged potential carrier"); dump_stat(ogged.potential);
3038 dump_prefix("o>c", "ogged bigger carrier"); dump_stat(ogged.bigger_ship);
3039 dump_prefix("o=c", "ogged same carrier"); dump_stat(ogged.same_ship);
3040 dump_prefix("o<c", "ogger smaller carrier"); dump_stat(ogged.smaller_ship);
3041 dump_prefix("osba", "ogged sb armies"); dump_stat(ogged.sb_armies);
3042 dump_prefix("ofc", "ogged friendly carrier"); dump_stat(ogged.friendly);
3043 dump_prefix("ofa", "ogged friendly armies"); dump_stat(ogged.friendly_armies);
3044 dump_prefix("at", "armies carried total"); dump_stat(armies.total);
3045 dump_prefix("aa", "armies used to attack"); dump_stat(armies.attack);
3046 dump_prefix("ar", "armies used to reinforce"); dump_stat(armies.reinforce);
3047 dump_prefix("af", "armies ferried"); dump_stat(armies.ferries);
3048 dump_prefix("ak", "armies killed"); dump_stat(armies.killed);
3049 dump_prefix("ct", "carries total"); dump_stat(carries.total);
3050 dump_prefix("cp", "carries partial"); dump_stat(carries.partial);
3051 dump_prefix("cc", "carries completed"); dump_stat(carries.completed);
3052 dump_prefix("ca", "carries to attack"); dump_stat(carries.attack);
3053 dump_prefix("cr", "carries to reinforce"); dump_stat(carries.reinforce);
3054 dump_prefix("cf", "carries to ferry"); dump_stat(carries.ferries);
3055 dump_prefix("tt", "ticks total"); dump_stat(ticks.total);
3056 dump_prefix("tyel", "ticks in yellow"); dump_stat(ticks.yellow);
3057 dump_prefix("tred", "ticks in red"); dump_stat(ticks.red);
3058 dump_prefix("tz0", "ticks in zone 0"); dump_stat(ticks.zone[0]);
3059 dump_prefix("tz1", "ticks in zone 1"); dump_stat(ticks.zone[1]);
3060 dump_prefix("tz2", "ticks in zone 2"); dump_stat(ticks.zone[2]);
3061 dump_prefix("tz3", "ticks in zone 3"); dump_stat(ticks.zone[3]);
3062 dump_prefix("tz4", "ticks in zone 4"); dump_stat(ticks.zone[4]);
3063 dump_prefix("tz5", "ticks in zone 5"); dump_stat(ticks.zone[5]);
3064 dump_prefix("tz6", "ticks in zone 6"); dump_stat(ticks.zone[6]);
3065 dump_prefix("tz7", "ticks in zone 7"); dump_stat(ticks.zone[7]);
3066 dump_prefix("tpc", "ticks as potential carrier"); dump_stat(ticks.potential);
3067 dump_prefix("tcc", "ticks as carrier++"); dump_stat(ticks.carrier);
3068 dump_prefix("tr", "ticks in repair"); dump_stat(ticks.repair);
3069 dump_prefix("dr", "damage repaired"); dump_stat(damage_repaired);
3070 dump_prefix("wpf", "weap phaser fired"); dump_stat(weapons.phaser.fired);
3071 dump_prefix("wph", "weap phaser hit"); dump_stat(weapons.phaser.hit);
3072 dump_prefix("wpdi", "weap phaser damage inflicted"); dump_stat(weapons.phaser.damage.inflicted);
3073 dump_prefix("wpdt", "weap phaser damage taken"); dump_stat(weapons.phaser.damage.taken);
3074 dump_prefix("wtf", "weap torp fired"); dump_stat(weapons.torps.fired);
3075 dump_prefix("wth", "weap torp hit"); dump_stat(weapons.torps.hit);
3076 dump_prefix("wtd", "weap torp detted"); dump_stat(weapons.torps.detted);
3077 dump_prefix("wts", "weap torp self detted"); dump_stat(weapons.torps.selfdetted);
3078 dump_prefix("wtw", "weap torp hit wall"); dump_stat(weapons.torps.wall);
3079 dump_prefix("wtdi", "weap torp damage inflicted"); dump_stat(weapons.torps.damage.inflicted);
3080 dump_prefix("wtdt", "weap torp damage taken"); dump_stat(weapons.torps.damage.taken);
3081 dump_prefix("wsf", "weap smack fired"); dump_stat(weapons.plasma.fired);
3082 dump_prefix("wsh", "weap smack hit"); dump_stat(weapons.plasma.hit);
3083 dump_prefix("wsp", "weap smack phasered"); dump_stat(weapons.plasma.phasered);
3084 dump_prefix("wsw", "weap smack hit wall"); dump_stat(weapons.plasma.wall);
3085 dump_prefix("wsdi", "weap smack damage inflicted"); dump_stat(weapons.plasma.damage.inflicted);
3086 dump_prefix("wsdt", "weap smack damage taken"); dump_stat(weapons.plasma.damage.taken);
3087 fprintf(stderr, "SP_LTD test output ends\n");
3088 }
3089
3090 #ifdef RSA
handleRSAKey(struct rsa_key_spacket * packet)3091 void handleRSAKey(struct rsa_key_spacket *packet)
3092 {
3093 struct rsa_key_cpacket response;
3094 struct sockaddr_in saddr;
3095 socklen_t len;
3096 unsigned char *data;
3097
3098 #ifdef GATEWAY
3099 extern unsigned LONG netaddr;
3100 extern int serv_port;
3101 #endif
3102
3103 bzero(&response, sizeof(response));
3104 response.type = CP_RSA_KEY;
3105 /* encryptRSAPacket (packet, &response); old style rsa-client */
3106
3107 #ifdef GATEWAY
3108 /* if we didn't get it from -H, go ahead and query the socket */
3109 if (netaddr == 0)
3110 {
3111 len = sizeof(saddr);
3112 if (getpeername(sock, (struct sockaddr *) &saddr, &len) < 0)
3113 {
3114 perror("getpeername(sock)");
3115 terminate(1);
3116 }
3117 }
3118 else
3119 {
3120 saddr.sin_addr.s_addr = htonl(netaddr);
3121 saddr.sin_port = htons(serv_port);
3122 }
3123 #else
3124 /* query the socket to determine the remote host (ATM) */
3125 len = sizeof(saddr);
3126 if (getpeername(sock, (struct sockaddr *) &saddr, &len) < 0)
3127 {
3128 perror("getpeername(sock)");
3129 terminate(1);
3130 }
3131 #endif
3132
3133 /* replace the first few bytes of the message */
3134 /* will be the low order bytes of the number */
3135 data = packet->data;
3136 MCOPY(&saddr.sin_addr.s_addr, data, sizeof(saddr.sin_addr.s_addr));
3137 data += sizeof(saddr.sin_addr.s_addr);
3138 MCOPY(&saddr.sin_port, data, sizeof(saddr.sin_port));
3139
3140 rsa_black_box(response.resp, packet->data, response.public, response.global);
3141
3142 sendServerPacket((struct player_spacket *) &response);
3143 }
3144 #endif
3145
3146 #ifdef INCLUDE_SCAN
handleScan(packet)3147 void handleScan(packet)
3148 struct scan_spacket *packet;
3149 {
3150 struct player *pp;
3151
3152 #ifdef CORRUPTED_PACKETS
3153 if (packet->pnum >= MAXPLAYER)
3154 {
3155 fprintf(stderr, "handleScan: bad index\n");
3156 return;
3157 }
3158 #endif
3159
3160 if (packet->success)
3161 {
3162 pp = &players[packet->pnum];
3163 pp->p_fuel = ntohl(packet->p_fuel);
3164 pp->p_armies = ntohl(packet->p_armies);
3165 pp->p_shield = ntohl(packet->p_shield);
3166 pp->p_damage = ntohl(packet->p_damage);
3167 pp->p_etemp = ntohl(packet->p_etemp);
3168 pp->p_wtemp = ntohl(packet->p_wtemp);
3169 informScan(packet->pnum);
3170 }
3171 }
3172
informScan(p)3173 informScan(p)
3174 int p;
3175 {
3176 }
3177 #endif /* INCLUDE_SCAN */
3178
3179 /* UDP stuff */
sendUdpReq(int req)3180 void sendUdpReq(int req)
3181 {
3182 struct udp_req_cpacket packet;
3183
3184 memset(&packet, 0, sizeof(struct udp_req_cpacket));
3185 packet.type = CP_UDP_REQ;
3186 packet.request = req;
3187
3188 if (req >= COMM_MODE)
3189 {
3190 packet.request = COMM_MODE;
3191 packet.connmode = req - COMM_MODE;
3192 sendServerPacket((struct player_spacket *) &packet);
3193 return;
3194 }
3195 if (req == COMM_UPDATE)
3196 {
3197
3198 #ifdef SHORT_PACKETS
3199 if (recv_short)
3200 { /* not necessary */
3201 /* Let the client do the work, and not the network :-) */
3202
3203 resetWeaponInfo();
3204 }
3205 #endif
3206
3207 sendServerPacket((struct player_spacket *) &packet);
3208 warning("Sent request for full update");
3209 return;
3210 }
3211 if (req == commModeReq)
3212 {
3213 warning("Request is in progress, do not disturb");
3214 return;
3215 }
3216 if (req == COMM_UDP)
3217 {
3218 /* open UDP port */
3219 if (openUdpConn() >= 0)
3220 {
3221 UDPDIAG(("Bound to local port %d on fd %d\n", udpLocalPort, udpSock));
3222 }
3223 else
3224 {
3225 UDPDIAG(("Bind to local port %d failed\n", udpLocalPort));
3226 commModeReq = COMM_TCP;
3227 commStatus = STAT_CONNECTED;
3228 commSwitchTimeout = 0;
3229 if (udpWin)
3230 udprefresh(UDP_STATUS);
3231 warning("Unable to establish UDP connection");
3232
3233 return;
3234 }
3235 }
3236 /* send the request */
3237 packet.type = CP_UDP_REQ;
3238 packet.request = req;
3239 packet.port = htonl(udpLocalPort);
3240
3241 #ifdef GATEWAY
3242 if (!strcmp(serverName, gw_mach))
3243 {
3244 packet.port = htons(gw_serv_port); /* gw port that server * *
3245 * should call */
3246 UDPDIAG(("+ Telling server to contact us on %d\n", gw_serv_port));
3247 }
3248 #endif
3249
3250 #ifdef UDP_PORTSWAP
3251 if (portSwap)
3252 packet.connmode = CONNMODE_PORT; /* have him send his port */
3253 else
3254 #endif
3255 packet.connmode = CONNMODE_PACKET; /* we get addr from packet */
3256
3257 sendServerPacket((struct player_spacket *) &packet);
3258
3259 /* update internal state stuff */
3260 commModeReq = req;
3261 if (req == COMM_TCP)
3262 commStatus = STAT_SWITCH_TCP;
3263 else
3264 commStatus = STAT_SWITCH_UDP;
3265 commSwitchTimeout = 25; /* wait 25 updates (about *
3266 * * five seconds) */
3267
3268 UDPDIAG(("Sent request for %s mode\n", (req == COMM_TCP) ?
3269 "TCP" : "UDP"));
3270
3271 #ifdef UDP_PORTSWAP
3272 if (!portSwap)
3273 #endif
3274 if ((req == COMM_UDP) && recvUdpConn() < 0)
3275 {
3276 UDPDIAG(("Sending TCP reset message\n"));
3277 packet.request = COMM_TCP;
3278 packet.port = 0;
3279 commModeReq = COMM_TCP;
3280 sendServerPacket((struct player_spacket *) &packet);
3281 /* we will likely get a SWITCH_UDP_OK later; better ignore it */
3282 commModeReq = COMM_TCP;
3283 commStatus = STAT_CONNECTED;
3284 commSwitchTimeout = 0;
3285 }
3286
3287 if (udpWin)
3288 udprefresh(UDP_STATUS);
3289 }
3290
handleUdpReply(struct udp_reply_spacket * packet)3291 void handleUdpReply(struct udp_reply_spacket *packet)
3292 {
3293 struct udp_req_cpacket response;
3294
3295 UDPDIAG(("Received UDP reply %d\n", packet->reply));
3296 commSwitchTimeout = 0;
3297
3298 memset(&response, 0, sizeof(struct udp_req_cpacket));
3299 response.type = CP_UDP_REQ;
3300
3301 switch (packet->reply)
3302 {
3303 case SWITCH_TCP_OK:
3304 if (commMode == COMM_TCP)
3305 {
3306 UDPDIAG(("Got SWITCH_TCP_OK while in TCP mode; ignoring\n"));
3307 }
3308 else
3309 {
3310 commMode = COMM_TCP;
3311 commStatus = STAT_CONNECTED;
3312 warning("Switched to TCP-only connection");
3313 closeUdpConn();
3314 UDPDIAG(("UDP port closed\n"));
3315 if (udpWin)
3316 {
3317 udprefresh(UDP_STATUS);
3318 udprefresh(UDP_CURRENT);
3319 }
3320 }
3321 break;
3322 case SWITCH_UDP_OK:
3323 if (commMode == COMM_UDP)
3324 {
3325 UDPDIAG(("Got SWITCH_UDP_OK while in UDP mode; ignoring\n"));
3326 }
3327 else
3328 {
3329 /* the server is forcing UDP down our throat? */
3330 if (commModeReq != COMM_UDP)
3331 {
3332 UDPDIAG(("Got unsolicited SWITCH_UDP_OK; ignoring\n"));
3333 }
3334 else
3335 {
3336
3337 #ifdef UDP_PORTSWAP
3338 if (portSwap)
3339 {
3340 udpServerPort = ntohl(packet->port);
3341 if (connUdpConn() < 0)
3342 {
3343 UDPDIAG(("Unable to connect, resetting\n"));
3344 warning("Connection attempt failed");
3345 commModeReq = COMM_TCP;
3346 commStatus = STAT_CONNECTED;
3347 if (udpSock >= 0)
3348 closeUdpConn();
3349 if (udpWin)
3350 {
3351 udprefresh(UDP_STATUS);
3352 udprefresh(UDP_CURRENT);
3353 }
3354 response.request = COMM_TCP;
3355 response.port = 0;
3356 goto send;
3357 }
3358 }
3359 #else
3360 /* this came down UDP, so we MUST be connected */
3361 /* (do the verify thing anyway just for kicks) */
3362 #endif
3363
3364 UDPDIAG(("Connected to server's UDP port\n"));
3365 commStatus = STAT_VERIFY_UDP;
3366 if (udpWin)
3367 udprefresh(UDP_STATUS);
3368 response.request = COMM_VERIFY; /* send verify request on *
3369 * * UDP */
3370 response.port = 0;
3371 commSwitchTimeout = 25; /* wait 25 updates */
3372 send:
3373 sendServerPacket((struct player_spacket *) &response);
3374 }
3375 }
3376 break;
3377 case SWITCH_DENIED:
3378 if (ntohs(packet->port))
3379 {
3380 UDPDIAG(("Switch to UDP failed (different version)\n"));
3381 warning("UDP protocol request failed (bad version)");
3382 }
3383 else
3384 {
3385 UDPDIAG(("Switch to UDP denied\n"));
3386 warning("UDP protocol request denied");
3387 }
3388 commModeReq = commMode;
3389 commStatus = STAT_CONNECTED;
3390 commSwitchTimeout = 0;
3391 if (udpWin)
3392 udprefresh(UDP_STATUS);
3393 if (udpSock >= 0)
3394 closeUdpConn();
3395 break;
3396 case SWITCH_VERIFY:
3397 UDPDIAG(("Received UDP verification\n"));
3398 break;
3399 default:
3400 fprintf(stderr, "netrek: Got funny reply (%d) in UDP_REPLY packet\n",
3401 packet->reply);
3402 break;
3403 }
3404 }
3405
3406 #define MAX_PORT_RETRY 10
openUdpConn(void)3407 static int openUdpConn(void)
3408 {
3409 struct sockaddr_in addr;
3410 struct hostent *hp;
3411 int attempts;
3412
3413 if (udpSock >= 0)
3414 {
3415 fprintf(stderr, "netrek: tried to open udpSock twice\n");
3416 return 0; /* pretend we succeeded * *
3417 * (this could be bad) */
3418 }
3419 if ((udpSock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
3420 {
3421 perror("netrek: unable to create DGRAM socket");
3422 return -1;
3423 }
3424
3425 #ifdef nodef
3426 set_udp_opts(udpSock);
3427 #endif /* nodef */
3428
3429 if (udpSock >= max_fd)
3430 max_fd = udpSock + 1;
3431
3432 addr.sin_addr.s_addr = INADDR_ANY;
3433 addr.sin_family = AF_INET;
3434
3435 errno = 0;
3436 udpLocalPort = (getpid() & 32767) + (RANDOM() % 256);
3437
3438 /* if baseLocalPort is defined, we want to start from that */
3439 if (baseLocalPort)
3440 {
3441 udpLocalPort = baseLocalPort;
3442 UDPDIAG(("using base port %d\n", baseLocalPort));
3443 }
3444
3445 for (attempts = 0; attempts < MAX_PORT_RETRY; attempts++)
3446 {
3447 while (udpLocalPort < 2048)
3448 {
3449 udpLocalPort = (udpLocalPort + 10687) & 32767;
3450 }
3451
3452 #ifdef GATEWAY
3453 /* we need the gateway to know where to find us */
3454 if (!strcmp(serverName, gw_mach))
3455 {
3456 UDPDIAG(("+ gateway test: binding to %d\n", gw_local_port));
3457 udpLocalPort = gw_local_port;
3458 }
3459 #endif
3460
3461 addr.sin_port = htons(udpLocalPort);
3462 if (bind(udpSock, (struct sockaddr *) &addr, sizeof(addr)) >= 0)
3463 break;
3464
3465 /* bind() failed, so find another port. If we're tunneling through a *
3466 *
3467 * * router-based firewall, we just increment; otherwise we try to mix
3468 * it * * up a little. The check for ports < 2048 is done above. */
3469 if (baseLocalPort)
3470 udpLocalPort++;
3471 else
3472 udpLocalPort = (udpLocalPort + 10687) & 32767;
3473 }
3474 if (attempts == MAX_PORT_RETRY)
3475 {
3476 perror("netrek: bind");
3477 UDPDIAG(("Unable to find a local port to bind to\n"));
3478 close(udpSock);
3479 udpSock = -1;
3480 return -1;
3481 }
3482 UDPDIAG(("Local port is %d\n", udpLocalPort));
3483
3484 /* determine the address of the server */
3485 if (!serveraddr)
3486 {
3487 if ((addr.sin_addr.s_addr = inet_addr(serverName)) == -1)
3488 {
3489 if ((hp = gethostbyname(serverName)) == NULL)
3490 {
3491 printf("Who is %s?\n", serverName);
3492 terminate(0);
3493 }
3494 else
3495 {
3496 addr.sin_addr.s_addr = *(LONG *) hp->h_addr;
3497 }
3498 }
3499 serveraddr = addr.sin_addr.s_addr;
3500 UDPDIAG(("Found serveraddr == %s\n", inet_ntoa(addr.sin_addr)));
3501 }
3502 return 0;
3503 }
3504
3505 #ifdef UDP_PORTSWAP
connUdpConn()3506 int connUdpConn()
3507 {
3508 struct sockaddr_in addr;
3509
3510 addr.sin_addr.s_addr = serveraddr;
3511 addr.sin_family = AF_INET;
3512 addr.sin_port = htons(udpServerPort);
3513
3514 UDPDIAG(("Connecting to host %s on port %d\n",
3515 inet_ntoa(addr.sin_addr), udpServerPort));
3516 if (connect(udpSock, (struct sockaddr *) &addr, sizeof(addr)) < 0)
3517 {
3518 perror("netrek: unable to connect UDP socket");
3519 printUdpInfo(); /* debug */
3520 return -1;
3521 }
3522
3523 #ifdef nodef
3524 len = sizeof(addr);
3525 if (getsockname(udpSock, &addr, &len) < 0)
3526 {
3527 perror("netrek: unable to getsockname(UDP)");
3528 UDPDIAG(("Can't get our own socket; connection failed\n"));
3529 close(udpSock);
3530 udpSock = -1;
3531 return -1;
3532 }
3533 printf("udpLocalPort %d, getsockname port %d\n",
3534 udpLocalPort, addr.sin_port);
3535 #endif
3536
3537 return 0;
3538 }
3539 #endif
3540
recvUdpConn(void)3541 static int recvUdpConn(void)
3542 {
3543 fd_set readfds;
3544 struct timeval to;
3545 struct sockaddr_in from;
3546 int res;
3547 socklen_t fromlen;
3548
3549 MZERO(&from, sizeof(from)); /* don't get garbage if * *
3550 * really broken */
3551 ns_init(3);
3552
3553 /* we patiently wait until the server sends a packet to us */
3554 /* (note that we silently eat the first one) */
3555 UDPDIAG(("Issuing recvfrom() call\n"));
3556 printUdpInfo();
3557 fromlen = sizeof(from);
3558 FD_ZERO(&readfds);
3559 FD_SET(udpSock, &readfds);
3560 to.tv_sec = 6; /* wait 3 seconds, then * *
3561 * abort */
3562 to.tv_usec = 0;
3563 if ((res = SELECT(max_fd, &readfds, 0, 0, &to)) <= 0)
3564 {
3565 if (!res)
3566 {
3567 UDPDIAG(("timed out waiting for response\n"));
3568 warning("UDP connection request timed out");
3569 return -1;
3570 }
3571 else
3572 {
3573 perror("select() before recvfrom()");
3574 return -1;
3575 }
3576 }
3577 if (recvfrom(udpSock, buf, BUFSIZE, 0, (struct sockaddr *) &from, &fromlen) < 0)
3578 {
3579 perror("recvfrom");
3580 UDPDIAG(("recvfrom failed, aborting UDP attempt\n"));
3581 return -1;
3582 }
3583 if (from.sin_addr.s_addr != serveraddr)
3584 {
3585 /* safe? */
3586 serveraddr = from.sin_addr.s_addr;
3587 UDPDIAG(("Warning: from different IP\n"));
3588 }
3589 if (from.sin_family != AF_INET)
3590 {
3591 UDPDIAG(("Warning: not AF_INET (%d)\n", from.sin_family));
3592 }
3593 udpServerPort = ntohs(from.sin_port);
3594 UDPDIAG(("recvfrom() succeeded; will use server port %d\n", udpServerPort));
3595
3596 #ifdef GATEWAY
3597 if (!strcmp(serverName, gw_mach))
3598 {
3599 UDPDIAG(("+ actually, I'm going to use %d\n", gw_port));
3600 udpServerPort = gw_port;
3601 from.sin_port = htons(udpServerPort);
3602 }
3603 #endif
3604
3605 if (connect(udpSock, (struct sockaddr *) &from, sizeof(from)) < 0)
3606 {
3607 perror("netrek: unable to connect UDP socket after recvfrom()");
3608 close(udpSock);
3609 udpSock = -1;
3610 return -1;
3611 }
3612 return 0;
3613 }
3614
closeUdpConn(void)3615 int closeUdpConn(void)
3616 {
3617 V_UDPDIAG(("Closing UDP socket\n"));
3618 if (udpSock < 0)
3619 {
3620 fprintf(stderr, "netrek: tried to close a closed UDP socket\n");
3621 return -1;
3622 }
3623 shutdown(udpSock, 2);
3624 close(udpSock);
3625 udpSock = -1;
3626 return 0;
3627 }
3628
printUdpInfo(void)3629 void printUdpInfo(void)
3630 /* doesn't use UDPDIAG macro because that is for level 2 of udpDebug;
3631 * printUdpInfo applies to level 1 as well */
3632 #define PUDPDIAG(x) { if (udpDebug) { printf("UDP: "); printf x; }}
3633 {
3634 struct sockaddr_in addr;
3635 socklen_t len;
3636
3637 len = sizeof(addr);
3638 if (getsockname(udpSock, (struct sockaddr *) &addr, &len) < 0)
3639 {
3640 /* perror("printUdpInfo: getsockname"); */
3641 return;
3642 }
3643
3644 PUDPDIAG(("LOCAL: addr=0x%x, family=%d, port=%d\n", addr.sin_addr.s_addr,
3645 addr.sin_family, ntohs(addr.sin_port)));
3646
3647 if (getpeername(udpSock, (struct sockaddr *) &addr, &len) < 0)
3648 {
3649 /* perror("printUdpInfo: getpeername"); */
3650 return;
3651 }
3652 PUDPDIAG(("PEER : addr=0x%x, family=%d, port=%d\n", addr.sin_addr.s_addr,
3653 addr.sin_family, ntohs(addr.sin_port)));
3654 }
3655 #undef PUDPDIAG
3656
handleSequence(struct sequence_spacket * packet)3657 void handleSequence(struct sequence_spacket *packet)
3658 {
3659 static int recent_count = 0, recent_dropped = 0;
3660 LONG newseq;
3661
3662 drop_flag = 0;
3663 if (chan != udpSock)
3664 return; /* don't pay attention to *
3665 * * TCP sequence #s */
3666 udpTotal++;
3667 recent_count++;
3668
3669 /* update percent display every 256 updates (~50 seconds usually) */
3670 if (!(udpTotal & 0xff))
3671 if (udpWin)
3672 udprefresh(UDP_DROPPED);
3673
3674 newseq = (LONG) ntohs(packet->sequence);
3675 /* printf("read %d - ", newseq); */
3676
3677 if (((unsigned short) sequence) > 65000 &&
3678 ((unsigned short) newseq) < 1000)
3679 {
3680 /* we rolled, set newseq = 65536+sequence and accept it */
3681 sequence = ((sequence + 65536) & 0xffff0000) | newseq;
3682 }
3683 else
3684 {
3685 /* adjust newseq and do compare */
3686 newseq |= (sequence & 0xffff0000);
3687
3688 if (!udpSequenceChk)
3689 { /* put this here so that * *
3690 * turning seq check */
3691 sequence = newseq; /* on and off doesn't make *
3692 *
3693 * * us think we lost */
3694 return; /* a whole bunch of packets.
3695 *
3696 */
3697 }
3698 if (newseq > sequence)
3699 {
3700 /* accept */
3701 if (newseq != sequence + 1)
3702 {
3703 udpDropped += (newseq - sequence) - 1;
3704 udpTotal += (newseq - sequence) - 1; /* want TOTAL packets
3705 *
3706 */
3707 recent_dropped += (newseq - sequence) - 1;
3708 recent_count += (newseq - sequence) - 1;
3709 if (udpWin)
3710 udprefresh(UDP_DROPPED);
3711 UDPDIAG(("sequence=%d, newseq=%d, we lost some\n",
3712 (int) sequence, (int) newseq));
3713 }
3714 sequence = newseq;
3715 /* S_P2 */
3716 if (shortversion == SHORTVERSION && recv_short)
3717 {
3718 me->p_flags = (me->p_flags & 0xffff00ff) | (unsigned int) packet->flag16 << 8;
3719 }
3720 }
3721 else
3722 {
3723 /* reject */
3724 if (packet->type == SP_SC_SEQUENCE)
3725 {
3726 V_UDPDIAG(("(ignoring repeat %d)\n", (int) newseq));
3727 }
3728 else
3729 {
3730 UDPDIAG(("sequence=%d, newseq=%d, ignoring transmission\n",
3731 (int) sequence, (int) newseq));
3732 }
3733 /* the remaining packets will be dropped and we shouldn't count the
3734 * * * SP_SEQUENCE packet either */
3735 packets_received--;
3736 drop_flag = 1;
3737 }
3738 }
3739 /* printf("newseq %d, sequence %d\n", newseq, sequence); */
3740 if (recent_count > UDP_RECENT_INTR)
3741 {
3742 /* once a minute (at 5 upd/sec), report on how many were dropped */
3743 /* during the last UDP_RECENT_INTR updates */
3744 udpRecentDropped = recent_dropped;
3745 recent_count = recent_dropped = 0;
3746 if (udpWin)
3747 udprefresh(UDP_DROPPED);
3748 }
3749 }
3750
3751
3752 #ifdef PACKET_LOG
3753 static int Max_CPS = 0;
3754 static int Max_CPSout = 0;
3755 static time_t Start_Time = 0;
3756 static double s2 = 0;
3757 static int sumpl = 0;
3758 static int numpl = 0;
3759 static int outdata_this_sec = 0;
3760 static double sout2 = 0;
3761 static int sumout = 0;
3762
3763 /* HW clumsy but who cares ... :-) */
3764 static int vari_sizes[NUM_PACKETS];
3765 static int cp_msg_size; /* For CP_S_MESSAGE */
3766
Log_Packet(char type,int act_size)3767 void Log_Packet(char type, int act_size)
3768 {
3769 static time_t lasttime;
3770 static int data_this_sec;
3771 time_t this_sec;
3772
3773 if (log_packets == 0)
3774 return;
3775
3776 if (type <= 0 && type > NUM_PACKETS)
3777 {
3778 fprintf(stderr, "Attempted to log a bad packet? \n");
3779 return;
3780 }
3781 packet_log[(unsigned) type]++;
3782 /* data_this_sec += handlers[type].size; */
3783 data_this_sec += act_size; /* HW */
3784 ALL_BYTES += act_size; /* To get all bytes */
3785 if (handlers[(unsigned) type].size == -1)
3786 { /* vari packet */
3787 vari_sizes[(unsigned) type] += act_size;
3788 }
3789 this_sec = time(NULL);
3790 if (this_sec != lasttime)
3791 {
3792 lasttime = this_sec;
3793 if (log_packets > 1)
3794 {
3795 fprintf(stdout, "%d %d %d\n", (int) (this_sec - Start_Time), data_this_sec, outdata_this_sec);
3796 }
3797 if (Start_Time == 0)
3798 {
3799 Start_Time = this_sec;
3800 }
3801 /* ignore baudage on the first few seconds of reception -- * that's * *
3802 * when we get crushed by the motd being sent */
3803 if (lasttime > Start_Time + 10)
3804 {
3805 if (data_this_sec > Max_CPS)
3806 Max_CPS = data_this_sec;
3807 if (outdata_this_sec > Max_CPSout)
3808 Max_CPSout = outdata_this_sec;
3809 sumpl += data_this_sec;
3810 s2 += (data_this_sec * data_this_sec);
3811 sout2 += outdata_this_sec * outdata_this_sec;
3812 sumout += outdata_this_sec;
3813 numpl++;
3814 }
3815 data_this_sec = 0;
3816 outdata_this_sec = 0;
3817 }
3818 }
3819
Log_OPacket(int type,int size)3820 void Log_OPacket(int type, int size)
3821 {
3822 /* Log Packet will handle the per second resets of this */
3823 if (log_packets == 0)
3824 return;
3825 outpacket_log[type]++;
3826 outdata_this_sec += size;
3827
3828 #ifdef SHORT_PACKETS
3829 if (type == CP_S_MESSAGE)
3830 cp_msg_size += size; /* HW */
3831 #endif
3832 }
3833
3834 /* print out out the cool information on packet logging */
Dump_Packet_Log_Info(void)3835 void Dump_Packet_Log_Info(void)
3836 {
3837 int i;
3838 time_t Now;
3839 int total_bytes = 0;
3840 int outtotal_bytes = 0;
3841 int calc_temp;
3842
3843 Now = time(NULL);
3844
3845 printf("Packet Logging Summary:\n");
3846 printf("Start time: %s ", ctime(&Start_Time));
3847 printf(" End time: %s Elapsed play time: %3.2f min\n",
3848 ctime(&Now), (float) ((Now - Start_Time) / 60));
3849 printf("Maximum CPS in during normal play: %d bytes per sec\n", Max_CPS);
3850 printf("Standard deviation in: %d\n",
3851 (int) sqrt((numpl * s2 - sumpl * sumpl) / (numpl * (numpl - 1))));
3852 printf("Maximum CPS out during normal play: %d bytes per sec\n", Max_CPSout);
3853 printf("Standard deviation out: %d\n",
3854 (int) sqrt((numpl * sout2 - sumout * sumout) / (numpl * (numpl - 1))));
3855
3856 #ifdef SHORT_PACKETS
3857 /* total_bytes = ALL_BYTES; *//* Hope this works HW */
3858 for (i = 0; i <= NUM_PACKETS; i++)
3859 { /* I think it must be <= */
3860 if (handlers[i].size != -1)
3861 total_bytes += handlers[i].size * packet_log[i];
3862 else
3863 total_bytes += vari_sizes[i];
3864 } /* The result should be == *
3865 *
3866 * * ALL_BYTES HW */
3867 #else
3868 for (i = 0; i <= NUM_PACKETS; i++)
3869 {
3870 total_bytes += handlers[i].size * packet_log[i];
3871 }
3872 #endif
3873
3874 for (i = 0; i <= NUM_SIZES; i++)
3875 {
3876
3877 #ifdef SHORT_PACKETS
3878 if (handlers[i].size != -1)
3879 outtotal_bytes += outpacket_log[i] * sizes[i];
3880 else
3881 outtotal_bytes += cp_msg_size; /* HW */
3882 #else
3883 outtotal_bytes += outpacket_log[i] * sizes[i];
3884 #endif
3885 }
3886
3887 printf("Total bytes received %d, average CPS: %4.1f\n",
3888 total_bytes, (float) (total_bytes / (Now - Start_Time)));
3889 printf("Server Packets Summary:\n");
3890 printf("Num #Rcvd Size TotlBytes %%Total\n");
3891 for (i = 0; i <= NUM_PACKETS; i++)
3892 {
3893
3894 #ifdef SHORT_PACKETS
3895 if (handlers[i].size != -1)
3896 calc_temp = handlers[i].size * packet_log[i];
3897 else
3898 calc_temp = vari_sizes[i];
3899
3900 printf("%3d %5d %4d %9d %3.2f\n",
3901 i, packet_log[i], handlers[i].size, calc_temp,
3902 (float) (calc_temp * 100 / total_bytes));
3903 #else
3904 calc_temp = handlers[i].size * packet_log[i];
3905 printf("%3d %5d %4d %9d %3.2f\n",
3906 i, packet_log[i], handlers[i].size, calc_temp,
3907 (float) (calc_temp * 100 / total_bytes));
3908 #endif
3909 }
3910 printf("Total bytes sent %d, average CPS: %4.1f\n",
3911 outtotal_bytes, (float) (outtotal_bytes / (Now - Start_Time)));
3912 printf("Client Packets Summary:\n");
3913 printf("Num #Sent Size TotlBytes %%Total\n");
3914 for (i = 0; i <= NUM_SIZES; i++)
3915 #ifdef SHORT_PACKETS
3916 {
3917 if (sizes[i] == -1)
3918 calc_temp = cp_msg_size;
3919 else
3920 calc_temp = sizes[i] * outpacket_log[i];
3921 printf("%3d %5d %4d %9d %3.2f\n",
3922 i, outpacket_log[i], sizes[i], calc_temp,
3923 (float) (calc_temp * 100 / outtotal_bytes));
3924 }
3925 #else
3926 {
3927 calc_temp = sizes[i] * outpacket_log[i];
3928 printf("%3d %5d %4d %9d %3.2f\n",
3929 i, outpacket_log[i], sizes[i], calc_temp,
3930 (float) (calc_temp * 100 / outtotal_bytes));
3931 }
3932 #endif
3933 }
3934
print_packet(char * packet,int size)3935 void print_packet(char *packet, int size)
3936 {
3937 int i; /* lcv */
3938 unsigned char *data;
3939 int kills, pnum, nplanets;
3940 struct planet_s_spacket *plpacket;
3941
3942 if(log_packets == 0) return;
3943
3944 switch ( packet[0] )
3945 {
3946 case SP_MESSAGE:
3947 fprintf(stderr, "\nS->C SP_MESSAGE\t");
3948 if (log_packets > 1)
3949 fprintf(stderr, " m_flags=0x%0X, m_recpt=%d, m_from=%d, mesg=\"%s\",",
3950 ((struct mesg_spacket *) packet)->m_flags,
3951 ((struct mesg_spacket *) packet)->m_recpt,
3952 ((struct mesg_spacket *) packet)->m_from,
3953 ((struct mesg_spacket *) packet)->mesg );
3954 break;
3955 case SP_PLAYER_INFO : /* general player info not */
3956 /* * elsewhere */
3957 fprintf(stderr, "\nS->C SP_PLAYER_INFO\t");
3958 if (log_packets > 1)
3959 fprintf(stderr, " pnum=%d, shiptype=%d, team=%d,",
3960 ((struct plyr_info_spacket *) packet)->pnum,
3961 ((struct plyr_info_spacket *) packet)->shiptype,
3962 ((struct plyr_info_spacket *) packet)->team );
3963 break;
3964 case SP_KILLS : /* # kills a player has */
3965 fprintf(stderr, "\nS->C SP_KILLS\t");
3966 if (log_packets > 1)
3967 fprintf(stderr, " pnum=%d, kills=%u,",
3968 ((struct kills_spacket *) packet)->pnum,
3969 ntohl(((struct kills_spacket *) packet)->kills) );
3970 break;
3971 case SP_PLAYER : /* x,y for player */
3972 fprintf(stderr, "\nS->C SP_PLAYER\t");
3973 if (log_packets > 1)
3974 fprintf(stderr, " pnum=%d, dir=%u, speed=%d, x=%d, y=%d,",
3975 ((struct player_spacket *) packet)->pnum,
3976 ((struct player_spacket *) packet)->dir,
3977 ((struct player_spacket *) packet)->speed,
3978 ntohl(((struct player_spacket *) packet)->x),
3979 ntohl(((struct player_spacket *) packet)->y) );
3980
3981 break;
3982 case SP_TORP_INFO : /* torp status */
3983 fprintf(stderr, "\nS->C SP_TORP_INFO\t");
3984 if (log_packets > 1)
3985 fprintf(stderr, " war=%d, status=%d, tnum=%u,",
3986 ((struct torp_info_spacket *) packet)->war,
3987 ((struct torp_info_spacket *) packet)->status,
3988 ntohs(((struct torp_info_spacket *) packet)->tnum) );
3989 break;
3990 case SP_TORP : /* torp location */
3991 fprintf(stderr, "\nS->C SP_TORP\t");
3992 if (log_packets > 1)
3993 fprintf(stderr, " dir=%d, tnum=%u, x=%u, y=%u,",
3994 ((struct torp_spacket *) packet)->dir,
3995 ntohs(((struct torp_spacket *) packet)->tnum),
3996 ntohl(((struct torp_spacket *) packet)->x),
3997 ntohl(((struct torp_spacket *) packet)->y) );
3998 break;
3999 case SP_PHASER : /* phaser status and * *
4000 * direction */
4001 fprintf(stderr, "\nS->C SP_PHASER\t");
4002 if (log_packets > 1)
4003 fprintf(stderr, " pnum=%d, status=%d, dir=%u, x=%d, y=%d, target=%d,",
4004 ((struct phaser_spacket *) packet)->pnum,
4005 ((struct phaser_spacket *) packet)->status,
4006 ((struct phaser_spacket *) packet)->dir,
4007 ntohl(((struct phaser_spacket *) packet)->x),
4008 ntohl(((struct phaser_spacket *) packet)->y),
4009 ntohl(((struct phaser_spacket *) packet)->target) );
4010 break;
4011 case SP_PLASMA_INFO : /* player login information */
4012 fprintf(stderr, "\nS->C SP_PLASMA_INFO\t");
4013 if (log_packets > 1)
4014 fprintf(stderr, " war=%d, status=%d pnum=%u,",
4015 ((struct plasma_info_spacket *) packet)->war,
4016 ((struct plasma_info_spacket *) packet)->status,
4017 ntohs(((struct plasma_info_spacket *) packet)->pnum) );
4018 break;
4019 case SP_PLASMA : /* like SP_TORP */
4020 fprintf(stderr, "\nS->C SP_PLASMA\t");
4021 if (log_packets > 1)
4022 fprintf(stderr, " pnum=%u, x=%d, y=%d,",
4023 ntohs(((struct plasma_spacket *) packet)->pnum),
4024 ntohl(((struct plasma_spacket *) packet)->x),
4025 ntohl(((struct plasma_spacket *) packet)->y) );
4026 break;
4027 case SP_WARNING : /* like SP_MESG */
4028 fprintf(stderr,"\nS->C SP_WARNING\t");
4029 if (log_packets > 1)
4030 fprintf(stderr, " mesg=\"%s\",",
4031 ((struct warning_spacket *) packet)->mesg);
4032 break;
4033 case SP_MOTD : /* line from .motd screen */
4034 fprintf(stderr,"\nS->C SP_MOTD\t");
4035 if (log_packets > 1)
4036 fprintf(stderr, " line=\"%s\",",
4037 ((struct motd_spacket *) packet)->line);
4038 break;
4039 case SP_YOU : /* info on you? */
4040 fprintf(stderr, "\nS->C SP_YOU\t");
4041 if (log_packets > 1)
4042 fprintf(stderr, " pnum=%d, hostile=%d, swar=%d, armies=%d, flags=0x%0X, damage=%d, shield=%d, fuel=%d, etemp=%u, wtemp=%u, whydead=%u, whodead=%u,",
4043 ((struct you_spacket *) packet)->pnum,
4044 ((struct you_spacket *) packet)->hostile,
4045 ((struct you_spacket *) packet)->swar,
4046 ((struct you_spacket *) packet)->armies,
4047 ntohs(((struct you_spacket *) packet)->flags),
4048 ntohl(((struct you_spacket *) packet)->damage),
4049 ntohl(((struct you_spacket *) packet)->shield),
4050 ntohl(((struct you_spacket *) packet)->fuel),
4051 ntohs(((struct you_spacket *) packet)->etemp),
4052 ntohs(((struct you_spacket *) packet)->wtemp),
4053 ntohs(((struct you_spacket *) packet)->whydead),
4054 ntohs(((struct you_spacket *) packet)->whodead) );
4055 break;
4056 case SP_QUEUE : /* estimated loc in queue? */
4057 fprintf(stderr, "\nS->C SP_QUEUE\t");
4058 if (log_packets > 1)
4059 fprintf(stderr, " pos=%u,",
4060 ntohs(((struct queue_spacket *) packet)->pos) );
4061 break;
4062 case SP_STATUS : /* galaxy status numbers */
4063 fprintf(stderr, "\nS->C SP_STATUS\t");
4064 if (log_packets > 1)
4065 fprintf(stderr, " tourn=%d, armsbomb=%u, planets=%u, kills=%u, losses=%u, time=%u, timeprod=%u,",
4066 ((struct status_spacket *) packet)->tourn,
4067 ntohl(((struct status_spacket *) packet)->armsbomb),
4068 ntohl(((struct status_spacket *) packet)->planets),
4069 ntohl(((struct status_spacket *) packet)->kills),
4070 ntohl(((struct status_spacket *) packet)->losses),
4071 ntohl(((struct status_spacket *) packet)->time),
4072 ntohl(((struct status_spacket *) packet)->timeprod) );
4073 break;
4074 case SP_PLANET : /* planet armies & * *
4075 * facilities */
4076 fprintf(stderr, "\nS->C SP_PLANET\t");
4077 if (log_packets > 1)
4078 fprintf(stderr, " pnum=%d, owner=%d, info=%d, flags=0x%0X, armies=%d,",
4079 ((struct planet_spacket *) packet)->pnum,
4080 ((struct planet_spacket *) packet)->owner,
4081 ((struct planet_spacket *) packet)->info,
4082 ntohs(((struct planet_spacket *) packet)->flags),
4083 ntohl(((struct planet_spacket *) packet)->armies) );
4084 break;
4085 case SP_PICKOK : /* your team & ship was * *
4086 * accepted */
4087 fprintf(stderr, "\nS->C SP_PICKOK\t");
4088 if (log_packets > 1)
4089 fprintf(stderr, " state=%d,",
4090 ((struct pickok_spacket *) packet)-> state );
4091 break;
4092 case SP_LOGIN : /* login response */
4093 fprintf(stderr, "\nS->C SP_LOGIN\t");
4094 if (log_packets > 1)
4095 fprintf(stderr, " accept=%d, flags=0x%0X, keymap=\"%s\",",
4096 ((struct login_spacket *) packet)->accept,
4097 ntohl(((struct login_spacket *) packet)->flags),
4098 ((struct login_spacket *) packet)->keymap );
4099 break;
4100 case SP_FLAGS : /* give flags for a player */
4101 fprintf(stderr, "\nS->C SP_FLAGS\t");
4102 if (log_packets > 1)
4103 fprintf(stderr, " pnum=%d, flags=0x%0X,",
4104 ((struct flags_spacket *) packet)->pnum,
4105 ntohl(((struct flags_spacket *) packet)->flags) );
4106 break;
4107 case SP_MASK : /* tournament mode mask */
4108 fprintf(stderr, "\nS->C SP_MASK\t");
4109 if (log_packets > 1)
4110 fprintf(stderr, " mask=%d,",
4111 ((struct mask_spacket *) packet)->mask );
4112 break;
4113 case SP_PSTATUS : /* give status for a player */
4114 fprintf(stderr, "\nS->C SP_PSTATUS\t");
4115 if (log_packets > 1)
4116 fprintf(stderr, " pnum=%d, status=%d,",
4117 ((struct pstatus_spacket *) packet)->pnum,
4118 ((struct pstatus_spacket *) packet)->status );
4119 break;
4120 case SP_BADVERSION : /* invalid version number */
4121 fprintf(stderr, "\nS->C SP_BADVERSION\t");
4122 if (log_packets > 1)
4123 fprintf(stderr, " why=%d,",
4124 ((struct badversion_spacket *) packet)->why );
4125 break;
4126 case SP_HOSTILE : /* hostility settings for a
4127 * * * player */
4128 fprintf(stderr, "\nS->C SP_HOSTILE\t");
4129 if (log_packets > 1)
4130 fprintf(stderr, " pnum=%d, war=%d, hostile=%d,",
4131 ((struct hostile_spacket *) packet)->pnum,
4132 ((struct hostile_spacket *) packet)->war,
4133 ((struct hostile_spacket *) packet)->hostile );
4134 break;
4135 case SP_STATS : /* a player's statistics */
4136 fprintf(stderr, "\nS->C SP_STATS\t");
4137 if (log_packets > 1)
4138 fprintf(stderr, " pnum=%d, tkills=%d, tlosses=%d, kills=%d, losses=%d, tticks=%d, tplanets=%d, tarmies=%d, sbkills=%d, sblosses=%d, armies=%d, planets=%d, maxkills=%d, sbmaxkills=%d,",
4139 ((struct stats_spacket *) packet)->pnum,
4140 ntohl(((struct stats_spacket *) packet)->tkills),
4141 ntohl(((struct stats_spacket *) packet)->tlosses),
4142 ntohl(((struct stats_spacket *) packet)->kills),
4143 ntohl(((struct stats_spacket *) packet)->losses),
4144 ntohl(((struct stats_spacket *) packet)->tticks),
4145 ntohl(((struct stats_spacket *) packet)->tplanets),
4146 ntohl(((struct stats_spacket *) packet)->tarmies),
4147 ntohl(((struct stats_spacket *) packet)->sbkills),
4148 ntohl(((struct stats_spacket *) packet)->sblosses),
4149 ntohl(((struct stats_spacket *) packet)->armies),
4150 ntohl(((struct stats_spacket *) packet)->planets),
4151 ntohl(((struct stats_spacket *) packet)->maxkills),
4152 ntohl(((struct stats_spacket *) packet)->sbmaxkills) );
4153 break;
4154 case SP_PL_LOGIN : /* new player logs in */
4155 fprintf(stderr, "\nS->C SP_PL_LOGIN\t");
4156 if (log_packets > 1)
4157 fprintf(stderr, " pnum=%d, rank=%d, name=\"%s\", monitor=\"%s\", login=\"%s\",",
4158 ((struct plyr_login_spacket *) packet)->pnum,
4159 ((struct plyr_login_spacket *) packet)->rank,
4160 ((struct plyr_login_spacket *) packet)->name,
4161 ((struct plyr_login_spacket *) packet)->monitor,
4162 ((struct plyr_login_spacket *) packet)->login );
4163 break;
4164 case SP_RESERVED : /* for future use */
4165 fprintf(stderr, "\nS->C SP_RESERVED\t");
4166 if (log_packets > 1)
4167 {
4168 fprintf(stderr, " data=");
4169 for( i = 0; i < 16; i++)
4170 fprintf(stderr, "0x%0X ", (unsigned char)((struct reserved_spacket *) packet)->data[i]);
4171 fprintf(stderr, ",");
4172 }
4173 break;
4174 case SP_PLANET_LOC : /* planet name, x, y */
4175 fprintf(stderr, "\nS->C SP_PLANET_LOC\t");
4176 if (log_packets > 1)
4177 fprintf(stderr, " pnum=%d, x=%d, y=%d, name=\"%s\",",
4178 ((struct planet_loc_spacket *) packet)->pnum,
4179 ntohl(((struct planet_loc_spacket *) packet)->x),
4180 ntohl(((struct planet_loc_spacket *) packet)->y),
4181 ((struct planet_loc_spacket *) packet)->name );
4182 break;
4183 #ifdef INCLUDE_SCAN
4184 /* NOTE: not implemented */
4185 case SP_SCAN : /* ATM: results of player *
4186 * * scan */
4187 fprintf(stderr, "\nS->C SP_SCAN\t");
4188 if(log_packets > 1)
4189 fprintf(stderr, "not implemented,");
4190 break;
4191 #endif
4192 case SP_UDP_REPLY : /* notify client of UDP * *
4193 * status */
4194 fprintf(stderr, "\nS->C SP_UDP_REPLY\t");
4195 if (log_packets > 1)
4196 fprintf(stderr, " reply=%d, port=%d,",
4197 ((struct udp_reply_spacket *) packet)->reply,
4198 ntohl(((struct udp_reply_spacket *) packet)->port) );
4199 break;
4200 case SP_SEQUENCE : /* sequence # packet */
4201 fprintf(stderr, "\nS->C SP_SEQUENCE\t");
4202 if (log_packets > 1)
4203 fprintf(stderr, " flag16=0x%0X, sequence=%u,",
4204 ((struct sequence_spacket *) packet)->flag16,
4205 ntohs(((struct sequence_spacket *) packet)->sequence) );
4206 break;
4207 case SP_SC_SEQUENCE : /* this trans is * *
4208 * semi-critical info */
4209 fprintf(stderr, "\nS->C SP_SC_SEQUENCE\t");
4210 if (log_packets > 1)
4211 fprintf(stderr, " sequence=%u,",
4212 ntohs(((struct sc_sequence_spacket *) packet)->sequence) );
4213 break;
4214
4215 #ifdef RSA
4216 case SP_RSA_KEY : /* handles binary * *
4217 * verification */
4218 fprintf(stderr, "\nS->C SP_RSA_KEY\t");
4219 if(log_packets > 1)
4220 {
4221 fprintf(stderr, " data=");
4222 for(i = 0; i < KEY_SIZE; i++)
4223 fprintf(stderr, "0x%0X ",((struct rsa_key_spacket *) packet)->data[i]);
4224 fprintf(stderr, ",");
4225 }
4226 break;
4227 #endif
4228 case SP_GENERIC_32 :
4229 fprintf(stderr, "\nS->C SP_GENERIC_32\t");
4230 if (log_packets > 1)
4231 switch (((struct generic_32_spacket *)packet)->version) {
4232 case 0x60+GENERIC_32_VERSION_A:
4233 fprintf(stderr, " version=%c, repair_time=%d, pl_orbit=%d,",
4234 ((struct generic_32_spacket_a *) packet)->version,
4235 ((struct generic_32_spacket_a *) packet)->repair_time,
4236 ((struct generic_32_spacket_a *) packet)->pl_orbit);
4237 break;
4238 case 0x60+GENERIC_32_VERSION_B:
4239 fprintf(stderr, " version=%c, repair_time=%d, pl_orbit=%d, gameup=0x%x, tourn_teams=%d, tourn_age=%d, tourn_age_units=%c, tourn_remain=%d, tourn_remain_units=%c, starbase_remain=%d, team_remain=%d,",
4240 ((struct generic_32_spacket_b *) packet)->version,
4241 ntohs(((struct generic_32_spacket_b *) packet)->repair_time),
4242 ((struct generic_32_spacket_b *) packet)->pl_orbit,
4243 ntohs(((struct generic_32_spacket_b *) packet)->gameup),
4244 ((struct generic_32_spacket_b *) packet)->tournament_teams,
4245 ((struct generic_32_spacket_b *) packet)->tournament_age,
4246 ((struct generic_32_spacket_b *) packet)->tournament_age_units,
4247 ((struct generic_32_spacket_b *) packet)->tournament_remain,
4248 ((struct generic_32_spacket_b *) packet)->tournament_remain_units,
4249 ((struct generic_32_spacket_b *) packet)->starbase_remain,
4250 ((struct generic_32_spacket_b *) packet)->team_remain );
4251 break;
4252 default:
4253 fprintf(stderr, " version=0x%x (unknown)", ((struct generic_32_spacket *)packet)->version);
4254 }
4255 break;
4256
4257 case SP_SHIP_CAP : /* Handles server ship mods */
4258 fprintf(stderr, "\nS->C SP_SHIP_CAP\t");
4259 if (log_packets > 1)
4260 fprintf(stderr, " operation=%d, s_type=%u, s_torpspeed=%u, s_phaserrange=%u, s_maxspeed=%d, s_maxfuel=%d, s_maxshield=%d, s_maxdamage=%d, s_maxwpntemp=%d, s_maxegntemp=%d, s_width=%u, s_height=%d, s_maxarmies=%d, s_letter=%d, s_name=\"%s\", s_desig1=%c, s_desig2=%c, s_bitmap=%u,",
4261 ((struct ship_cap_spacket *) packet)->operation,
4262 ntohs(((struct ship_cap_spacket *) packet)->s_type),
4263 ntohs(((struct ship_cap_spacket *) packet)->s_torpspeed),
4264 ntohs(((struct ship_cap_spacket *) packet)->s_phaserrange),
4265 ((struct ship_cap_spacket *) packet)->s_maxspeed,
4266 ((struct ship_cap_spacket *) packet)->s_maxfuel,
4267 ((struct ship_cap_spacket *) packet)->s_maxshield,
4268 ((struct ship_cap_spacket *) packet)->s_maxdamage,
4269 ((struct ship_cap_spacket *) packet)->s_maxwpntemp,
4270 ((struct ship_cap_spacket *) packet)->s_maxegntemp,
4271 ntohs(((struct ship_cap_spacket *) packet)->s_width),
4272 ntohs(((struct ship_cap_spacket *) packet)->s_height),
4273 ntohs(((struct ship_cap_spacket *) packet)->s_maxarmies),
4274 ((struct ship_cap_spacket *) packet)->s_letter,
4275 ((struct ship_cap_spacket *) packet)->s_name,
4276 ((struct ship_cap_spacket *) packet)->s_desig1,
4277 ((struct ship_cap_spacket *) packet)->s_desig2,
4278 ntohs(((struct ship_cap_spacket *) packet)->s_bitmap) );
4279
4280 break;
4281 #ifdef SHORT_PACKETS
4282 case SP_S_REPLY : /* reply to send-short * *
4283 * request */
4284 fprintf(stderr, "\nS->C SP_S_REPLY\t");
4285 if (log_packets > 1)
4286 fprintf(stderr," repl=%d, windside=%u, gwidth=%d,",
4287 ((struct shortreply_spacket *) packet)->repl,
4288 ntohs(((struct shortreply_spacket *) packet)->winside),
4289 ntohl(((struct shortreply_spacket *) packet)->gwidth) );
4290 break;
4291 case SP_S_MESSAGE : /* var. Message Packet */
4292 fprintf(stderr, "\nS->C SP_S_MESSAGE\t");
4293 if (log_packets > 1)
4294
4295 fprintf(stderr, " m_flags=0x%0X, m_recpt=%u, m_from=%u, length=%u, mesg=\"%s\",",
4296 ((struct mesg_s_spacket *) packet)->m_flags,
4297 ((struct mesg_s_spacket *) packet)->m_recpt,
4298 ((struct mesg_s_spacket *) packet)->m_from,
4299 ((struct mesg_s_spacket *) packet)->length,
4300 &( ((struct mesg_s_spacket *) packet)->mesg ) );
4301 break;
4302 case SP_S_WARNING : /* Warnings with 4 Bytes */
4303 fprintf(stderr, "\nS->C SP_S_WARNING\t");
4304 if (log_packets > 1)
4305 fprintf(stderr, " whichmessage=%u, argument=%d, argument2=%d,",
4306 ((struct warning_s_spacket *) packet)->whichmessage,
4307 ((struct warning_s_spacket *) packet)->argument,
4308 ((struct warning_s_spacket *) packet)->argument2 );
4309 break;
4310 case SP_S_YOU : /* hostile,armies,whydead,etc
4311 * * * .. */
4312 fprintf(stderr, "\nS->C SP_S_YOU\t");
4313 if (log_packets > 1)
4314 fprintf(stderr, " pnum=%d, hostile=%d, swar=%d, armies=%d, whydead=%d, whodead=%d, flags=0x%0X,",
4315 ((struct youshort_spacket *) packet)->pnum,
4316 ((struct youshort_spacket *) packet)->hostile,
4317 ((struct youshort_spacket *) packet)->swar,
4318 ((struct youshort_spacket *) packet)->armies,
4319 ((struct youshort_spacket *) packet)->whydead,
4320 ((struct youshort_spacket *) packet)->whodead,
4321 ntohl(((struct youshort_spacket *) packet)->flags) );
4322 break;
4323 case SP_S_YOU_SS : /* your ship status */
4324 fprintf(stderr, "\nS->C SP_S_YOU_SS\t");
4325 if (log_packets > 1)
4326 fprintf(stderr, " ddamage=%u, shield=%u, fuel=%u, etemp=%u, wtemp=%u,",
4327 ntohs(((struct youss_spacket *) packet)->damage),
4328 ntohs(((struct youss_spacket *) packet)->shield),
4329 ntohs(((struct youss_spacket *) packet)->fuel),
4330 ntohs(((struct youss_spacket *) packet)->etemp),
4331 ntohs(((struct youss_spacket *) packet)->wtemp) );
4332 break;
4333 case SP_S_PLAYER : /* variable length player *
4334 * * packet */
4335 fprintf(stderr, "\nS->C SP_S_PLAYER\t");
4336 if (log_packets > 1)
4337 fprintf(stderr, " packets=%d, dir=%u, speed=%d, x=%d, y=%d,",
4338 ((struct player_s_spacket *) packet)->packets,
4339 ntohl(((struct player_s_spacket *) packet)->dir),
4340 ((struct player_s_spacket *) packet)->speed,
4341 ntohl(((struct player_s_spacket *) packet)->x),
4342 ntohl(((struct player_s_spacket *) packet)->y) );
4343 break;
4344 #endif
4345
4346 #ifdef PING
4347 case SP_PING : /* ping packet */
4348 fprintf(stderr, "\nS->C SP_PING\t");
4349 if (log_packets > 1)
4350 fprintf(stderr, " number=%u, lag=%u, tloss_sc=%u, tloss_cs=%u, iloss_sc=%u, iloss_cs=%u,",
4351 ((struct ping_spacket *) packet)->number,
4352 ((struct ping_spacket *) packet)->lag,
4353 ((struct ping_spacket *) packet)->tloss_sc,
4354 ((struct ping_spacket *) packet)->tloss_cs,
4355 ((struct ping_spacket *) packet)->iloss_sc,
4356 ((struct ping_spacket *) packet)->iloss_cs );
4357 break;
4358 #endif
4359 #ifdef FEATURE_PACKETS
4360 case SP_FEATURE :
4361 fprintf(stderr, "\nS->C SP_FEATURE\t");
4362 if (log_packets > 1)
4363 fprintf(stderr, " feature_type=%c, arg1=%d, arg2=%d, value=%d, name=\"%s\",",
4364 ((struct feature_cpacket *) packet)->feature_type,
4365 ((struct feature_cpacket *) packet)->arg1,
4366 ((struct feature_cpacket *) packet)->arg2,
4367 ntohl(((struct feature_cpacket *) packet)->value),
4368 ((struct feature_cpacket *) packet)->name );
4369 break;
4370 #endif
4371 case SP_RANK :
4372 fprintf(stderr, "\nS->C SP_RANK\t");
4373 if (log_packets > 1)
4374 fprintf(stderr, " rnum=%d, rmax=%d, name=\"%s\", hours=%d, ratings=%d, offense=%d, cname=\"%s\"",
4375 ((struct rank_spacket *) packet)->rnum,
4376 ((struct rank_spacket *) packet)->rmax,
4377 ((struct rank_spacket *) packet)->name,
4378 ntohl(((struct rank_spacket *) packet)->hours),
4379 ntohl(((struct rank_spacket *) packet)->ratings),
4380 ntohl(((struct rank_spacket *) packet)->offense),
4381 ((struct rank_spacket *) packet)->cname );
4382 break;
4383 case SP_LTD :
4384 fprintf(stderr, "\nS->C SP_LTD\t");
4385 if (log_packets > 2) {
4386 struct ltd_spacket *lp = (struct ltd_spacket *) packet;
4387 fprintf(stderr,
4388 " version='%c', "
4389 "kt=%d, "
4390 "kmax=%d/100, "
4391 "k1=%d, "
4392 "k1p=%d, "
4393 "k1c=%d, "
4394 "k2=%d, "
4395 "k2p=%d, "
4396 "k2c=%d, "
4397 "kbp=%d, "
4398 "kbt=%d, "
4399 "kbs=%d, "
4400 "dt=%d, "
4401 "dpc=%d, "
4402 "dcc=%d, "
4403 "ddc=%d, "
4404 "dbp=%d, "
4405 "dbt=%d, "
4406 "dbs=%d, "
4407 "acc=%d, "
4408 "ptt=%d, "
4409 "pdt=%d, "
4410 "bpt=%d, "
4411 "bp8=%d, "
4412 "bpc=%d, "
4413 "bat=%d, "
4414 "ba8=%d, "
4415 "bac=%d, "
4416 "oat=%d, "
4417 "odc=%d, "
4418 "occ=%d, "
4419 "opc=%d, "
4420 "ogc=%d, "
4421 "oec=%d, "
4422 "olc=%d, "
4423 "osba=%d, "
4424 "ofc=%d, "
4425 "ofa=%d, "
4426 "at=%d, "
4427 "aa=%d, "
4428 "ar=%d, "
4429 "af=%d, "
4430 "ak=%d, "
4431 "ct=%d, "
4432 "cp=%d, "
4433 "cc=%d, "
4434 "ca=%d, "
4435 "cr=%d, "
4436 "cf=%d, "
4437 "tt=%d, "
4438 "tyel=%d, "
4439 "tred=%d, "
4440 "tz0=%d, "
4441 "tz1=%d, "
4442 "tz2=%d, "
4443 "tz3=%d, "
4444 "tz4=%d, "
4445 "tz5=%d, "
4446 "tz6=%d, "
4447 "tz7=%d, "
4448 "tpc=%d, "
4449 "tcc=%d, "
4450 "tr=%d, "
4451 "dr=%d, "
4452 "wpf=%d, "
4453 "wph=%d, "
4454 "wpdi=%d, "
4455 "wpdt=%d, "
4456 "wtf=%d, "
4457 "wth=%d, "
4458 "wtd=%d, "
4459 "wts=%d, "
4460 "wtw=%d, "
4461 "wtdi=%d, "
4462 "wtdt=%d, "
4463 "wsf=%d, "
4464 "wsh=%d, "
4465 "wsp=%d, "
4466 "wsw=%d, "
4467 "wsdi=%d, "
4468 "wsdt=%d, \n",
4469 lp->version,
4470 ntohl(lp->kt),
4471 ntohl(lp->kmax),
4472 ntohl(lp->k1),
4473 ntohl(lp->k1p),
4474 ntohl(lp->k1c),
4475 ntohl(lp->k2),
4476 ntohl(lp->k2p),
4477 ntohl(lp->k2c),
4478 ntohl(lp->kbp),
4479 ntohl(lp->kbt),
4480 ntohl(lp->kbs),
4481 ntohl(lp->dt),
4482 ntohl(lp->dpc),
4483 ntohl(lp->dcc),
4484 ntohl(lp->ddc),
4485 ntohl(lp->dbp),
4486 ntohl(lp->dbt),
4487 ntohl(lp->dbs),
4488 ntohl(lp->acc),
4489 ntohl(lp->ptt),
4490 ntohl(lp->pdt),
4491 ntohl(lp->bpt),
4492 ntohl(lp->bp8),
4493 ntohl(lp->bpc),
4494 ntohl(lp->bat),
4495 ntohl(lp->ba8),
4496 ntohl(lp->bac),
4497 ntohl(lp->oat),
4498 ntohl(lp->odc),
4499 ntohl(lp->occ),
4500 ntohl(lp->opc),
4501 ntohl(lp->ogc),
4502 ntohl(lp->oec),
4503 ntohl(lp->olc),
4504 ntohl(lp->osba),
4505 ntohl(lp->ofc),
4506 ntohl(lp->ofa),
4507 ntohl(lp->at),
4508 ntohl(lp->aa),
4509 ntohl(lp->ar),
4510 ntohl(lp->af),
4511 ntohl(lp->ak),
4512 ntohl(lp->ct),
4513 ntohl(lp->cp),
4514 ntohl(lp->cc),
4515 ntohl(lp->ca),
4516 ntohl(lp->cr),
4517 ntohl(lp->cf),
4518 ntohl(lp->tt),
4519 ntohl(lp->tyel),
4520 ntohl(lp->tred),
4521 ntohl(lp->tz0),
4522 ntohl(lp->tz1),
4523 ntohl(lp->tz2),
4524 ntohl(lp->tz3),
4525 ntohl(lp->tz4),
4526 ntohl(lp->tz5),
4527 ntohl(lp->tz6),
4528 ntohl(lp->tz7),
4529 ntohl(lp->tpc),
4530 ntohl(lp->tcc),
4531 ntohl(lp->tr),
4532 ntohl(lp->dr),
4533 ntohl(lp->wpf),
4534 ntohl(lp->wph),
4535 ntohl(lp->wpdi),
4536 ntohl(lp->wpdt),
4537 ntohl(lp->wtf),
4538 ntohl(lp->wth),
4539 ntohl(lp->wtd),
4540 ntohl(lp->wts),
4541 ntohl(lp->wtw),
4542 ntohl(lp->wtdi),
4543 ntohl(lp->wtdt),
4544 ntohl(lp->wsf),
4545 ntohl(lp->wsh),
4546 ntohl(lp->wsp),
4547 ntohl(lp->wsw),
4548 ntohl(lp->wsdi),
4549 ntohl(lp->wsdt)
4550 );
4551 }
4552 break;
4553 #ifdef SHORT_PACKETS
4554 case SP_S_TORP : /* variable length torp * *
4555 * packet */
4556 fprintf(stderr, "\nS->C SP_S_TORP\t");
4557 if (log_packets > 1)
4558 print_sp_s_torp(packet, 1);
4559 break;
4560 case SP_S_TORP_INFO : /* SP_S_TORP with TorpInfo */
4561 fprintf(stderr, "\nS->C SP_S_TORP_INFO\t");
4562 if (log_packets > 1) /* struct built by hand in handleVTorp */
4563 print_sp_s_torp(packet, 3);
4564 break;
4565 case SP_S_8_TORP : /* optimized SP_S_TORP */
4566 fprintf(stderr, "\nS->C SP_S_8_TORP\t");
4567 if (log_packets > 1)
4568 print_sp_s_torp(packet, 2);
4569 break;
4570 case SP_S_PLANET : /* see SP_PLANET */
4571 fprintf(stderr, "\nS->C SP_S_PLANET\t");
4572 if (log_packets > 1)
4573 {
4574 plpacket = (struct planet_s_spacket *) &packet[2];
4575 nplanets = packet[1];
4576 fprintf(stderr, "nplanets = %d, ", nplanets);
4577 for(i = 0; i < nplanets; i++, plpacket++ )
4578 fprintf(stderr,
4579 "pnum = %d, pl_owner = %d, info = %d, flags = %d, armies = %d ",
4580 plpacket->pnum,
4581 plpacket->owner,
4582 plpacket->info,
4583 plpacket->armies,
4584 ntohs(plpacket->flags) );
4585 }
4586 fprintf(stderr,"\n");
4587 break;
4588
4589 /* S_P2 */
4590 case SP_S_SEQUENCE : /* SP_SEQUENCE for * *
4591 * compressed packets */
4592 fprintf(stderr, "\nS->C SP_S_SEQUENCE\t");
4593 if (log_packets > 1)
4594 fprintf(stderr, " No struct defined,");
4595 break;
4596 case SP_S_PHASER : /* see struct */
4597 fprintf(stderr, "\nS->C SP_S_PHASER\t");
4598 if (log_packets > 1)
4599 fprintf(stderr, " status=%d, pnum=%d, target=%d, dir=%d, x=%d, y=%d",
4600 ((((struct phaser_s_spacket *) packet)->status) & 0x0f),
4601 ((((struct phaser_s_spacket *) packet)->pnum) & 0x3f),
4602 ((struct phaser_s_spacket *) packet)->target,
4603 ((struct phaser_s_spacket *) packet)->dir,
4604 (SCALE * (ntohs(((struct phaser_s_spacket*) packet)->x))),
4605 (SCALE * (ntohs(((struct phaser_s_spacket*) packet)->y))) );
4606 break;
4607 case SP_S_KILLS : /* # of kills player have */
4608 fprintf(stderr, "\nS->C SP_S_KILLS\t");
4609 if (log_packets > 1)
4610 {
4611 fprintf(stderr, " pnum=%d, ",
4612 (unsigned char) packet[1]);
4613 data = (unsigned char *) &packet[2];
4614 for (i = 0; i < (unsigned) packet[1]; i++)
4615 {
4616 kills = (unsigned short) *data++;
4617 kills |= (unsigned short) ((*data & 0x03) << 8);
4618 pnum = (unsigned char) *data++ >> 2;
4619 fprintf(stderr, "pnum = %d, kills = %d ",pnum, kills);
4620 }
4621 }
4622 fprintf(stderr,"\n");
4623 break;
4624 case SP_S_STATS : /* see SP_STATS */
4625 fprintf(stderr, "\nS->C SP_S_STATS\t");
4626 if (log_packets > 1)
4627 fprintf(stderr, " pnum=%d, tplanets=%d, tkills=%d, tlosses=%d, kills=%d, losses=%d, tticks=%d, tarmies=%d, sbkills=%d, sblosses=%d, armies=%d, planets=%d, maxkills=%d, sbmaxkills=%d,",
4628 ((struct stats_spacket *) packet)->pnum,
4629 ntohs(((struct stats_spacket *) packet)->tplanets),
4630 ntohs(((struct stats_spacket *) packet)->tkills),
4631 ntohs(((struct stats_spacket *) packet)->tlosses),
4632 ntohs(((struct stats_spacket *) packet)->kills),
4633 ntohs(((struct stats_spacket *) packet)->losses),
4634 ntohl(((struct stats_spacket *) packet)->tticks),
4635 ntohl(((struct stats_spacket *) packet)->tarmies),
4636 ntohs(((struct stats_spacket *) packet)->sbkills),
4637 ntohs(((struct stats_spacket *) packet)->sblosses),
4638 ntohs(((struct stats_spacket *) packet)->armies),
4639 ntohs(((struct stats_spacket *) packet)->planets),
4640 ntohl(((struct stats_spacket *) packet)->maxkills),
4641 ntohl(((struct stats_spacket *) packet)->sbmaxkills) );
4642 break;
4643 #endif
4644 default:
4645 fprintf(stderr, "\nS->C UNKNOWN\t");
4646 if(log_packets > 1)
4647 fprintf(stderr, " type=%d,",packet[0]);
4648 }
4649
4650 #ifdef nodef /* #ifdef SHORT_PACKETS */
4651 switch( *((char *) packet) )
4652 {
4653 /* variable length packets */
4654 case VPLAYER_SIZE :
4655 fprintf(stderr, "\nS->C VPLAYER_SIZE\t");
4656 if (log_packets > 1)
4657 fprintf(stderr, " No struct defined, same enum value as SP_PLAYER,");
4658 break;
4659 case SHORTVERSION : /* other number blocks, like
4660 * * * UDP Version */
4661 fprintf(stderr, "\nS->C SHORTVERSION\t");
4662 if (log_packets > 1)
4663 fprintf(stderr, " No struct defined, same enum value as SP_MOTD,");
4664 break;
4665 case OLDSHORTVERSION : /* S_P2 */
4666 fprintf(stderr, "\nS->C OLDSHORTVERSION\t");
4667 if (log_packets > 1)
4668 fprintf(stderr, " No struct defined, same enum value as SP_WARNING,");
4669 break;
4670 }
4671 #endif
4672
4673 }
4674
4675
print_opacket(char * packet,int size)4676 void print_opacket(char *packet, int size)
4677 {
4678 int i; /* lcv */
4679
4680 switch(packet[0])
4681 {
4682 /* packets sent from remote client to xtrek server */
4683 case CP_MESSAGE : /* send a message */
4684 fprintf(stderr, "\nC->S CP_MESSAGE\t");
4685 if (log_packets > 1)
4686 fprintf(stderr, " group=%d, indiv=%d, mesg=\"%s\",",
4687 ((struct mesg_cpacket *) packet)->group,
4688 ((struct mesg_cpacket *) packet)->indiv,
4689 ((struct mesg_cpacket *) packet)->mesg );
4690 break;
4691 case CP_SPEED : /* set speed */
4692 fprintf(stderr, "\nC->S CP_SPEED\t");
4693 if (log_packets > 1)
4694 fprintf(stderr, " speed=%d,",
4695 ((struct speed_cpacket *) packet)->speed );
4696 break;
4697 case CP_DIRECTION : /* change direction */
4698 fprintf(stderr, "\nC->S CP_DIRECTION\t");
4699 if (log_packets > 1)
4700 fprintf(stderr, " dir=%u,",
4701 ((struct dir_cpacket *) packet)->dir );
4702 break;
4703 case CP_PHASER : /* phaser in a direction */
4704 fprintf(stderr, "\nC->S CP_PHASER\t");
4705 if (log_packets > 1)
4706 fprintf(stderr, " dir=%u,",
4707 ((struct phaser_cpacket *) packet)-> dir );
4708 break;
4709 case CP_PLASMA : /* plasma (in a direction) */
4710 fprintf(stderr, "\nC->S CP_PLAMSA\t");
4711 if (log_packets > 1)
4712 fprintf(stderr, " dir=%u,",
4713 ((struct plasma_cpacket *) packet)->dir );
4714 break;
4715 case CP_TORP : /* fire torp in a direction */
4716 fprintf(stderr, "\nC->S CP_TORP\t");
4717 if (log_packets > 1)
4718 fprintf(stderr, " dir=%u,",
4719 ((struct torp_cpacket *) packet)->dir );
4720 break;
4721 case CP_QUIT : /* self destruct */
4722 fprintf(stderr, "\nC->S CP_QUIT\t");
4723 if (log_packets > 1)
4724 fprintf(stderr, " no args,");
4725 break;
4726 case CP_LOGIN : /* log in (name, password) */
4727 fprintf(stderr, "\nC->S CP_LOGIN\t");
4728 if (log_packets > 1)
4729 fprintf(stderr, " query=%d, name=\"%s\", password=\"%s\", login=\"%s\",",
4730 ((struct login_cpacket *) packet)->query,
4731 ((struct login_cpacket *) packet)->name,
4732 ((struct login_cpacket *) packet)->password,
4733 ((struct login_cpacket *) packet)->login );
4734 break;
4735 case CP_OUTFIT : /* outfit to new ship */
4736 fprintf(stderr, "\nC->S CP_OUTFIT\t");
4737 if (log_packets > 1)
4738 fprintf(stderr, " team=%d, ship=%d,",
4739 ((struct outfit_cpacket *) packet)->team,
4740 ((struct outfit_cpacket *) packet)->ship );
4741 break;
4742 case CP_WAR : /* change war status */
4743 fprintf(stderr, "\nC->S CP_WAR\t");
4744 if (log_packets > 1)
4745 fprintf(stderr, " newmask=0x%0X,",
4746 ((struct war_cpacket *) packet)->newmask );
4747 break;
4748 case CP_PRACTR : /* create practice robot? */
4749 fprintf(stderr, "\nC->S CP_PRACTR\t");
4750 if (log_packets > 1)
4751 fprintf(stderr, " no args,");
4752 break;
4753 case CP_SHIELD : /* raise/lower sheilds */
4754 fprintf(stderr, "\nC->S CP_SHIELD\t");
4755 if (log_packets > 1)
4756 fprintf(stderr, " state=%d,",
4757 ((struct shield_cpacket *) packet)->state );
4758 break;
4759 case CP_REPAIR : /* enter repair mode */
4760 fprintf(stderr, "\nC->S CP_REPAIR\t");
4761 if (log_packets > 1)
4762 fprintf(stderr, " state=%d,",
4763 ((struct repair_cpacket *) packet)-> state );
4764 break;
4765 case CP_ORBIT : /* orbit planet/starbase */
4766 fprintf(stderr, "\nC->S CP_ORBIT\t");
4767 if (log_packets > 1)
4768 fprintf(stderr, " state=%d,",
4769 ((struct orbit_cpacket *) packet)->state );
4770 break;
4771 case CP_PLANLOCK : /* lock on planet */
4772 fprintf(stderr, "\nC->S CP_PLANLOCK\t");
4773 if (log_packets > 1)
4774 fprintf(stderr, " pnum = %d,",
4775 ((struct planlock_cpacket *) packet)->pnum );
4776 break;
4777 case CP_PLAYLOCK : /* lock on player */
4778 fprintf(stderr, "\nC->S CP_PLAYLOCK\t");
4779 if (log_packets > 1)
4780 fprintf(stderr, " pnum=%d,",
4781 ((struct playlock_cpacket *) packet)->pnum );
4782 break;
4783 case CP_BOMB : /* bomb a planet */
4784 fprintf(stderr, "\nC->S CP_BOMB\t");
4785 if (log_packets > 1)
4786 fprintf(stderr, " state=%d,",
4787 ((struct bomb_cpacket *) packet)->state );
4788 break;
4789 case CP_BEAM : /* beam armies up/down */
4790 fprintf(stderr, "\nC->S CP_BEAM\t");
4791 if (log_packets > 1)
4792 fprintf(stderr, " state=%d,",
4793 ((struct beam_cpacket *) packet)->state );
4794 break;
4795 case CP_CLOAK : /* cloak on/off */
4796 fprintf(stderr, "\nC->S CP_CLOAK\t");
4797 if (log_packets > 1)
4798 fprintf(stderr, " state=%d,",
4799 ((struct cloak_cpacket *) packet)->state );
4800 break;
4801 case CP_DET_TORPS : /* detonate enemy torps */
4802 fprintf(stderr, "\nC->S CP_DET_TORPS\t");
4803 if (log_packets > 1)
4804 fprintf(stderr, " no args,");
4805 break;
4806 case CP_DET_MYTORP : /* detonate one of my torps */
4807 fprintf(stderr, "\nC->S CP_DET_MYTORP\t");
4808 if (log_packets > 1)
4809 fprintf(stderr, " tnum=%u,",
4810 ntohs(((struct det_mytorp_cpacket *) packet)->tnum) );
4811 break;
4812 case CP_COPILOT : /* toggle copilot mode */
4813 fprintf(stderr, "\nC->S CP_COPILOT\t");
4814 if (log_packets > 1)
4815 fprintf(stderr, " state=%d,",
4816 ((struct copilot_cpacket *) packet)->state );
4817 break;
4818 case CP_REFIT : /* refit to different ship *
4819 *
4820 * * type */
4821 fprintf(stderr, "\nC->S CP_REFIT\t");
4822 if (log_packets > 1)
4823 fprintf(stderr, " ship=%d,",
4824 ((struct refit_cpacket *) packet)->ship );
4825 break;
4826 case CP_TRACTOR : /* tractor on/off */
4827 fprintf(stderr, "\nC->S CP_TRACTOR\t");
4828 if (log_packets > 1)
4829 fprintf(stderr, " state=%d, pnum=%d,",
4830 ((struct tractor_cpacket *) packet)->state,
4831 ((struct tractor_cpacket *) packet)->pnum );
4832 break;
4833 case CP_REPRESS : /* pressor on/off */
4834 fprintf(stderr, "\nC->S CP_REPRESS\t");
4835 if (log_packets > 1)
4836 fprintf(stderr, " state=%d, pnum=%d,",
4837 ((struct repress_cpacket *) packet)->state,
4838 ((struct repress_cpacket *) packet)->pnum );
4839 break;
4840 case CP_COUP : /* coup home planet */
4841 fprintf(stderr, "\nC->S CP_COUP\t");
4842 if (log_packets > 1)
4843 fprintf(stderr, " no args,");
4844 break;
4845 case CP_SOCKET : /* new socket for * *
4846 * reconnection */
4847 fprintf(stderr, "\nC->S CP_SOCKET\t");
4848 if (log_packets > 1)
4849 fprintf(stderr, " version=%d, udp_version=%d\n, socket=%u,",
4850 ((struct socket_cpacket *) packet)->version,
4851 ((struct socket_cpacket *) packet)->udp_version,
4852 ntohl(((struct socket_cpacket *) packet)->socket) );
4853 break;
4854 case CP_OPTIONS : /* send my options to be * *
4855 * saved */
4856 fprintf(stderr, "\nC->S CP_OPTIONS\t");
4857 if (log_packets > 1)
4858 fprintf(stderr, " flags=0x%0X, keymap=\"%s\",",
4859 ntohl(((struct options_cpacket *) packet)->flags),
4860 ((struct options_cpacket *) packet)->keymap );
4861 break;
4862 case CP_BYE : /* I'm done! */
4863 fprintf(stderr, "\nC->S CP_BYE\t");
4864 if (log_packets > 1)
4865 fprintf(stderr, " no args,");
4866 break;
4867 case CP_DOCKPERM : /* set docking permissions */
4868 fprintf(stderr, "\nC->S CP_DOCKPERM\t");
4869 if (log_packets > 1)
4870 fprintf(stderr, " state=%d,",
4871 ((struct dockperm_cpacket *) packet)->state );
4872 break;
4873 case CP_UPDATES : /* set number of usecs per *
4874 *
4875 * * update */
4876 fprintf(stderr, "\nC->S CP_UPDATES\t");
4877 if (log_packets > 1)
4878 fprintf(stderr, " usecs=%u,",
4879 ntohl(((struct updates_cpacket *) packet)->usecs) );
4880 break;
4881 case CP_RESETSTATS : /* reset my stats packet */
4882 fprintf(stderr, "\nC->S CP_RESETSTATS\t");
4883 if (log_packets > 1)
4884 fprintf(stderr, " verify=%c,",
4885 ((struct resetstats_cpacket *) packet)->verify );
4886 break;
4887 case CP_RESERVED : /* for future use */
4888 fprintf(stderr, "\nC->S CP_RESERVED\t");
4889 if (log_packets > 1)
4890 {
4891 fprintf(stderr, " data=" );
4892 for( i = 0; i < 16; i++)
4893 fprintf(stderr, "0x%0X ", (unsigned char)((struct reserved_cpacket *) packet)->data[i]);
4894 fprintf(stderr, ", resp=" );
4895 for( i = 0; i < 16; i++)
4896 fprintf(stderr, "0x%0X ", (unsigned char)((struct reserved_cpacket *) packet)->resp[i]);
4897 fprintf(stderr, ",");
4898 }
4899 break;
4900
4901 #ifdef INCLUDE_SCAN
4902 /* NOTE: not implemented. */
4903 case CP_SCAN : /* ATM: request for player *
4904 *
4905 * * scan */
4906 fprintf(stderr, "\nC->S CP_SCAN\t");
4907 if (log_packets > 1)
4908 fprintf(stderr, " not implemented," );
4909 break;
4910 #endif
4911
4912 case CP_UDP_REQ : /* request UDP on/off */
4913 fprintf(stderr, "\nC->S CP_UDP_REQ\t");
4914 if (log_packets > 1)
4915 fprintf(stderr, " request=%d, connmode=%d, port=%d,",
4916 ((struct udp_req_cpacket *) packet)->request,
4917 ((struct udp_req_cpacket *) packet)->connmode,
4918 ntohl(((struct udp_req_cpacket *) packet)->port) );
4919 break;
4920 case CP_SEQUENCE : /* sequence # packet */
4921 fprintf(stderr, "\nC->S CP_SEQUENCE\t");
4922 if (log_packets > 1)
4923 fprintf(stderr, " sequence=%u,",
4924 ntohs(((struct sequence_cpacket *) packet)->sequence) );
4925 break;
4926
4927 #ifdef RSA
4928 case CP_RSA_KEY : /* handles binary * *
4929 * verification */
4930 fprintf(stderr, "\nC->S CP_RSA_KEY\t");
4931 if (log_packets > 1)
4932 {
4933 fprintf(stderr, " global=");
4934 for(i = 0; i < KEY_SIZE; i++)
4935 fprintf(stderr, "0x%0X ",((struct rsa_key_cpacket *)packet)->global[i]);
4936 fprintf(stderr,",");
4937 fprintf(stderr, " public=");
4938 for(i = 0; i < KEY_SIZE; i++)
4939 fprintf(stderr, "0x%0X ",((struct rsa_key_cpacket *)packet)->public[i]);
4940 fprintf(stderr,",");
4941 fprintf(stderr, " resp=");
4942 for(i = 0; i < KEY_SIZE; i++)
4943 fprintf(stderr, "0x%0X ",((struct rsa_key_cpacket *)packet)->resp[i]);
4944 fprintf(stderr,",");
4945 }
4946 break;
4947 #endif
4948 case CP_PING_RESPONSE : /* client response */
4949 /* note: ping.c calls gwrite directly, so we do not see this */
4950 fprintf(stderr, "\nC->S CP_PING_RESPONSE\t");
4951 if (log_packets > 1)
4952 fprintf(stderr, " number=%u, pingme=%d, cp_sent=%d, cp_recv=%d",
4953 ((struct ping_cpacket *) packet)->number,
4954 ((struct ping_cpacket *) packet)->pingme,
4955 ntohl(((struct ping_cpacket *) packet)->cp_sent),
4956 ntohl(((struct ping_cpacket *) packet)->cp_recv) );
4957 break;
4958
4959 #ifdef SHORT_PACKETS
4960 case CP_S_REQ :
4961 fprintf(stderr, "\nC->S CP_S_REQ\t");
4962 if (log_packets > 1)
4963 fprintf(stderr, " req=%d, version=%d,",
4964 ((struct shortreq_cpacket *) packet)->req,
4965 ((struct shortreq_cpacket *) packet)->version );
4966 break;
4967 case CP_S_THRS :
4968 fprintf(stderr, "\nC->S CP_S_THRS\t");
4969 if (log_packets > 1)
4970 fprintf(stderr, " thresh=%u,",
4971 ntohs(((struct threshold_cpacket *) packet)->thresh) );
4972 break;
4973 case CP_S_MESSAGE : /* vari. Message Packet */
4974 fprintf(stderr, "\nC->S CP_S_MESSAGE\t");
4975 if (log_packets > 1)
4976 fprintf(stderr, " size=%d, group=%d, indiv=%d, mess=\"%s\",",
4977 ((struct mesg_cpacket *) packet)->pad1,
4978 ((struct mesg_cpacket *) packet)->group,
4979 ((struct mesg_cpacket *) packet)->indiv,
4980 ((struct mesg_cpacket *) packet)->mesg );
4981 break;
4982 case CP_S_RESERVED :
4983 fprintf(stderr, "\nC->S CP_S_RESERVED\t");
4984 if (log_packets > 1)
4985 fprintf(stderr, " no struct defined,");
4986 break;
4987 case CP_S_DUMMY :
4988 fprintf(stderr, "\nC->S CP_S_DUMMY\t");
4989 if (log_packets > 1)
4990 fprintf(stderr, " no struct defined,");
4991 break;
4992 #endif
4993
4994 #ifdef FEATURE_PACKETS
4995 case CP_FEATURE :
4996 fprintf(stderr, "\nC->S CP_FEATURE\t");
4997 if (log_packets > 1)
4998 fprintf(stderr, " feature_type=%c, arg1=%d, arg2=%d, value=%d, name=\"%s\",",
4999 ((struct feature_cpacket *) packet)->feature_type,
5000 ((struct feature_cpacket *) packet)->arg1,
5001 ((struct feature_cpacket *) packet)->arg2,
5002 ntohl(((struct feature_cpacket *) packet)->value),
5003 ((struct feature_cpacket *) packet)->name );
5004 break;
5005 #endif
5006 default :
5007 fprintf(stderr, "\nC->S UNKNOWN\t");
5008 if(log_packets > 1)
5009 fprintf(stderr, " type=%d,",packet[0]);
5010 }
5011
5012
5013 }
5014
5015 #endif /* PACKET_LOG */
5016
5017 char *
strcpyp_return(register char * s1,register char * s2,register int length)5018 strcpyp_return(register char *s1, register char *s2, register int length)
5019 {
5020 while (length && *s2)
5021 {
5022 *s1++ = *s2++;
5023 length--;
5024 }
5025 if (length > 0)
5026 {
5027 while (length--)
5028 *s1++ = ' ';
5029 }
5030 return s1;
5031 }
5032