<URL: http://bugs.freeciv.org/Ticket/Display.html?id=39956 >
Implement part of the bug fix proposal in PR#39579. server/ruleset.c load_rulesets() remove redundant send_rulesets(), usually sent later after game_load(), instead send only after explicit server/stdinhand.c set_rulesetdir() In addition, this fixes a bug sending rulesets to game.all_connections instead of the correct game.est_connections (established). Now, all rulesets are sent only 2 times. Sending once would be better, but that requires a packet change with significant redesign and restructuring! server/savegame.c game_load() remove redundant send_ruleset_nations(), sent later with send_rulesets() Now, nation rulesets are sent only 2 times, as above. server/srv_main.c start_game() remove redundant send_server_settings() Now, server settings are sent only 3 times. The third time is probably redundant, but various settings are changing without update packets sent! Therefore, left the remaining redundancy in place (suitably logged). Generally, send_server_settings() after send_rulesets() for delta compression of the redundancy and updates. Also, the server and client had identically named handle_packet_input() routines, yet were not the generated packet handler names. Renamed to avoid confusion with each other, and with packets.def handlers. client/repodlgs_common.c calloc instead of malloc
Index: server/srv_main.c =================================================================== --- server/srv_main.c (revision 14148) +++ server/srv_main.c (working copy) @@ -976,7 +976,6 @@ set_server_state(S_S_GENERATING_WAITING); /* loaded ??? */ force_end_of_sniff = TRUE; - send_server_settings(NULL); /* There's no stateful packet set to client until srv_ready(). */ } @@ -1073,7 +1072,7 @@ Returns 0 if connection should be closed (because the clients was rejected). Returns 1 else. **************************************************************************/ -bool handle_packet_input(struct connection *pconn, void *packet, int type) +bool server_packet_input(struct connection *pconn, void *packet, int type) { struct player *pplayer; @@ -1502,8 +1501,7 @@ send_player_info(pplayer, NULL); /* Note this is called even if the player has pressed /start once - * before. This is a good thing given that no other code supports - * is_started yet. For instance if a player leaves everyone left + * before. For instance, when a player leaves everyone remaining * might have pressed /start already but the start won't happen * until someone presses it again. Also you can press start more * than once to remind other people to start (which is a good thing @@ -1996,10 +1994,17 @@ set_server_state(S_S_RUNNING); (void) send_server_info_to_metaserver(META_INFO); + + freelog(LOG_VERBOSE, "srv_ready() mostly redundant send_server_settings()"); send_server_settings(NULL); if (game.info.is_new_game) { - /* Before the player map is allocated (and initiailized)! */ + /* If we're starting a new game, reset the max_players to be the + * number of players currently in the game. + */ + game.info.max_players = game.info.nplayers; + + /* Before the player map is allocated (and initialized)! */ game.fogofwar_old = game.info.fogofwar; players_iterate(pplayer) { @@ -2034,15 +2039,7 @@ } } players_iterate_end; - assert(game.info.is_new_game); { /* FIXME: inexplicable test */ - /* If we're starting a new game, reset the rules.max_players to be the - * number of players currently in the game. But when loading a game - * we don't want to change it. */ - game.info.max_players = game.info.nplayers; - } - /* Set up alliances based on team selections */ - assert(game.info.is_new_game); /* FIXME: inexplicable test */ players_iterate(pplayer) { players_iterate(pdest) { if (players_on_same_team(pplayer, pdest) @@ -2054,7 +2051,8 @@ } players_iterate_end; } players_iterate_end; } - + + /* FIXME: can this be moved? */ players_iterate(pplayer) { ai_data_analyze_rulesets(pplayer); } players_iterate_end; Index: server/srv_main.h =================================================================== --- server/srv_main.h (revision 14148) +++ server/srv_main.h (working copy) @@ -61,7 +61,7 @@ bool check_for_game_over(void); -bool handle_packet_input(struct connection *pconn, void *packet, int type); +bool server_packet_input(struct connection *pconn, void *packet, int type); void start_game(void); void save_game(char *orig_filename, const char *save_reason); void pick_random_player_name(const struct nation_type *pnation, Index: server/connecthand.c =================================================================== --- server/connecthand.c (revision 14148) +++ server/connecthand.c (working copy) @@ -47,7 +47,7 @@ has started. If pconn is NULL, is an AI, else a client. N.B. this only attachs a connection to a player if - pconn->name == player->username + pconn->username == player->username **************************************************************************/ void establish_new_connection(struct connection *pconn) { @@ -59,7 +59,7 @@ /* zero out the password */ memset(pconn->server.password, 0, sizeof(pconn->server.password)); - /* send off login_replay packet */ + /* send join_reply packet */ packet.you_can_join = TRUE; sz_strlcpy(packet.capability, our_capability); my_snprintf(packet.message, sizeof(packet.message), _("%s Welcome"), @@ -316,8 +316,8 @@ } unattach_connection_from_player(pconn); + send_conn_info_remove(pconn->self, game.est_connections); - send_conn_info_remove(pconn->self, game.est_connections); if (S_S_RUNNING == server_state()) { /* Player info is only updated when the game is running; this must be * done consistently or the client will end up with inconsistent errors. @@ -413,7 +413,7 @@ If pplayer is NULL, take the next available player that is not already associated. Note "observer" connections do not count for is_connected. You must set - pconn->obserber to TRUE before attaching! + pconn->observer to TRUE before attaching! **************************************************************************/ bool attach_connection_to_player(struct connection *pconn, struct player *pplayer) Index: server/ruleset.c =================================================================== --- server/ruleset.c (revision 14148) +++ server/ruleset.c (working copy) @@ -120,7 +120,6 @@ static void load_ruleset_governments(struct section_file *file); static void load_ruleset_terrain(struct section_file *file); static void load_ruleset_cities(struct section_file *file); -static void load_ruleset_nations(struct section_file *file); static void load_ruleset_effects(struct section_file *file); static void load_ruleset_game(void); @@ -3381,7 +3380,7 @@ Send the nations ruleset information (info on each nation) to the specified connections. **************************************************************************/ -void send_ruleset_nations(struct conn_list *dest) +static void send_ruleset_nations(struct conn_list *dest) { struct packet_ruleset_nation packet; struct packet_ruleset_nation_groups groups_packet; @@ -3573,12 +3572,6 @@ script_init(); openload_script_file("script"); - if (game.all_connections) { - /* Now that the rulesets are loaded we immediately send updates to any - * connected clients. */ - send_rulesets(game.all_connections); - } - /* Build AI unit class cache corresponding to loaded rulesets */ unit_class_ai_init(); } Index: server/ruleset.h =================================================================== --- server/ruleset.h (revision 14148) +++ server/ruleset.h (working copy) @@ -23,6 +23,4 @@ void load_rulesets(void); void send_rulesets(struct conn_list *dest); -void send_ruleset_nations(struct conn_list *dest); - #endif /* FC__RULESET_H */ Index: server/gamehand.c =================================================================== --- server/gamehand.c (revision 14148) +++ server/gamehand.c (working copy) @@ -515,12 +515,6 @@ static char **rulesets = NULL; int i; - if (pc->access_level != ALLOW_HACK) { - freelog(LOG_ERROR, "Trying to send ruleset choices to " - "unprivileged client."); - return; - } - if (!rulesets) { /* This is only read once per server invocation. Add a new ruleset * and you have to restart the server. */ Index: server/gamehand.h =================================================================== --- server/gamehand.h (revision 14148) +++ server/gamehand.h (working copy) @@ -28,6 +28,4 @@ const char *new_challenge_filename(struct connection *pc); -struct packet_single_want_hack_req; - #endif /* FC__GAMEHAND_H */ Index: server/sernet.c =================================================================== --- server/sernet.c (revision 14148) +++ server/sernet.c (working copy) @@ -371,7 +371,7 @@ Precondition - we have read_socket_data. Postcondition - there are no more packets to handle on this connection. *****************************************************************************/ -static void handle_incoming_client_packets(struct connection *pconn) +static void incoming_client_packets(struct connection *pconn) { struct packet_to_handle packet; #if PROCESSING_TIME_STATISTICS @@ -392,7 +392,7 @@ connection_do_buffer(pconn); start_processing_request(pconn, pconn->server.last_request_id_seen); - command_ok = handle_packet_input(pconn, packet.data, packet.type); + command_ok = server_packet_input(pconn, packet.data, packet.type); free(packet.data); finish_processing_request(pconn); @@ -728,7 +728,7 @@ if (read_socket_data(pconn->sock, pconn->buffer) >= 0) { /* We read packets; now handle them. */ - handle_incoming_client_packets(pconn); + incoming_client_packets(pconn); } else { /* Read failure; the connection is closed. */ close_socket_callback(pconn); Index: server/stdinhand.c =================================================================== --- server/stdinhand.c (revision 14148) +++ server/stdinhand.c (working copy) @@ -2946,8 +2946,9 @@ if (S_S_RUNNING == server_state()) { send_rulesets(pconn->self); send_server_settings(pconn->self); + send_game_info(pconn->self); send_player_info_c(NULL, pconn->self); - send_conn_info(game.est_connections, pconn->self); + send_conn_info(game.est_connections, pconn->self); } /* if we're taking another player with a user attached, @@ -3272,7 +3273,6 @@ sz_strlcpy(srvarg.load_filename, arg); game_load(&file); - send_server_settings(NULL); section_file_check_unused(&file, arg); section_file_free(&file); @@ -3282,7 +3282,9 @@ sanity_check(); + freelog(LOG_VERBOSE, "load_command() does send_rulesets()"); send_rulesets(game.est_connections); + send_server_settings(game.est_connections); send_game_info(game.est_connections); /* Everything seemed to load ok; spread the good news. */ @@ -3350,8 +3352,17 @@ } cmd_reply(CMD_RULESETDIR, caller, C_OK, _("Ruleset directory set to \"%s\""), str); - sz_strlcpy(game.rulesetdir, str); + + freelog(LOG_VERBOSE, "set_rulesetdir() does load_rulesets() with \"%s\"", + str); + sz_strlcpy(game.rulesetdir, str); load_rulesets(); + + if (game.est_connections) { + /* Now that the rulesets are loaded we immediately send updates to any + * connected clients. */ + send_rulesets(game.est_connections); + } } return TRUE; } Index: server/savegame.c =================================================================== --- server/savegame.c (revision 14148) +++ server/savegame.c (working copy) @@ -3555,7 +3555,8 @@ } /*************************************************************** -... + Called only in server/stdinhand.c load_command() + Entire ruleset is always sent afterward. ***************************************************************/ void game_load(struct section_file *file) { @@ -4049,13 +4050,8 @@ /* Initialize nations we loaded from rulesets. This has to be after * map loading and before we seek nations for players */ init_available_nations(); - if (game.est_connections) { - /* Update client knowledge about available nations after - * init_available_nations() may have marked some of them unavailable - * in this scenario */ - send_ruleset_nations(game.est_connections); - } + /* Now, load the players. */ players_iterate(pplayer) { player_load(pplayer, player_number(pplayer), file, improvement_order, improvement_order_size, technology_order, Index: client/repodlgs_common.c =================================================================== --- client/repodlgs_common.c (revision 14148) +++ client/repodlgs_common.c (working copy) @@ -251,8 +251,8 @@ settable_options_free(); - options_categories = fc_malloc(packet->num_categories - * sizeof(*options_categories)); + options_categories = fc_calloc(packet->num_categories, + sizeof(*options_categories)); num_options_categories = packet->num_categories; for (i = 0; i < num_options_categories; i++) { @@ -264,8 +264,8 @@ return; } - settable_options = fc_malloc(packet->num_settings - * sizeof(*settable_options)); + settable_options = fc_calloc(packet->num_settings, + sizeof(*settable_options)); num_settable_options = packet->num_settings; for (i = 0; i < num_settable_options; i++) { Index: client/clinet.c =================================================================== --- client/clinet.c (revision 14148) +++ client/clinet.c (working copy) @@ -379,7 +379,7 @@ if (result) { assert(packet != NULL); - handle_packet_input(packet, type); + client_packet_input(packet, type); free(packet); } else { assert(packet == NULL); @@ -393,7 +393,7 @@ /************************************************************************** This function will sniff at the given fd, get the packet and call - handle_packet_input. It will return if there is a network error or if + client_packet_input. It will return if there is a network error or if the PACKET_PROCESSING_FINISHED packet for the given request is received. **************************************************************************/ @@ -421,7 +421,7 @@ } assert(packet != NULL); - handle_packet_input(packet, type); + client_packet_input(packet, type); free(packet); if (type == PACKET_PROCESSING_FINISHED) { Index: client/civclient.c =================================================================== --- client/civclient.c (revision 14148) +++ client/civclient.c (working copy) @@ -437,7 +437,7 @@ /************************************************************************** ... **************************************************************************/ -void handle_packet_input(void *packet, int type) +void client_packet_input(void *packet, int type) { if (!client_handle_packet(type, packet)) { freelog(LOG_ERROR, "Received unknown packet (type %d) from server!", Index: client/civclient.h =================================================================== --- client/civclient.h (revision 14148) +++ client/civclient.h (working copy) @@ -33,7 +33,7 @@ C_S_OVER, }; -void handle_packet_input(void *packet, int type); +void client_packet_input(void *packet, int type); void send_report_request(enum report_type type); void send_attribute_block_request(void);
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev