Freeciv-3.4
Loading...
Searching...
No Matches
connecthand.c
Go to the documentation of this file.
1/***********************************************************************
2 Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12***********************************************************************/
13
14#ifdef HAVE_CONFIG_H
15#include <fc_config.h>
16#endif
17
18#include <string.h>
19
20/* utility */
21#include "capability.h"
22#include "fcintl.h"
23#include "log.h"
24#include "mem.h"
25#include "rand.h"
26#include "support.h"
27
28/* common */
29#include "capstr.h"
30#include "events.h"
31#include "game.h"
32#include "packets.h"
33#include "player.h"
34#include "version.h"
35
36/* server */
37#include "aahand.h"
38#include "aiiface.h"
39#include "auth.h"
40#include "diplhand.h"
41#include "edithand.h"
42#include "gamehand.h"
43#include "maphand.h"
44#include "meta.h"
45#include "notify.h"
46#include "plrhand.h"
47#include "report.h"
48#include "ruleload.h"
49#include "sernet.h"
50#include "settings.h"
51#include "srv_main.h"
52#include "stdinhand.h"
53#include "voting.h"
54
55/* server/scripting */
56#include "script_fcdb.h"
57
58#include "connecthand.h"
59
60
61static bool connection_attach_real(struct connection *pconn,
62 struct player *pplayer,
63 bool observing, bool connecting);
64
65/**********************************************************************/
74 bool granted)
75{
77
78 pconn->access_level = new_level;
79 if (granted) {
80 pconn->server.granted_access_level = new_level;
81 }
82
83 /* Send updated settings only if settings control already sent.
84 * Otherwise client is not ready to receive them, AND we will send
85 * them later anyway. */
86 if (old_level != new_level && pconn->server.settings_sent) {
88 }
89}
90
91/**********************************************************************/
99{
100 /* Restore previous privileges. */
101 enum cmdlevel level = pconn->server.granted_access_level;
102
103 /* Detached connections must have at most the same privileges
104 * as observers, unless they were granted something higher than
105 * ALLOW_BASIC in the first place. */
106 if ((pconn->observer || !pconn->playing) && level == ALLOW_BASIC) {
108 }
109
111}
112
113/**********************************************************************/
132{
133 struct conn_list *dest = pconn->self;
134 struct player *pplayer;
135 struct packet_server_join_reply packet;
137 char hostname[512];
138 bool delegation_error = FALSE;
140
141 /* Zero out the password */
142 memset(pconn->server.password, 0, sizeof(pconn->server.password));
143
144 /* Send join_reply packet */
145 packet.you_can_join = TRUE;
147 fc_snprintf(packet.message, sizeof(packet.message), _("%s Welcome"),
148 pconn->username);
150 packet.conn_id = pconn->id;
152
153 /* "establish" the connection */
154 pconn->established = TRUE;
155 pconn->server.status = AS_ESTABLISHED;
156
157 pconn->server.delegation.status = FALSE;
158 pconn->server.delegation.playing = nullptr;
159 pconn->server.delegation.observer = FALSE;
160 pconn->server.settings_sent = FALSE;
161
164 /* First connection
165 * Replace "restarting in x seconds" meta message */
168 }
169
170 /* Introduce the server to the connection */
171 if (fc_gethostname(hostname, sizeof(hostname)) == 0) {
172 notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
173 _("Welcome to the %s Server running at %s port %d."),
175 } else {
176 notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
177 _("Welcome to the %s Server at port %d."),
179 }
180
181 /* FIXME: This (getting messages about others logging on) should be
182 * a message option for the client with event */
183
184 /* Notify the console that you're here. */
185 log_normal(_("%s has connected from %s."), pconn->username, pconn->addr);
186
187 if (srvarg.fcdb_enabled) {
188 script_fcdb_call("conn_established", pconn);
189 }
190
192 send_rulesets(dest);
195 send_scenario_info(dest);
197 send_game_info(dest);
198 topo_packet.topology_id = wld.map.topology_id;
199 topo_packet.wrap_id = wld.map.wrap_id;
201
202 /* Do we have a player that a delegate is currently controlling? */
203 if ((pplayer = player_by_user_delegated(pconn->username))) {
204 /* Reassert our control over the player. */
205 struct connection *pdelegate;
206
207 fc_assert_ret(player_delegation_get(pplayer) != nullptr);
209
211 /* Delegate now detached from our player. We will restore control
212 * over them as normal below. */
213 notify_conn(pconn->self, nullptr, E_CONNECTION, ftc_server,
214 _("Your delegate %s was controlling your player '%s'; "
215 "now detached."), pdelegate->username,
216 player_name(pplayer));
218 _("%s reconnected, ending your delegated control of "
219 "player '%s'."), pconn->username, player_name(pplayer));
220 } else {
222 /* This really shouldn't happen. */
223 log_error("Failed to revoke delegate %s's control of %s, so owner %s "
224 "can't regain control.", pdelegate->username,
225 player_name(pplayer), pconn->username);
226 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
227 _("Couldn't get control of '%s' from delegation to %s."),
228 player_name(pplayer), pdelegate->username);
230 pplayer = nullptr;
231 }
232 }
233
234 if (!delegation_error) {
235 if ((pplayer = player_by_user(pconn->username))
236 && connection_attach_real(pconn, pplayer, FALSE, TRUE)) {
237 /* A player has already been created for this user, reconnect */
238
239 if (S_S_INITIAL == server_state()) {
240 send_player_info_c(nullptr, dest);
241 }
242 } else {
243 int total_free_weight = 0;
244
246 if (wplayer->autoselect_weight > 0
247 && !wplayer->is_connected
249 total_free_weight += wplayer->autoselect_weight;
250 }
252
253 if (total_free_weight > 0) {
255
257 if (wplayer->autoselect_weight > 0
258 && !wplayer->is_connected
260 weight_rand -= wplayer->autoselect_weight;
261 if (weight_rand < 0) {
262 log_normal("Trying to attach %s to %s",
263 pconn->username, wplayer->name);
265 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
266 _("Couldn't attach your connection to a scenario player."));
267 log_verbose("%s is not attached to a player", pconn->username);
268 }
269 break;
270 }
271 }
273 } else if (!game_was_started()) {
274 if (connection_attach_real(pconn, nullptr, FALSE, TRUE)) {
275 pplayer = conn_get_player(pconn);
276 fc_assert(pplayer != nullptr);
277 } else {
278 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
279 _("Couldn't attach your connection to new player."));
280 log_verbose("%s is not attached to a player", pconn->username);
281 }
282 }
283 send_player_info_c(nullptr, dest);
284 }
285 }
286
288
289 if (pplayer == nullptr) {
290 /* Else this has already been done in connection_attach_real(). */
295
296 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
297 _("You are logged in as '%s' connected to no player."),
298 pconn->username);
299 } else {
300 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
301 _("You are logged in as '%s' connected to %s."),
302 pconn->username,
303 player_name(pconn->playing));
304 }
305
306 /* Send information about delegation(s). */
308
309 /* Notify the *other* established connections that you are connected, and
310 * add the info for all in event cache. Note we must to do it after we
311 * sent the pending events to pconn (from this function and also
312 * connection_attach()), otherwise pconn will receive it too. */
314 if (game.server.ip_hide) {
316 _("%s has connected (player %s)."),
317 pconn->username,
319 } else {
321 _("%s has connected from %s (player %s)."),
322 pconn->username, pconn->addr,
324 }
325 } else {
326 if (game.server.ip_hide) {
328 _("%s has connected."),
329 pconn->username);
330 } else {
332 _("%s has connected from %s."),
333 pconn->username, pconn->addr);
334 }
335 }
337 if (aconn != pconn) {
339 }
342
343 /* If need be, tell who we're waiting on to end the game.info.turn */
346 if (is_human(cplayer)
347 && !cplayer->phase_done
348 && cplayer != pconn->playing) { /* skip current player */
349 notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
350 _("Turn-blocking game play: "
351 "waiting on %s to finish turn..."),
353 }
355 }
356
357 if (game.info.is_edit_mode) {
358 notify_conn(dest, nullptr, E_SETTING, ftc_editor,
359 _(" *** Server is in edit mode. *** "));
360 }
361
362 if (pplayer != nullptr) {
363 /* Else, no need to do anything. */
366 }
367
369
371}
372
373/**********************************************************************/
376void reject_new_connection(const char *msg, struct connection *pconn)
377{
378 struct packet_server_join_reply packet;
379
380 /* Zero out the password */
381 memset(pconn->server.password, 0, sizeof(pconn->server.password));
382
383 packet.you_can_join = FALSE;
385 sz_strlcpy(packet.message, msg);
386 packet.challenge_file[0] = '\0';
387 packet.conn_id = -1;
389 log_normal(_("Client rejected: %s."), conn_description(pconn));
391}
392
393/**********************************************************************/
398 struct packet_server_join_req *req)
399{
400 char msg[MAX_LEN_MSG];
402
403 if (pconn->established || pconn->server.status != AS_NOT_ESTABLISHED) {
404 /* We read the PACKET_SERVER_JOIN_REQ twice from this connection,
405 * this is probably not a Freeciv client. */
406 return FALSE;
407 }
408
409 log_normal(_("Connection request from %s from %s"),
410 req->username, pconn->addr);
411
412 /* Print server and client capabilities to console */
413 log_normal(_("%s has client version %d.%d.%d%s"),
414 pconn->username, req->major_version, req->minor_version,
415 req->patch_version, req->version_label);
416 log_verbose("Client caps: %s", req->capability);
417 log_verbose("Server caps: %s", our_capability);
419
420 /* Make sure the server has every capability the client needs */
422 fc_snprintf(msg, sizeof(msg),
423 _("The client is missing a capability that this server needs.\n"
424 "Server version: %d.%d.%d%s Client version: %d.%d.%d%s."
425 " Upgrading may help!"),
427 req->major_version, req->minor_version,
428 req->patch_version, req->version_label);
430 log_normal(_("%s was rejected: Mismatched capabilities."),
431 req->username);
432 return FALSE;
433 }
434
435 /* Make sure the client has every capability the server needs */
437 fc_snprintf(msg, sizeof(msg),
438 _("The server is missing a capability that the client needs.\n"
439 "Server version: %d.%d.%d%s Client version: %d.%d.%d%s."
440 " Upgrading may help!"),
442 req->major_version, req->minor_version,
443 req->patch_version, req->version_label);
445 log_normal(_("%s was rejected: Mismatched capabilities."),
446 req->username);
447 return FALSE;
448 }
449
450 {
451 /* Client is compatible. That includes ability to receive server info.
452 * Send it. */
453 struct packet_server_info info;
454
458#ifdef EMERGENCY_VERSION
460#else
461 info.emerg_version = 0;
462#endif
465 }
466
468
469 /* Name-sanity check: could add more checks? */
470 if (!is_valid_username(req->username)) {
471 fc_snprintf(msg, sizeof(msg), _("Invalid username '%s'"), req->username);
473 log_normal(_("%s was rejected: Invalid name [%s]."),
474 req->username, pconn->addr);
475 return FALSE;
476 }
477
479 fc_snprintf(msg, sizeof(msg), _("You have been kicked from this server "
480 "and cannot reconnect for %d seconds."),
483 log_normal(_("%s was rejected: Connection kicked "
484 "(%d seconds remaining)."),
486 return FALSE;
487 }
488
489 /* Don't allow duplicate logins */
491 if (fc_strcasecmp(req->username, aconn->username) == 0) {
492 fc_snprintf(msg, sizeof(msg), _("'%s' already connected."),
493 req->username);
495 log_normal(_("%s was rejected: Duplicate login name [%s]."),
496 req->username, pconn->addr);
497 return FALSE;
498 }
500
501 /* Remove the ping timeout given in sernet.c:server_make_connection(). */
502 fc_assert_msg(1 == timer_list_size(pconn->server.ping_timers),
503 "Ping timer list size %d, should be 1. Have we sent "
504 "a ping to unestablished connection %s?",
505 timer_list_size(pconn->server.ping_timers),
507 timer_list_pop_front(pconn->server.ping_timers);
508
509 if (game.server.connectmsg[0] != '\0') {
510 log_debug("Sending connectmsg: %s", game.server.connectmsg);
512 }
513
514 if (srvarg.auth_enabled) {
515 return auth_user(pconn, req->username);
516 } else {
517 sz_strlcpy(pconn->username, req->username);
519 return TRUE;
520 }
521}
522
523/**********************************************************************/
532{
533 const char *desc = conn_description(pconn);
534
535 fc_assert_ret(pconn->server.is_closing);
536
537 log_normal(_("Lost connection: %s."), desc);
538
539 /* Special color (white on black) for player loss */
542 _("Lost connection: %s."), desc);
543
547
549}
550
551/**********************************************************************/
555 struct packet_conn_info *packet)
556{
557 packet->id = pconn->id;
558 packet->used = pconn->used;
559 packet->established = pconn->established;
560 packet->player_num = (pconn->playing != nullptr)
561 ? player_number(pconn->playing)
563 packet->observer = pconn->observer;
564 packet->access_level = pconn->access_level;
565
566 sz_strlcpy(packet->username, pconn->username);
567 if (game.server.ip_hide) {
568 sz_strlcpy(packet->addr, Q_("?IP:Hidden"));
569 } else {
570 sz_strlcpy(packet->addr, pconn->addr);
571 }
572 sz_strlcpy(packet->capability, pconn->capability);
573}
574
575/**********************************************************************/
580static void send_conn_info_arg(struct conn_list *src,
581 struct conn_list *dest, bool remove_conn)
582{
583 struct packet_conn_info packet;
584
585 if (!dest) {
586 dest = game.est_connections;
587 }
588
589 conn_list_iterate(src, psrc) {
590 package_conn_info(psrc, &packet);
591 if (remove_conn) {
592 packet.used = FALSE;
593 }
594 lsend_packet_conn_info(dest, &packet);
596}
597
598/**********************************************************************/
602void send_conn_info(struct conn_list *src, struct conn_list *dest)
603{
604 send_conn_info_arg(src, dest, FALSE);
605}
606
607/**********************************************************************/
611void send_conn_info_remove(struct conn_list *src, struct conn_list *dest)
612{
613 send_conn_info_arg(src, dest, TRUE);
614}
615
616/**********************************************************************/
620{
622 if (!played->is_connected && !played->was_created) {
623 return played;
624 }
626
627 return nullptr;
628}
629
630/**********************************************************************/
647 struct player *pplayer,
648 bool observing, bool connecting)
649{
650 fc_assert_ret_val(pconn != nullptr, FALSE);
651 fc_assert_ret_val_msg(!pconn->observer && pconn->playing == nullptr, FALSE,
652 "connections must be detached with "
653 "connection_detach() before calling this!");
654
655 if (!observing) {
656 if (pplayer == nullptr) {
657 /* Search for uncontrolled player */
658 pplayer = find_uncontrolled_player();
659
660 if (pplayer == nullptr) {
661 /* No uncontrolled player found */
663 || normal_player_count() >= server.playable_nations) {
664 return FALSE;
665 }
666 /* Add new player, or not */
667 /* Should only be called in such a way as to create a new player
668 * in the pregame */
671 nullptr, FALSE);
672 /* Pregame => no need to assign_player_colors() */
673 if (!pplayer) {
674 return FALSE;
675 }
676 } else {
677 team_remove_player(pplayer);
678 }
679 server_player_init(pplayer, FALSE, TRUE);
680
681 /* Make it human! */
682 set_as_human(pplayer);
683 }
684
685 sz_strlcpy(pplayer->username, pconn->username);
686 pplayer->unassigned_user = FALSE;
687 pplayer->user_turns = 0; /* Reset for a new user */
688 pplayer->is_connected = TRUE;
689
690 if (!game_was_started()) {
691 if (!pplayer->was_created && pplayer->nation == nullptr) {
692 /* Temporarily set player_name() to username. */
694 }
696 }
697
698 if (game.server.auto_ai_toggle && !is_human(pplayer)) {
699 toggle_ai_player_direct(nullptr, pplayer);
700 }
701
703
704 /* Remove from global observers list, if was there */
706 } else if (pplayer == nullptr) {
707 /* Global observer */
708 bool already = FALSE;
709
711
713 if (pconn2 == pconn) {
714 already = TRUE;
715 break;
716 }
718
719 if (!already) {
721 }
722 }
723
724 /* We don't want the connection's username on another player. */
726 if (aplayer != pplayer
727 && !fc_strncmp(aplayer->username, pconn->username, MAX_LEN_NAME)) {
728 sz_strlcpy(aplayer->username, _(ANON_USER_NAME));
729 aplayer->unassigned_user = TRUE;
730 send_player_info_c(aplayer, nullptr);
731 }
733
734 pconn->observer = observing;
735 pconn->playing = pplayer;
736 if (pplayer) {
738 }
739
741
742 /* Reset the delta-state. */
743 send_conn_info(pconn->self, game.est_connections); /* Client side. */
744 conn_reset_delta_state(pconn); /* Server side. */
745
746 /* Initial packets don't need to be resent. See comment for
747 * connecthand.c::establish_new_connection(). */
748 switch (server_state()) {
749 case S_S_INITIAL:
752 break;
753
754 case S_S_RUNNING:
756 send_all_info(pconn->self);
759 }
761 /* Enter C_S_RUNNING client state. */
763 /* Must be after C_S_RUNNING client state to be effective. */
768 break;
769
770 case S_S_OVER:
772 send_all_info(pconn->self);
775 }
780 if (!connecting) {
781 /* Send information about delegation(s). */
783 }
784 break;
785 }
786
788
789 return TRUE;
790}
791
792/**********************************************************************/
795bool connection_attach(struct connection *pconn, struct player *pplayer,
796 bool observing)
797{
798 return connection_attach_real(pconn, pplayer, observing, FALSE);
799}
800
801/**********************************************************************/
812{
813 struct player *pplayer;
814
815 fc_assert_ret(pconn != nullptr);
816
817 if ((pplayer = pconn->playing) != nullptr) {
818 bool was_connected = pplayer->is_connected;
819
822 pconn->playing = nullptr;
823 pconn->observer = FALSE;
828
829 /* If any other (non-observing) conn is attached to this player, the
830 * player is still connected. */
831 pplayer->is_connected = FALSE;
833 if (!aconn->observer) {
834 pplayer->is_connected = TRUE;
835 break;
836 }
838
839 if (was_connected && !pplayer->is_connected) {
840 /* Player just lost its controlling connection. */
842 && !pplayer->was_created && !game_was_started()) {
843 /* Remove player. */
845 /* Detach all. */
846 fc_assert_action(aconn != pconn, continue);
847 notify_conn(aconn->self, nullptr, E_CONNECTION, ftc_server,
848 _("Detaching from %s."), player_name(pplayer));
849 /* Recursive... but shouldn't be a problem, as this can only
850 * be a non-controlling connection so can't get back here. */
853
854 /* Actually do the removal. */
855 server_remove_player(pplayer);
858 } else {
859 /* Aitoggle the player if no longer connected. */
860 if (game.server.auto_ai_toggle && is_human(pplayer)) {
861 toggle_ai_player_direct(nullptr, pplayer);
862 /* send_player_info_c() was formerly updated by
863 * toggle_ai_player_direct(), so it must be safe to send here now?
864 *
865 * At other times, data from send_conn_info() is used by the
866 * client to display player information.
867 * See establish_new_connection().
868 */
869 log_verbose("connection_detach() calls send_player_info_c()");
870 send_player_info_c(pplayer, nullptr);
871
873 }
874 }
875 }
876 } else {
877 pconn->observer = FALSE;
880 }
881}
882
883/**********************************************************************/
887 struct player *dplayer)
888{
889 fc_assert_ret_val(!pconn->server.delegation.status, FALSE);
890
891 /* Save the original player of this connection and the original username of
892 * the player. */
893 pconn->server.delegation.status = TRUE;
894 pconn->server.delegation.playing = conn_get_player(pconn);
895 pconn->server.delegation.observer = pconn->observer;
897 /* Setting orig_username in the player we're about to put aside is
898 * a flag that no-one should be allowed to mess with it (e.g. /take). */
900
902 fc_assert_ret_val(strlen(oplayer->server.orig_username) == 0, FALSE);
903 sz_strlcpy(oplayer->server.orig_username, oplayer->username);
904 }
905 fc_assert_ret_val(strlen(dplayer->server.orig_username) == 0, FALSE);
906 sz_strlcpy(dplayer->server.orig_username, dplayer->username);
907
908 /* Detach the current connection. */
909 if (pconn->playing != nullptr || pconn->observer) {
911 }
912
913 /* Try to attach to the new player */
915
916 /* Restore original connection. */
917#ifndef FREECIV_NDEBUG
918 bool success =
919#endif
921 pconn->server.delegation.playing,
922 pconn->server.delegation.observer);
924
925 /* Reset all changes done above. */
926 pconn->server.delegation.status = FALSE;
927 pconn->server.delegation.playing = nullptr;
928 pconn->server.delegation.observer = FALSE;
931 oplayer->server.orig_username[0] = '\0';
932 }
933 dplayer->server.orig_username[0] = '\0';
934
935 return FALSE;
936 }
937
938 return TRUE;
939}
940
941/**********************************************************************/
948{
949 struct player *dplayer;
950
951 if (!pconn->server.delegation.status) {
952 return FALSE;
953 }
954
955 if (pconn->server.delegation.playing
956 && !pconn->server.delegation.observer) {
957 /* If restoring to controlling another player, and we're not the
958 * original controller of that player, something's gone wrong. */
960 strcmp(pconn->server.delegation.playing->server.orig_username,
961 pconn->username) == 0, FALSE);
962 }
963
964 /* Save the current (delegated) player. */
966
967 /* There should be a delegated player connected to pconn. */
969
970 /* Detach the current (delegate) connection from the delegated player. */
971 if (pconn->playing != nullptr || pconn->observer) {
973 }
974
975 /* Try to attach to the delegate's original player */
976 if ((pconn->server.delegation.playing != nullptr
977 || pconn->server.delegation.observer)
978 && !connection_attach(pconn, pconn->server.delegation.playing,
979 pconn->server.delegation.observer)) {
980 return FALSE;
981 }
982
983 /* Reset data. */
984 pconn->server.delegation.status = FALSE;
985 pconn->server.delegation.playing = nullptr;
986 pconn->server.delegation.observer = FALSE;
987 if (conn_controls_player(pconn) && conn_get_player(pconn) != nullptr) {
988 /* Remove flag that we had 'put aside' our original player. */
990
992 oplayer->server.orig_username[0] = '\0';
993 }
994
995 /* Restore the username of the original controller in the previously-
996 * delegated player. */
997 sz_strlcpy(dplayer->username, dplayer->server.orig_username);
998 dplayer->server.orig_username[0] = '\0';
999 /* Send updated username to all connections. */
1000 send_player_info_c(dplayer, nullptr);
1001
1002 return TRUE;
1003}
1004
1005/**********************************************************************/
1010{
1011 /* Restore possible delegations before the connection is closed. */
1014}
1015
1016/**********************************************************************/
1019void handle_sync_serial(struct connection *conn, int serial)
1020{
1021 dsend_packet_sync_serial_reply(conn, serial);
1022}
void send_access_area_info(struct connection *pconn)
Definition aahand.c:133
const char * default_ai_type_name(void)
Definition aiiface.c:249
bool auth_user(struct connection *pconn, char *username)
Definition auth.c:73
bool has_capabilities(const char *us, const char *them)
Definition capability.c:88
const char *const our_capability
Definition capstr.c:32
char * incite_cost
Definition comments.c:77
#define MAX_LEN_MSG
Definition conn_types.h:37
static bool connection_attach_real(struct connection *pconn, struct player *pplayer, bool observing, bool connecting)
void send_conn_info(struct conn_list *src, struct conn_list *dest)
bool connection_attach(struct connection *pconn, struct player *pplayer, bool observing)
static void package_conn_info(struct connection *pconn, struct packet_conn_info *packet)
void reject_new_connection(const char *msg, struct connection *pconn)
static void send_conn_info_arg(struct conn_list *src, struct conn_list *dest, bool remove_conn)
void handle_sync_serial(struct connection *conn, int serial)
bool connection_delegate_take(struct connection *pconn, struct player *dplayer)
bool handle_login_request(struct connection *pconn, struct packet_server_join_req *req)
struct player * find_uncontrolled_player(void)
static void restore_access_level(struct connection *pconn)
Definition connecthand.c:98
void lost_connection_to_client(struct connection *pconn)
void connection_close_server(struct connection *pconn, const char *reason)
void connection_detach(struct connection *pconn, bool remove_unused_player)
void conn_set_access(struct connection *pconn, enum cmdlevel new_level, bool granted)
Definition connecthand.c:73
bool connection_delegate_restore(struct connection *pconn)
void send_conn_info_remove(struct conn_list *src, struct conn_list *dest)
void establish_new_connection(struct connection *pconn)
struct player * conn_get_player(const struct connection *pconn)
Definition connection.c:765
bool can_conn_edit(const struct connection *pconn)
Definition connection.c:513
struct connection * conn_by_user(const char *user_name)
Definition connection.c:379
void flush_connection_send_buffer_all(struct connection *pc)
Definition connection.c:231
void conn_set_capability(struct connection *pconn, const char *capability)
Definition connection.c:663
void conn_reset_delta_state(struct connection *pc)
Definition connection.c:675
void connection_close(struct connection *pconn, const char *reason)
Definition connection.c:88
bool conn_controls_player(const struct connection *pconn)
Definition connection.c:747
const char * conn_description(const struct connection *pconn)
Definition connection.c:476
void conn_compression_freeze(struct connection *pconn)
Definition connection.c:696
enum cmdlevel conn_get_access(const struct connection *pconn)
Definition connection.c:778
@ AS_NOT_ESTABLISHED
Definition connection.h:93
@ AS_ESTABLISHED
Definition connection.h:97
bool conn_compression_thaw(struct connection *pconn)
Definition packets.c:194
#define conn_list_iterate(connlist, pconn)
Definition connection.h:108
#define conn_list_iterate_end
Definition connection.h:110
void send_diplomatic_meetings(struct connection *dest)
Definition diplhand.c:881
void edithand_send_initial_packets(struct conn_list *dest)
Definition edithand.c:112
#define MAX_LEN_NAME
Definition fc_types.h:68
#define Q_(String)
Definition fcintl.h:70
#define _(String)
Definition fcintl.h:67
const struct ft_color ftc_player_lost
const struct ft_color ftc_server
const struct ft_color ftc_editor
const struct ft_color ftc_any
struct civ_game game
Definition game.c:62
struct world wld
Definition game.c:63
void send_scenario_description(struct conn_list *dest)
Definition gamehand.c:967
void send_scenario_info(struct conn_list *dest)
Definition gamehand.c:953
void send_game_info(struct conn_list *dest)
Definition gamehand.c:910
const char * new_challenge_filename(struct connection *pc)
Definition gamehand.c:1099
#define fc_assert_msg(condition, message,...)
Definition log.h:182
#define fc_assert_ret(condition)
Definition log.h:192
#define log_verbose(message,...)
Definition log.h:110
#define fc_assert(condition)
Definition log.h:177
#define fc_assert_ret_val(condition, val)
Definition log.h:195
#define fc_assert_action(condition, action)
Definition log.h:188
#define log_debug(message,...)
Definition log.h:116
#define log_normal(message,...)
Definition log.h:108
#define log_error(message,...)
Definition log.h:104
#define fc_assert_ret_val_msg(condition, val, message,...)
Definition log.h:209
int dsend_packet_connect_msg(struct connection *pc, const char *message)
void lsend_packet_conn_info(struct conn_list *dest, const struct packet_conn_info *packet)
int send_packet_server_info(struct connection *pc, const struct packet_server_info *packet)
int send_packet_chat_msg(struct connection *pc, const struct packet_chat_msg *packet)
int send_packet_set_topology(struct connection *pc, const struct packet_set_topology *packet)
int dsend_packet_sync_serial_reply(struct connection *pc, int serial)
int dsend_packet_start_phase(struct connection *pc, int phase)
int send_packet_server_join_reply(struct connection *pc, const struct packet_server_join_reply *packet)
void maybe_automatic_meta_message(const char *automatic)
Definition meta.c:152
const char * default_meta_message_string(void)
Definition meta.c:91
bool send_server_info_to_metaserver(enum meta_flag flag)
Definition meta.c:491
@ META_INFO
Definition meta.h:26
void send_pending_events(struct connection *pconn, bool include_public)
Definition notify.c:753
void notify_conn(struct conn_list *dest, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:238
void package_event(struct packet_chat_msg *packet, const struct tile *ptile, enum event_type event, const struct ft_color color, const char *format,...)
Definition notify.c:168
void event_cache_add_for_all(const struct packet_chat_msg *packet)
Definition notify.c:619
bool is_valid_username(const char *name)
Definition player.c:1897
int player_count(void)
Definition player.c:806
int player_slot_count(void)
Definition player.c:415
int player_number(const struct player *pplayer)
Definition player.c:826
const char * player_name(const struct player *pplayer)
Definition player.c:885
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1979
struct player * player_by_user(const char *name)
Definition player.c:932
#define players_iterate_end
Definition player.h:552
#define players_iterate(_pplayer)
Definition player.h:547
#define ANON_USER_NAME
Definition player.h:48
#define set_as_human(plr)
Definition player.h:233
#define players_iterate_alive_end
Definition player.h:562
#define is_human(plr)
Definition player.h:231
#define players_iterate_alive(_pplayer)
Definition player.h:557
void server_player_set_name(struct player *pplayer, const char *name)
Definition plrhand.c:2270
struct player * server_create_player(int player_id, const char *ai_tname, struct rgbcolor *prgbcolor, bool allow_ai_type_fallbacking)
Definition plrhand.c:1896
int normal_player_count(void)
Definition plrhand.c:3217
struct player * player_by_user_delegated(const char *name)
Definition plrhand.c:3331
void send_player_info_c(struct player *src, struct conn_list *dest)
Definition plrhand.c:1148
void send_delegation_info(const struct connection *pconn)
Definition plrhand.c:3287
void server_remove_player(struct player *pplayer)
Definition plrhand.c:1945
void server_player_init(struct player *pplayer, bool initmap, bool needs_team)
Definition plrhand.c:1620
const char * player_delegation_get(const struct player *pplayer)
Definition plrhand.c:3250
void reset_all_start_commands(bool plrchange)
Definition plrhand.c:2737
#define fc_rand(_size)
Definition rand.h:56
void report_final_scores(struct conn_list *dest)
Definition report.c:1724
void send_current_history_report(struct conn_list *dest)
Definition report.c:381
void send_rulesets(struct conn_list *dest)
Definition ruleload.c:9842
bool script_fcdb_call(const char *func_name,...)
struct setting_list * level[OLEVELS_NUM]
Definition settings.c:190
void send_server_setting_control(struct connection *pconn)
Definition settings.c:5492
void send_server_settings(struct conn_list *dest)
Definition settings.c:5448
void send_server_access_level_settings(struct conn_list *dest, enum cmdlevel old_level, enum cmdlevel new_level)
Definition settings.c:5460
void remove_leading_trailing_spaces(char *s)
Definition shared.c:444
const char * aifill(int amount)
Definition srv_main.c:2556
bool game_was_started(void)
Definition srv_main.c:357
struct server_arguments srvarg
Definition srv_main.c:182
void check_for_full_turn_done(void)
Definition srv_main.c:2306
void send_all_info(struct conn_list *dest)
Definition srv_main.c:734
enum server_states server_state(void)
Definition srv_main.c:341
void notify_if_first_access_level_is_available(void)
Definition stdinhand.c:1425
bool conn_is_kicked(struct connection *pconn, int *time_remaining)
Definition stdinhand.c:6299
void toggle_ai_player_direct(struct connection *caller, struct player *pplayer)
Definition stdinhand.c:675
char connectmsg[MAX_LEN_MSG]
Definition game.h:226
struct conn_list * glob_observers
Definition game.h:98
struct conn_list * est_connections
Definition game.h:97
struct packet_game_info info
Definition game.h:89
bool ip_hide
Definition game.h:181
struct conn_list * all_connections
Definition game.h:96
struct civ_game::@32::@36 server
int max_players
Definition game.h:163
bool auto_ai_toggle
Definition game.h:137
bool turnblock
Definition game.h:204
int topology_id
Definition map_types.h:72
int wrap_id
Definition map_types.h:73
char addr[MAX_LEN_ADDR]
char capability[MAX_LEN_CAPSTR]
enum cmdlevel access_level
char username[MAX_LEN_NAME]
char username[MAX_LEN_NAME]
Definition player.h:252
bool is_connected
Definition player.h:296
bool was_created
Definition player.h:294
struct conn_list * connections
Definition player.h:298
struct nation_type * nation
Definition player.h:260
int user_turns
Definition player.h:256
bool unassigned_user
Definition player.h:253
struct civ_map map
int fc_snprintf(char *str, size_t n, const char *format,...)
Definition support.c:925
int fc_gethostname(char *buf, size_t len)
Definition support.c:972
int fc_strcasecmp(const char *str0, const char *str1)
Definition support.c:186
#define sz_strlcpy(dest, src)
Definition support.h:195
#define TRUE
Definition support.h:46
#define FALSE
Definition support.h:47
#define fc_strncmp(_s1_, _s2_, _len_)
Definition support.h:160
void team_remove_player(struct player *pplayer)
Definition team.c:485
const char * freeciv_name_version(void)
Definition version.c:35
#define MINOR_VERSION
Definition version_gen.h:7
#define VERSION_LABEL
Definition version_gen.h:11
#define EMERGENCY_VERSION
Definition version_gen.h:9
#define MAJOR_VERSION
Definition version_gen.h:6
#define PATCH_VERSION
Definition version_gen.h:8
void send_running_votes(struct connection *pconn, bool only_team_votes)
Definition voting.c:810
void send_remove_team_votes(struct connection *pconn)
Definition voting.c:841
void cancel_connection_votes(struct connection *pconn)
Definition voting.c:691
void send_updated_vote_totals(struct conn_list *dest)
Definition voting.c:866