… | |
… | |
47 | if (destroyed ()) |
47 | if (destroyed ()) |
48 | return; |
48 | return; |
49 | |
49 | |
50 | #if HAVE_TCP_INFO |
50 | #if HAVE_TCP_INFO |
51 | // check about once per second, spread evenly over all clients |
51 | // check about once per second, spread evenly over all clients |
52 | if (!((pticks + fd) & 7)) |
52 | // do this only when player is active |
|
|
53 | if (!((pticks + fd) & 7) && pl && pl->active) |
53 | { |
54 | { |
54 | // check time of last ack, and, if too old, kill connection |
55 | // check time of last ack, and, if too old, kill connection |
55 | struct tcp_info tcpi; |
56 | struct tcp_info tcpi; |
56 | socklen_t len = sizeof (tcpi); |
57 | socklen_t len = sizeof (tcpi); |
57 | |
58 | |
58 | if (!getsockopt (fd, IPPROTO_TCP, TCP_INFO, &tcpi, &len) && len == sizeof (tcpi)) |
59 | if (!getsockopt (fd, IPPROTO_TCP, TCP_INFO, &tcpi, &len) && len == sizeof (tcpi)) |
59 | { |
60 | { |
|
|
61 | if (tcpi.tcpi_snd_mss) |
|
|
62 | mss = tcpi.tcpi_snd_mss; |
|
|
63 | |
60 | rtt = tcpi.tcpi_rtt; |
64 | rtt = tcpi.tcpi_rtt; |
61 | rttvar = tcpi.tcpi_rttvar; |
65 | rttvar = tcpi.tcpi_rttvar; |
62 | |
66 | |
63 | if (tcpi.tcpi_last_ack_recv > int (SOCKET_TIMEOUT * 1000)) |
67 | if (tcpi.tcpi_last_ack_recv > int (SOCKET_TIMEOUT * 1000)) |
64 | { |
68 | { |
… | |
… | |
81 | */ |
85 | */ |
82 | |
86 | |
83 | // write a nop to the socket at least every IDLE_NOP seconds. |
87 | // write a nop to the socket at least every IDLE_NOP seconds. |
84 | if (!outputbuffer.len) |
88 | if (!outputbuffer.len) |
85 | { |
89 | { |
86 | if (last_send + IDLE_PING <= NOW) |
90 | if (last_send + IDLE_PING <= NOW && pl && pl->active) |
87 | { |
91 | { |
88 | // this is a bit ugly, but map1/map1a seem to be the only |
92 | // this is a bit ugly, but map1/map1a seem to be the only |
89 | // nop'able commands and they are quite small. |
93 | // nop'able commands and they are quite small. |
90 | packet sl (mapmode == Map1Cmd ? "map1" : "map1a"); |
94 | packet sl (mapmode == Map1Cmd ? "map1" : "map1a"); |
91 | send_packet (sl); |
95 | send_packet (sl); |
… | |
… | |
507 | va_end (ap); |
511 | va_end (ap); |
508 | |
512 | |
509 | send_packet (sl); |
513 | send_packet (sl); |
510 | } |
514 | } |
511 | |
515 | |
512 | void |
516 | // returns true when the message needs special (read: perl) treatment |
513 | client::send_drawinfo (const char *msg, int flags) |
517 | static bool |
514 | { |
518 | msg_is_special (const char *msg) |
515 | send_packet_printf ("drawinfo %d %s", flags, msg); |
519 | { |
|
|
520 | return msg [strcspn (msg, "<[&\n")]; |
516 | } |
521 | } |
517 | |
522 | |
518 | void |
523 | void |
519 | client::send_msg (int color, const char *type, const char *msg) |
524 | client::send_msg (int color, const char *type, const char *msg) |
520 | { |
525 | { |
|
|
526 | if (msg_is_special (msg)) |
|
|
527 | cfperl_send_msg (this, color, type, msg); |
521 | if (can_msg) |
528 | else if (can_msg) |
522 | send_packet_printf ("msg %d %s %s", color, type, msg); |
529 | send_packet_printf ("msg %d %s %s", color, type, msg); |
523 | else if (color < 0) |
530 | else if (color < 0) |
524 | return; // client cannot handle this |
531 | return; // client cannot handle this |
525 | else if (strchr (msg, '<') || strchr (msg, '&')) |
|
|
526 | { |
|
|
527 | //TODO: should escape/modify to old syntax |
|
|
528 | send_packet_printf ("drawinfo %d %s", color, msg); |
|
|
529 | } |
|
|
530 | else |
532 | else |
531 | send_packet_printf ("drawinfo %d %s", color, msg); |
533 | send_packet_printf ("drawinfo %d %s", color, msg); |
|
|
534 | } |
|
|
535 | |
|
|
536 | void |
|
|
537 | client::send_drawinfo (const char *msg, int flags) |
|
|
538 | { |
|
|
539 | send_msg (flags, "log", msg); |
532 | } |
540 | } |
533 | |
541 | |
534 | /*********************************************************************** |
542 | /*********************************************************************** |
535 | * |
543 | * |
536 | * packet functions/utilities |
544 | * packet functions/utilities |