1 /* $Id: netserver.c,v 5.33 2002/08/21 14:22:31 bertg Exp $
2  *
3  * XPilot, a multiplayer gravity war game.  Copyright (C) 1991-2001 by
4  *
5  *      Bj�rn Stabell        <bjoern@xpilot.org>
6  *      Ken Ronny Schouten   <ken@xpilot.org>
7  *      Bert Gijsbers        <bert@xpilot.org>
8  *      Dick Balaska         <dick@xpilot.org>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23  */
24 
25 /*
26  * This is the server side of the network connnection stuff.
27  *
28  * We try very hard to not let the game be disturbed by
29  * players logging in.  Therefore a new connection
30  * passes through several states before it is actively
31  * playing.
32  * First we make a new connection structure available
33  * with a new socket to listen on.  This socket port
34  * number is told to the client via the pack mechanism.
35  * In this state the client has to send a packet to this
36  * newly created socket with its name and playing parameters.
37  * If this succeeds the connection advances to its second state.
38  * In this second state the essential server configuration
39  * like the map and so on is transmitted to the client.
40  * If the client has acknowledged all this data then it
41  * advances to the third state, which is the
42  * ready-but-not-playing-yet state.  In this state the client
43  * has some time to do its final initializations, like mapping
44  * its user interface windows and so on.
45  * When the client is ready to accept frame updates and process
46  * keyboard events then it sends the start-play packet.
47  * This play packet advances the connection state into the
48  * actively-playing state.  A player structure is allocated and
49  * initialized and the other human players are told about this new player.
50  * The newly started client is told about the already playing players and
51  * play has begun.
52  * Apart from these four states there are also two intermediate states.
53  * These intermediate states are entered when the previous state
54  * has filled the reliable data buffer and the client has not
55  * acknowledged all the data yet that is in this reliable data buffer.
56  * They are so called output drain states.  Not doing anything else
57  * then waiting until the buffer is empty.
58  * The difference between these two intermediate states is tricky.
59  * The second intermediate state is entered after the
60  * ready-but-not-playing-yet state and before the actively-playing state.
61  * The difference being that in this second intermediate state the client
62  * is already considered an active player by the rest of the server
63  * but should not get frame updates yet until it has acknowledged its last
64  * reliable data.
65  *
66  * Communication between the server and the clients is only done
67  * using UDP datagrams.  The first client/serverized version of XPilot
68  * was using TCP only, but this was too unplayable across the Internet,
69  * because TCP is a data stream always sending the next byte.
70  * If a packet gets lost then the server has to wait for a
71  * timeout before a retransmission can occur.  This is too slow
72  * for a real-time program like this game, which is more interested
73  * in recent events than in sequenced/reliable events.
74  * Therefore UDP is now used which gives more network control to the
75  * program.
76  * Because some data is considered crucial, like the names of
77  * new players and so on, there also had to be a mechanism which
78  * enabled reliable data transmission.  Here this is done by creating
79  * a data stream which is piggybacked on top of the unreliable data
80  * packets.  The client acknowledges this reliable data by sending
81  * its byte position in the reliable data stream.  So if the client gets
82  * a new reliable data packet and it has not had this data before and
83  * there is also no data packet missing inbetween, then it advances
84  * its byte position and acknowledges this new position to the server.
85  * Otherwise it discards the packet and sends its old byte position
86  * to the server meaning that it detected a packet loss.
87  * The server maintains an acknowledgement timeout timer for each
88  * connection so that it can retransmit a reliable data packet
89  * if the acknowledgement timer expires.
90  */
91 
92 #include <stdlib.h>
93 #include <stdio.h>
94 #include <string.h>
95 #include <errno.h>
96 #include <ctype.h>
97 #include <fcntl.h>
98 #include <time.h>
99 #include <sys/types.h>
100 #include <sys/stat.h>
101 
102 #ifndef _WINDOWS
103 # include <unistd.h>
104 # include <sys/param.h>
105 # ifdef _AIX
106 #  ifndef _BSD_INCLUDES
107 #   define _BSD_INCLUDES
108 #  endif
109 # endif
110 # ifndef __hpux
111 #  include <sys/time.h>
112 # endif
113 # include <sys/socket.h>
114 # include <netinet/in.h>
115 # include <netdb.h>
116 #endif
117 
118 #ifdef _WINDOWS
119 # include "NT/winServer.h"
120 # include <io.h>
121 #endif
122 
123 #define SERVER
124 #include "version.h"
125 #include "config.h"
126 #include "serverconst.h"
127 #include "global.h"
128 #include "proto.h"
129 #include "map.h"
130 #include "pack.h"
131 #include "bit.h"
132 #include "types.h"
133 #include "socklib.h"
134 #include "sched.h"
135 #include "net.h"
136 #include "error.h"
137 #define NETSERVER_C
138 #include "netserver.h"
139 #include "packet.h"
140 #include "setup.h"
141 #include "connection.h"
142 #undef NETSERVER_C
143 #include "saudio.h"
144 #include "checknames.h"
145 #include "server.h"
146 #include "commonproto.h"
147 #include "asteroid.h"
148 #include "score.h"
149 
150 char netserver_version[] = VERSION;
151 
152 #define MAX_SELECT_FD			(sizeof(int) * 8 - 1)
153 #define MAX_RELIABLE_DATA_PACKET_SIZE	1024
154 
155 #define MAX_MOTD_CHUNK			512
156 #define MAX_MOTD_SIZE			(30*1024)
157 #define MAX_MOTD_LOOPS			(10*FPS)
158 
159 static connection_t	*Conn = NULL;
160 static int		max_connections = 0;
161 static setup_t		*Setup = NULL;
162 static int		(*playing_receive[256])(int ind),
163 			(*login_receive[256])(int ind),
164 			(*drain_receive[256])(int ind);
165 int			compress_maps = 1;
166 int			login_in_progress;
167 static int		num_logins, num_logouts;
168 
169 
170 /*
171  * Compress the map data using a simple Run Length Encoding algorithm.
172  * If there is more than one consecutive byte with the same type
173  * then we set the high bit of the byte and then the next byte
174  * gives the number of repetitions.
175  * This works well for most maps which have lots of series of the
176  * same map object and is simple enough to got implemented quickly.
177  */
Compress_map(unsigned char * map,int size)178 static int Compress_map(unsigned char *map, int size)
179 {
180     int			i, j, k;
181 
182     for (i = j = 0; i < size; i++, j++) {
183 	if (i + 1 < size
184 	    && map[i] == map[i + 1]) {
185 	    for (k = 2; i + k < size; k++) {
186 		if (map[i] != map[i + k]) {
187 		    break;
188 		}
189 		if (k == 255) {
190 		    break;
191 		}
192 	    }
193 	    map[j] = (map[i] | SETUP_COMPRESSED);
194 	    map[++j] = k;
195 	    i += k - 1;
196 	} else {
197 	    map[j] = map[i];
198 	}
199     }
200     return j;
201 }
202 
203 /*
204  * Initialize the structure that gives the client information
205  * about our setup.  Like the map and playing rules.
206  * We only setup this structure once to save time when new
207  * players log in during play.
208  */
Init_setup(void)209 static int Init_setup(void)
210 {
211     int			i, x, y, team, type, size,
212 			wormhole = 0,
213 			treasure = 0,
214 			target = 0,
215 			base = 0,
216 			cannon = 0;
217     unsigned char	*mapdata, *mapptr;
218 
219     if ((mapdata = (unsigned char *) malloc(World.x * World.y)) == NULL) {
220 	error("No memory for mapdata");
221 	return -1;
222     }
223     memset(mapdata, SETUP_SPACE, World.x * World.y);
224     mapptr = mapdata;
225     errno = 0;
226     for (x = 0; x < World.x; x++) {
227 	for (y = 0; y < World.y; y++, mapptr++) {
228 	    type = World.block[x][y];
229 	    switch (type) {
230 	    case ACWISE_GRAV:
231 	    case CWISE_GRAV:
232 	    case POS_GRAV:
233 	    case NEG_GRAV:
234 	    case UP_GRAV:
235 	    case DOWN_GRAV:
236 	    case RIGHT_GRAV:
237 	    case LEFT_GRAV:
238 		if (!gravityVisible)
239 		    type = SPACE;
240 		break;
241 	    case WORMHOLE:
242 		if (!wormholeVisible)
243 		    type = SPACE;
244 		break;
245 	    case ITEM_CONCENTRATOR:
246 		if (!itemConcentratorVisible)
247 		    type = SPACE;
248 		break;
249 	    case ASTEROID_CONCENTRATOR:
250 		if (!asteroidConcentratorVisible)
251 		    type = SPACE;
252 		break;
253 	    case FRICTION:
254 		if (!blockFrictionVisible)
255 		    type = SPACE;
256 		else
257 		    type = DECOR_FILLED;
258 		break;
259 	    default:
260 		break;
261 	    }
262 	    switch (type) {
263 	    case SPACE:		*mapptr = SETUP_SPACE; break;
264 	    case FILLED:	*mapptr = SETUP_FILLED; break;
265 	    case REC_RU:	*mapptr = SETUP_REC_RU; break;
266 	    case REC_RD:	*mapptr = SETUP_REC_RD; break;
267 	    case REC_LU:	*mapptr = SETUP_REC_LU; break;
268 	    case REC_LD:	*mapptr = SETUP_REC_LD; break;
269 	    case FUEL:		*mapptr = SETUP_FUEL; break;
270 	    case ACWISE_GRAV:	*mapptr = SETUP_ACWISE_GRAV; break;
271 	    case CWISE_GRAV:	*mapptr = SETUP_CWISE_GRAV; break;
272 	    case POS_GRAV:	*mapptr = SETUP_POS_GRAV; break;
273 	    case NEG_GRAV:	*mapptr = SETUP_NEG_GRAV; break;
274 	    case UP_GRAV:	*mapptr = SETUP_UP_GRAV; break;
275 	    case DOWN_GRAV:	*mapptr = SETUP_DOWN_GRAV; break;
276 	    case RIGHT_GRAV:	*mapptr = SETUP_RIGHT_GRAV; break;
277 	    case LEFT_GRAV:	*mapptr = SETUP_LEFT_GRAV; break;
278 	    case ITEM_CONCENTRATOR: *mapptr = SETUP_ITEM_CONCENTRATOR; break;
279 	    case ASTEROID_CONCENTRATOR:	*mapptr = SETUP_ASTEROID_CONCENTRATOR; break;
280 	    case DECOR_FILLED:	*mapptr = SETUP_DECOR_FILLED; break;
281 	    case DECOR_RU:	*mapptr = SETUP_DECOR_RU; break;
282 	    case DECOR_RD:	*mapptr = SETUP_DECOR_RD; break;
283 	    case DECOR_LU:	*mapptr = SETUP_DECOR_LU; break;
284 	    case DECOR_LD:	*mapptr = SETUP_DECOR_LD; break;
285 	    case WORMHOLE:
286 		switch (World.wormHoles[wormhole++].type) {
287 		case WORM_NORMAL: *mapptr = SETUP_WORM_NORMAL; break;
288 		case WORM_IN:     *mapptr = SETUP_WORM_IN; break;
289 		case WORM_OUT:    *mapptr = SETUP_WORM_OUT; break;
290 		default:
291 		    error("Bad wormhole (%d,%d).", x, y);
292 		    free(mapdata);
293 		    return -1;
294 		}
295 		break;
296 	    case TREASURE:
297 		*mapptr = SETUP_TREASURE + World.treasures[treasure++].team;
298 		break;
299 	    case TARGET:
300 		*mapptr = SETUP_TARGET + World.targets[target++].team;
301 		break;
302 	    case BASE:
303 		if (World.base[base].team == TEAM_NOT_SET) {
304 		    team = 0;
305 		} else {
306 		    team = World.base[base].team;
307 		}
308 		switch (World.base[base++].dir) {
309 		case DIR_UP:    *mapptr = SETUP_BASE_UP + team; break;
310 		case DIR_RIGHT: *mapptr = SETUP_BASE_RIGHT + team; break;
311 		case DIR_DOWN:  *mapptr = SETUP_BASE_DOWN + team; break;
312 		case DIR_LEFT:  *mapptr = SETUP_BASE_LEFT + team; break;
313 		default:
314 		    error("Bad base at (%d,%d).", x, y);
315 		    free(mapdata);
316 		    return -1;
317 		}
318 		break;
319 	    case CANNON:
320 		switch (World.cannon[cannon++].dir) {
321 		case DIR_UP:	*mapptr = SETUP_CANNON_UP; break;
322 		case DIR_RIGHT:	*mapptr = SETUP_CANNON_RIGHT; break;
323 		case DIR_DOWN:	*mapptr = SETUP_CANNON_DOWN; break;
324 		case DIR_LEFT:	*mapptr = SETUP_CANNON_LEFT; break;
325 		default:
326 		    error("Bad cannon at (%d,%d).", x, y);
327 		    free(mapdata);
328 		    return -1;
329 		}
330 		break;
331 	    case CHECK:
332 		for (i = 0; i < World.NumChecks; i++) {
333 		    if (x != World.check[i].x
334 			|| y != World.check[i].y) {
335 			continue;
336 		    }
337 		    *mapptr = SETUP_CHECK + i;
338 		    break;
339 		}
340 		if (i >= World.NumChecks) {
341 		    error("Bad checkpoint at (%d,%d).", x, y);
342 		    free(mapdata);
343 		    return -1;
344 		}
345 		break;
346 	    default:
347 		error("Unknown map type (%d) at (%d,%d).", type, x, y);
348 		*mapptr = SETUP_SPACE;
349 		break;
350 	    }
351 	}
352     }
353     if (compress_maps == 0) {
354 	type = SETUP_MAP_UNCOMPRESSED;
355 	size = World.x * World.y;
356     } else {
357 	type = SETUP_MAP_ORDER_XY;
358 	size = Compress_map(mapdata, World.x * World.y);
359 	if (size <= 0 || size > World.x * World.y) {
360 	    errno = 0;
361 	    error("Map compression error (%d)", size);
362 	    free(mapdata);
363 	    return -1;
364 	}
365 	if ((mapdata = (unsigned char *)realloc(mapdata, size)) == NULL) {
366 	    error("Cannot reallocate mapdata");
367 	    return -1;
368 	}
369     }
370 
371 #ifndef SILENT
372     if (type != SETUP_MAP_UNCOMPRESSED) {
373 	xpprintf("%s Map compression ratio is %-4.2f%%\n", showtime(),
374 	    100.0 * size / (World.x * World.y));
375     }
376 #endif
377     if ((Setup = (setup_t *) malloc(sizeof(setup_t) + size)) == NULL) {
378 	error("No memory to hold setup");
379 	free(mapdata);
380 	return -1;
381     }
382     memset(Setup, 0, sizeof(setup_t) + size);
383     memcpy(Setup->map_data, mapdata, size);
384     free(mapdata);
385     Setup->setup_size = ((char *) &Setup->map_data[0] - (char *) Setup) + size;
386     Setup->map_data_len = size;
387     Setup->map_order = type;
388     Setup->frames_per_second = FPS;
389     Setup->lives = World.rules->lives;
390     Setup->mode = World.rules->mode;
391     Setup->x = World.x;
392     Setup->y = World.y;
393     strlcpy(Setup->name, World.name, sizeof(Setup->name));
394     strlcpy(Setup->author, World.author, sizeof(Setup->author));
395 
396     return 0;
397 }
398 
399 /*
400  * Initialize the function dispatch tables for the various client
401  * connection states.  Some states use the same table.
402  */
Init_receive(void)403 static void Init_receive(void)
404 {
405     int			i;
406 
407     for (i = 0; i < 256; i++) {
408 	login_receive[i] = Receive_undefined;
409 	playing_receive[i] = Receive_undefined;
410 	drain_receive[i] = Receive_undefined;
411     }
412 
413     drain_receive[PKT_QUIT]			= Receive_quit;
414     drain_receive[PKT_ACK]			= Receive_ack;
415     drain_receive[PKT_VERIFY]			= Receive_discard;
416     drain_receive[PKT_PLAY]			= Receive_discard;
417     drain_receive[PKT_SHAPE]			= Receive_discard;
418 
419     login_receive[PKT_PLAY]			= Receive_play;
420     login_receive[PKT_QUIT]			= Receive_quit;
421     login_receive[PKT_ACK]			= Receive_ack;
422     login_receive[PKT_VERIFY]			= Receive_discard;
423     login_receive[PKT_POWER]			= Receive_power;
424     login_receive[PKT_POWER_S]			= Receive_power;
425     login_receive[PKT_TURNSPEED]		= Receive_power;
426     login_receive[PKT_TURNSPEED_S]		= Receive_power;
427     login_receive[PKT_TURNRESISTANCE]		= Receive_power;
428     login_receive[PKT_TURNRESISTANCE_S]		= Receive_power;
429     login_receive[PKT_DISPLAY]			= Receive_display;
430     login_receive[PKT_MODIFIERBANK]		= Receive_modifier_bank;
431     login_receive[PKT_MOTD]			= Receive_motd;
432     login_receive[PKT_SHAPE]			= Receive_shape;
433     login_receive[PKT_REQUEST_AUDIO]		= Receive_audio_request;
434     login_receive[PKT_ASYNC_FPS]		= Receive_fps_request;
435 
436     playing_receive[PKT_ACK]			= Receive_ack;
437     playing_receive[PKT_VERIFY]			= Receive_discard;
438     playing_receive[PKT_PLAY]			= Receive_play;
439     playing_receive[PKT_QUIT]			= Receive_quit;
440     playing_receive[PKT_KEYBOARD]		= Receive_keyboard;
441     playing_receive[PKT_POWER]			= Receive_power;
442     playing_receive[PKT_POWER_S]		= Receive_power;
443     playing_receive[PKT_TURNSPEED]		= Receive_power;
444     playing_receive[PKT_TURNSPEED_S]		= Receive_power;
445     playing_receive[PKT_TURNRESISTANCE]		= Receive_power;
446     playing_receive[PKT_TURNRESISTANCE_S]	= Receive_power;
447     playing_receive[PKT_ACK_CANNON]		= Receive_ack_cannon;
448     playing_receive[PKT_ACK_FUEL]		= Receive_ack_fuel;
449     playing_receive[PKT_ACK_TARGET]		= Receive_ack_target;
450     playing_receive[PKT_TALK]			= Receive_talk;
451     playing_receive[PKT_DISPLAY]		= Receive_display;
452     playing_receive[PKT_MODIFIERBANK]		= Receive_modifier_bank;
453     playing_receive[PKT_MOTD]			= Receive_motd;
454     playing_receive[PKT_SHAPE]			= Receive_shape;
455     playing_receive[PKT_POINTER_MOVE]		= Receive_pointer_move;
456     playing_receive[PKT_REQUEST_AUDIO]		= Receive_audio_request;
457     playing_receive[PKT_ASYNC_FPS]		= Receive_fps_request;
458 }
459 
460 /*
461  * Initialize the connection structures.
462  */
Setup_net_server(void)463 int Setup_net_server(void)
464 {
465     size_t	size;
466 
467     Init_receive();
468 
469     if (Init_setup() == -1) {
470 	return -1;
471     }
472     /*
473      * The number of connections is limited by the number of bases
474      * and the max number of possible file descriptors to use in
475      * the select(2) call minus those for stdin, stdout, stderr,
476      * the contact socket, and the socket for the resolver library routines.
477      */
478     max_connections = MIN(MAX_SELECT_FD - 5, World.NumBases);
479     size = max_connections * sizeof(*Conn);
480     if ((Conn = (connection_t *) malloc(size)) == NULL) {
481 	error("Cannot allocate memory for connections");
482 	return -1;
483     }
484     memset(Conn, 0, size);
485 
486     return 0;
487 }
488 
Conn_set_state(connection_t * connp,int state,int drain_state)489 static void Conn_set_state(connection_t *connp, int state, int drain_state)
490 {
491     static int num_conn_busy;
492     static int num_conn_playing;
493 
494     if ((connp->state & (CONN_PLAYING | CONN_READY)) != 0) {
495 	num_conn_playing--;
496     }
497     else if (connp->state == CONN_FREE) {
498 	num_conn_busy++;
499     }
500 
501     connp->state = state;
502     connp->drain_state = drain_state;
503     connp->start = main_loops;
504 
505     if (connp->state == CONN_PLAYING) {
506 	num_conn_playing++;
507 	connp->timeout = IDLE_TIMEOUT;
508     }
509     else if (connp->state == CONN_READY) {
510 	num_conn_playing++;
511 	connp->timeout = READY_TIMEOUT;
512     }
513     else if (connp->state == CONN_LOGIN) {
514 	connp->timeout = LOGIN_TIMEOUT;
515     }
516     else if (connp->state == CONN_SETUP) {
517 	connp->timeout = SETUP_TIMEOUT;
518     }
519     else if (connp->state == CONN_LISTENING) {
520 	connp->timeout = LISTEN_TIMEOUT;
521     }
522     else if (connp->state == CONN_FREE) {
523 	num_conn_busy--;
524 	connp->timeout = IDLE_TIMEOUT;
525     }
526 
527     login_in_progress = num_conn_busy - num_conn_playing;
528 }
529 
530 /*
531  * Cleanup a connection.  The client may not know yet that
532  * it is thrown out of the game so we send it a quit packet.
533  * We send it twice because of UDP it could get lost.
534  * Since 3.0.6 the client receives a short message
535  * explaining why the connection was terminated.
536  */
Destroy_connection(int ind,const char * reason)537 void Destroy_connection(int ind, const char *reason)
538 {
539     connection_t	*connp = &Conn[ind];
540     int			id,
541 			len;
542     sock_t		*sock;
543     char		pkt[MAX_CHARS];
544 
545     if (connp->state == CONN_FREE) {
546 	errno = 0;
547 	error("Cannot destroy empty connection (\"%s\")", reason);
548 	return;
549     }
550 
551     sock = &connp->w.sock;
552     remove_input(sock->fd);
553 
554     pkt[0] = PKT_QUIT;
555     strlcpy(&pkt[1], reason, sizeof(pkt) - 1);
556     len = strlen(pkt) + 1;
557     if (sock_write(sock, pkt, len) != len) {
558 	sock_get_error(sock);
559 	sock_write(sock, pkt, len);
560     }
561 #ifndef SILENT
562     xpprintf("%s Goodbye %s=%s@%s|%s (\"%s\")\n",
563 	   showtime(),
564 	   connp->nick ? connp->nick : "",
565 	   connp->real ? connp->real : "",
566 	   connp->host ? connp->host : "",
567 	   connp->dpy ? connp->dpy : "",
568 	   reason);
569 #endif
570 
571     Conn_set_state(connp, CONN_FREE, CONN_FREE);
572 
573     if (connp->id != NO_ID) {
574 	id = connp->id;
575 	connp->id = NO_ID;
576 	Players[GetInd[id]]->conn = NOT_CONNECTED;
577 	Delete_player(GetInd[id]);
578     }
579     if (connp->real != NULL) {
580 	free(connp->real);
581     }
582     if (connp->nick != NULL) {
583 	free(connp->nick);
584     }
585     if (connp->dpy != NULL) {
586 	free(connp->dpy);
587     }
588     if (connp->addr != NULL) {
589 	free(connp->addr);
590     }
591     if (connp->host != NULL) {
592 	free(connp->host);
593     }
594     Sockbuf_cleanup(&connp->w);
595     Sockbuf_cleanup(&connp->r);
596     Sockbuf_cleanup(&connp->c);
597 
598     num_logouts++;
599 
600     if (sock_write(sock, pkt, len) != len) {
601 	sock_get_error(sock);
602 	sock_write(sock, pkt, len);
603     }
604     sock_close(sock);
605 
606     memset(connp, 0, sizeof(*connp));
607 }
608 
Check_connection(char * real,char * nick,char * dpy,char * addr)609 int Check_connection(char *real, char *nick, char *dpy, char *addr)
610 {
611     int			i;
612     connection_t	*connp;
613 
614     for (i = 0; i < max_connections; i++) {
615 	connp = &Conn[i];
616 	if (connp->state == CONN_LISTENING) {
617 	    if (strcasecmp(connp->nick, nick) == 0) {
618 		if (!strcmp(real, connp->real)
619 		    && !strcmp(dpy, connp->dpy)
620 		    && !strcmp(addr, connp->addr)) {
621 		    return connp->my_port;
622 		}
623 		return -1;
624 	    }
625 	}
626     }
627     return -1;
628 }
629 
630 /*
631  * A client has requested a playing connection with this server.
632  * See if we have room for one more player and if his name is not
633  * already in use by some other player.  Because the confirmation
634  * may get lost we are willing to send it another time if the
635  * client connection is still in the CONN_LISTENING state.
636  */
Setup_connection(char * real,char * nick,char * dpy,int team,char * addr,char * host,unsigned version)637 int Setup_connection(char *real, char *nick, char *dpy, int team,
638 		     char *addr, char *host, unsigned version)
639 {
640     int			i,
641 			free_conn_index = max_connections,
642 			my_port;
643     sock_t		sock;
644     connection_t	*connp;
645 
646     for (i = 0; i < max_connections; i++) {
647 	connp = &Conn[i];
648 	if (connp->state == CONN_FREE) {
649 	    if (free_conn_index == max_connections) {
650 		free_conn_index = i;
651 	    }
652 	    continue;
653 	}
654 	if (strcasecmp(connp->nick, nick) == 0) {
655 	    if (connp->state == CONN_LISTENING
656 		&& strcmp(real, connp->real) == 0
657 		&& strcmp(dpy, connp->dpy) == 0
658 		&& version == connp->version) {
659 		/*
660 		 * May happen for multi-homed hosts
661 		 * and if previous packet got lost.
662 		 */
663 		return connp->my_port;
664 	    } else {
665 		/*
666 		 * Nick already in use.
667 		 */
668 		return -1;
669 	    }
670 	}
671     }
672 
673     if (free_conn_index >= max_connections) {
674 #ifndef SILENT
675 	xpprintf("%s Full house for %s(%s)@%s(%s)\n",
676 		 showtime(), real, nick, host, dpy);
677 #endif
678 	return -1;
679     }
680     connp = &Conn[free_conn_index];
681     if (clientPortStart && (!clientPortEnd || clientPortEnd > 65535)) {
682 	clientPortEnd = 65535;
683     }
684     if (clientPortEnd && (!clientPortStart || clientPortStart < 1024)) {
685 	clientPortStart = 1024;
686     }
687 
688     if (!clientPortStart || !clientPortEnd ||
689 	(clientPortStart > clientPortEnd)) {
690 
691         if (sock_open_udp(&sock, serverAddr, 0) == SOCK_IS_ERROR) {
692             error("Cannot create datagram socket (%d)", sock.error.error);
693             return -1;
694         }
695     }
696     else {
697 	int found_socket = 0;
698         for (i = clientPortStart; i <= clientPortEnd; i++) {
699             if (sock_open_udp(&sock, serverAddr, i) != SOCK_IS_ERROR) {
700 		found_socket = 1;
701                 break;
702 	    }
703 	}
704 	if (found_socket == 0) {
705 	    error("Could not find a usable port in given port range");
706 	    return -1;
707 	}
708     }
709 
710     if ((my_port = sock_get_port(&sock)) == -1) {
711 	error("Cannot get port from socket");
712 	sock_close(&sock);
713 	return -1;
714     }
715     if (sock_set_non_blocking(&sock, 1) == -1) {
716 	error("Cannot make client socket non-blocking");
717 	sock_close(&sock);
718 	return -1;
719     }
720     if (sock_set_receive_buffer_size(&sock, SERVER_RECV_SIZE + 256) == -1) {
721 	error("Cannot set receive buffer size to %d", SERVER_RECV_SIZE + 256);
722     }
723     if (sock_set_send_buffer_size(&sock, SERVER_SEND_SIZE + 256) == -1) {
724 	error("Cannot set send buffer size to %d", SERVER_SEND_SIZE + 256);
725     }
726 
727     Sockbuf_init(&connp->w, &sock, SERVER_SEND_SIZE,
728 		 SOCKBUF_WRITE | SOCKBUF_DGRAM);
729 
730     Sockbuf_init(&connp->r, &sock, SERVER_RECV_SIZE,
731 		 SOCKBUF_READ | SOCKBUF_DGRAM);
732 
733     Sockbuf_init(&connp->c, (sock_t *) NULL, MAX_SOCKBUF_SIZE,
734 		 SOCKBUF_WRITE | SOCKBUF_READ | SOCKBUF_LOCK);
735 
736     connp->my_port = my_port;
737     connp->real = xp_strdup(real);
738     connp->nick = xp_strdup(nick);
739     connp->dpy = xp_strdup(dpy);
740     connp->addr = xp_strdup(addr);
741     connp->host = xp_strdup(host);
742     connp->ship = NULL;
743     connp->team = team;
744     connp->version = version;
745     connp->start = main_loops;
746     connp->magic = randomMT() + my_port + sock.fd + team + main_loops;
747     connp->id = NO_ID;
748     connp->timeout = LISTEN_TIMEOUT;
749     connp->last_key_change = 0;
750     connp->reliable_offset = 0;
751     connp->reliable_unsent = 0;
752     connp->last_send_loops = 0;
753     connp->retransmit_at_loop = 0;
754     connp->rtt_retransmit = DEFAULT_RETRANSMIT;
755     connp->rtt_smoothed = 0;
756     connp->rtt_dev = 0;
757     connp->rtt_timeouts = 0;
758     connp->acks = 0;
759     connp->setup = 0;
760     connp->motd_offset = -1;
761     connp->motd_stop = 0;
762     connp->view_width = DEF_VIEW_SIZE;
763     connp->view_height = DEF_VIEW_SIZE;
764     connp->debris_colors = 0;
765     connp->spark_rand = DEF_SPARK_RAND;
766     Conn_set_state(connp, CONN_LISTENING, CONN_FREE);
767     if (connp->w.buf == NULL
768 	|| connp->r.buf == NULL
769 	|| connp->c.buf == NULL
770 	|| connp->real == NULL
771 	|| connp->nick == NULL
772 	|| connp->dpy == NULL
773 	|| connp->addr == NULL
774 	|| connp->host == NULL
775 	) {
776 	error("Not enough memory for connection");
777 	/* socket is not yet connected, but it doesn't matter much. */
778 	Destroy_connection(free_conn_index, "no memory");
779 	return -1;
780     }
781 
782     install_input(Handle_input, sock.fd, (void *)free_conn_index);
783 
784     return my_port;
785 }
786 
787 /*
788  * Handle a connection that is in the listening state.
789  */
Handle_listening(int ind)790 static int Handle_listening(int ind)
791 {
792     connection_t	*connp = &Conn[ind];
793     unsigned char	type;
794     int			n;
795     char		nick[MAX_CHARS],
796 			real[MAX_CHARS];
797 
798     if (connp->state != CONN_LISTENING) {
799 	Destroy_connection(ind, "not listening");
800 	return -1;
801     }
802     Sockbuf_clear(&connp->r);
803     errno = 0;
804     n = sock_receive_any(&connp->r.sock, connp->r.buf, connp->r.size);
805     if (n <= 0) {
806 	if (n == 0
807 	    || errno == EWOULDBLOCK
808 	    || errno == EAGAIN) {
809 	    n = 0;
810 	}
811 	else if (n != 0) {
812 	    Destroy_connection(ind, "read first packet error");
813 	}
814 	return n;
815     }
816     connp->r.len = n;
817     connp->his_port = sock_get_last_port(&connp->r.sock);
818     if (sock_connect(&connp->w.sock, connp->addr, connp->his_port) == -1) {
819 	error("Cannot connect datagram socket (%s,%d,%d,%d,%d)",
820 	      connp->addr, connp->his_port,
821 	      connp->w.sock.error.error,
822 	      connp->w.sock.error.call,
823 	      connp->w.sock.error.line);
824 	if (sock_get_error(&connp->w.sock)) {
825 	    error("sock_get_error fails too, giving up");
826 	    Destroy_connection(ind, "connect error");
827 	    return -1;
828 	}
829 	errno = 0;
830 	if (sock_connect(&connp->w.sock, connp->addr, connp->his_port) == -1) {
831 	    error("Still cannot connect datagram socket (%s,%d,%d,%d,%d)",
832 		  connp->addr, connp->his_port,
833 		  connp->w.sock.error.error,
834 		  connp->w.sock.error.call,
835 		  connp->w.sock.error.line);
836 	    Destroy_connection(ind, "connect error");
837 	    return -1;
838 	}
839     }
840 #ifndef SILENT
841     xpprintf("%s Welcome %s=%s@%s|%s (%s/%d)", showtime(), connp->nick,
842 	   connp->real, connp->host, connp->dpy, connp->addr, connp->his_port);
843     if (connp->version != MY_VERSION) {
844 	xpprintf(" (version %04x)\n", connp->version);
845     } else {
846 	xpprintf("\n");
847     }
848 #endif
849     if (connp->r.ptr[0] != PKT_VERIFY) {
850 	Send_reply(ind, PKT_VERIFY, PKT_FAILURE);
851 	Send_reliable(ind);
852 	Destroy_connection(ind, "not connecting");
853 	return -1;
854     }
855     if ((n = Packet_scanf(&connp->r, "%c%s%s",
856 			  &type, real, nick)) <= 0) {
857 	Send_reply(ind, PKT_VERIFY, PKT_FAILURE);
858 	Send_reliable(ind);
859 	Destroy_connection(ind, "verify incomplete");
860 	return -1;
861     }
862     Fix_real_name(real);
863     Fix_nick_name(nick);
864     if (strcmp(real, connp->real)) {
865 #ifndef SILENT
866 	xpprintf("%s Client verified incorrectly (%s,%s)(%s,%s)\n",
867 		 showtime(), real, nick, connp->real, connp->nick);
868 #endif
869 	Send_reply(ind, PKT_VERIFY, PKT_FAILURE);
870 	Send_reliable(ind);
871 	Destroy_connection(ind, "verify incorrect");
872 	return -1;
873     }
874     Sockbuf_clear(&connp->w);
875     if (Send_reply(ind, PKT_VERIFY, PKT_SUCCESS) == -1
876 	|| Packet_printf(&connp->c, "%c%u", PKT_MAGIC, connp->magic) <= 0
877 	|| Send_reliable(ind) <= 0) {
878 	Destroy_connection(ind, "confirm failed");
879 	return -1;
880     }
881 
882     Conn_set_state(connp, CONN_DRAIN, CONN_SETUP);
883 
884     return 1;	/* success! */
885 }
886 
887 /*
888  * Handle a connection that is in the transmit-server-configuration-data state.
889  */
Handle_setup(int ind)890 static int Handle_setup(int ind)
891 {
892     connection_t	*connp = &Conn[ind];
893     char		*buf;
894     int			n,
895 			len;
896 
897     if (connp->state != CONN_SETUP) {
898 	Destroy_connection(ind, "not setup");
899 	return -1;
900     }
901 
902     if (connp->setup == 0) {
903 	n = Packet_printf(&connp->c,
904 			  "%ld" "%ld%hd" "%hd%hd" "%hd%hd" "%s%s",
905 			  Setup->map_data_len,
906 			  Setup->mode, Setup->lives,
907 			  Setup->x, Setup->y,
908 			  Setup->frames_per_second, Setup->map_order,
909 			  Setup->name, Setup->author);
910 	if (n <= 0) {
911 	    Destroy_connection(ind, "setup 0 write error");
912 	    return -1;
913 	}
914 	connp->setup = (char *) &Setup->map_data[0] - (char *) Setup;
915     }
916     else if (connp->setup < Setup->setup_size) {
917 	if (connp->c.len > 0) {
918 	    /* If there is still unacked reliable data test for acks. */
919 	    Handle_input(-1, (void *) ind);
920 	    if (connp->state == CONN_FREE) {
921 		return -1;
922 	    }
923 	}
924     }
925     if (connp->setup < Setup->setup_size) {
926 	len = MIN(connp->c.size, 4096) - connp->c.len;
927 	if (len <= 0) {
928 	    /* Wait for acknowledgement of previously transmitted data. */
929 	    return 0;
930 	}
931 	if (len > Setup->setup_size - connp->setup) {
932 	    len = Setup->setup_size - connp->setup;
933 	}
934 	buf = (char *) Setup;
935 	if (Sockbuf_write(&connp->c, &buf[connp->setup], len) != len) {
936 	    Destroy_connection(ind, "sockbuf write setup error");
937 	    return -1;
938 	}
939 	connp->setup += len;
940 	if (len >= 512) {
941 	    connp->start += (len * FPS) / (8 * 512) + 1;
942 	}
943     }
944     if (connp->setup >= Setup->setup_size) {
945 	Conn_set_state(connp, CONN_DRAIN, CONN_LOGIN);
946     }
947 
948     return 0;
949 }
950 
951 /*
952  * A client has requested to start active play.
953  * See if we can allocate a player structure for it
954  * and if this succeeds update the player information
955  * to all connected players.
956  */
Handle_login(int ind,char * errmsg,int errsize)957 static int Handle_login(int ind, char *errmsg, int errsize)
958 {
959     connection_t	*connp = &Conn[ind];
960     player		*pl;
961     int			i,
962 			war_on_id,
963 			conn_bit;
964     char		msg[MSG_LEN];
965 
966     if (NumPlayers - NumPseudoPlayers >= World.NumBases) {
967 	errno = 0;
968 	strlcpy(errmsg, "Not enough bases for players", errsize);
969 	error("%s", errmsg);
970 	return -1;
971     }
972     if (BIT(World.rules->mode, TEAM_PLAY)) {
973 	if (connp->team < 0 || connp->team >= MAX_TEAMS
974 	    || (reserveRobotTeam && (connp->team == robotTeam))) {
975 	    connp->team = TEAM_NOT_SET;
976 	}
977 	else if (World.teams[connp->team].NumBases <= 0) {
978 	    connp->team = TEAM_NOT_SET;
979 	}
980 	else {
981 	    Check_team_members(connp->team);
982 	    if (World.teams[connp->team].NumMembers
983 		- World.teams[connp->team].NumRobots
984 		>= World.teams[connp->team].NumBases) {
985 		connp->team = TEAM_NOT_SET;
986 	    }
987 	}
988 	if (connp->team == TEAM_NOT_SET) {
989 	    connp->team = Pick_team(PickForHuman);
990 	    if (connp->team == TEAM_NOT_SET ||
991 		(connp->team == robotTeam && reserveRobotTeam)) {
992 		errno = 0;
993 		strlcpy(errmsg, "Can't pick team", errsize);
994 		error("%s", errmsg);
995 		return -1;
996 	    }
997 	}
998     } else {
999 	connp->team = TEAM_NOT_SET;
1000     }
1001     for (i = 0; i < NumPlayers; i++) {
1002 	if (strcasecmp(Players[i]->name, connp->nick) == 0) {
1003 	    errno = 0;
1004 	    error("Name already in use %s", connp->nick);
1005 	    strlcpy(errmsg, "Name already in use", errsize);
1006 	    return -1;
1007 	}
1008     }
1009     if (Init_player(NumPlayers, connp->ship) <= 0) {
1010 	strlcpy(errmsg, "Init_player failed: no free ID", errsize);
1011 	return -1;
1012     }
1013     pl = Players[NumPlayers];
1014     strlcpy(pl->name, connp->nick, MAX_CHARS);
1015     strlcpy(pl->realname, connp->real, MAX_CHARS);
1016     strlcpy(pl->hostname, connp->host, MAX_CHARS);
1017     pl->isowner = (!strcmp(pl->realname, Server.owner) &&
1018 		   !strcmp(connp->addr, "127.0.0.1"));
1019     if (connp->team != TEAM_NOT_SET) {
1020 	pl->team = connp->team;
1021     }
1022     pl->version = connp->version;
1023 
1024     Pick_startpos(NumPlayers);
1025     Go_home(NumPlayers);
1026     if (pl->team != TEAM_NOT_SET) {
1027 	World.teams[pl->team].NumMembers++;
1028 	if (teamShareScore) {
1029 	    if (World.teams[pl->team].NumMembers == 1) {
1030 		/* reset team score on first player */
1031 		World.teams[pl->team].score = 0;
1032 	    }
1033 	    TEAM_SCORE(pl->team, 0);
1034 	}
1035     }
1036     NumPlayers++;
1037     request_ID();
1038     connp->id = pl->id;
1039     pl->conn = ind;
1040     memset(pl->last_keyv, 0, sizeof(pl->last_keyv));
1041     memset(pl->prev_keyv, 0, sizeof(pl->prev_keyv));
1042 
1043     Conn_set_state(connp, CONN_READY, CONN_PLAYING);
1044 
1045     if (Send_reply(ind, PKT_PLAY, PKT_SUCCESS) <= 0) {
1046 	strlcpy(errmsg, "Cannot send play reply", errsize);
1047 	error("%s", errmsg);
1048 	return -1;
1049     }
1050 
1051 #ifndef	SILENT
1052     xpprintf("%s %s (%d) starts at startpos %d.\n", showtime(),
1053 	   pl->name, NumPlayers, pl->home_base);
1054 #endif
1055 
1056     /*
1057      * Tell him about himself first.
1058      */
1059     Send_player(pl->conn, pl->id);
1060     Send_score(pl->conn, pl->id, pl->score,
1061 	       pl->life, pl->mychar, pl->alliance);
1062     Send_base(pl->conn, pl->id, pl->home_base);
1063     /*
1064      * And tell him about all the others.
1065      */
1066     for (i = 0; i < NumPlayers - 1; i++) {
1067 	Send_player(pl->conn, Players[i]->id);
1068 	Send_score(pl->conn, Players[i]->id, Players[i]->score,
1069 		   Players[i]->life, Players[i]->mychar, Players[i]->alliance);
1070 	if (!IS_TANK_IND(i)) {
1071 	    Send_base(pl->conn, Players[i]->id, Players[i]->home_base);
1072 	}
1073     }
1074     /*
1075      * And about all the teams.
1076      */
1077     if (BIT(World.rules->mode, TEAM_PLAY)) {
1078 	for (i = 0; i < MAX_TEAMS; i++) {
1079 	    if (World.teams[i].NumMembers > 0) {
1080 		Send_team_score(pl->conn, i, World.teams[i].score);
1081 	    }
1082 	}
1083     }
1084     /*
1085      * And tell all the others about him.
1086      */
1087     for (i = 0; i < NumPlayers - 1; i++) {
1088 	if (Players[i]->conn != NOT_CONNECTED) {
1089 	    Send_player(Players[i]->conn, pl->id);
1090 	    Send_score(Players[i]->conn, pl->id, pl->score,
1091 		       pl->life, pl->mychar, pl->alliance);
1092 	    Send_base(Players[i]->conn, pl->id, pl->home_base);
1093 	}
1094 	/*
1095 	 * And tell him about the relationships others have with eachother.
1096 	 */
1097 	else if (IS_ROBOT_IND(i)) {
1098 	    if ((war_on_id = Robot_war_on_player(i)) != NO_ID) {
1099 		Send_war(pl->conn, Players[i]->id, war_on_id);
1100 	    }
1101 	}
1102     }
1103 
1104     if (NumPlayers == 1) {
1105 	sprintf(msg, "Welcome to \"%s\", made by %s.",
1106 		World.name, World.author);
1107     } else if (BIT(World.rules->mode, TEAM_PLAY)) {
1108 	sprintf(msg, "%s (%s, team %d) has entered \"%s\", made by %s.",
1109 		pl->name, pl->realname, pl->team, World.name, World.author);
1110     } else {
1111 	sprintf(msg, "%s (%s) has entered \"%s\", made by %s.",
1112 		pl->name, pl->realname, World.name, World.author);
1113     }
1114     Set_message(msg);
1115 
1116     if (connp->version < MY_VERSION) {
1117 	const char sender[] = "[*Server notice*]";
1118 	sprintf(msg, "Server runs version %s. %s", VERSION, sender);
1119 	Set_player_message(pl, msg);
1120 	if (connp->version < 0x4401) {
1121 	    sprintf(msg,
1122 		    "Your client does not support the fast radar packet. %s",
1123 		   sender);
1124 	    Set_player_message(pl, msg);
1125 	}
1126 	if (connp->version < 0x4400 && maxAsteroidDensity > 0) {
1127 	    sprintf(msg,
1128 		    "Your client will see the %d asteroids as balls. %s",
1129 		    (int)World.asteroids.max,
1130 		    sender);
1131 	    Set_player_message(pl, msg);
1132 	}
1133     }
1134 
1135     conn_bit = (1 << ind);
1136     for (i = 0; i < World.NumCannons; i++) {
1137 	/*
1138 	 * The client assumes at startup that all cannons are active.
1139 	 */
1140 	if (World.cannon[i].dead_time == 0) {
1141 	    SET_BIT(World.cannon[i].conn_mask, conn_bit);
1142 	} else {
1143 	    CLR_BIT(World.cannon[i].conn_mask, conn_bit);
1144 	}
1145     }
1146     for (i = 0; i < World.NumFuels; i++) {
1147 	/*
1148 	 * The client assumes at startup that all fuelstations are filled.
1149 	 */
1150 	if (World.fuel[i].fuel == MAX_STATION_FUEL) {
1151 	    SET_BIT(World.fuel[i].conn_mask, conn_bit);
1152 	} else {
1153 	    CLR_BIT(World.fuel[i].conn_mask, conn_bit);
1154 	}
1155     }
1156     for (i = 0; i < World.NumTargets; i++) {
1157 	/*
1158 	 * The client assumes at startup that all targets are not damaged.
1159 	 */
1160 	if (World.targets[i].dead_time == 0
1161 	    && World.targets[i].damage == TARGET_DAMAGE) {
1162 	    SET_BIT(World.targets[i].conn_mask, conn_bit);
1163 	    CLR_BIT(World.targets[i].update_mask, conn_bit);
1164 	} else {
1165 	    CLR_BIT(World.targets[i].conn_mask, conn_bit);
1166 	    SET_BIT(World.targets[i].update_mask, conn_bit);
1167 	}
1168     }
1169 
1170     sound_player_init(pl);
1171 
1172     sound_play_all(START_SOUND);
1173 
1174     num_logins++;
1175 
1176     if (resetOnHuman > 0
1177 	&& (NumPlayers - NumPseudoPlayers - NumRobots) <= resetOnHuman
1178 	&& !round_delay) {
1179 	if (BIT(World.rules->mode, TIMING)) {
1180 	    Race_game_over();
1181 	} else if (BIT(World.rules->mode, TEAM_PLAY)) {
1182 	    Team_game_over(-1, "");
1183 	} else if (BIT(World.rules->mode, LIMITED_LIVES)) {
1184 	    Individual_game_over(-1);
1185 	}
1186     }
1187 
1188     /* if the next round is delayed, delay it again */
1189     if (round_delay > 0 || NumPlayers == 1) {
1190 	round_delay = roundDelaySeconds * FPS;
1191 	if (maxRoundTime > 0 && roundDelaySeconds == 0) {
1192 	    roundtime = maxRoundTime * FPS;
1193 	} else {
1194 	    roundtime = -1;
1195 	}
1196 	sprintf(msg, "Player entered. Delaying %d seconds until next %s.",
1197 		roundDelaySeconds, (BIT(World.rules->mode, TIMING) ?
1198 			     "race" : "round"));
1199 	Set_message(msg);
1200     }
1201 
1202     return 0;
1203 }
1204 
1205 /*
1206  * Process a client packet.
1207  * The client may be in one of several states,
1208  * therefore we use function dispatch tables for easy processing.
1209  * Some functions may process requests from clients being
1210  * in different states.
1211  */
Handle_input(int fd,void * arg)1212 static void Handle_input(int fd, void *arg)
1213 {
1214     int			ind = (int) arg;
1215     connection_t	*connp = &Conn[ind];
1216     int			type,
1217 			result,
1218 			(**receive_tbl)(int ind);
1219 
1220     if (connp->state & (CONN_PLAYING | CONN_READY)) {
1221 	receive_tbl = &playing_receive[0];
1222     }
1223     else if (connp->state == CONN_LOGIN) {
1224 	receive_tbl = &login_receive[0];
1225     }
1226     else if (connp->state & (CONN_DRAIN | CONN_SETUP)) {
1227 	receive_tbl = &drain_receive[0];
1228     }
1229     else if (connp->state == CONN_LISTENING) {
1230 	Handle_listening(ind);
1231 	return;
1232     } else {
1233 	if (connp->state != CONN_FREE) {
1234 	    Destroy_connection(ind, "not input");
1235 	}
1236 	return;
1237     }
1238     connp->num_keyboard_updates = 0;
1239 
1240     Sockbuf_clear(&connp->r);
1241     if (Sockbuf_read(&connp->r) == -1) {
1242 	Destroy_connection(ind, "input error");
1243 	return;
1244     }
1245     if (connp->r.len <= 0) {
1246 	/*
1247 	 * No input.
1248 	 */
1249 	return;
1250     }
1251     while (connp->r.ptr < connp->r.buf + connp->r.len) {
1252 	type = (connp->r.ptr[0] & 0xFF);
1253 	result = (*receive_tbl[type])(ind);
1254 	if (result == -1) {
1255 	    /*
1256 	     * Unrecoverable error.
1257 	     * Connection has been destroyed.
1258 	     */
1259 	    return;
1260 	}
1261 	if (result == 0) {
1262 	    /*
1263 	     * Incomplete client packet.
1264 	     * Drop rest of packet.
1265 	     */
1266 	    Sockbuf_clear(&connp->r);
1267 	    break;
1268 	}
1269 	if (connp->state == CONN_PLAYING) {
1270 	    connp->start = main_loops;
1271 	}
1272     }
1273 }
1274 
Input(void)1275 int Input(void)
1276 {
1277     int			i,
1278 			ind,
1279 			num_reliable = 0,
1280 			input_reliable[MAX_SELECT_FD];
1281     connection_t	*connp;
1282     char		msg[MSG_LEN];
1283 
1284     for (i = 0; i < max_connections; i++) {
1285 	connp = &Conn[i];
1286 	if (connp->state == CONN_FREE) {
1287 	    continue;
1288 	}
1289 	if (connp->start + connp->timeout * FPS < main_loops) {
1290 	    /*
1291 	     * Timeout this fellow if we have not heard a single thing
1292 	     * from him for a long time.
1293 	     */
1294 	    if (connp->state & (CONN_PLAYING | CONN_READY)) {
1295 		sprintf(msg, "%s mysteriously disappeared!?", connp->nick);
1296 		Set_message(msg);
1297 	    }
1298 	    sprintf(msg, "timeout %02x", connp->state);
1299 	    Destroy_connection(i, msg);
1300 	    continue;
1301 	}
1302 	if (connp->state != CONN_PLAYING) {
1303 	    input_reliable[num_reliable++] = i;
1304 	    if (connp->state == CONN_SETUP) {
1305 		Handle_setup(i);
1306 		continue;
1307 	    }
1308 	}
1309     }
1310 
1311     for (i = 0; i < num_reliable; i++) {
1312 	ind = input_reliable[i];
1313 	connp = &Conn[ind];
1314 	if (connp->state & (CONN_DRAIN | CONN_READY | CONN_SETUP
1315 			    | CONN_LOGIN)) {
1316 	    if (connp->c.len > 0) {
1317 		if (Send_reliable(ind) == -1) {
1318 		    continue;
1319 		}
1320 	    }
1321 	}
1322     }
1323 
1324     if (num_logins | num_logouts) {
1325 	/* Tell the meta server */
1326 	Meta_update(1);
1327 	num_logins = 0;
1328 	num_logouts = 0;
1329     }
1330 
1331     return login_in_progress;
1332 }
1333 
1334 /*
1335  * Send a reply to a special client request.
1336  * Not used consistently everywhere.
1337  * It could be used to setup some form of reliable
1338  * communication from the client to the server.
1339  */
Send_reply(int ind,int replyto,int result)1340 int Send_reply(int ind, int replyto, int result)
1341 {
1342     connection_t	*connp = &Conn[ind];
1343     int			n;
1344 
1345     n = Packet_printf(&connp->c, "%c%c%c", PKT_REPLY, replyto, result);
1346     if (n == -1) {
1347 	Destroy_connection(ind, "write error");
1348 	return -1;
1349     }
1350     return n;
1351 }
1352 
Send_modifiers(int ind,char * mods)1353 static int Send_modifiers(int ind, char *mods)
1354 {
1355     return Packet_printf(&Conn[ind].w, "%c%s", PKT_MODIFIERS, mods);
1356 }
1357 
1358 /*
1359  * Send items.
1360  * The advantage of this scheme is that it only uses bytes for items
1361  * which the player actually owns.  This reduces the packet size.
1362  * Another advantage is that here it doesn't matter if an old client
1363  * receives counts for items it doesn't know about.
1364  * This is new since pack version 4203.
1365  */
Send_self_items(int ind,player * pl)1366 static int Send_self_items(int ind, player *pl)
1367 {
1368     connection_t	*connp = &Conn[ind];
1369     unsigned		item_mask = 0;
1370     int			i, n;
1371     int			item_count = 0;
1372 
1373     /* older clients should have the items sent as part of the self packet. */
1374     if (connp->version < 0x4203) {
1375 	return 1;
1376     }
1377     /* build mask with one bit for each item type which the player owns. */
1378     for (i = 0; i < NUM_ITEMS; i++) {
1379 	if (pl->item[i] > 0) {
1380 	    item_mask |= (1 << i);
1381 	    item_count++;
1382 	}
1383     }
1384     /* don't send anything if there are no items. */
1385     if (item_count == 0) {
1386 	return 1;
1387     }
1388     /* check if enough buffer space is available for the complete packet. */
1389     if (connp->w.size - connp->w.len <= 5 + item_count) {
1390 	return 0;
1391     }
1392     /* build the header. */
1393     n = Packet_printf(&connp->w, "%c%u", PKT_SELF_ITEMS, item_mask);
1394     if (n <= 0) {
1395 	return n;
1396     }
1397     /* build rest of packet containing the per item counts. */
1398     for (i = 0; i < NUM_ITEMS; i++) {
1399 	if (item_mask & (1 << i)) {
1400 	    connp->w.buf[connp->w.len++] = pl->item[i];
1401 	}
1402     }
1403     /* return the number of bytes added to the packet. */
1404     return 5 + item_count;
1405 }
1406 
1407 /*
1408  * Send all frame data related to the player self and his HUD.
1409  */
Send_self(int ind,player * pl,int lock_id,int lock_dist,int lock_dir,int autopilotlight,long status,char * mods)1410 int Send_self(int ind,
1411 	      player *pl,
1412 	      int lock_id,
1413 	      int lock_dist,
1414 	      int lock_dir,
1415 	      int autopilotlight,
1416 	      long status,
1417 	      char *mods)
1418 {
1419     connection_t	*connp = &Conn[ind];
1420     int			n;
1421     u_byte		stat = (u_byte)status;
1422     int			sbuf_len = connp->w.len;
1423 
1424     if (connp->version >= 0x4203) {
1425 	n = Packet_printf(&connp->w,
1426 			  "%c"
1427 			  "%hd%hd%hd%hd%c"
1428 			  "%c%c%c"
1429 			  "%hd%hd%c%c"
1430 			  "%c%hd%hd"
1431 			  "%hd%hd%c"
1432 			  "%c%c"
1433 			  ,
1434 			  PKT_SELF,
1435 			  (int) (pl->pos.x + 0.5), (int) (pl->pos.y + 0.5),
1436 			  (int) pl->vel.x, (int) pl->vel.y,
1437 			  pl->dir,
1438 			  (int) (pl->power + 0.5),
1439 			  (int) (pl->turnspeed + 0.5),
1440 			  (int) (pl->turnresistance * 255.0 + 0.5),
1441 			  lock_id, lock_dist, lock_dir,
1442 			  pl->check,
1443 
1444 			  pl->fuel.current,
1445 			  pl->fuel.sum >> FUEL_SCALE_BITS,
1446 			  pl->fuel.max >> FUEL_SCALE_BITS,
1447 
1448 			  connp->view_width, connp->view_height,
1449 			  connp->debris_colors,
1450 
1451 			  stat,
1452 			  autopilotlight
1453 
1454 			  );
1455 	if (n <= 0) {
1456 	    return n;
1457 	}
1458 	n = Send_self_items(ind, pl);
1459 	if (n <= 0) {
1460 	    return n;
1461 	}
1462 	return Send_modifiers(ind, mods);
1463     }
1464 
1465     n = Packet_printf(&connp->w,
1466 		      "%c"
1467 		      "%hd%hd%hd%hd%c"
1468 		      "%c%c%c"
1469 		      "%hd%hd%c%c"
1470 		      "%c%c%c%c%c"
1471 		      "%c%c%c%c%c"
1472 		      "%c%c%c%c"
1473 		      "%c%hd%hd"
1474 		      "%hd%hd%c"
1475 		      "%c%c"
1476 		      ,
1477 		      PKT_SELF,
1478 		      (int) (pl->pos.x + 0.5), (int) (pl->pos.y + 0.5),
1479 		      (int) pl->vel.x, (int) pl->vel.y,
1480 		      pl->dir,
1481 		      (int) (pl->power + 0.5),
1482 		      (int) (pl->turnspeed + 0.5),
1483 		      (int) (pl->turnresistance * 255.0 + 0.5),
1484 		      lock_id, lock_dist, lock_dir,
1485 		      pl->check,
1486 
1487 		      pl->item[ITEM_CLOAK],
1488 		      pl->item[ITEM_SENSOR],
1489 		      pl->item[ITEM_MINE],
1490 		      pl->item[ITEM_MISSILE],
1491 		      pl->item[ITEM_ECM],
1492 
1493 		      pl->item[ITEM_TRANSPORTER],
1494 		      pl->item[ITEM_WIDEANGLE],
1495 		      pl->item[ITEM_REARSHOT],
1496 		      pl->item[ITEM_AFTERBURNER],
1497 		      pl->fuel.num_tanks,
1498 
1499 		      pl->item[ITEM_LASER],
1500 		      pl->item[ITEM_EMERGENCY_THRUST],
1501 		      pl->item[ITEM_TRACTOR_BEAM],
1502 		      pl->item[ITEM_AUTOPILOT],
1503 
1504 		      pl->fuel.current,
1505 		      pl->fuel.sum >> FUEL_SCALE_BITS,
1506 		      pl->fuel.max >> FUEL_SCALE_BITS,
1507 
1508 		      connp->view_width, connp->view_height,
1509 		      connp->debris_colors,
1510 
1511 		      stat,
1512 		      autopilotlight
1513 
1514 		      );
1515     if (n <= 0) {
1516 	return n;
1517     }
1518     if (connp->version >= 0x3800) {
1519 	n = Packet_printf(&connp->w,
1520 			  "%c%c%c%c",	/* %c", */
1521 			  pl->item[ITEM_EMERGENCY_SHIELD],
1522 			  pl->item[ITEM_DEFLECTOR],
1523 			  pl->item[ITEM_HYPERJUMP],
1524 			  pl->item[ITEM_PHASING] /* ,
1525 			  pl->item[ITEM_MIRROR] */
1526 			  );
1527 	if (n <= 0) {
1528 	    connp->w.len = sbuf_len;
1529 	    return n;
1530 	}
1531 	if (connp->version >= 0x4100) {
1532 	    n = Packet_printf(&connp->w,
1533 			      "%c",
1534 			      pl->item[ITEM_MIRROR]
1535 			      );
1536 	    if (n <= 0) {
1537 		connp->w.len = sbuf_len;
1538 		return n;
1539 	    }
1540 	    if (connp->version >= 0x4201) {
1541 		n = Packet_printf(&connp->w,
1542 				  "%c",
1543 				  pl->item[ITEM_ARMOR]
1544 				  );
1545 		if (n <= 0) {
1546 		    connp->w.len = sbuf_len;
1547 		    return n;
1548 		}
1549 	    }
1550 	}
1551     }
1552     else if (connp->version >= 0x3200) {
1553 	n = Packet_printf(&connp->w,
1554 			  "%c",
1555 			  pl->item[ITEM_EMERGENCY_SHIELD]);
1556 	if (n <= 0) {
1557 	    connp->w.len = sbuf_len;
1558 	    return n;
1559 	}
1560     }
1561 
1562     return Send_modifiers(ind, mods);
1563 }
1564 
1565 /*
1566  * Somebody is leaving the game.
1567  */
Send_leave(int ind,int id)1568 int Send_leave(int ind, int id)
1569 {
1570     connection_t	*connp = &Conn[ind];
1571 
1572     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1573 	errno = 0;
1574 	error("Connection not ready for leave info (%d,%d)",
1575 	      connp->state, connp->id);
1576 	return 0;
1577     }
1578     return Packet_printf(&connp->c, "%c%hd", PKT_LEAVE, id);
1579 }
1580 
1581 /*
1582  * Somebody is declaring war.
1583  */
Send_war(int ind,int robot_id,int killer_id)1584 int Send_war(int ind, int robot_id, int killer_id)
1585 {
1586     connection_t	*connp = &Conn[ind];
1587 
1588     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1589 	errno = 0;
1590 	error("Connection not ready for war declaration (%d,%d,%d)",
1591 	      ind, connp->state, connp->id);
1592 	return 0;
1593     }
1594     return Packet_printf(&connp->c, "%c%hd%hd", PKT_WAR,
1595 			 robot_id, killer_id);
1596 }
1597 
1598 /*
1599  * Somebody is programming a robot to seek some player.
1600  */
Send_seek(int ind,int programmer_id,int robot_id,int sought_id)1601 int Send_seek(int ind, int programmer_id, int robot_id, int sought_id)
1602 {
1603     connection_t	*connp = &Conn[ind];
1604 
1605     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1606 	errno = 0;
1607 	error("Connection not ready for seek declaration (%d,%d,%d)",
1608 	      ind, connp->state, connp->id);
1609 	return 0;
1610     }
1611     return Packet_printf(&connp->c, "%c%hd%hd%hd", PKT_SEEK,
1612 			 programmer_id, robot_id, sought_id);
1613 }
1614 
1615 /*
1616  * Somebody is joining the game.
1617  */
Send_player(int ind,int id)1618 int Send_player(int ind, int id)
1619 {
1620     connection_t	*connp = &Conn[ind];
1621     player		*pl = Players[GetInd[id]];
1622     int			n;
1623     char		buf[MSG_LEN], ext[MSG_LEN];
1624     int			sbuf_len = connp->c.len;
1625 
1626     if (!BIT(connp->state, CONN_PLAYING|CONN_READY)) {
1627 	errno = 0;
1628 	error("Connection not ready for player info (%d,%d)",
1629 	      connp->state, connp->id);
1630 	return 0;
1631     }
1632     Convert_ship_2_string(pl->ship, buf, ext,
1633 			  (connp->version < 0x3200) ? 0x3100 : 0x3200);
1634     n = Packet_printf(&connp->c,
1635 		      "%c%hd" "%c%c" "%s%s%s" "%S",
1636 		      PKT_PLAYER, pl->id,
1637 		      pl->team, pl->mychar,
1638 		      pl->name, pl->realname, pl->hostname,
1639 		      buf);
1640     if (connp->version > 0x3200) {
1641 	if (n > 0) {
1642 	    n = Packet_printf(&connp->c, "%S", ext);
1643 	    if (n <= 0) {
1644 		connp->c.len = sbuf_len;
1645 	    }
1646 	}
1647     }
1648     return n;
1649 }
1650 
1651 /*
1652  * Send the new score for some player to a client.
1653  */
Send_score(int ind,int id,DFLOAT score,int life,int mychar,int alliance)1654 int Send_score(int ind, int id, DFLOAT score,
1655 	       int life, int mychar, int alliance)
1656 {
1657     connection_t	*connp = &Conn[ind];
1658 
1659     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1660 	errno = 0;
1661 	error("Connection not ready for score(%d,%d)",
1662 	    connp->state, connp->id);
1663 	return 0;
1664     }
1665     if (connp->version < 0x4500) {
1666 	/* older clients don't get alliance info or decimals of the score */
1667 	return Packet_printf(&connp->c, "%c%hd%hd%hd%c", PKT_SCORE,
1668 			     id, (int)(score + (score > 0 ? 0.5 : -0.5)),
1669 			     life, mychar);
1670     } else {
1671 	int allchar = ' ';
1672 	if (alliance != ALLIANCE_NOT_SET) {
1673 	    if (announceAlliances) {
1674 		allchar = alliance + '0';
1675 	    } else {
1676 		if (Players[GetInd[connp->id]]->alliance == alliance)
1677 		    allchar = '+';
1678 	    }
1679 	}
1680 	return Packet_printf(&connp->c, "%c%hd%d%hd%c%c", PKT_SCORE, id,
1681 			     (int)(score * 100 + (score > 0 ? 0.5 : -0.5)),
1682 			     life, mychar, allchar);
1683     }
1684 }
1685 
1686 /*
1687  * Send the new score for some team to a client.
1688  */
Send_team_score(int ind,int team,DFLOAT score)1689 int Send_team_score(int ind, int team, DFLOAT score)
1690 {
1691     connection_t	*connp = &Conn[ind];
1692 
1693     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1694 	errno = 0;
1695 	error("Connection not ready for team score(%d,%d)",
1696 	      connp->state, connp->id);
1697 	return 0;
1698     }
1699     if (connp->version < 0x4500) {
1700 	/* older clients don't know about team scores */
1701 	return 0;
1702     }
1703     return Packet_printf(&connp->c, "%c%hd%d", PKT_TEAM_SCORE,
1704 		         team, (int)(score * 100 + (score > 0 ? 0.5 : -0.5)));
1705 }
1706 
1707 /*
1708  * Send the new race info for some player to a client.
1709  */
Send_timing(int ind,int id,int check,int round)1710 int Send_timing(int ind, int id, int check, int round)
1711 {
1712     connection_t	*connp = &Conn[ind];
1713 
1714     if (connp->version < 0x3261) {
1715 	return 1;
1716     }
1717     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1718 	errno = 0;
1719 	error("Connection not ready for timing(%d,%d)",
1720 	      connp->state, connp->id);
1721 	return 0;
1722     }
1723     return Packet_printf(&connp->c, "%c%hd%hu", PKT_TIMING,
1724 			 id, round * MAX_CHECKS + check);
1725 }
1726 
1727 /*
1728  * Send info about a player having which base.
1729  */
Send_base(int ind,int id,int num)1730 int Send_base(int ind, int id, int num)
1731 {
1732     connection_t	*connp = &Conn[ind];
1733 
1734     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1735 	errno = 0;
1736 	error("Connection not ready for base info (%d,%d)",
1737 	    connp->state, connp->id);
1738 	return 0;
1739     }
1740     return Packet_printf(&connp->c, "%c%hd%hu", PKT_BASE, id, num);
1741 }
1742 
1743 /*
1744  * Send the amount of fuel in a fuelstation.
1745  */
Send_fuel(int ind,int num,int fuel)1746 int Send_fuel(int ind, int num, int fuel)
1747 {
1748     return Packet_printf(&Conn[ind].w, "%c%hu%hu", PKT_FUEL,
1749 			 num, fuel >> FUEL_SCALE_BITS);
1750 }
1751 
Send_score_object(int ind,DFLOAT score,int x,int y,const char * string)1752 int Send_score_object(int ind, DFLOAT score, int x, int y, const char *string)
1753 {
1754     connection_t	*connp = &Conn[ind];
1755 
1756     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
1757 	errno = 0;
1758 	error("Connection not ready for base info (%d,%d)",
1759 	    connp->state, connp->id);
1760 	return 0;
1761     }
1762     if (connp->version < 0x4500) {
1763 	/* older clients don't get decimals of the score */
1764 	return Packet_printf(&Conn[ind].c, "%c%hd%hu%hu%s",PKT_SCORE_OBJECT,
1765 			     (int)(score + (score > 0 ? 0.5 : -0.5)),
1766 			     x, y, string);
1767     } else {
1768 	return Packet_printf(&Conn[ind].c, "%c%d%hu%hu%s",PKT_SCORE_OBJECT,
1769 			     (int)(score * 100 + (score > 0 ? 0.5 : -0.5)),
1770 			     x, y, string);
1771     }
1772 }
1773 
Send_cannon(int ind,int num,int dead_time)1774 int Send_cannon(int ind, int num, int dead_time)
1775 {
1776     return Packet_printf(&Conn[ind].w, "%c%hu%hu", PKT_CANNON,
1777 	num, dead_time);
1778 }
1779 
Send_destruct(int ind,int count)1780 int Send_destruct(int ind, int count)
1781 {
1782     return Packet_printf(&Conn[ind].w, "%c%hd", PKT_DESTRUCT, count);
1783 }
1784 
Send_shutdown(int ind,int count,int delay)1785 int Send_shutdown(int ind, int count, int delay)
1786 {
1787     return Packet_printf(&Conn[ind].w, "%c%hd%hd", PKT_SHUTDOWN,
1788 	count, delay);
1789 }
1790 
Send_thrusttime(int ind,int count,int max)1791 int Send_thrusttime(int ind, int count, int max)
1792 {
1793     return Packet_printf(&Conn[ind].w, "%c%hd%hd", PKT_THRUSTTIME, count, max);
1794 }
1795 
Send_shieldtime(int ind,int count,int max)1796 int Send_shieldtime(int ind, int count, int max)
1797 {
1798     if (Conn[ind].version < 0x3200) {
1799 	return 1;
1800     }
1801     return Packet_printf(&Conn[ind].w, "%c%hd%hd", PKT_SHIELDTIME, count, max);
1802 }
1803 
Send_phasingtime(int ind,int count,int max)1804 int Send_phasingtime(int ind, int count, int max)
1805 {
1806     if (Conn[ind].version < 0x3800) {
1807 	return 1;
1808     }
1809     return Packet_printf(&Conn[ind].w, "%c%hd%hd", PKT_PHASINGTIME, count, max);
1810 }
1811 
Send_rounddelay(int ind,int count,int max)1812 int Send_rounddelay(int ind, int count, int max)
1813 {
1814     if (Conn[ind].version < 0x3800) {
1815 	return 1;
1816     }
1817     return(Packet_printf(&Conn[ind].w, "%c%hd%hd", PKT_ROUNDDELAY, count, max));
1818 }
1819 
Send_debris(int ind,int type,unsigned char * p,int n)1820 int Send_debris(int ind, int type, unsigned char *p, int n)
1821 {
1822     int			avail;
1823     sockbuf_t		*w = &Conn[ind].w;
1824 
1825     if ((n & 0xFF) != n) {
1826 	errno = 0;
1827 	error("Bad number of debris %d", n);
1828 	return 0;
1829     }
1830     avail = w->size - w->len - SOCKBUF_WRITE_SPARE - 2;
1831     if (n * 2 >= avail) {
1832 	if (avail > 2) {
1833 	    n = (avail - 1) / 2;
1834 	} else {
1835 	    return 0;
1836 	}
1837     }
1838     w->buf[w->len++] = PKT_DEBRIS + type;
1839     w->buf[w->len++] = n;
1840     memcpy(&w->buf[w->len], p, n * 2);
1841     w->len += n * 2;
1842 
1843     return n;
1844 }
1845 
Send_wreckage(int ind,int x,int y,u_byte wrtype,u_byte size,u_byte rot)1846 int Send_wreckage(int ind, int x, int y, u_byte wrtype, u_byte size, u_byte rot)
1847 {
1848     if (Conn[ind].version < 0x3800) {
1849 	return 1;
1850     }
1851 
1852     if (wreckageCollisionMayKill && Conn[ind].version > 0x4201) {
1853 	/* Set the highest bit when wreckage is deadly. */
1854 	wrtype |= 0x80;
1855     } else {
1856 	wrtype &= ~0x80;
1857     }
1858 
1859     return Packet_printf(&Conn[ind].w, "%c%hd%hd%c%c%c", PKT_WRECKAGE,
1860 			 x, y, wrtype, size, rot);
1861 }
1862 
Send_asteroid(int ind,int x,int y,u_byte type,u_byte size,u_byte rot)1863 int Send_asteroid(int ind, int x, int y, u_byte type, u_byte size, u_byte rot)
1864 {
1865     u_byte	type_size;
1866 
1867     if (Conn[ind].version < 0x4400) {
1868 	return Send_ecm(ind, x, y, 2 * (int) ASTEROID_RADIUS(size));
1869     }
1870 
1871     type_size = ((type & 0x0F) << 4) | (size & 0x0F);
1872 
1873     return Packet_printf(&Conn[ind].w, "%c%hd%hd%c%c", PKT_ASTEROID,
1874 		         x, y, type_size, rot);
1875 }
1876 
Send_fastshot(int ind,int type,unsigned char * p,int n)1877 int Send_fastshot(int ind, int type, unsigned char *p, int n)
1878 {
1879     int			avail;
1880     sockbuf_t		*w = &Conn[ind].w;
1881 
1882     if ((n & 0xFF) != n) {
1883 	errno = 0;
1884 	error("Bad number of fastshot %d", n);
1885 	return 0;
1886     }
1887     avail = w->size - w->len - SOCKBUF_WRITE_SPARE - 3;
1888     if (n * 2 >= avail) {
1889 	if (avail > 2) {
1890 	    n = (avail - 1) / 2;
1891 	} else {
1892 	    return 0;
1893 	}
1894     }
1895     w->buf[w->len++] = PKT_FASTSHOT;
1896     w->buf[w->len++] = type;
1897     w->buf[w->len++] = n;
1898     memcpy(&w->buf[w->len], p, n * 2);
1899     w->len += n * 2;
1900 
1901     return n;
1902 }
1903 
Send_missile(int ind,int x,int y,int len,int dir)1904 int Send_missile(int ind, int x, int y, int len, int dir)
1905 {
1906     return Packet_printf(&Conn[ind].w, "%c%hd%hd%c%c",
1907 			 PKT_MISSILE, x, y, len, dir);
1908 }
1909 
Send_ball(int ind,int x,int y,int id)1910 int Send_ball(int ind, int x, int y, int id)
1911 {
1912     return Packet_printf(&Conn[ind].w, "%c%hd%hd%hd", PKT_BALL, x, y, id);
1913 }
1914 
Send_mine(int ind,int x,int y,int teammine,int id)1915 int Send_mine(int ind, int x, int y, int teammine, int id)
1916 {
1917     connection_t	*connp = &Conn[ind];
1918 
1919     return Packet_printf(&connp->w, "%c%hd%hd%c%hd", PKT_MINE, x, y,
1920 			 teammine, id);
1921 }
1922 
Send_target(int ind,int num,int dead_time,int damage)1923 int Send_target(int ind, int num, int dead_time, int damage)
1924 {
1925     return Packet_printf(&Conn[ind].w, "%c%hu%hu%hu", PKT_TARGET,
1926 			 num, dead_time, damage);
1927 }
1928 
Send_wormhole(int ind,int x,int y)1929 int Send_wormhole(int ind, int x, int y)
1930 {
1931     if (Conn[ind].version < 0x4501) {
1932 	const int wormStep = 5;
1933 	int wormAngle = (frame_loops & 7) * (RES / 8);
1934 
1935 	return Send_ecm(ind,
1936 			x,
1937 			y,
1938 			BLOCK_SZ - 2) +
1939 	       Send_ecm(ind,
1940 			(int) (x + wormStep * tcos(wormAngle)),
1941 			(int) (y + wormStep * tsin(wormAngle)),
1942 			BLOCK_SZ - 2 - 2 * wormStep) +
1943 	       Send_ecm(ind,
1944 			(int) (x + 2 * wormStep * tcos(wormAngle)),
1945 			(int) (y + 2 * wormStep * tsin(wormAngle)),
1946 			BLOCK_SZ - 2 - 4 * wormStep);
1947     }
1948     return Packet_printf(&Conn[ind].w, "%c%hd%hd", PKT_WORMHOLE, x, y);
1949 }
1950 
Send_item(int ind,int x,int y,int type)1951 int Send_item(int ind, int x, int y, int type)
1952 {
1953     if (type >= ITEM_EMERGENCY_SHIELD) {
1954 	if (Conn[ind].version < 0x3200) {
1955 	    return 1;
1956 	}
1957     }
1958     return Packet_printf(&Conn[ind].w, "%c%hd%hd%c", PKT_ITEM, x, y, type);
1959 }
1960 
Send_paused(int ind,int x,int y,int count)1961 int Send_paused(int ind, int x, int y, int count)
1962 {
1963     return Packet_printf(&Conn[ind].w, "%c%hd%hd%hd", PKT_PAUSED, x, y, count);
1964 }
1965 
Send_ecm(int ind,int x,int y,int size)1966 int Send_ecm(int ind, int x, int y, int size)
1967 {
1968     return Packet_printf(&Conn[ind].w, "%c%hd%hd%hd", PKT_ECM, x, y, size);
1969 }
1970 
Send_trans(int ind,int x1,int y1,int x2,int y2)1971 int Send_trans(int ind, int x1, int y1, int x2, int y2)
1972 {
1973     return Packet_printf(&Conn[ind].w,"%c%hd%hd%hd%hd",
1974 			 PKT_TRANS, x1, y1, x2, y2);
1975 }
1976 
Send_ship(int ind,int x,int y,int id,int dir,int shield,int cloak,int emergency_shield,int phased,int deflector)1977 int Send_ship(int ind, int x, int y, int id, int dir,
1978 	      int shield, int cloak, int emergency_shield, int phased, int deflector)
1979 {
1980     if (Conn[ind].version < 0x4300) {
1981 	/* cloaking bit was also true if phased and that was used
1982 	 * to determine how to draw the ship.
1983 	 */
1984 	cloak = (cloak || phased);
1985     }
1986     return Packet_printf(&Conn[ind].w,
1987 			 "%c%hd%hd%hd" "%c" "%c",
1988 			 PKT_SHIP, x, y, id,
1989 			 dir,
1990 			 (shield != 0)
1991 				| ((cloak != 0) << 1)
1992 			    | ((emergency_shield != 0) << 2)
1993 				| ((phased != 0) << 3)		/* clients older than 3.8.0 will ignore this */
1994 				| ((deflector != 0) << 4)	/* clients older than 3.8.0 will ignore this */
1995 			);
1996 }
1997 
Send_refuel(int ind,int x0,int y0,int x1,int y1)1998 int Send_refuel(int ind, int x0, int y0, int x1, int y1)
1999 {
2000     return Packet_printf(&Conn[ind].w,
2001 			 "%c%hd%hd%hd%hd",
2002 			 PKT_REFUEL, x0, y0, x1, y1);
2003 }
2004 
Send_connector(int ind,int x0,int y0,int x1,int y1,int tractor)2005 int Send_connector(int ind, int x0, int y0, int x1, int y1, int tractor)
2006 {
2007     connection_t *connp = &Conn[ind];
2008 
2009     return Packet_printf(&connp->w,
2010 			 "%c%hd%hd%hd%hd%c",
2011 			 PKT_CONNECTOR, x0, y0, x1, y1, tractor);
2012 }
2013 
Send_laser(int ind,int color,int x,int y,int len,int dir)2014 int Send_laser(int ind, int color, int x, int y, int len, int dir)
2015 {
2016     connection_t *connp = &Conn[ind];
2017 
2018     return Packet_printf(&connp->w, "%c%c%hd%hd%hd%c", PKT_LASER,
2019 			 color, x, y, len, dir);
2020 }
2021 
Send_radar(int ind,int x,int y,int size)2022 int Send_radar(int ind, int x, int y, int size)
2023 {
2024     connection_t *connp = &Conn[ind];
2025 
2026     /* Only since 4.2.1 can clients correctly handle teammates in green. */
2027     /* Except the original patch from kth.se was 4.1.0 "experimental 1" */
2028     if (connp->version < 0x4210 && connp->version != 0x4101) {
2029 	size &= ~0x80;
2030     }
2031     return Packet_printf(&connp->w, "%c%hd%hd%c", PKT_RADAR, x, y, size);
2032 }
2033 
Send_fastradar(int ind,unsigned char * buf,int n)2034 int Send_fastradar(int ind, unsigned char *buf, int n)
2035 {
2036     int			avail;
2037     sockbuf_t		*w = &Conn[ind].w;
2038 
2039     if ((n & 0xFF) != n) {
2040 	errno = 0;
2041 	error("Bad number of fastradar %d", n);
2042 	return 0;
2043     }
2044     avail = w->size - w->len - SOCKBUF_WRITE_SPARE - 3;
2045     if (n * 3 >= avail) {
2046 	if (avail > 3) {
2047 	    n = (avail - 2) / 3;
2048 	} else {
2049 	    return 0;
2050 	}
2051     }
2052     w->buf[w->len++] = PKT_FASTRADAR;
2053     w->buf[w->len++] = (unsigned char)(n & 0xFF);
2054     memcpy(&w->buf[w->len], buf, n * 3);
2055     w->len += n * 3;
2056 
2057     return (2 + (n * 3));
2058 }
2059 
Send_damaged(int ind,int damaged)2060 int Send_damaged(int ind, int damaged)
2061 {
2062     return Packet_printf(&Conn[ind].w, "%c%c", PKT_DAMAGED, damaged);
2063 }
2064 
Send_audio(int ind,int type,int vol)2065 int Send_audio(int ind, int type, int vol)
2066 {
2067     connection_t *connp = &Conn[ind];
2068 
2069     if (connp->w.size - connp->w.len <= 32) {
2070 	return 0;
2071     }
2072     return Packet_printf(&connp->w, "%c%c%c", PKT_AUDIO, type, vol);
2073 }
2074 
Send_time_left(int ind,long sec)2075 int Send_time_left(int ind, long sec)
2076 {
2077     connection_t *connp = &Conn[ind];
2078 
2079     return Packet_printf(&connp->w, "%c%ld", PKT_TIME_LEFT, sec);
2080 }
2081 
Send_eyes(int ind,int id)2082 int Send_eyes(int ind, int id)
2083 {
2084     connection_t *connp = &Conn[ind];
2085 
2086     return Packet_printf(&connp->w, "%c%hd", PKT_EYES, id);
2087 }
2088 
Send_message(int ind,const char * msg)2089 int Send_message(int ind, const char *msg)
2090 {
2091     connection_t	*connp = &Conn[ind];
2092 
2093     if (!BIT(connp->state, CONN_PLAYING | CONN_READY)) {
2094 	errno = 0;
2095 	error("Connection not ready for message (%d,%d)",
2096 	    connp->state, connp->id);
2097 	return 0;
2098     }
2099     return Packet_printf(&connp->c, "%c%S", PKT_MESSAGE, msg);
2100 }
2101 
Send_loseitem(int lose_item_index,int ind)2102 int Send_loseitem(int lose_item_index, int ind)
2103 {
2104     if (Conn[ind].version < 0x3400) { /* this should never hit since */
2105 				      /* only a 3.4+ client would send */
2106 				      /* the loseitem key */
2107 	return 1;
2108     }
2109     return Packet_printf(&Conn[ind].w, "%c%c", PKT_LOSEITEM, lose_item_index);
2110 }
2111 
Send_start_of_frame(int ind)2112 int Send_start_of_frame(int ind)
2113 {
2114     connection_t	*connp = &Conn[ind];
2115 
2116     if (connp->state != CONN_PLAYING) {
2117 	if (connp->state != CONN_READY) {
2118 	    errno = 0;
2119 	    error("Connection not ready for frame (%d,%d)",
2120 		connp->state, connp->id);
2121 	}
2122 	return -1;
2123     }
2124     /*
2125      * We tell the client which frame number this is and
2126      * which keyboard update we have last received.
2127      */
2128     Sockbuf_clear(&connp->w);
2129     if (Packet_printf(&connp->w,
2130 		      "%c%ld%ld",
2131 		      PKT_START, frame_loops, connp->last_key_change) <= 0) {
2132 	Destroy_connection(ind, "write error");
2133 	return -1;
2134     }
2135 
2136     /* Return ok */
2137     return 0;
2138 }
2139 
Send_end_of_frame(int ind)2140 int Send_end_of_frame(int ind)
2141 {
2142     connection_t	*connp = &Conn[ind];
2143     int			n;
2144 
2145     last_packet_of_frame = 1;
2146     n = Packet_printf(&connp->w, "%c%ld", PKT_END, frame_loops);
2147     last_packet_of_frame = 0;
2148     if (n == -1) {
2149 	Destroy_connection(ind, "write error");
2150 	return -1;
2151     }
2152     if (n == 0) {
2153 	/*
2154 	 * Frame update size exceeded buffer size.
2155 	 * Drop this packet.
2156 	 */
2157 	Sockbuf_clear(&connp->w);
2158 	return 0;
2159     }
2160     while (connp->motd_offset >= 0
2161 	&& connp->c.len + connp->w.len < MAX_RELIABLE_DATA_PACKET_SIZE) {
2162 	Send_motd(ind);
2163     }
2164     if (connp->c.len > 0 && connp->w.len < MAX_RELIABLE_DATA_PACKET_SIZE) {
2165 	if (Send_reliable(ind) == -1) {
2166 	    return -1;
2167 	}
2168 	if (connp->w.len == 0) {
2169 	    return 1;
2170 	}
2171     }
2172     if (Sockbuf_flush(&connp->w) == -1) {
2173 	Destroy_connection(ind, "flush error");
2174 	return -1;
2175     }
2176     Sockbuf_clear(&connp->w);
2177     return 0;
2178 }
2179 
Receive_keyboard(int ind)2180 static int Receive_keyboard(int ind)
2181 {
2182     connection_t	*connp = &Conn[ind];
2183     player		*pl;
2184     long		change;
2185     u_byte		ch;
2186     int			size = KEYBOARD_SIZE;
2187 
2188     if (connp->version < 0x3800) {
2189 	/* older servers have a keyboard_size of 8 bytes instead of 9. */
2190 	size--;
2191     }
2192     if (connp->r.ptr - connp->r.buf + size + 1 + 4 > connp->r.len) {
2193 	/*
2194 	 * Incomplete client packet.
2195 	 */
2196 	return 0;
2197     }
2198     Packet_scanf(&connp->r, "%c%ld", &ch, &change);
2199     if (change <= connp->last_key_change) {
2200 	/*
2201 	 * We already have this key.
2202 	 * Nothing to do.
2203 	 */
2204 	connp->r.ptr += size;
2205     }
2206     else {
2207 	connp->last_key_change = change;
2208 	pl = Players[GetInd[connp->id]];
2209 	memcpy(pl->last_keyv, connp->r.ptr, size);
2210 	connp->r.ptr += size;
2211 	Handle_keyboard(GetInd[connp->id]);
2212     }
2213     if (connp->num_keyboard_updates++ && (connp->state & CONN_PLAYING)) {
2214 	Destroy_connection(ind, "no macros");
2215 	return -1;
2216     }
2217 
2218     return 1;
2219 }
2220 
Receive_quit(int ind)2221 static int Receive_quit(int ind)
2222 {
2223     Destroy_connection(ind, "client quit");
2224 
2225     return -1;
2226 }
2227 
Receive_play(int ind)2228 static int Receive_play(int ind)
2229 {
2230     connection_t	*connp = &Conn[ind];
2231     unsigned char	ch;
2232     int			n;
2233     char		errmsg[MAX_CHARS];
2234 
2235     if ((n = Packet_scanf(&connp->r, "%c", &ch)) != 1) {
2236 	errno = 0;
2237 	error("Cannot receive play packet");
2238 	Destroy_connection(ind, "receive error");
2239 	return -1;
2240     }
2241     if (ch != PKT_PLAY) {
2242 	errno = 0;
2243 	error("Packet is not of play type");
2244 	Destroy_connection(ind, "not play");
2245 	return -1;
2246     }
2247     if (connp->state != CONN_LOGIN) {
2248 	if (connp->state != CONN_PLAYING) {
2249 	    if (connp->state == CONN_READY) {
2250 		connp->r.ptr = connp->r.buf + connp->r.len;
2251 		return 0;
2252 	    }
2253 	    errno = 0;
2254 	    error("Connection not in login state (%02x)", connp->state);
2255 	    Destroy_connection(ind, "not login");
2256 	    return -1;
2257 	}
2258 	if (Send_reliable(ind) == -1) {
2259 	    return -1;
2260 	}
2261 	return 0;
2262     }
2263     Sockbuf_clear(&connp->w);
2264     strlcpy(errmsg, "login failed", sizeof(errmsg));
2265     if (Handle_login(ind, errmsg, sizeof(errmsg)) == -1) {
2266 	Destroy_connection(ind, errmsg);
2267 	return -1;
2268     }
2269 
2270     return 2;
2271 }
2272 
Receive_power(int ind)2273 static int Receive_power(int ind)
2274 {
2275     connection_t	*connp = &Conn[ind];
2276     player		*pl;
2277     unsigned char	ch;
2278     short		tmp;
2279     int			n;
2280     DFLOAT		power;
2281     int			autopilot;
2282 
2283     if ((n = Packet_scanf(&connp->r, "%c%hd", &ch, &tmp)) <= 0) {
2284 	if (n == -1) {
2285 	    Destroy_connection(ind, "read error");
2286 	}
2287 	return n;
2288     }
2289     power = (DFLOAT) tmp / 256.0F;
2290     pl = Players[GetInd[connp->id]];
2291     autopilot = BIT(pl->used, HAS_AUTOPILOT);
2292     /* old client are going to send autopilot-mangled data, ignore it */
2293     if (autopilot && pl->version < 0x4200)
2294 	return 1;
2295 
2296     switch (ch) {
2297     case PKT_POWER:
2298 	if (autopilot)
2299 	    pl->auto_power_s = power;
2300 	else
2301 	    pl->power = power;
2302 	break;
2303     case PKT_POWER_S:
2304 	pl->power_s = power;
2305 	break;
2306     case PKT_TURNSPEED:
2307 	if (autopilot)
2308 	    pl->auto_turnspeed_s = power;
2309 	else
2310 	    pl->turnspeed = power;
2311 	break;
2312     case PKT_TURNSPEED_S:
2313 	pl->turnspeed_s = power;
2314 	break;
2315     case PKT_TURNRESISTANCE:
2316 	if (autopilot)
2317 	    pl->auto_turnresistance_s = power;
2318 	else
2319 	    pl->turnresistance = power;
2320 	break;
2321     case PKT_TURNRESISTANCE_S:
2322 	pl->turnresistance_s = power;
2323 	break;
2324     default:
2325 	errno = 0;
2326 	error("Not a power packet (%d,%02x)", ch, connp->state);
2327 	Destroy_connection(ind, "not power");
2328 	return -1;
2329     }
2330     return 1;
2331 }
2332 
2333 /*
2334  * Send the reliable data.
2335  * If the client is in the receive-frame-updates state then
2336  * all reliable data is piggybacked at the end of the
2337  * frame update packets.  (Except maybe for the MOTD data, which
2338  * could be transmitted in its own packets since MOTDs can be big.)
2339  * Otherwise if the client is not actively playing yet then
2340  * the reliable data is sent in its own packets since there
2341  * is no other data to combine it with.
2342  *
2343  * This thing still is not finished, but it works better than in 3.0.0 I hope.
2344  */
Send_reliable(int ind)2345 int Send_reliable(int ind)
2346 {
2347     connection_t	*connp = &Conn[ind];
2348     char		*read_buf;
2349     int			i,
2350 			n,
2351 			len,
2352 			todo,
2353 			max_todo;
2354     long		rel_off;
2355     const int		max_packet_size = MAX_RELIABLE_DATA_PACKET_SIZE,
2356 			min_send_size = 1;  /* was 4 in 3.0.7, 1 in 3.1.0 */
2357 
2358     if (connp->c.len <= 0
2359 	|| connp->last_send_loops == main_loops) {
2360 	connp->last_send_loops = main_loops;
2361 	return 0;
2362     }
2363     read_buf = connp->c.buf;
2364     max_todo = connp->c.len;
2365     rel_off = connp->reliable_offset;
2366     if (connp->w.len > 0) {
2367 	/* We are piggybacking on a frame update. */
2368 	if (connp->w.len >= max_packet_size - min_send_size) {
2369 	    /* Frame already too big */
2370 	    return 0;
2371 	}
2372 	if (max_todo > max_packet_size - connp->w.len) {
2373 	    /* Do not exceed minimum fragment size. */
2374 	    max_todo = max_packet_size - connp->w.len;
2375 	}
2376     }
2377     if (connp->retransmit_at_loop > main_loops) {
2378 	/*
2379 	 * It is no time to retransmit yet.
2380 	 */
2381 	if (max_todo <= connp->reliable_unsent - connp->reliable_offset
2382 			+ min_send_size
2383 	    || connp->w.len == 0) {
2384 	    /*
2385 	     * And we cannot send anything new either
2386 	     * and we do not want to introduce a new packet.
2387 	     */
2388 	    return 0;
2389 	}
2390     }
2391     else if (connp->retransmit_at_loop != 0) {
2392 	/*
2393 	 * Timeout.
2394 	 * Either our packet or the acknowledgement got lost,
2395 	 * so retransmit.
2396 	 */
2397 	connp->acks >>= 1;
2398     }
2399 
2400     todo = max_todo;
2401     for (i = 0; i <= connp->acks && todo > 0; i++) {
2402 	len = (todo > max_packet_size) ? max_packet_size : todo;
2403 	if (Packet_printf(&connp->w, "%c%hd%ld%ld", PKT_RELIABLE,
2404 			  len, rel_off, main_loops) <= 0
2405 	    || Sockbuf_write(&connp->w, read_buf, len) != len) {
2406 	    error("Cannot write reliable data");
2407 	    Destroy_connection(ind, "write error");
2408 	    return -1;
2409 	}
2410 	if ((n = Sockbuf_flush(&connp->w)) < len) {
2411 	    if (n == 0
2412 		&& (errno == EWOULDBLOCK
2413 		    || errno == EAGAIN)) {
2414 		connp->acks = 0;
2415 		break;
2416 	    } else {
2417 		error("Cannot flush reliable data (%d)", n);
2418 		Destroy_connection(ind, "flush error");
2419 		return -1;
2420 	    }
2421 	}
2422 	todo -= len;
2423 	rel_off += len;
2424 	read_buf += len;
2425     }
2426 
2427     /*
2428      * Drop rest of outgoing data packet if something remains at all.
2429      */
2430     Sockbuf_clear(&connp->w);
2431 
2432     connp->last_send_loops = main_loops;
2433 
2434     if (max_todo - todo <= 0) {
2435 	/*
2436 	 * We have not transmitted anything at all.
2437 	 */
2438 	return 0;
2439     }
2440 
2441     /*
2442      * Retransmission timer with exponential backoff.
2443      */
2444     if (connp->rtt_retransmit > MAX_RETRANSMIT) {
2445 	connp->rtt_retransmit = MAX_RETRANSMIT;
2446     }
2447     if (connp->retransmit_at_loop <= main_loops) {
2448 	connp->retransmit_at_loop = main_loops + connp->rtt_retransmit;
2449 	connp->rtt_retransmit <<= 1;
2450 	connp->rtt_timeouts++;
2451     } else {
2452 	connp->retransmit_at_loop = main_loops + connp->rtt_retransmit;
2453     }
2454 
2455     if (rel_off > connp->reliable_unsent) {
2456 	connp->reliable_unsent = rel_off;
2457     }
2458 
2459     return (max_todo - todo);
2460 }
2461 
Receive_ack(int ind)2462 static int Receive_ack(int ind)
2463 {
2464     connection_t	*connp = &Conn[ind];
2465     int			n;
2466     unsigned char	ch;
2467     long		rel,
2468 			rtt,	/* RoundTrip Time */
2469 			diff,
2470 			delta,
2471 			rel_loops;
2472 
2473     if ((n = Packet_scanf(&connp->r, "%c%ld%ld",
2474 			  &ch, &rel, &rel_loops)) <= 0) {
2475 	errno = 0;
2476 	error("Cannot read ack packet (%d)", n);
2477 	Destroy_connection(ind, "read error");
2478 	return -1;
2479     }
2480     if (ch != PKT_ACK) {
2481 	errno = 0;
2482 	error("Not an ack packet (%d)", ch);
2483 	Destroy_connection(ind, "not ack");
2484 	return -1;
2485     }
2486     rtt = main_loops - rel_loops;
2487     if (rtt > 0 && rtt <= MAX_RTT) {
2488 	/*
2489 	 * These roundtrip estimation calculations are derived from Comer's
2490 	 * books "Internetworking with TCP/IP" parts I & II.
2491 	 */
2492 	if (connp->rtt_smoothed == 0) {
2493 	    /*
2494 	     * Initialize the rtt estimator by this first measurement.
2495 	     * The estimator is scaled by 3 bits.
2496 	     */
2497 	    connp->rtt_smoothed = rtt << 3;
2498 	}
2499 	/*
2500 	 * Scale the estimator back by 3 bits before calculating the error.
2501 	 */
2502 	delta = rtt - (connp->rtt_smoothed >> 3);
2503 	/*
2504 	 * Add one eigth of the error to the estimator.
2505 	 */
2506 	connp->rtt_smoothed += delta;
2507 	/*
2508 	 * Now we need the absolute value of the error.
2509 	 */
2510 	if (delta < 0) {
2511 	    delta = -delta;
2512 	}
2513 	/*
2514 	 * The rtt deviation is scaled by 2 bits.
2515 	 * Now we add one fourth of the difference between the
2516 	 * error and the previous deviation to the deviation.
2517 	 */
2518 	connp->rtt_dev += delta - (connp->rtt_dev >> 2);
2519 	/*
2520 	 * The calculation of the retransmission timeout is what this is
2521 	 * all about.  We take the smoothed rtt plus twice the deviation
2522 	 * as the next retransmission timeout to use.  Because of the
2523 	 * scaling used we get the following statement:
2524 	 */
2525 	connp->rtt_retransmit = ((connp->rtt_smoothed >> 2)
2526 	    + connp->rtt_dev) >> 1;
2527 	/*
2528 	 * Now keep it within reasonable bounds.
2529 	 */
2530 	if (connp->rtt_retransmit < MIN_RETRANSMIT) {
2531 	    connp->rtt_retransmit = MIN_RETRANSMIT;
2532 	}
2533     }
2534     diff = rel - connp->reliable_offset;
2535     if (diff > connp->c.len) {
2536 	/* Impossible to ack data that has not been send */
2537 	errno = 0;
2538 	error("Bad ack (diff=%ld,cru=%ld,c=%ld,len=%d)",
2539 	    diff, rel, connp->reliable_offset, connp->c.len);
2540 	Destroy_connection(ind, "bad ack");
2541 	return -1;
2542     }
2543     else if (diff <= 0) {
2544 	/* Late or duplicate ack of old data.  Discard. */
2545 	return 1;
2546     }
2547     Sockbuf_advance(&connp->c, (int) diff);
2548     connp->reliable_offset += diff;
2549     if ((n = ((diff + 512 - 1) / 512)) > connp->acks) {
2550 	connp->acks = n;
2551     }
2552     else {
2553 	connp->acks++;
2554     }
2555     if (connp->reliable_offset >= connp->reliable_unsent) {
2556 	/*
2557 	 * All reliable data has been sent and acked.
2558 	 */
2559 	connp->retransmit_at_loop = 0;
2560 	if (connp->state == CONN_DRAIN) {
2561 	    Conn_set_state(connp, connp->drain_state, connp->drain_state);
2562 	}
2563     }
2564     if (connp->state == CONN_READY
2565 	&& (connp->c.len <= 0
2566 	    || (connp->c.buf[0] != PKT_REPLY
2567 		&& connp->c.buf[0] != PKT_PLAY
2568 		&& connp->c.buf[0] != PKT_SUCCESS
2569 		&& connp->c.buf[0] != PKT_FAILURE))) {
2570 	Conn_set_state(connp, connp->drain_state, connp->drain_state);
2571     }
2572     connp->rtt_timeouts = 0;
2573 
2574     return 1;
2575 }
2576 
Receive_discard(int ind)2577 static int Receive_discard(int ind)
2578 {
2579     connection_t	*connp = &Conn[ind];
2580 
2581     errno = 0;
2582     error("Discarding packet %d while in state %02x",
2583 	  connp->r.ptr[0], connp->state);
2584     connp->r.ptr = connp->r.buf + connp->r.len;
2585 
2586     return 0;
2587 }
2588 
Receive_undefined(int ind)2589 static int Receive_undefined(int ind)
2590 {
2591     connection_t	*connp = &Conn[ind];
2592 
2593     errno = 0;
2594     error("Unknown packet type (%d,%02x)", connp->r.ptr[0], connp->state);
2595     Destroy_connection(ind, "undefined packet");
2596     return -1;
2597 }
2598 
Receive_ack_cannon(int ind)2599 static int Receive_ack_cannon(int ind)
2600 {
2601     connection_t	*connp = &Conn[ind];
2602     long		loops_ack;
2603     unsigned char	ch;
2604     int			n;
2605     unsigned short	num;
2606 
2607     if ((n = Packet_scanf(&connp->r, "%c%ld%hu",
2608 			  &ch, &loops_ack, &num)) <= 0) {
2609 	if (n == -1) {
2610 	    Destroy_connection(ind, "read error");
2611 	}
2612 	return n;
2613     }
2614     if (num >= World.NumCannons) {
2615 	Destroy_connection(ind, "bad cannon ack");
2616 	return -1;
2617     }
2618     if (loops_ack > World.cannon[num].last_change) {
2619 	SET_BIT(World.cannon[num].conn_mask, 1 << ind);
2620     }
2621     return 1;
2622 }
2623 
Receive_ack_fuel(int ind)2624 static int Receive_ack_fuel(int ind)
2625 {
2626     connection_t	*connp = &Conn[ind];
2627     long		loops_ack;
2628     unsigned char	ch;
2629     int			n;
2630     unsigned short	num;
2631 
2632     if ((n = Packet_scanf(&connp->r, "%c%ld%hu",
2633 			  &ch, &loops_ack, &num)) <= 0) {
2634 	if (n == -1) {
2635 	    Destroy_connection(ind, "read error");
2636 	}
2637 	return n;
2638     }
2639     if (num >= World.NumFuels) {
2640 	Destroy_connection(ind, "bad fuel ack");
2641 	return -1;
2642     }
2643     if (loops_ack > World.fuel[num].last_change) {
2644 	SET_BIT(World.fuel[num].conn_mask, 1 << ind);
2645     }
2646     return 1;
2647 }
2648 
Receive_ack_target(int ind)2649 static int Receive_ack_target(int ind)
2650 {
2651     connection_t	*connp = &Conn[ind];
2652     long		loops_ack;
2653     unsigned char	ch;
2654     int			n;
2655     unsigned short	num;
2656 
2657     if ((n = Packet_scanf(&connp->r, "%c%ld%hu",
2658 			  &ch, &loops_ack, &num)) <= 0) {
2659 	if (n == -1) {
2660 	    Destroy_connection(ind, "read error");
2661 	}
2662 	return n;
2663     }
2664     if (num >= World.NumTargets) {
2665 	Destroy_connection(ind, "bad target ack");
2666 	return -1;
2667     }
2668     /*
2669      * Because the "loops" value as received by the client as part
2670      * of a frame update is 1 higher than the actual change to the
2671      * target in collision.c a valid map object change
2672      * acknowledgement must be at least 1 higher.
2673      * That's why we should use the '>' symbol to compare
2674      * and not the '>=' symbol.
2675      * The same applies to cannon and fuelstation updates.
2676      * This fix was discovered for 3.2.7, previously some
2677      * destroyed targets could have been displayed with
2678      * a diagonal cross through them.
2679      */
2680     if (loops_ack > World.targets[num].last_change) {
2681 	SET_BIT(World.targets[num].conn_mask, 1 << ind);
2682 	CLR_BIT(World.targets[num].update_mask, 1 << ind);
2683     }
2684     return 1;
2685 }
2686 
2687 /*
2688  * If a message contains a colon then everything before that colon is
2689  * either a unique player name prefix, or a team number with players.
2690  * If the string does not match one team or one player the message is not sent.
2691  * If no colon, the message is general.
2692  */
Handle_talk(int ind,char * str)2693 static void Handle_talk(int ind, char *str)
2694 {
2695     connection_t	*connp = &Conn[ind];
2696     player		*pl = Players[GetInd[connp->id]];
2697     int			i, sent, team;
2698 	unsigned int	len;
2699     char		*cp,
2700 			msg[MSG_LEN * 2];
2701 
2702     if ((cp = strchr (str, ':')) == NULL
2703 	|| cp == str
2704 	|| strchr("-_~)(/\\}{[]", cp[1])	/* smileys are smileys */
2705 	) {
2706 	sprintf(msg, "%s [%s]", str, pl->name);
2707 	Set_message(msg);
2708 	return;
2709     }
2710     *cp++ = '\0';
2711     len = strlen (str);
2712     sprintf(msg, "%s [%s]", cp, pl->name);
2713 
2714     if (strspn(str, "0123456789") == len) {		/* Team message */
2715 	team = atoi (str);
2716 	sprintf(msg + strlen(msg), ":[%d]", team);
2717 	for (sent = i = 0; i < NumPlayers; i++) {
2718 	    if (Players[i]->team != TEAM_NOT_SET && Players[i]->team == team) {
2719 		sent++;
2720 		Set_player_message (Players[i], msg);
2721 	    }
2722 	}
2723 	if (sent) {
2724 	    if (pl->team != team)
2725 		Set_player_message (pl, msg);
2726 	} else {
2727 	    sprintf(msg, "Message not sent, nobody in team %d!",
2728 		    team);
2729 	    Set_player_message(pl, msg);
2730 	}
2731     }
2732     else if (strcasecmp(str, "god") == 0) {
2733 	Server_log_admin_message(GetInd[connp->id], cp);
2734     }
2735     else {						/* Player message */
2736 	sent = -1;
2737 	/* first look for an exact match on player nickname. */
2738 	for (i = 0; i < NumPlayers; i++) {
2739 	    if (strcasecmp(Players[i]->name, str) == 0) {
2740 		sent = i;
2741 		break;
2742 	    }
2743 	}
2744 	if (sent == -1) {
2745 	    /* now look for a partial match on both nick and realname. */
2746 	    for (sent = -1, i = 0; i < NumPlayers; i++) {
2747 		if (strncasecmp(Players[i]->name, str, len) == 0
2748 		    || strncasecmp(Players[i]->realname, str, len) == 0)
2749 		    sent = (sent == -1) ? i : -2;
2750 	    }
2751 	}
2752 	switch (sent) {
2753 	case -2:
2754 	    sprintf(msg, "Message not sent, %s matches more than one player!",
2755 		    str);
2756 	    Set_player_message(pl, msg);
2757 	    break;
2758 	case -1:
2759 	    sprintf(msg, "Message not sent, %s does not match any player!",
2760 		    str);
2761 	    Set_player_message(pl, msg);
2762 	    break;
2763 	default:
2764 	    if (Players[sent] != pl) {
2765 		sprintf(msg + strlen(msg), ":[%s]", Players[sent]->name);
2766 		Set_player_message(Players[sent], msg);
2767 		Set_player_message(pl, msg);
2768 	    }
2769 	    break;
2770 	}
2771     }
2772 }
2773 
Receive_talk(int ind)2774 static int Receive_talk(int ind)
2775 {
2776     connection_t	*connp = &Conn[ind];
2777     unsigned char	ch;
2778     int			n;
2779     long		seq;
2780     char		str[MAX_CHARS];
2781 
2782     if ((n = Packet_scanf(&connp->r, "%c%ld%s", &ch, &seq, str)) <= 0) {
2783 	if (n == -1) {
2784 	    Destroy_connection(ind, "read error");
2785 	}
2786 	return n;
2787     }
2788     if (seq > connp->talk_sequence_num) {
2789 	if ((n = Packet_printf(&connp->c, "%c%ld", PKT_TALK_ACK, seq)) <= 0) {
2790 	    if (n == -1) {
2791 		Destroy_connection(ind, "write error");
2792 	    }
2793 	    return n;
2794 	}
2795 	connp->talk_sequence_num = seq;
2796 	if (*str == '/') {
2797 	    Handle_player_command(Players[GetInd[connp->id]], str + 1);
2798 	}
2799 	else {
2800 	    Handle_talk(ind, str);
2801 	}
2802     }
2803     return 1;
2804 }
2805 
Receive_display(int ind)2806 static int Receive_display(int ind)
2807 {
2808     connection_t	*connp = &Conn[ind];
2809     unsigned char	ch, debris_colors, spark_rand;
2810     short		width, height;
2811     int			n;
2812 
2813     if ((n = Packet_scanf(&connp->r, "%c%hd%hd%c%c", &ch, &width, &height,
2814 			  &debris_colors, &spark_rand)) <= 0) {
2815 	if (n == -1) {
2816 	    Destroy_connection(ind, "read error");
2817 	}
2818 	return n;
2819     }
2820     LIMIT(width, MIN_VIEW_SIZE, MAX_VIEW_SIZE);
2821     LIMIT(height, MIN_VIEW_SIZE, MAX_VIEW_SIZE);
2822     connp->view_width = width;
2823     connp->view_height = height;
2824     connp->debris_colors = debris_colors;
2825     connp->spark_rand = spark_rand;
2826     return 1;
2827 }
2828 
str2num(char ** strp,int min,int max)2829 static int str2num (char **strp, int min, int max)
2830 {
2831     char *str = *strp;
2832     int num = 0;
2833 
2834     while (isdigit(*str)) {
2835 	num *= 10;
2836 	num += *str++ - '0';
2837     }
2838     *strp = str;
2839     if (num < min || num > max)
2840 	return min;
2841     return num;
2842 }
2843 
Receive_modifier_bank(int ind)2844 static int Receive_modifier_bank(int ind)
2845 {
2846     connection_t	*connp = &Conn[ind];
2847     player		*pl;
2848     unsigned char	bank;
2849     char		str[MAX_CHARS];
2850     unsigned char	ch;
2851     char		*cp;
2852     modifiers		mods;
2853     int			n;
2854 
2855     if ((n = Packet_scanf(&connp->r, "%c%c%s", &ch, &bank, str)) <= 0) {
2856 	if (n == -1) {
2857 	    Destroy_connection(ind, "read modbank");
2858 	}
2859 	return n;
2860     }
2861     pl = Players[GetInd[connp->id]];
2862     if (bank < NUM_MODBANKS) {
2863 	CLEAR_MODS(mods);
2864 	if (BIT(World.rules->mode, ALLOW_MODIFIERS)) {
2865 	    for (cp = str; *cp; cp++) {
2866 		switch (*cp) {
2867 		case 'F': case 'f':
2868 		    if (!BIT(World.rules->mode, ALLOW_NUKES))
2869 			break;
2870 		    if (*(cp+1) == 'N' || *(cp+1) == 'n')
2871 			SET_BIT(mods.nuclear, FULLNUCLEAR);
2872 		    break;
2873 		case 'N': case 'n':
2874 		    if (!BIT(World.rules->mode, ALLOW_NUKES))
2875 			break;
2876 		    SET_BIT(mods.nuclear, NUCLEAR);
2877 		    break;
2878 		case 'C': case 'c':
2879 		    if (!BIT(World.rules->mode, ALLOW_CLUSTERS))
2880 			break;
2881 		    SET_BIT(mods.warhead, CLUSTER);
2882 		    break;
2883 		case 'I': case 'i':
2884 		    SET_BIT(mods.warhead, IMPLOSION);
2885 		    break;
2886 		case 'V': case 'v':
2887 		    cp++; mods.velocity = str2num (&cp, 0, MODS_VELOCITY_MAX);
2888 		    cp--;
2889 		    break;
2890 		case 'X': case 'x':
2891 		    cp++; mods.mini = str2num (&cp, 1, MODS_MINI_MAX+1) - 1;
2892 		    cp--;
2893 		    break;
2894 		case 'Z': case 'z':
2895 		    cp++; mods.spread = str2num (&cp, 0, MODS_SPREAD_MAX);
2896 		    cp--;
2897 		    break;
2898 		case 'B': case 'b':
2899 		    cp++; mods.power = str2num (&cp, 0, MODS_POWER_MAX);
2900 		    cp--;
2901 		    break;
2902 		case 'L': case 'l':
2903 		    cp++;
2904 		    if (!BIT(World.rules->mode, ALLOW_LASER_MODIFIERS))
2905 			break;
2906 		    if (*cp == 'S' || *cp == 's')
2907 			SET_BIT(mods.laser, STUN);
2908 		    if (*cp == 'B' || *cp == 'b')
2909 			SET_BIT(mods.laser, BLIND);
2910 		    break;
2911 		}
2912 	    }
2913 	}
2914 	pl->modbank[bank] = mods;
2915     }
2916     return 1;
2917 }
2918 
Get_display_parameters(int ind,int * width,int * height,int * debris_colors,int * spark_rand)2919 void Get_display_parameters(int ind, int *width, int *height,
2920 			    int *debris_colors, int *spark_rand)
2921 {
2922     connection_t	*connp = &Conn[ind];
2923 
2924     *width = connp->view_width;
2925     *height = connp->view_height;
2926     *debris_colors = connp->debris_colors;
2927     *spark_rand = connp->spark_rand;
2928 }
2929 
Get_player_id(int ind)2930 int Get_player_id(int ind)
2931 {
2932     connection_t	*connp = &Conn[ind];
2933 
2934     return connp->id;
2935 }
2936 
Get_conn_version(int ind)2937 int Get_conn_version(int ind)
2938 {
2939     connection_t	*connp = &Conn[ind];
2940 
2941     return connp->version;
2942 }
2943 
Get_player_addr(int ind)2944 const char *Get_player_addr(int ind)
2945 {
2946     connection_t	*connp = &Conn[ind];
2947 
2948     return connp->addr;
2949 }
2950 
Get_player_dpy(int ind)2951 const char *Get_player_dpy(int ind)
2952 {
2953     connection_t	*connp = &Conn[ind];
2954 
2955     return connp->dpy;
2956 }
2957 
Receive_shape(int ind)2958 static int Receive_shape(int ind)
2959 {
2960     connection_t	*connp = &Conn[ind];
2961     int			n;
2962     char		ch;
2963     char		str[2*MSG_LEN];
2964 
2965     if ((n = Packet_scanf(&connp->r, "%c%S", &ch, str)) <= 0) {
2966 	if (n == -1) {
2967 	    Destroy_connection(ind, "read shape");
2968 	}
2969 	return n;
2970     }
2971     if (connp->version > 0x3200) {
2972 	if ((n = Packet_scanf(&connp->r, "%S", &str[strlen(str)])) <= 0) {
2973 	    if (n == -1) {
2974 		Destroy_connection(ind, "read shape ext");
2975 	    }
2976 	    return n;
2977 	}
2978     }
2979     if (connp->state == CONN_LOGIN && connp->ship == NULL) {
2980 	connp->ship = Parse_shape_str(str);
2981     }
2982     return 1;
2983 }
2984 
Receive_motd(int ind)2985 static int Receive_motd(int ind)
2986 {
2987     connection_t	*connp = &Conn[ind];
2988     unsigned char	ch;
2989     long		offset;
2990     int			n;
2991     long		bytes;
2992 
2993     if ((n = Packet_scanf(&connp->r,
2994 			  "%c%ld%ld",
2995 			  &ch, &offset, &bytes)) <= 0) {
2996 	if (n == -1) {
2997 	    Destroy_connection(ind, "read error");
2998 	}
2999 	return n;
3000     }
3001     connp->motd_offset = offset;
3002     connp->motd_stop = offset + bytes;
3003 
3004     return 1;
3005 }
3006 
3007 /*
3008  * Return part of the MOTD into buf starting from offset
3009  * and continueing at most for maxlen bytes.
3010  * Return the total MOTD size in size_ptr.
3011  * The return value is the actual amount of MOTD bytes copied
3012  * or -1 on error.  A value of 0 means EndOfMOTD.
3013  *
3014  * The MOTD is completely read into a dynamic buffer.
3015  * If this MOTD buffer hasn't been accessed for a while
3016  * then on the next access the MOTD file is checked for changes.
3017  */
3018 #ifdef _WINDOWS
3019 #define	close(__a)	_close(__a)
3020 #endif
Get_motd(char * buf,int offset,int maxlen,int * size_ptr)3021 int Get_motd(char *buf, int offset, int maxlen, int *size_ptr)
3022 {
3023     static int		motd_size;
3024     static char		*motd_buf;
3025     static long		motd_loops;
3026     static time_t	motd_mtime;
3027 
3028     if (size_ptr) {
3029 	*size_ptr = 0;
3030     }
3031     if (offset < 0 || maxlen < 0) {
3032 	return -1;
3033     }
3034 
3035     if (!motd_loops
3036 	|| (motd_loops + MAX_MOTD_LOOPS < main_loops
3037 	    && offset == 0)) {
3038 
3039 	int			fd, size;
3040 	struct stat		st;
3041 
3042 	motd_loops = main_loops;
3043 
3044 	if ((fd = open(motdFileName, O_RDONLY)) == -1) {
3045 	    motd_size = 0;
3046 	    return -1;
3047 	}
3048 	if (fstat(fd, &st) == -1 || st.st_size == 0) {
3049 	    motd_size = 0;
3050 	    close(fd);
3051 	    return -1;
3052 	}
3053 	size = st.st_size;
3054 	if (size > MAX_MOTD_SIZE) {
3055 	    size = MAX_MOTD_SIZE;
3056 	}
3057 	if (size != motd_size) {
3058 	    motd_mtime = 0;
3059 	    motd_size = size;
3060 	    if (motd_size == 0) {
3061 		close(fd);
3062 		return 0;
3063 	    }
3064 	    if (motd_buf) {
3065 		free(motd_buf);
3066 	    }
3067 	    if ((motd_buf = (char *) malloc(size)) == NULL) {
3068 		close(fd);
3069 		return -1;
3070 	    }
3071 	}
3072 	if (motd_mtime != st.st_mtime) {
3073 	    motd_mtime = st.st_mtime;
3074 	    if ((size = read(fd, motd_buf, motd_size)) <= 0) {
3075 		free(motd_buf);
3076 		motd_buf = 0;
3077 		close(fd);
3078 		motd_size = 0;
3079 		return -1;
3080 	    }
3081 	    motd_size = size;
3082 	}
3083 	close(fd);
3084     }
3085 
3086     motd_loops = main_loops;
3087 
3088     if (size_ptr) {
3089 	*size_ptr = motd_size;
3090     }
3091     if (offset + maxlen > motd_size) {
3092 	maxlen = motd_size - offset;
3093     }
3094     if (maxlen <= 0) {
3095 	return 0;
3096     }
3097     memcpy(buf, motd_buf + offset, maxlen);
3098     return maxlen;
3099 }
3100 
3101 /*
3102  * Send the server MOTD to the client.
3103  * The last time we send a motd packet it should
3104  * have datalength zero to mean EOMOTD.
3105  */
Send_motd(int ind)3106 static int Send_motd(int ind)
3107 {
3108     connection_t	*connp = &Conn[ind];
3109     int			len;
3110     int			off = connp->motd_offset,
3111 			size = 0;
3112     char		buf[MAX_MOTD_CHUNK];
3113 
3114     len = MIN(MAX_MOTD_CHUNK, MAX_RELIABLE_DATA_PACKET_SIZE - connp->c.len - 10);
3115     if (len >= 10) {
3116 	len = Get_motd(buf, off, len, &size);
3117 	if (len <= 0) {
3118 	    len = 0;
3119 	    connp->motd_offset = -1;
3120 	}
3121 	if (Packet_printf(&connp->c,
3122 			  "%c%ld%hd%ld",
3123 			  PKT_MOTD, off, len, size) <= 0) {
3124 	    Destroy_connection(ind, "motd header");
3125 	    return -1;
3126 	}
3127 	if (len > 0) {
3128 	    connp->motd_offset += len;
3129 	    if (Sockbuf_write(&connp->c, buf, len) != len) {
3130 		Destroy_connection(ind, "motd data");
3131 		return -1;
3132 	    }
3133 	}
3134     }
3135 
3136     /* Return ok */
3137     return 1;
3138 }
3139 
Receive_pointer_move(int ind)3140 static int Receive_pointer_move(int ind)
3141 {
3142     connection_t	*connp = &Conn[ind];
3143     player		*pl;
3144     unsigned char	ch;
3145     short		movement;
3146     int			n;
3147     DFLOAT		turnspeed, turndir;
3148 
3149     if ((n = Packet_scanf(&connp->r, "%c%hd", &ch, &movement)) <= 0) {
3150 	if (n == -1) {
3151 	    Destroy_connection(ind, "read error");
3152 	}
3153 	return n;
3154     }
3155     pl = Players[GetInd[connp->id]];
3156     if (BIT(pl->status, HOVERPAUSE))
3157 	return 1;
3158 
3159     if (BIT(pl->used, HAS_AUTOPILOT))
3160 	Autopilot(GetInd[connp->id], 0);
3161     turnspeed = movement * pl->turnspeed / MAX_PLAYER_TURNSPEED;
3162     if (turnspeed < 0) {
3163 	turndir = -1.0;
3164 	turnspeed = -turnspeed;
3165     }
3166     else {
3167 	turndir = 1.0;
3168     }
3169     if (pl->turnresistance)
3170 	LIMIT(turnspeed, MIN_PLAYER_TURNSPEED, MAX_PLAYER_TURNSPEED);
3171       /* Minimum amount of turning if you want to turn at all?
3172 	And the only effect of that maximum is making
3173         finding the correct settings harder for new mouse players,
3174         because the limit is checked BEFORE multiplying by turnres!
3175         Kept here to avoid changing the feeling for old players who
3176         are already used to this odd behavior. New players should set
3177         turnresistance to 0.
3178       */
3179     else
3180 	LIMIT(turnspeed, 0, 5*RES);
3181 
3182     pl->turnvel -= turndir * turnspeed;
3183 
3184     return 1;
3185 }
3186 
Receive_fps_request(int ind)3187 static int Receive_fps_request(int ind)
3188 {
3189     connection_t	*connp = &Conn[ind];
3190     player		*pl;
3191     int			n;
3192     unsigned char	ch;
3193     unsigned char	fps;
3194 
3195     if ((n = Packet_scanf(&connp->r, "%c%c", &ch, &fps)) <= 0) {
3196 	if (n == -1) {
3197 	    Destroy_connection(ind, "read error");
3198 	}
3199 	return n;
3200     }
3201     if (connp->id != NO_ID) {
3202 	pl = Players[GetInd[connp->id]];
3203 	pl->player_fps = fps;
3204 	if (fps > FPS) pl->player_fps = FPS;
3205 	if (fps < (FPS / 2)) pl->player_fps = (FPS+1) / 2;
3206 	if (fps == 0) pl->player_fps = FPS;
3207 	if ((fps == 20) && ignore20MaxFPS) pl->player_fps = FPS;
3208 	n = FPS - pl->player_fps;
3209 	if (n <= 0) {
3210 	    pl->player_count = 0;
3211 	} else {
3212 	    pl->player_count = FPS / n;
3213 	}
3214     }
3215 
3216     return 1;
3217 }
3218 
Receive_audio_request(int ind)3219 static int Receive_audio_request(int ind)
3220 {
3221     connection_t	*connp = &Conn[ind];
3222     player		*pl;
3223     int			n;
3224     unsigned char	ch;
3225     unsigned char	onoff;
3226 
3227     if ((n = Packet_scanf(&connp->r, "%c%c", &ch, &onoff)) <= 0) {
3228 	if (n == -1) {
3229 	    Destroy_connection(ind, "read error");
3230 	}
3231 	return n;
3232     }
3233     if (connp->id != NO_ID) {
3234 	pl = Players[GetInd[connp->id]];
3235 	sound_player_onoff(pl, onoff);
3236     }
3237 
3238     return 1;
3239 }
3240 
Check_max_clients_per_IP(char * host_addr)3241 int Check_max_clients_per_IP(char *host_addr)
3242 {
3243     int			i, clients_per_ip = 0;
3244     connection_t	*connp;
3245 
3246     if (maxClientsPerIP <= 0)
3247 	return 0;
3248 
3249     for (i = 0; i < max_connections; i++) {
3250 	connp = &Conn[i];
3251 	if (connp->state != CONN_FREE && !strcasecmp(connp->addr, host_addr))
3252 	    clients_per_ip++;
3253     }
3254 
3255     if (clients_per_ip >= maxClientsPerIP)
3256 	return 1;
3257 
3258     return 0;
3259 }
3260 
3261