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