<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

Reply via email to