Freeciv-3.3
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 "aiiface.h"
38#include "auth.h"
39#include "diplhand.h"
40#include "edithand.h"
41#include "gamehand.h"
42#include "maphand.h"
43#include "meta.h"
44#include "notify.h"
45#include "plrhand.h"
46#include "report.h"
47#include "ruleload.h"
48#include "sernet.h"
49#include "settings.h"
50#include "srv_main.h"
51#include "stdinhand.h"
52#include "voting.h"
53
54/* server/scripting */
55#include "script_fcdb.h"
56
57#include "connecthand.h"
58
59
60static bool connection_attach_real(struct connection *pconn,
61 struct player *pplayer,
62 bool observing, bool connecting);
63
64/**********************************************************************/
73 bool granted)
74{
76
77 pconn->access_level = new_level;
78 if (granted) {
79 pconn->server.granted_access_level = new_level;
80 }
81
82 /* Send updated settings only if settings control already sent.
83 * Otherwise client is not ready to receive them, AND we will send
84 * them later anyway. */
85 if (old_level != new_level && pconn->server.settings_sent) {
87 }
88}
89
90/**********************************************************************/
98{
99 /* Restore previous privileges. */
100 enum cmdlevel level = pconn->server.granted_access_level;
101
102 /* Detached connections must have at most the same privileges
103 * as observers, unless they were granted something higher than
104 * ALLOW_BASIC in the first place. */
105 if ((pconn->observer || !pconn->playing) && level == ALLOW_BASIC) {
107 }
108
110}
111
112/**********************************************************************/
131{
132 struct conn_list *dest = pconn->self;
133 struct player *pplayer;
134 struct packet_server_join_reply packet;
136 char hostname[512];
137 bool delegation_error = FALSE;
139
140 /* Zero out the password */
141 memset(pconn->server.password, 0, sizeof(pconn->server.password));
142
143 /* Send join_reply packet */
144 packet.you_can_join = TRUE;
146 fc_snprintf(packet.message, sizeof(packet.message), _("%s Welcome"),
147 pconn->username);
149 packet.conn_id = pconn->id;
151
152 /* "establish" the connection */
153 pconn->established = TRUE;
154 pconn->server.status = AS_ESTABLISHED;
155
156 pconn->server.delegation.status = FALSE;
157 pconn->server.delegation.playing = nullptr;
158 pconn->server.delegation.observer = FALSE;
159 pconn->server.settings_sent = FALSE;
160
163 /* First connection
164 * Replace "restarting in x seconds" meta message */
167 }
168
169 /* Introduce the server to the connection */
170 if (fc_gethostname(hostname, sizeof(hostname)) == 0) {
171 notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
172 _("Welcome to the %s Server running at %s port %d."),
174 } else {
175 notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
176 _("Welcome to the %s Server at port %d."),
178 }
179
180 /* FIXME: this (getting messages about others logging on) should be
181 * a message option for the client with event */
182
183 /* Notify the console that you're here. */
184 log_normal(_("%s has connected from %s."), pconn->username, pconn->addr);
185
186 if (srvarg.fcdb_enabled) {
187 script_fcdb_call("conn_established", pconn);
188 }
189
191 send_rulesets(dest);
194 send_scenario_info(dest);
196 send_game_info(dest);
197 topo_packet.topology_id = wld.map.topology_id;
198 topo_packet.wrap_id = wld.map.wrap_id;
200
201 /* Do we have a player that a delegate is currently controlling? */
202 if ((pplayer = player_by_user_delegated(pconn->username))) {
203 /* Reassert our control over the player. */
204 struct connection *pdelegate;
205
206 fc_assert_ret(player_delegation_get(pplayer) != nullptr);
208
210 /* Delegate now detached from our player. We will restore control
211 * over them as normal below. */
212 notify_conn(pconn->self, nullptr, E_CONNECTION, ftc_server,
213 _("Your delegate %s was controlling your player '%s'; "
214 "now detached."), pdelegate->username,
215 player_name(pplayer));
217 _("%s reconnected, ending your delegated control of "
218 "player '%s'."), pconn->username, player_name(pplayer));
219 } else {
221 /* This really shouldn't happen. */
222 log_error("Failed to revoke delegate %s's control of %s, so owner %s "
223 "can't regain control.", pdelegate->username,
224 player_name(pplayer), pconn->username);
225 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
226 _("Couldn't get control of '%s' from delegation to %s."),
227 player_name(pplayer), pdelegate->username);
229 pplayer = nullptr;
230 }
231 }
232
233 if (!delegation_error) {
234 if ((pplayer = player_by_user(pconn->username))
235 && connection_attach_real(pconn, pplayer, FALSE, TRUE)) {
236 /* A player has already been created for this user, reconnect */
237
238 if (S_S_INITIAL == server_state()) {
239 send_player_info_c(nullptr, dest);
240 }
241 } else {
242 int total_free_weight = 0;
243
245 if (wplayer->autoselect_weight > 0
246 && !wplayer->is_connected
248 total_free_weight += wplayer->autoselect_weight;
249 }
251
252 if (total_free_weight > 0) {
254
256 if (wplayer->autoselect_weight > 0
257 && !wplayer->is_connected
259 weight_rand -= wplayer->autoselect_weight;
260 if (weight_rand < 0) {
261 log_normal("Trying to attach %s to %s",
262 pconn->username, wplayer->name);
264 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
265 _("Couldn't attach your connection to a scenario player."));
266 log_verbose("%s is not attached to a player", pconn->username);
267 }
268 break;
269 }
270 }
272 } else if (!game_was_started()) {
273 if (connection_attach_real(pconn, nullptr, FALSE, TRUE)) {
274 pplayer = conn_get_player(pconn);
275 fc_assert(pplayer != nullptr);
276 } else {
277 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
278 _("Couldn't attach your connection to new player."));
279 log_verbose("%s is not attached to a player", pconn->username);
280 }
281 }
282 send_player_info_c(nullptr, dest);
283 }
284 }
285
287
288 if (pplayer == nullptr) {
289 /* Else this has already been done in connection_attach_real(). */
294
295 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
296 _("You are logged in as '%s' connected to no player."),
297 pconn->username);
298 } else {
299 notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
300 _("You are logged in as '%s' connected to %s."),
301 pconn->username,
302 player_name(pconn->playing));
303 }
304
305 /* Send information about delegation(s). */
307
308 /* Notify the *other* established connections that you are connected, and
309 * add the info for all in event cache. Note we must to do it after we
310 * sent the pending events to pconn (from this function and also
311 * connection_attach()), otherwise pconn will receive it too. */
313 if (game.server.ip_hide) {
315 _("%s has connected (player %s)."),
316 pconn->username,
318 } else {
320 _("%s has connected from %s (player %s)."),
321 pconn->username, pconn->addr,
323 }
324 } else {
325 if (game.server.ip_hide) {
327 _("%s has connected."),
328 pconn->username);
329 } else {
331 _("%s has connected from %s."),
332 pconn->username, pconn->addr);
333 }
334 }
336 if (aconn != pconn) {
338 }
341
342 /* If need be, tell who we're waiting on to end the game.info.turn */
345 if (is_human(cplayer)
346 && !cplayer->phase_done
347 && cplayer != pconn->playing) { /* skip current player */
348 notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
349 _("Turn-blocking game play: "
350 "waiting on %s to finish turn..."),
352 }
354 }
355
356 if (game.info.is_edit_mode) {
357 notify_conn(dest, nullptr, E_SETTING, ftc_editor,
358 _(" *** Server is in edit mode. *** "));
359 }
360
361 if (pplayer != nullptr) {
362 /* Else, no need to do anything. */
365 }
366
368
370}
371
372/**********************************************************************/
375void reject_new_connection(const char *msg, struct connection *pconn)
376{
377 struct packet_server_join_reply packet;
378
379 /* Zero out the password */
380 memset(pconn->server.password, 0, sizeof(pconn->server.password));
381
382 packet.you_can_join = FALSE;
384 sz_strlcpy(packet.message, msg);
385 packet.challenge_file[0] = '\0';
386 packet.conn_id = -1;
388 log_normal(_("Client rejected: %s."), conn_description(pconn));
390}
391
392/**********************************************************************/
397 struct packet_server_join_req *req)
398{
399 char msg[MAX_LEN_MSG];
401
402 if (pconn->established || pconn->server.status != AS_NOT_ESTABLISHED) {
403 /* We read the PACKET_SERVER_JOIN_REQ twice from this connection,
404 * this is probably not a Freeciv client. */
405 return FALSE;
406 }
407
408 log_normal(_("Connection request from %s from %s"),
409 req->username, pconn->addr);
410
411 /* Print server and client capabilities to console */
412 log_normal(_("%s has client version %d.%d.%d%s"),
413 pconn->username, req->major_version, req->minor_version,
414 req->patch_version, req->version_label);
415 log_verbose("Client caps: %s", req->capability);
416 log_verbose("Server caps: %s", our_capability);
418
419 /* Make sure the server has every capability the client needs */
421 fc_snprintf(msg, sizeof(msg),
422 _("The client is missing a capability that this server needs.\n"
423 "Server version: %d.%d.%d%s Client version: %d.%d.%d%s."
424 " Upgrading may help!"),
426 req->major_version, req->minor_version,
427 req->patch_version, req->version_label);
429 log_normal(_("%s was rejected: Mismatched capabilities."),
430 req->username);
431 return FALSE;
432 }
433
434 /* Make sure the client has every capability the server needs */
436 fc_snprintf(msg, sizeof(msg),
437 _("The server is missing a capability that the client needs.\n"
438 "Server version: %d.%d.%d%s Client version: %d.%d.%d%s."
439 " Upgrading may help!"),
441 req->major_version, req->minor_version,
442 req->patch_version, req->version_label);
444 log_normal(_("%s was rejected: Mismatched capabilities."),
445 req->username);
446 return FALSE;
447 }
448
449 {
450 /* Client is compatible. That includes ability to receive server info.
451 * Send it. */
452 struct packet_server_info info;
453
457#ifdef EMERGENCY_VERSION
459#else
460 info.emerg_version = 0;
461#endif
464 }
465
467
468 /* Name-sanity check: could add more checks? */
469 if (!is_valid_username(req->username)) {
470 fc_snprintf(msg, sizeof(msg), _("Invalid username '%s'"), req->username);
472 log_normal(_("%s was rejected: Invalid name [%s]."),
473 req->username, pconn->addr);
474 return FALSE;
475 }
476
478 fc_snprintf(msg, sizeof(msg), _("You have been kicked from this server "
479 "and cannot reconnect for %d seconds."),
482 log_normal(_("%s was rejected: Connection kicked "
483 "(%d seconds remaining)."),
485 return FALSE;
486 }
487
488 /* Don't allow duplicate logins */
490 if (fc_strcasecmp(req->username, aconn->username) == 0) {
491 fc_snprintf(msg, sizeof(msg), _("'%s' already connected."),
492 req->username);
494 log_normal(_("%s was rejected: Duplicate login name [%s]."),
495 req->username, pconn->addr);
496 return FALSE;
497 }
499
500 /* Remove the ping timeout given in sernet.c:server_make_connection(). */
501 fc_assert_msg(1 == timer_list_size(pconn->server.ping_timers),
502 "Ping timer list size %d, should be 1. Have we sent "
503 "a ping to unestablished connection %s?",
504 timer_list_size(pconn->server.ping_timers),
506 timer_list_pop_front(pconn->server.ping_timers);
507
508 if (game.server.connectmsg[0] != '\0') {
509 log_debug("Sending connectmsg: %s", game.server.connectmsg);
511 }
512
513 if (srvarg.auth_enabled) {
514 return auth_user(pconn, req->username);
515 } else {
516 sz_strlcpy(pconn->username, req->username);
518 return TRUE;
519 }
520}
521
522/**********************************************************************/
531{
532 const char *desc = conn_description(pconn);
533
534 fc_assert_ret(pconn->server.is_closing);
535
536 log_normal(_("Lost connection: %s."), desc);
537
538 /* Special color (white on black) for player loss */
541 _("Lost connection: %s."), desc);
542
546
548}
549
550/**********************************************************************/
554 struct packet_conn_info *packet)
555{
556 packet->id = pconn->id;
557 packet->used = pconn->used;
558 packet->established = pconn->established;
559 packet->player_num = (pconn->playing != nullptr)
560 ? player_number(pconn->playing)
562 packet->observer = pconn->observer;
563 packet->access_level = pconn->access_level;
564
565 sz_strlcpy(packet->username, pconn->username);
566 if (game.server.ip_hide) {
567 sz_strlcpy(packet->addr, Q_("?IP:Hidden"));
568 } else {
569 sz_strlcpy(packet->addr, pconn->addr);
570 }
571 sz_strlcpy(packet->capability, pconn->capability);
572}
573
574/**********************************************************************/
579static void send_conn_info_arg(struct conn_list *src,
580 struct conn_list *dest, bool remove_conn)
581{
582 struct packet_conn_info packet;
583
584 if (!dest) {
585 dest = game.est_connections;
586 }
587
588 conn_list_iterate(src, psrc) {
589 package_conn_info(psrc, &packet);
590 if (remove_conn) {
591 packet.used = FALSE;
592 }
593 lsend_packet_conn_info(dest, &packet);
595}
596
597/**********************************************************************/
601void send_conn_info(struct conn_list *src, struct conn_list *dest)
602{
603 send_conn_info_arg(src, dest, FALSE);
604}
605
606/**********************************************************************/
610void send_conn_info_remove(struct conn_list *src, struct conn_list *dest)
611{
612 send_conn_info_arg(src, dest, TRUE);
613}
614
615/**********************************************************************/
619{
621 if (!played->is_connected && !played->was_created) {
622 return played;
623 }
625
626 return nullptr;
627}
628
629/**********************************************************************/
646 struct player *pplayer,
647 bool observing, bool connecting)
648{
649 fc_assert_ret_val(pconn != nullptr, FALSE);
650 fc_assert_ret_val_msg(!pconn->observer && pconn->playing == nullptr, FALSE,
651 "connections must be detached with "
652 "connection_detach() before calling this!");
653
654 if (!observing) {
655 if (pplayer == nullptr) {
656 /* Search for uncontrolled player */
657 pplayer = find_uncontrolled_player();
658
659 if (pplayer == nullptr) {
660 /* No uncontrolled player found */
662 || normal_player_count() >= server.playable_nations) {
663 return FALSE;
664 }
665 /* Add new player, or not */
666 /* Should only be called in such a way as to create a new player
667 * in the pregame */
670 nullptr, FALSE);
671 /* Pregame => no need to assign_player_colors() */
672 if (!pplayer) {
673 return FALSE;
674 }
675 } else {
676 team_remove_player(pplayer);
677 }
678 server_player_init(pplayer, FALSE, TRUE);
679
680 /* Make it human! */
681 set_as_human(pplayer);
682 }
683
684 sz_strlcpy(pplayer->username, pconn->username);
685 pplayer->unassigned_user = FALSE;
686 pplayer->user_turns = 0; /* Reset for a new user */
687 pplayer->is_connected = TRUE;
688
689 if (!game_was_started()) {
690 if (!pplayer->was_created && pplayer->nation == nullptr) {
691 /* Temporarily set player_name() to username. */
693 }
695 }
696
697 if (game.server.auto_ai_toggle && !is_human(pplayer)) {
698 toggle_ai_player_direct(nullptr, pplayer);
699 }
700
702
703 /* Remove from global observers list, if was there */
705 } else if (pplayer == nullptr) {
706 /* Global observer */
707 bool already = FALSE;
708
710
712 if (pconn2 == pconn) {
713 already = TRUE;
714 break;
715 }
717
718 if (!already) {
720 }
721 }
722
723 /* We don't want the connection's username on another player. */
725 if (aplayer != pplayer
726 && !fc_strncmp(aplayer->username, pconn->username, MAX_LEN_NAME)) {
727 sz_strlcpy(aplayer->username, _(ANON_USER_NAME));
728 aplayer->unassigned_user = TRUE;
729 send_player_info_c(aplayer, nullptr);
730 }
732
733 pconn->observer = observing;
734 pconn->playing = pplayer;
735 if (pplayer) {
737 }
738
740
741 /* Reset the delta-state. */
742 send_conn_info(pconn->self, game.est_connections); /* Client side. */
743 conn_reset_delta_state(pconn); /* Server side. */
744
745 /* Initial packets don't need to be resent. See comment for
746 * connecthand.c::establish_new_connection(). */
747 switch (server_state()) {
748 case S_S_INITIAL:
751 break;
752
753 case S_S_RUNNING:
755 send_all_info(pconn->self);
758 }
760 /* Enter C_S_RUNNING client state. */
762 /* Must be after C_S_RUNNING client state to be effective. */
766 break;
767
768 case S_S_OVER:
770 send_all_info(pconn->self);
773 }
778 if (!connecting) {
779 /* Send information about delegation(s). */
781 }
782 break;
783 }
784
786
787 return TRUE;
788}
789
790/**********************************************************************/
793bool connection_attach(struct connection *pconn, struct player *pplayer,
794 bool observing)
795{
796 return connection_attach_real(pconn, pplayer, observing, FALSE);
797}
798
799/**********************************************************************/
810{
811 struct player *pplayer;
812
813 fc_assert_ret(pconn != nullptr);
814
815 if ((pplayer = pconn->playing) != nullptr) {
816 bool was_connected = pplayer->is_connected;
817
820 pconn->playing = nullptr;
821 pconn->observer = FALSE;
826
827 /* If any other (non-observing) conn is attached to this player, the
828 * player is still connected. */
829 pplayer->is_connected = FALSE;
831 if (!aconn->observer) {
832 pplayer->is_connected = TRUE;
833 break;
834 }
836
837 if (was_connected && !pplayer->is_connected) {
838 /* Player just lost its controlling connection. */
840 && !pplayer->was_created && !game_was_started()) {
841 /* Remove player. */
843 /* Detach all. */
844 fc_assert_action(aconn != pconn, continue);
845 notify_conn(aconn->self, nullptr, E_CONNECTION, ftc_server,
846 _("Detaching from %s."), player_name(pplayer));
847 /* Recursive... but shouldn't be a problem, as this can only
848 * be a non-controlling connection so can't get back here. */
851
852 /* Actually do the removal. */
853 server_remove_player(pplayer);
856 } else {
857 /* Aitoggle the player if no longer connected. */
858 if (game.server.auto_ai_toggle && is_human(pplayer)) {
859 toggle_ai_player_direct(nullptr, pplayer);
860 /* send_player_info_c() was formerly updated by
861 * toggle_ai_player_direct(), so it must be safe to send here now?
862 *
863 * At other times, data from send_conn_info() is used by the
864 * client to display player information.
865 * See establish_new_connection().
866 */
867 log_verbose("connection_detach() calls send_player_info_c()");
868 send_player_info_c(pplayer, nullptr);
869
871 }
872 }
873 }
874 } else {
875 pconn->observer = FALSE;
878 }
879}
880
881/**********************************************************************/
885 struct player *dplayer)
886{
887 fc_assert_ret_val(!pconn->server.delegation.status, FALSE);
888
889 /* Save the original player of this connection and the original username of
890 * the player. */
891 pconn->server.delegation.status = TRUE;
892 pconn->server.delegation.playing = conn_get_player(pconn);
893 pconn->server.delegation.observer = pconn->observer;
895 /* Setting orig_username in the player we're about to put aside is
896 * a flag that no-one should be allowed to mess with it (e.g. /take). */
898
900 fc_assert_ret_val(strlen(oplayer->server.orig_username) == 0, FALSE);
901 sz_strlcpy(oplayer->server.orig_username, oplayer->username);
902 }
903 fc_assert_ret_val(strlen(dplayer->server.orig_username) == 0, FALSE);
904 sz_strlcpy(dplayer->server.orig_username, dplayer->username);
905
906 /* Detach the current connection. */
907 if (pconn->playing != nullptr || pconn->observer) {
909 }
910
911 /* Try to attach to the new player */
913
914 /* Restore original connection. */
915#ifndef FREECIV_NDEBUG
916 bool success =
917#endif
919 pconn->server.delegation.playing,
920 pconn->server.delegation.observer);
922
923 /* Reset all changes done above. */
924 pconn->server.delegation.status = FALSE;
925 pconn->server.delegation.playing = nullptr;
926 pconn->server.delegation.observer = FALSE;
929 oplayer->server.orig_username[0] = '\0';
930 }
931 dplayer->server.orig_username[0] = '\0';
932
933 return FALSE;
934 }
935
936 return TRUE;
937}
938
939/**********************************************************************/
946{
947 struct player *dplayer;
948
949 if (!pconn->server.delegation.status) {
950 return FALSE;
951 }
952
953 if (pconn->server.delegation.playing
954 && !pconn->server.delegation.observer) {
955 /* If restoring to controlling another player, and we're not the
956 * original controller of that player, something's gone wrong. */
958 strcmp(pconn->server.delegation.playing->server.orig_username,
959 pconn->username) == 0, FALSE);
960 }
961
962 /* Save the current (delegated) player. */
964
965 /* There should be a delegated player connected to pconn. */
967
968 /* Detach the current (delegate) connection from the delegated player. */
969 if (pconn->playing != nullptr || pconn->observer) {
971 }
972
973 /* Try to attach to the delegate's original player */
974 if ((pconn->server.delegation.playing != nullptr
975 || pconn->server.delegation.observer)
976 && !connection_attach(pconn, pconn->server.delegation.playing,
977 pconn->server.delegation.observer)) {
978 return FALSE;
979 }
980
981 /* Reset data. */
982 pconn->server.delegation.status = FALSE;
983 pconn->server.delegation.playing = nullptr;
984 pconn->server.delegation.observer = FALSE;
985 if (conn_controls_player(pconn) && conn_get_player(pconn) != nullptr) {
986 /* Remove flag that we had 'put aside' our original player. */
988
990 oplayer->server.orig_username[0] = '\0';
991 }
992
993 /* Restore the username of the original controller in the previously-
994 * delegated player. */
995 sz_strlcpy(dplayer->username, dplayer->server.orig_username);
996 dplayer->server.orig_username[0] = '\0';
997 /* Send updated username to all connections. */
998 send_player_info_c(dplayer, nullptr);
999
1000 return TRUE;
1001}
1002
1003/**********************************************************************/
1008{
1009 /* Restore possible delegations before the connection is closed. */
1012}
1013
1014/**********************************************************************/
1017void handle_sync_serial(struct connection *conn, int serial)
1018{
1019 dsend_packet_sync_serial_reply(conn, serial);
1020}
const char * default_ai_type_name(void)
Definition aiiface.c:264
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:76
#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:97
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:72
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:763
bool can_conn_edit(const struct connection *pconn)
Definition connection.c:511
struct connection * conn_by_user(const char *user_name)
Definition connection.c:377
void flush_connection_send_buffer_all(struct connection *pc)
Definition connection.c:230
void conn_set_capability(struct connection *pconn, const char *capability)
Definition connection.c:661
void conn_reset_delta_state(struct connection *pc)
Definition connection.c:673
void connection_close(struct connection *pconn, const char *reason)
Definition connection.c:88
bool conn_controls_player(const struct connection *pconn)
Definition connection.c:745
const char * conn_description(const struct connection *pconn)
Definition connection.c:474
void conn_compression_freeze(struct connection *pconn)
Definition connection.c:694
enum cmdlevel conn_get_access(const struct connection *pconn)
Definition connection.c:775
@ 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:885
void edithand_send_initial_packets(struct conn_list *dest)
Definition edithand.c:112
#define MAX_LEN_NAME
Definition fc_types.h:66
#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:61
struct world wld
Definition game.c:62
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
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
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)
bool is_valid_username(const char *name)
Definition player.c:1914
int player_count(void)
Definition player.c:817
int player_slot_count(void)
Definition player.c:418
int player_number(const struct player *pplayer)
Definition player.c:837
const char * player_name(const struct player *pplayer)
Definition player.c:895
bool player_has_flag(const struct player *pplayer, enum plr_flag_id flag)
Definition player.c:1996
struct player * player_by_user(const char *name)
Definition player.c:940
#define players_iterate_end
Definition player.h:542
#define players_iterate(_pplayer)
Definition player.h:537
#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:552
#define is_human(plr)
Definition player.h:231
#define players_iterate_alive(_pplayer)
Definition player.h:547
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:3209
struct player * player_by_user_delegated(const char *name)
Definition plrhand.c:3323
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:3279
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:3242
void reset_all_start_commands(bool plrchange)
Definition plrhand.c:2729
#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:9539
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:5438
void send_server_settings(struct conn_list *dest)
Definition settings.c:5394
void send_server_access_level_settings(struct conn_list *dest, enum cmdlevel old_level, enum cmdlevel new_level)
Definition settings.c:5406
void remove_leading_trailing_spaces(char *s)
Definition shared.c:444
const char * aifill(int amount)
Definition srv_main.c:2506
bool game_was_started(void)
Definition srv_main.c:354
struct server_arguments srvarg
Definition srv_main.c:181
void check_for_full_turn_done(void)
Definition srv_main.c:2256
void send_all_info(struct conn_list *dest)
Definition srv_main.c:730
enum server_states server_state(void)
Definition srv_main.c:338
void notify_if_first_access_level_is_available(void)
Definition stdinhand.c:1451
bool conn_is_kicked(struct connection *pconn, int *time_remaining)
Definition stdinhand.c:6284
void toggle_ai_player_direct(struct connection *caller, struct player *pplayer)
Definition stdinhand.c:706
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 capability[MAX_LEN_CAPSTR]
char addr[MAX_LEN_ADDR]
char username[MAX_LEN_NAME]
enum cmdlevel access_level
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:960
int fc_gethostname(char *buf, size_t len)
Definition support.c:1007
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:502
const char * freeciv_name_version(void)
Definition version.c:35
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