Complete.Org: Mailing Lists: Archives: freeciv-dev: October 2005:
[Freeciv-Dev] (PR#13262) Include pubserver jobs v6
Home

[Freeciv-Dev] (PR#13262) Include pubserver jobs v6

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13262) Include pubserver jobs v6
From: "Per I. Mathisen" <per@xxxxxxxxxxx>
Date: Sat, 15 Oct 2005 12:49:36 -0700
Reply-to: bugs@xxxxxxxxxxx

<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13262 >

New version, just updated to most recent cv^H^Hsvn. Much of the previous
patch has been committed as smaller pieces.

  - Per

Index: server/civserver.c
===================================================================
--- server/civserver.c  (revision 11143)
+++ server/civserver.c  (working copy)
@@ -105,6 +105,7 @@
 #endif
 
   /* initialize server */
+  game.info.pubserver[0] = '\0';   /* identifies it as not pubserver */
   srv_init();
 
   /* parse command-line arguments... */
@@ -145,6 +146,9 @@
       free(option);
     } else if ((option = get_option_malloc("--bind", argv, &inx, argc))) {
       srvarg.bind_addr = option; /* Never freed. */
+    } else if ((option = get_option_malloc("--Pubserver", argv, &inx, argc))) {
+      sz_strlcpy(game.info.pubserver, option);
+      free(option);
     } else if ((option = get_option_malloc("--read", argv, &inx, argc)))
       srvarg.script_filename = option; /* Never freed. */
     else if ((option = get_option_malloc("--quitidle", argv, &inx, argc))) {
@@ -173,7 +177,8 @@
       sz_strlcpy(srvarg.serverid, option);
       free(option);
     } else if ((option = get_option_malloc("--saves", argv, &inx, argc))) {
-      srvarg.saves_pathname = option; /* Never freed. */
+      srvarg.saves_pathname = option; /* Base path. Never freed. */
+      sz_strlcpy(srvarg.final_savepath, option); /* Possibly changing path. */
     } else if (is_option("--version", argv[inx]))
       showvers = TRUE;
     else {
@@ -184,6 +189,11 @@
     inx++;
   }
 
+  if (is_pubserver() && !srvarg.exit_on_end) {
+    fc_fprintf(stderr, _("Pubserver mode requires --exit-on-end\n"));
+    exit(EXIT_FAILURE);
+  }
+
   if (showvers && !showhelp) {
     fc_fprintf(stderr, "%s \n", freeciv_name_version());
     exit(EXIT_SUCCESS);
@@ -221,6 +231,8 @@
 
     fc_fprintf(stderr, _("  -p, --port PORT\tListen for clients on "
                         "port PORT\n"));
+    fc_fprintf(stderr, _("  -P, --Pubserver VAL\tSee http://www.freeciv";
+                         "/index.php/Pubserver (requires -e)\n"));
     fc_fprintf(stderr, _("  -q, --quitidle TIME\tQuit if no players "
                         "for TIME seconds\n"));
     fc_fprintf(stderr, _("  -e, --exit-on-end\t"
Index: server/srv_main.c
===================================================================
--- server/srv_main.c   (revision 11144)
+++ server/srv_main.c   (working copy)
@@ -17,10 +17,14 @@
 
 #include <assert.h>
 #include <ctype.h>
+#include <dirent.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <time.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <sys/types.h>
 
 #ifdef HAVE_NETDB_H
 #include <netdb.h>
@@ -140,6 +144,14 @@
 static bool has_been_srv_init = FALSE;
 
 /**************************************************************************
+  Are we running in pubserver mode?
+**************************************************************************/
+bool is_pubserver(void)
+{
+  return (game.info.pubserver[0] != '\0');
+}
+
+/**************************************************************************
   Initialize the game seed.  This may safely be called multiple times.
 **************************************************************************/
 void init_game_seed(void)
@@ -179,6 +191,7 @@
   srvarg.load_filename[0] = '\0';
   srvarg.script_filename = NULL;
   srvarg.saves_pathname = "";
+  srvarg.final_savepath[0] = '\0';
 
   srvarg.quitidle = 0;
 
@@ -708,7 +721,7 @@
 **************************************************************************/
 void save_game(char *orig_filename, const char *save_reason)
 {
-  char filename[600];
+  char filename[600] = "civgame";
   char *dot;
   struct section_file file;
   struct timer *timer_cpu, *timer_user;
@@ -724,10 +737,16 @@
     *dot = '\0';
   }
 
-  /* If orig_filename is NULL or empty, use "civgame.info.year>m". */
-  if (filename[0] == '\0'){
-    my_snprintf(filename, sizeof(filename),
-       "%s%+05dm", game.save_name, game.info.year);
+  if (is_pubserver()) {
+    /* game.savename could have been renamed, and we need to be sure
+     * the game is not, for scripts that may want to find it */
+    sz_strlcpy(filename, "civgame"); 
+  } else {
+    /* If orig_filename is NULL or empty, use "civgame.info.year>m". */
+    if (filename[0] == '\0'){
+      my_snprintf(filename, sizeof(filename),
+       "  %s%+05dm", game.save_name, game.info.year);
+    }
   }
   
   timer_cpu = new_timer_start(TIMER_CPU, TIMER_ACTIVE);
@@ -748,9 +767,9 @@
     char tmpname[600];
 
     /* Ensure the saves directory exists. */
-    make_dir(srvarg.saves_pathname);
+    make_dir(srvarg.final_savepath);
 
-    sz_strlcpy(tmpname, srvarg.saves_pathname);
+    sz_strlcpy(tmpname, srvarg.final_savepath);
     if (tmpname[0] != '\0') {
       sz_strlcat(tmpname, "/");
     }
@@ -758,10 +777,11 @@
     sz_strlcpy(filename, tmpname);
   }
 
-  if(!section_file_save(&file, filename, game.info.save_compress_level))
+  if (!section_file_save(&file, filename, game.info.save_compress_level)) {
     con_write(C_FAIL, _("Failed saving game as %s"), filename);
-  else
+  } else {
     con_write(C_OK, _("Game saved as %s"), filename);
+  }
 
   section_file_free(&file);
 
@@ -1309,12 +1329,17 @@
     int num_ready = 0, num_unready = 0;
 
     players_iterate(pplayer) {
-      if (pplayer->is_connected) {
-       if (pplayer->is_ready) {
-         num_ready++;
-       } else {
-         num_unready++;
-       }
+      /* For pubserver:  If we load a game, some players may be assigned 
+       * to user accounts, in which case we should not start until they 
+       * have joined too.  Otherwise it would be easy to cheat.  This 
+       * will be problematic for scenarios where creators forget to 
+       * reset usernames. */
+      if (pplayer->is_ready && pplayer->is_connected) {
+       num_ready++;
+      } else if (pplayer->is_connected 
+                 || (is_valid_username(pplayer->username)
+                     && is_pubserver() > 0)) {
+       num_unready++;
       }
     } players_iterate_end;
     if (num_unready > 0) {
@@ -1625,6 +1650,36 @@
 }
 
 /**************************************************************************
+  Special public server code.  Enabled with the -P command-line option.
+**************************************************************************/
+static void pubserver_init(void)
+{
+  if (is_pubserver()) {
+    DIR *dir;
+    char path[90], gamelogfile[100], conlogfile[100];
+
+    /* Create directory */
+    my_snprintf(path, sizeof(path), "%s%s%s",
+                strlen(srvarg.saves_pathname) > 0 ? srvarg.saves_pathname : "",
+                strlen(srvarg.saves_pathname) > 0 ? "/" : "",
+                game.info.pubserver);
+    dir = opendir(path);
+    if (dir == NULL) {
+      freelog(LOG_FATAL, "Could not open directory \"%s\".", path);
+      exit(EXIT_FAILURE);
+    }
+    /* Redirect output to saves directory */
+    sz_strlcpy(srvarg.final_savepath, path);
+    my_snprintf(gamelogfile, sizeof(gamelogfile), "%s/gamelog.txt", 
+                srvarg.final_savepath);
+    my_snprintf(conlogfile, sizeof(conlogfile), "%s/cmdline.txt", 
+                srvarg.final_savepath);
+    con_log_init(conlogfile, srvarg.loglevel);
+    gamelog_init(gamelogfile);
+  }
+}
+
+/**************************************************************************
   Server initialization.
 **************************************************************************/
 void srv_main(void)
@@ -1681,6 +1736,7 @@
 
   /* Run server loop */
   while (TRUE) {
+    pubserver_init();
     srv_loop();
 
     send_game_state(game.est_connections, CLIENT_GAME_OVER_STATE);
Index: server/srv_main.h
===================================================================
--- server/srv_main.h   (revision 11143)
+++ server/srv_main.h   (working copy)
@@ -33,11 +33,12 @@
   /* the log level */
   int loglevel;
   /* filenames */
-  char *log_filename;
-  char *gamelog_filename;
+  char *log_filename;      /* ignored by pubserver */
+  char *gamelog_filename;  /* ignored by pubserver */
   char load_filename[512]; /* FIXME: may not be long enough? use MAX_PATH? */
   char *script_filename;
-  char *saves_pathname;
+  char *saves_pathname;     /* base path; used by pubserver for all output */
+  char final_savepath[512]; /* may be changed by pubserver code */
   char serverid[256];
   /* quit if there no players after a given time interval */
   int quitidle;
@@ -80,5 +81,7 @@
 
 extern bool force_end_of_sniff;
 
+bool is_pubserver(void);
+
 void init_available_nations(void);
 #endif /* FC__SRV_MAIN_H */
Index: server/connecthand.c
===================================================================
--- server/connecthand.c        (revision 11143)
+++ server/connecthand.c        (working copy)
@@ -103,6 +103,13 @@
                _("Welcome to the %s Server at port %d."),
                 freeciv_name_version(), srvarg.port);
   }
+  if (is_pubserver()) {
+    notify_conn(dest, NULL, E_MESSAGE_WALL, 
+                _("Server is running in public mode. Some commands will "
+                "be restricted. This is game \"%s\". Use this number "
+                "to load a saved game or report problems."), 
+                game.info.pubserver);
+  }
 
   /* FIXME: this (getting messages about others logging on) should be a 
    * message option for the client with event */
Index: server/stdinhand.c
===================================================================
--- server/stdinhand.c  (revision 11144)
+++ server/stdinhand.c  (working copy)
@@ -117,7 +117,7 @@
 *********************************************************************/
 static bool is_restricted(struct connection *caller)
 {
-  return (caller && caller->access_level != ALLOW_HACK);
+  return (is_pubserver() || (caller && caller->access_level != ALLOW_HACK));
 }
 
 /********************************************************************
@@ -2897,6 +2897,14 @@
     goto end;
   } 
 
+  if (!game.info.is_new_game
+      && is_valid_username(pplayer->username)
+      && is_pubserver()) {
+    cmd_reply(CMD_TAKE, caller, C_FAIL,
+              _("You cannot take over other players in a loaded game."));
+    goto end;
+  }
+
   res = TRUE;
   if (check) {
     goto end;
@@ -3170,6 +3178,7 @@
   struct timer *loadtimer, *uloadtimer;  
   struct section_file file;
   char arg[MAX_LEN_PATH];
+  int i;
 
   if (!filename || filename[0] == '\0') {
     cmd_reply(CMD_LOAD, caller, C_FAIL, _("Usage: load <game name>"));
@@ -3180,7 +3189,13 @@
               "security reasons."), filename);
     return FALSE;
   }
-  {
+  /* if filename is a valid number, it may be a pubserver savegame */
+  if (is_pubserver() && sscanf(filename, "%d", &i) == 1) {
+    my_snprintf(arg, sizeof(arg), "%s%s%s/civgame.sav%s",
+                srvarg.saves_pathname,
+                srvarg.saves_pathname[0] == '\0' ? "" : "/",
+                filename, game.info.save_compress_level > 0 ? ".gz" : "");
+  } else {
     /* it is a normal savegame or maybe a scenario */
     char tmp[MAX_LEN_PATH];
 
Index: common/packets.def
===================================================================
--- common/packets.def  (revision 11143)
+++ common/packets.def  (working copy)
@@ -351,6 +351,7 @@
   
   UINT8 aifill;
 
+  STRING pubserver[MAX_LEN_NAME]; add-cap(pubserver)
   BOOL is_new_game;   # TRUE only in pregame for "new" (not loaded) games
   FLOAT seconds_to_phasedone;
   UINT32 timeout;
Index: common/packets_gen.c
===================================================================
--- common/packets_gen.c        (revision 11143)
+++ common/packets_gen.c        (working copy)
@@ -3281,7 +3281,7 @@
 
 #define cmp_packet_game_info_100 cmp_const
 
-BV_DEFINE(packet_game_info_100_fields, 106);
+BV_DEFINE(packet_game_info_100_fields, 107);
 
 static struct packet_game_info *receive_packet_game_info_100(struct connection 
*pc, enum packet_type type)
 {
@@ -3337,6 +3337,1695 @@
       real_packet->aifill = readin;
     }
   }
+  if (BV_ISSET(fields, 4)) {
+    dio_get_string(&din, real_packet->pubserver, 
sizeof(real_packet->pubserver));
+  }
+  real_packet->is_new_game = BV_ISSET(fields, 5);
+  if (BV_ISSET(fields, 6)) {
+    {
+      int tmp;
+      
+      dio_get_uint32(&din, &tmp);
+      real_packet->seconds_to_phasedone = (float)(tmp) / 10000.0;
+    }
+  }
+  if (BV_ISSET(fields, 7)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->timeout = readin;
+    }
+  }
+  if (BV_ISSET(fields, 8)) {
+    {
+      int readin;
+    
+      dio_get_sint16(&din, &readin);
+      real_packet->turn = readin;
+    }
+  }
+  if (BV_ISSET(fields, 9)) {
+    {
+      int readin;
+    
+      dio_get_sint16(&din, &readin);
+      real_packet->phase = readin;
+    }
+  }
+  if (BV_ISSET(fields, 10)) {
+    {
+      int readin;
+    
+      dio_get_sint16(&din, &readin);
+      real_packet->year = readin;
+    }
+  }
+  if (BV_ISSET(fields, 11)) {
+    {
+      int readin;
+    
+      dio_get_sint16(&din, &readin);
+      real_packet->end_year = readin;
+    }
+  }
+  real_packet->simultaneous_phases = BV_ISSET(fields, 12);
+  if (BV_ISSET(fields, 13)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->num_phases = readin;
+    }
+  }
+  if (BV_ISSET(fields, 14)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->min_players = readin;
+    }
+  }
+  if (BV_ISSET(fields, 15)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->max_players = readin;
+    }
+  }
+  if (BV_ISSET(fields, 16)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->nplayers = readin;
+    }
+  }
+  if (BV_ISSET(fields, 17)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->player_idx = readin;
+    }
+  }
+  if (BV_ISSET(fields, 18)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->globalwarming = readin;
+    }
+  }
+  if (BV_ISSET(fields, 19)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->heating = readin;
+    }
+  }
+  if (BV_ISSET(fields, 20)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->warminglevel = readin;
+    }
+  }
+  if (BV_ISSET(fields, 21)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->nuclearwinter = readin;
+    }
+  }
+  if (BV_ISSET(fields, 22)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->cooling = readin;
+    }
+  }
+  if (BV_ISSET(fields, 23)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->coolinglevel = readin;
+    }
+  }
+  if (BV_ISSET(fields, 24)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->cityfactor = readin;
+    }
+  }
+  if (BV_ISSET(fields, 25)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->diplcost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 26)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->freecost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 27)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->conquercost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 28)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->unhappysize = readin;
+    }
+  }
+  if (BV_ISSET(fields, 29)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->angrycitizen = readin;
+    }
+  }
+  if (BV_ISSET(fields, 30)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->techpenalty = readin;
+    }
+  }
+  if (BV_ISSET(fields, 31)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->foodbox = readin;
+    }
+  }
+  if (BV_ISSET(fields, 32)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->shieldbox = readin;
+    }
+  }
+  if (BV_ISSET(fields, 33)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->sciencebox = readin;
+    }
+  }
+  if (BV_ISSET(fields, 34)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->diplomacy = readin;
+    }
+  }
+  if (BV_ISSET(fields, 35)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->dispersion = readin;
+    }
+  }
+  if (BV_ISSET(fields, 36)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->tcptimeout = readin;
+    }
+  }
+  if (BV_ISSET(fields, 37)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->netwait = readin;
+    }
+  }
+  if (BV_ISSET(fields, 38)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->pingtimeout = readin;
+    }
+  }
+  if (BV_ISSET(fields, 39)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->pingtime = readin;
+    }
+  }
+  if (BV_ISSET(fields, 40)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->diplchance = readin;
+    }
+  }
+  if (BV_ISSET(fields, 41)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->citymindist = readin;
+    }
+  }
+  if (BV_ISSET(fields, 42)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->civilwarsize = readin;
+    }
+  }
+  if (BV_ISSET(fields, 43)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->contactturns = readin;
+    }
+  }
+  if (BV_ISSET(fields, 44)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->rapturedelay = readin;
+    }
+  }
+  if (BV_ISSET(fields, 45)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->celebratesize = readin;
+    }
+  }
+  if (BV_ISSET(fields, 46)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->barbarianrate = readin;
+    }
+  }
+  if (BV_ISSET(fields, 47)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->onsetbarbarian = readin;
+    }
+  }
+  if (BV_ISSET(fields, 48)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->occupychance = readin;
+    }
+  }
+  real_packet->autoattack = BV_ISSET(fields, 49);
+  real_packet->spacerace = BV_ISSET(fields, 50);
+  if (BV_ISSET(fields, 51)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->aqueductloss = readin;
+    }
+  }
+  if (BV_ISSET(fields, 52)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->killcitizen = readin;
+    }
+  }
+  if (BV_ISSET(fields, 53)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->razechance = readin;
+    }
+  }
+  real_packet->savepalace = BV_ISSET(fields, 54);
+  real_packet->natural_city_names = BV_ISSET(fields, 55);
+  real_packet->turnblock = BV_ISSET(fields, 56);
+  real_packet->fixedlength = BV_ISSET(fields, 57);
+  real_packet->auto_ai_toggle = BV_ISSET(fields, 58);
+  real_packet->fogofwar = BV_ISSET(fields, 59);
+  if (BV_ISSET(fields, 60)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->borders = readin;
+    }
+  }
+  if (BV_ISSET(fields, 61)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->nbarbarians = readin;
+    }
+  }
+  real_packet->happyborders = BV_ISSET(fields, 62);
+  real_packet->slow_invasions = BV_ISSET(fields, 63);
+  if (BV_ISSET(fields, 64)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->add_to_size_limit = readin;
+    }
+  }
+  if (BV_ISSET(fields, 65)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->notradesize = readin;
+    }
+  }
+  if (BV_ISSET(fields, 66)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->fulltradesize = readin;
+    }
+  }
+  if (BV_ISSET(fields, 67)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->allowed_city_names = readin;
+    }
+  }
+  if (BV_ISSET(fields, 68)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->palace_building = readin;
+    }
+  }
+  if (BV_ISSET(fields, 69)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->land_defend_building = readin;
+    }
+  }
+  real_packet->changable_tax = BV_ISSET(fields, 70);
+  if (BV_ISSET(fields, 71)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->forced_science = readin;
+    }
+  }
+  if (BV_ISSET(fields, 72)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->forced_luxury = readin;
+    }
+  }
+  if (BV_ISSET(fields, 73)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->forced_gold = readin;
+    }
+  }
+  if (BV_ISSET(fields, 74)) {
+    
+    {
+      int i;
+    
+      for (i = 0; i < O_MAX; i++) {
+        {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->min_city_center_output[i] = readin;
+    }
+      }
+    }
+  }
+  if (BV_ISSET(fields, 75)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->min_dist_bw_cities = readin;
+    }
+  }
+  if (BV_ISSET(fields, 76)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->init_vis_radius_sq = readin;
+    }
+  }
+  if (BV_ISSET(fields, 77)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->hut_overflight = readin;
+    }
+  }
+  real_packet->pillage_select = BV_ISSET(fields, 78);
+  if (BV_ISSET(fields, 79)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->nuke_contamination = readin;
+    }
+  }
+  if (BV_ISSET(fields, 80)) {
+    
+    {
+      int i;
+    
+      for (i = 0; i < MAX_GRANARY_INIS; i++) {
+        {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->granary_food_ini[i] = readin;
+    }
+      }
+    }
+  }
+  if (BV_ISSET(fields, 81)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->granary_num_inis = readin;
+    }
+  }
+  if (BV_ISSET(fields, 82)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->granary_food_inc = readin;
+    }
+  }
+  if (BV_ISSET(fields, 83)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->tech_cost_style = readin;
+    }
+  }
+  if (BV_ISSET(fields, 84)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->tech_leakage = readin;
+    }
+  }
+  if (BV_ISSET(fields, 85)) {
+    {
+      int readin;
+    
+      dio_get_sint16(&din, &readin);
+      real_packet->tech_cost_double_year = readin;
+    }
+  }
+  real_packet->killstack = BV_ISSET(fields, 86);
+  if (BV_ISSET(fields, 87)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->autoupgrade_veteran_loss = readin;
+    }
+  }
+  if (BV_ISSET(fields, 88)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->incite_improvement_factor = readin;
+    }
+  }
+  if (BV_ISSET(fields, 89)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->incite_unit_factor = readin;
+    }
+  }
+  if (BV_ISSET(fields, 90)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->incite_total_factor = readin;
+    }
+  }
+  if (BV_ISSET(fields, 91)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->government_when_anarchy_id = readin;
+    }
+  }
+  if (BV_ISSET(fields, 92)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->revolution_length = readin;
+    }
+  }
+  if (BV_ISSET(fields, 93)) {
+    {
+      int readin;
+    
+      dio_get_sint16(&din, &readin);
+      real_packet->base_pollution = readin;
+    }
+  }
+  if (BV_ISSET(fields, 94)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->happy_cost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 95)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->food_cost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 96)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->base_bribe_cost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 97)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->base_incite_cost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 98)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->base_tech_cost = readin;
+    }
+  }
+  if (BV_ISSET(fields, 99)) {
+    {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->ransom_gold = readin;
+    }
+  }
+  if (BV_ISSET(fields, 100)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->save_nturns = readin;
+    }
+  }
+  if (BV_ISSET(fields, 101)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->save_compress_level = readin;
+    }
+  }
+  if (BV_ISSET(fields, 102)) {
+    dio_get_string(&din, real_packet->start_units, 
sizeof(real_packet->start_units));
+  }
+  if (BV_ISSET(fields, 103)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->num_teams = readin;
+    }
+  }
+  if (BV_ISSET(fields, 104)) {
+    
+    {
+      int i;
+    
+      if(real_packet->num_teams > MAX_NUM_TEAMS) {
+        freelog(LOG_ERROR, "packets_gen.c: WARNING: truncation array");
+        real_packet->num_teams = MAX_NUM_TEAMS;
+      }
+      for (i = 0; i < real_packet->num_teams; i++) {
+        dio_get_string(&din, real_packet->team_names_orig[i], 
sizeof(real_packet->team_names_orig[i]));
+      }
+    }
+  }
+  if (BV_ISSET(fields, 105)) {
+    
+    for (;;) {
+      int i;
+    
+      dio_get_uint8(&din, &i);
+      if(i == 255) {
+        break;
+      }
+      if(i > A_LAST) {
+        freelog(LOG_ERROR, "packets_gen.c: WARNING: ignoring intra array 
diff");
+      } else {
+        dio_get_bool8(&din, &real_packet->global_advances[i]);
+      }
+    }
+  }
+  if (BV_ISSET(fields, 106)) {
+    
+    for (;;) {
+      int i;
+    
+      dio_get_uint8(&din, &i);
+      if(i == 255) {
+        break;
+      }
+      if(i > B_LAST) {
+        freelog(LOG_ERROR, "packets_gen.c: WARNING: ignoring intra array 
diff");
+      } else {
+        {
+      int readin;
+    
+      dio_get_uint16(&din, &readin);
+      real_packet->great_wonders[i] = readin;
+    }
+      }
+    }
+  }
+
+  clone = fc_malloc(sizeof(*clone));
+  *clone = *real_packet;
+  if (old) {
+    free(old);
+  }
+  hash_insert(*hash, clone, clone);
+
+  RECEIVE_PACKET_END(real_packet);
+}
+
+static int send_packet_game_info_100(struct connection *pc, const struct 
packet_game_info *packet)
+{
+  const struct packet_game_info *real_packet = packet;
+  packet_game_info_100_fields fields;
+  struct packet_game_info *old, *clone;
+  bool differ, old_from_hash, force_send_of_unchanged = TRUE;
+  struct hash_table **hash = &pc->phs.sent[PACKET_GAME_INFO];
+  int different = 0;
+  SEND_PACKET_START(PACKET_GAME_INFO);
+
+  if (!*hash) {
+    *hash = hash_new(hash_packet_game_info_100, cmp_packet_game_info_100);
+  }
+  BV_CLR_ALL(fields);
+
+  old = hash_lookup_data(*hash, real_packet);
+  old_from_hash = (old != NULL);
+  if (!old) {
+    old = fc_malloc(sizeof(*old));
+    memset(old, 0, sizeof(*old));
+    force_send_of_unchanged = TRUE;
+  }
+
+  differ = (old->gold != real_packet->gold);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 0);}
+
+  differ = (old->tech != real_packet->tech);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 1);}
+
+  differ = (old->skill_level != real_packet->skill_level);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 2);}
+
+  differ = (old->aifill != real_packet->aifill);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 3);}
+
+  differ = (strcmp(old->pubserver, real_packet->pubserver) != 0);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 4);}
+
+  differ = (old->is_new_game != real_packet->is_new_game);
+  if(differ) {different++;}
+  if(packet->is_new_game) {BV_SET(fields, 5);}
+
+  differ = (old->seconds_to_phasedone != real_packet->seconds_to_phasedone);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 6);}
+
+  differ = (old->timeout != real_packet->timeout);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 7);}
+
+  differ = (old->turn != real_packet->turn);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 8);}
+
+  differ = (old->phase != real_packet->phase);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 9);}
+
+  differ = (old->year != real_packet->year);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 10);}
+
+  differ = (old->end_year != real_packet->end_year);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 11);}
+
+  differ = (old->simultaneous_phases != real_packet->simultaneous_phases);
+  if(differ) {different++;}
+  if(packet->simultaneous_phases) {BV_SET(fields, 12);}
+
+  differ = (old->num_phases != real_packet->num_phases);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 13);}
+
+  differ = (old->min_players != real_packet->min_players);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 14);}
+
+  differ = (old->max_players != real_packet->max_players);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 15);}
+
+  differ = (old->nplayers != real_packet->nplayers);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 16);}
+
+  differ = (old->player_idx != real_packet->player_idx);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 17);}
+
+  differ = (old->globalwarming != real_packet->globalwarming);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 18);}
+
+  differ = (old->heating != real_packet->heating);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 19);}
+
+  differ = (old->warminglevel != real_packet->warminglevel);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 20);}
+
+  differ = (old->nuclearwinter != real_packet->nuclearwinter);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 21);}
+
+  differ = (old->cooling != real_packet->cooling);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 22);}
+
+  differ = (old->coolinglevel != real_packet->coolinglevel);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 23);}
+
+  differ = (old->cityfactor != real_packet->cityfactor);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 24);}
+
+  differ = (old->diplcost != real_packet->diplcost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 25);}
+
+  differ = (old->freecost != real_packet->freecost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 26);}
+
+  differ = (old->conquercost != real_packet->conquercost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 27);}
+
+  differ = (old->unhappysize != real_packet->unhappysize);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 28);}
+
+  differ = (old->angrycitizen != real_packet->angrycitizen);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 29);}
+
+  differ = (old->techpenalty != real_packet->techpenalty);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 30);}
+
+  differ = (old->foodbox != real_packet->foodbox);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 31);}
+
+  differ = (old->shieldbox != real_packet->shieldbox);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 32);}
+
+  differ = (old->sciencebox != real_packet->sciencebox);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 33);}
+
+  differ = (old->diplomacy != real_packet->diplomacy);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 34);}
+
+  differ = (old->dispersion != real_packet->dispersion);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 35);}
+
+  differ = (old->tcptimeout != real_packet->tcptimeout);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 36);}
+
+  differ = (old->netwait != real_packet->netwait);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 37);}
+
+  differ = (old->pingtimeout != real_packet->pingtimeout);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 38);}
+
+  differ = (old->pingtime != real_packet->pingtime);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 39);}
+
+  differ = (old->diplchance != real_packet->diplchance);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 40);}
+
+  differ = (old->citymindist != real_packet->citymindist);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 41);}
+
+  differ = (old->civilwarsize != real_packet->civilwarsize);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 42);}
+
+  differ = (old->contactturns != real_packet->contactturns);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 43);}
+
+  differ = (old->rapturedelay != real_packet->rapturedelay);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 44);}
+
+  differ = (old->celebratesize != real_packet->celebratesize);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 45);}
+
+  differ = (old->barbarianrate != real_packet->barbarianrate);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 46);}
+
+  differ = (old->onsetbarbarian != real_packet->onsetbarbarian);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 47);}
+
+  differ = (old->occupychance != real_packet->occupychance);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 48);}
+
+  differ = (old->autoattack != real_packet->autoattack);
+  if(differ) {different++;}
+  if(packet->autoattack) {BV_SET(fields, 49);}
+
+  differ = (old->spacerace != real_packet->spacerace);
+  if(differ) {different++;}
+  if(packet->spacerace) {BV_SET(fields, 50);}
+
+  differ = (old->aqueductloss != real_packet->aqueductloss);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 51);}
+
+  differ = (old->killcitizen != real_packet->killcitizen);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 52);}
+
+  differ = (old->razechance != real_packet->razechance);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 53);}
+
+  differ = (old->savepalace != real_packet->savepalace);
+  if(differ) {different++;}
+  if(packet->savepalace) {BV_SET(fields, 54);}
+
+  differ = (old->natural_city_names != real_packet->natural_city_names);
+  if(differ) {different++;}
+  if(packet->natural_city_names) {BV_SET(fields, 55);}
+
+  differ = (old->turnblock != real_packet->turnblock);
+  if(differ) {different++;}
+  if(packet->turnblock) {BV_SET(fields, 56);}
+
+  differ = (old->fixedlength != real_packet->fixedlength);
+  if(differ) {different++;}
+  if(packet->fixedlength) {BV_SET(fields, 57);}
+
+  differ = (old->auto_ai_toggle != real_packet->auto_ai_toggle);
+  if(differ) {different++;}
+  if(packet->auto_ai_toggle) {BV_SET(fields, 58);}
+
+  differ = (old->fogofwar != real_packet->fogofwar);
+  if(differ) {different++;}
+  if(packet->fogofwar) {BV_SET(fields, 59);}
+
+  differ = (old->borders != real_packet->borders);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 60);}
+
+  differ = (old->nbarbarians != real_packet->nbarbarians);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 61);}
+
+  differ = (old->happyborders != real_packet->happyborders);
+  if(differ) {different++;}
+  if(packet->happyborders) {BV_SET(fields, 62);}
+
+  differ = (old->slow_invasions != real_packet->slow_invasions);
+  if(differ) {different++;}
+  if(packet->slow_invasions) {BV_SET(fields, 63);}
+
+  differ = (old->add_to_size_limit != real_packet->add_to_size_limit);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 64);}
+
+  differ = (old->notradesize != real_packet->notradesize);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 65);}
+
+  differ = (old->fulltradesize != real_packet->fulltradesize);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 66);}
+
+  differ = (old->allowed_city_names != real_packet->allowed_city_names);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 67);}
+
+  differ = (old->palace_building != real_packet->palace_building);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 68);}
+
+  differ = (old->land_defend_building != real_packet->land_defend_building);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 69);}
+
+  differ = (old->changable_tax != real_packet->changable_tax);
+  if(differ) {different++;}
+  if(packet->changable_tax) {BV_SET(fields, 70);}
+
+  differ = (old->forced_science != real_packet->forced_science);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 71);}
+
+  differ = (old->forced_luxury != real_packet->forced_luxury);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 72);}
+
+  differ = (old->forced_gold != real_packet->forced_gold);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 73);}
+
+
+    {
+      differ = (O_MAX != O_MAX);
+      if(!differ) {
+        int i;
+        for (i = 0; i < O_MAX; i++) {
+          if (old->min_city_center_output[i] != 
real_packet->min_city_center_output[i]) {
+            differ = TRUE;
+            break;
+          }
+        }
+      }
+    }
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 74);}
+
+  differ = (old->min_dist_bw_cities != real_packet->min_dist_bw_cities);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 75);}
+
+  differ = (old->init_vis_radius_sq != real_packet->init_vis_radius_sq);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 76);}
+
+  differ = (old->hut_overflight != real_packet->hut_overflight);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 77);}
+
+  differ = (old->pillage_select != real_packet->pillage_select);
+  if(differ) {different++;}
+  if(packet->pillage_select) {BV_SET(fields, 78);}
+
+  differ = (old->nuke_contamination != real_packet->nuke_contamination);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 79);}
+
+
+    {
+      differ = (MAX_GRANARY_INIS != MAX_GRANARY_INIS);
+      if(!differ) {
+        int i;
+        for (i = 0; i < MAX_GRANARY_INIS; i++) {
+          if (old->granary_food_ini[i] != real_packet->granary_food_ini[i]) {
+            differ = TRUE;
+            break;
+          }
+        }
+      }
+    }
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 80);}
+
+  differ = (old->granary_num_inis != real_packet->granary_num_inis);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 81);}
+
+  differ = (old->granary_food_inc != real_packet->granary_food_inc);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 82);}
+
+  differ = (old->tech_cost_style != real_packet->tech_cost_style);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 83);}
+
+  differ = (old->tech_leakage != real_packet->tech_leakage);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 84);}
+
+  differ = (old->tech_cost_double_year != real_packet->tech_cost_double_year);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 85);}
+
+  differ = (old->killstack != real_packet->killstack);
+  if(differ) {different++;}
+  if(packet->killstack) {BV_SET(fields, 86);}
+
+  differ = (old->autoupgrade_veteran_loss != 
real_packet->autoupgrade_veteran_loss);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 87);}
+
+  differ = (old->incite_improvement_factor != 
real_packet->incite_improvement_factor);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 88);}
+
+  differ = (old->incite_unit_factor != real_packet->incite_unit_factor);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 89);}
+
+  differ = (old->incite_total_factor != real_packet->incite_total_factor);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 90);}
+
+  differ = (old->government_when_anarchy_id != 
real_packet->government_when_anarchy_id);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 91);}
+
+  differ = (old->revolution_length != real_packet->revolution_length);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 92);}
+
+  differ = (old->base_pollution != real_packet->base_pollution);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 93);}
+
+  differ = (old->happy_cost != real_packet->happy_cost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 94);}
+
+  differ = (old->food_cost != real_packet->food_cost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 95);}
+
+  differ = (old->base_bribe_cost != real_packet->base_bribe_cost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 96);}
+
+  differ = (old->base_incite_cost != real_packet->base_incite_cost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 97);}
+
+  differ = (old->base_tech_cost != real_packet->base_tech_cost);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 98);}
+
+  differ = (old->ransom_gold != real_packet->ransom_gold);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 99);}
+
+  differ = (old->save_nturns != real_packet->save_nturns);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 100);}
+
+  differ = (old->save_compress_level != real_packet->save_compress_level);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 101);}
+
+  differ = (strcmp(old->start_units, real_packet->start_units) != 0);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 102);}
+
+  differ = (old->num_teams != real_packet->num_teams);
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 103);}
+
+
+    {
+      differ = (old->num_teams != real_packet->num_teams);
+      if(!differ) {
+        int i;
+        for (i = 0; i < real_packet->num_teams; i++) {
+          if (strcmp(old->team_names_orig[i], real_packet->team_names_orig[i]) 
!= 0) {
+            differ = TRUE;
+            break;
+          }
+        }
+      }
+    }
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 104);}
+
+
+    {
+      differ = (A_LAST != A_LAST);
+      if(!differ) {
+        int i;
+        for (i = 0; i < A_LAST; i++) {
+          if (old->global_advances[i] != real_packet->global_advances[i]) {
+            differ = TRUE;
+            break;
+          }
+        }
+      }
+    }
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 105);}
+
+
+    {
+      differ = (B_LAST != B_LAST);
+      if(!differ) {
+        int i;
+        for (i = 0; i < B_LAST; i++) {
+          if (old->great_wonders[i] != real_packet->great_wonders[i]) {
+            differ = TRUE;
+            break;
+          }
+        }
+      }
+    }
+  if(differ) {different++;}
+  if(differ) {BV_SET(fields, 106);}
+
+  if (different == 0 && !force_send_of_unchanged) {
+    return 0;
+  }
+
+  DIO_BV_PUT(&dout, fields);
+
+  if (BV_ISSET(fields, 0)) {
+    dio_put_uint32(&dout, real_packet->gold);
+  }
+  if (BV_ISSET(fields, 1)) {
+    dio_put_uint32(&dout, real_packet->tech);
+  }
+  if (BV_ISSET(fields, 2)) {
+    dio_put_uint32(&dout, real_packet->skill_level);
+  }
+  if (BV_ISSET(fields, 3)) {
+    dio_put_uint8(&dout, real_packet->aifill);
+  }
+  if (BV_ISSET(fields, 4)) {
+    dio_put_string(&dout, real_packet->pubserver);
+  }
+  /* field 5 is folded into the header */
+  if (BV_ISSET(fields, 6)) {
+    dio_put_uint32(&dout, (int)(real_packet->seconds_to_phasedone * 10000));
+  }
+  if (BV_ISSET(fields, 7)) {
+    dio_put_uint32(&dout, real_packet->timeout);
+  }
+  if (BV_ISSET(fields, 8)) {
+    dio_put_sint16(&dout, real_packet->turn);
+  }
+  if (BV_ISSET(fields, 9)) {
+    dio_put_sint16(&dout, real_packet->phase);
+  }
+  if (BV_ISSET(fields, 10)) {
+    dio_put_sint16(&dout, real_packet->year);
+  }
+  if (BV_ISSET(fields, 11)) {
+    dio_put_sint16(&dout, real_packet->end_year);
+  }
+  /* field 12 is folded into the header */
+  if (BV_ISSET(fields, 13)) {
+    dio_put_uint32(&dout, real_packet->num_phases);
+  }
+  if (BV_ISSET(fields, 14)) {
+    dio_put_uint8(&dout, real_packet->min_players);
+  }
+  if (BV_ISSET(fields, 15)) {
+    dio_put_uint8(&dout, real_packet->max_players);
+  }
+  if (BV_ISSET(fields, 16)) {
+    dio_put_uint8(&dout, real_packet->nplayers);
+  }
+  if (BV_ISSET(fields, 17)) {
+    dio_put_uint8(&dout, real_packet->player_idx);
+  }
+  if (BV_ISSET(fields, 18)) {
+    dio_put_uint32(&dout, real_packet->globalwarming);
+  }
+  if (BV_ISSET(fields, 19)) {
+    dio_put_uint32(&dout, real_packet->heating);
+  }
+  if (BV_ISSET(fields, 20)) {
+    dio_put_uint32(&dout, real_packet->warminglevel);
+  }
+  if (BV_ISSET(fields, 21)) {
+    dio_put_uint32(&dout, real_packet->nuclearwinter);
+  }
+  if (BV_ISSET(fields, 22)) {
+    dio_put_uint32(&dout, real_packet->cooling);
+  }
+  if (BV_ISSET(fields, 23)) {
+    dio_put_uint32(&dout, real_packet->coolinglevel);
+  }
+  if (BV_ISSET(fields, 24)) {
+    dio_put_uint8(&dout, real_packet->cityfactor);
+  }
+  if (BV_ISSET(fields, 25)) {
+    dio_put_uint8(&dout, real_packet->diplcost);
+  }
+  if (BV_ISSET(fields, 26)) {
+    dio_put_uint8(&dout, real_packet->freecost);
+  }
+  if (BV_ISSET(fields, 27)) {
+    dio_put_uint8(&dout, real_packet->conquercost);
+  }
+  if (BV_ISSET(fields, 28)) {
+    dio_put_uint8(&dout, real_packet->unhappysize);
+  }
+  if (BV_ISSET(fields, 29)) {
+    dio_put_uint8(&dout, real_packet->angrycitizen);
+  }
+  if (BV_ISSET(fields, 30)) {
+    dio_put_uint8(&dout, real_packet->techpenalty);
+  }
+  if (BV_ISSET(fields, 31)) {
+    dio_put_uint32(&dout, real_packet->foodbox);
+  }
+  if (BV_ISSET(fields, 32)) {
+    dio_put_uint32(&dout, real_packet->shieldbox);
+  }
+  if (BV_ISSET(fields, 33)) {
+    dio_put_uint32(&dout, real_packet->sciencebox);
+  }
+  if (BV_ISSET(fields, 34)) {
+    dio_put_uint8(&dout, real_packet->diplomacy);
+  }
+  if (BV_ISSET(fields, 35)) {
+    dio_put_uint8(&dout, real_packet->dispersion);
+  }
+  if (BV_ISSET(fields, 36)) {
+    dio_put_uint16(&dout, real_packet->tcptimeout);
+  }
+  if (BV_ISSET(fields, 37)) {
+    dio_put_uint16(&dout, real_packet->netwait);
+  }
+  if (BV_ISSET(fields, 38)) {
+    dio_put_uint16(&dout, real_packet->pingtimeout);
+  }
+  if (BV_ISSET(fields, 39)) {
+    dio_put_uint16(&dout, real_packet->pingtime);
+  }
+  if (BV_ISSET(fields, 40)) {
+    dio_put_uint8(&dout, real_packet->diplchance);
+  }
+  if (BV_ISSET(fields, 41)) {
+    dio_put_uint8(&dout, real_packet->citymindist);
+  }
+  if (BV_ISSET(fields, 42)) {
+    dio_put_uint8(&dout, real_packet->civilwarsize);
+  }
+  if (BV_ISSET(fields, 43)) {
+    dio_put_uint8(&dout, real_packet->contactturns);
+  }
+  if (BV_ISSET(fields, 44)) {
+    dio_put_uint8(&dout, real_packet->rapturedelay);
+  }
+  if (BV_ISSET(fields, 45)) {
+    dio_put_uint8(&dout, real_packet->celebratesize);
+  }
+  if (BV_ISSET(fields, 46)) {
+    dio_put_uint8(&dout, real_packet->barbarianrate);
+  }
+  if (BV_ISSET(fields, 47)) {
+    dio_put_uint8(&dout, real_packet->onsetbarbarian);
+  }
+  if (BV_ISSET(fields, 48)) {
+    dio_put_uint8(&dout, real_packet->occupychance);
+  }
+  /* field 49 is folded into the header */
+  /* field 50 is folded into the header */
+  if (BV_ISSET(fields, 51)) {
+    dio_put_uint8(&dout, real_packet->aqueductloss);
+  }
+  if (BV_ISSET(fields, 52)) {
+    dio_put_uint8(&dout, real_packet->killcitizen);
+  }
+  if (BV_ISSET(fields, 53)) {
+    dio_put_uint8(&dout, real_packet->razechance);
+  }
+  /* field 54 is folded into the header */
+  /* field 55 is folded into the header */
+  /* field 56 is folded into the header */
+  /* field 57 is folded into the header */
+  /* field 58 is folded into the header */
+  /* field 59 is folded into the header */
+  if (BV_ISSET(fields, 60)) {
+    dio_put_uint8(&dout, real_packet->borders);
+  }
+  if (BV_ISSET(fields, 61)) {
+    dio_put_uint8(&dout, real_packet->nbarbarians);
+  }
+  /* field 62 is folded into the header */
+  /* field 63 is folded into the header */
+  if (BV_ISSET(fields, 64)) {
+    dio_put_uint8(&dout, real_packet->add_to_size_limit);
+  }
+  if (BV_ISSET(fields, 65)) {
+    dio_put_uint8(&dout, real_packet->notradesize);
+  }
+  if (BV_ISSET(fields, 66)) {
+    dio_put_uint8(&dout, real_packet->fulltradesize);
+  }
+  if (BV_ISSET(fields, 67)) {
+    dio_put_uint8(&dout, real_packet->allowed_city_names);
+  }
+  if (BV_ISSET(fields, 68)) {
+    dio_put_uint8(&dout, real_packet->palace_building);
+  }
+  if (BV_ISSET(fields, 69)) {
+    dio_put_uint8(&dout, real_packet->land_defend_building);
+  }
+  /* field 70 is folded into the header */
+  if (BV_ISSET(fields, 71)) {
+    dio_put_uint8(&dout, real_packet->forced_science);
+  }
+  if (BV_ISSET(fields, 72)) {
+    dio_put_uint8(&dout, real_packet->forced_luxury);
+  }
+  if (BV_ISSET(fields, 73)) {
+    dio_put_uint8(&dout, real_packet->forced_gold);
+  }
+  if (BV_ISSET(fields, 74)) {
+  
+    {
+      int i;
+
+      for (i = 0; i < O_MAX; i++) {
+        dio_put_uint8(&dout, real_packet->min_city_center_output[i]);
+      }
+    } 
+  }
+  if (BV_ISSET(fields, 75)) {
+    dio_put_uint8(&dout, real_packet->min_dist_bw_cities);
+  }
+  if (BV_ISSET(fields, 76)) {
+    dio_put_uint8(&dout, real_packet->init_vis_radius_sq);
+  }
+  if (BV_ISSET(fields, 77)) {
+    dio_put_uint8(&dout, real_packet->hut_overflight);
+  }
+  /* field 78 is folded into the header */
+  if (BV_ISSET(fields, 79)) {
+    dio_put_uint8(&dout, real_packet->nuke_contamination);
+  }
+  if (BV_ISSET(fields, 80)) {
+  
+    {
+      int i;
+
+      for (i = 0; i < MAX_GRANARY_INIS; i++) {
+        dio_put_uint8(&dout, real_packet->granary_food_ini[i]);
+      }
+    } 
+  }
+  if (BV_ISSET(fields, 81)) {
+    dio_put_uint8(&dout, real_packet->granary_num_inis);
+  }
+  if (BV_ISSET(fields, 82)) {
+    dio_put_uint8(&dout, real_packet->granary_food_inc);
+  }
+  if (BV_ISSET(fields, 83)) {
+    dio_put_uint8(&dout, real_packet->tech_cost_style);
+  }
+  if (BV_ISSET(fields, 84)) {
+    dio_put_uint8(&dout, real_packet->tech_leakage);
+  }
+  if (BV_ISSET(fields, 85)) {
+    dio_put_sint16(&dout, real_packet->tech_cost_double_year);
+  }
+  /* field 86 is folded into the header */
+  if (BV_ISSET(fields, 87)) {
+    dio_put_uint8(&dout, real_packet->autoupgrade_veteran_loss);
+  }
+  if (BV_ISSET(fields, 88)) {
+    dio_put_uint16(&dout, real_packet->incite_improvement_factor);
+  }
+  if (BV_ISSET(fields, 89)) {
+    dio_put_uint16(&dout, real_packet->incite_unit_factor);
+  }
+  if (BV_ISSET(fields, 90)) {
+    dio_put_uint16(&dout, real_packet->incite_total_factor);
+  }
+  if (BV_ISSET(fields, 91)) {
+    dio_put_uint8(&dout, real_packet->government_when_anarchy_id);
+  }
+  if (BV_ISSET(fields, 92)) {
+    dio_put_uint8(&dout, real_packet->revolution_length);
+  }
+  if (BV_ISSET(fields, 93)) {
+    dio_put_sint16(&dout, real_packet->base_pollution);
+  }
+  if (BV_ISSET(fields, 94)) {
+    dio_put_uint8(&dout, real_packet->happy_cost);
+  }
+  if (BV_ISSET(fields, 95)) {
+    dio_put_uint8(&dout, real_packet->food_cost);
+  }
+  if (BV_ISSET(fields, 96)) {
+    dio_put_uint16(&dout, real_packet->base_bribe_cost);
+  }
+  if (BV_ISSET(fields, 97)) {
+    dio_put_uint16(&dout, real_packet->base_incite_cost);
+  }
+  if (BV_ISSET(fields, 98)) {
+    dio_put_uint8(&dout, real_packet->base_tech_cost);
+  }
+  if (BV_ISSET(fields, 99)) {
+    dio_put_uint16(&dout, real_packet->ransom_gold);
+  }
+  if (BV_ISSET(fields, 100)) {
+    dio_put_uint8(&dout, real_packet->save_nturns);
+  }
+  if (BV_ISSET(fields, 101)) {
+    dio_put_uint8(&dout, real_packet->save_compress_level);
+  }
+  if (BV_ISSET(fields, 102)) {
+    dio_put_string(&dout, real_packet->start_units);
+  }
+  if (BV_ISSET(fields, 103)) {
+    dio_put_uint8(&dout, real_packet->num_teams);
+  }
+  if (BV_ISSET(fields, 104)) {
+  
+    {
+      int i;
+
+      for (i = 0; i < real_packet->num_teams; i++) {
+        dio_put_string(&dout, real_packet->team_names_orig[i]);
+      }
+    } 
+  }
+  if (BV_ISSET(fields, 105)) {
+  
+    {
+      int i;
+
+      assert(A_LAST < 255);
+
+      for (i = 0; i < A_LAST; i++) {
+        if(old->global_advances[i] != real_packet->global_advances[i]) {
+          dio_put_uint8(&dout, i);
+          dio_put_bool8(&dout, real_packet->global_advances[i]);
+        }
+      }
+      dio_put_uint8(&dout, 255);
+    } 
+  }
+  if (BV_ISSET(fields, 106)) {
+  
+    {
+      int i;
+
+      assert(B_LAST < 255);
+
+      for (i = 0; i < B_LAST; i++) {
+        if(old->great_wonders[i] != real_packet->great_wonders[i]) {
+          dio_put_uint8(&dout, i);
+          dio_put_uint16(&dout, real_packet->great_wonders[i]);
+        }
+      }
+      dio_put_uint8(&dout, 255);
+    } 
+  }
+
+
+  if (old_from_hash) {
+    hash_delete_entry(*hash, old);
+  }
+
+  clone = old;
+
+  *clone = *real_packet;
+  hash_insert(*hash, clone, clone);
+  SEND_PACKET_END;
+}
+
+#define hash_packet_game_info_101 hash_const
+
+#define cmp_packet_game_info_101 cmp_const
+
+BV_DEFINE(packet_game_info_101_fields, 106);
+
+static struct packet_game_info *receive_packet_game_info_101(struct connection 
*pc, enum packet_type type)
+{
+  packet_game_info_101_fields fields;
+  struct packet_game_info *old;
+  struct hash_table **hash = &pc->phs.received[type];
+  struct packet_game_info *clone;
+  RECEIVE_PACKET_START(packet_game_info, real_packet);
+
+  DIO_BV_GET(&din, fields);
+
+
+  if (!*hash) {
+    *hash = hash_new(hash_packet_game_info_101, cmp_packet_game_info_101);
+  }
+  old = hash_delete_entry(*hash, real_packet);
+
+  if (old) {
+    *real_packet = *old;
+  } else {
+    memset(real_packet, 0, sizeof(*real_packet));
+  }
+
+  if (BV_ISSET(fields, 0)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->gold = readin;
+    }
+  }
+  if (BV_ISSET(fields, 1)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->tech = readin;
+    }
+  }
+  if (BV_ISSET(fields, 2)) {
+    {
+      int readin;
+    
+      dio_get_uint32(&din, &readin);
+      real_packet->skill_level = readin;
+    }
+  }
+  if (BV_ISSET(fields, 3)) {
+    {
+      int readin;
+    
+      dio_get_uint8(&din, &readin);
+      real_packet->aifill = readin;
+    }
+  }
   real_packet->is_new_game = BV_ISSET(fields, 4);
   if (BV_ISSET(fields, 5)) {
     {
@@ -4095,10 +5784,10 @@
   RECEIVE_PACKET_END(real_packet);
 }
 
-static int send_packet_game_info_100(struct connection *pc, const struct 
packet_game_info *packet)
+static int send_packet_game_info_101(struct connection *pc, const struct 
packet_game_info *packet)
 {
   const struct packet_game_info *real_packet = packet;
-  packet_game_info_100_fields fields;
+  packet_game_info_101_fields fields;
   struct packet_game_info *old, *clone;
   bool differ, old_from_hash, force_send_of_unchanged = TRUE;
   struct hash_table **hash = &pc->phs.sent[PACKET_GAME_INFO];
@@ -4106,7 +5795,7 @@
   SEND_PACKET_START(PACKET_GAME_INFO);
 
   if (!*hash) {
-    *hash = hash_new(hash_packet_game_info_100, cmp_packet_game_info_100);
+    *hash = hash_new(hash_packet_game_info_101, cmp_packet_game_info_101);
   }
   BV_CLR_ALL(fields);
 
@@ -4965,8 +6654,10 @@
   }
 
   if(FALSE) {
-  } else if(TRUE) {
+  } else if((has_capability("pubserver", pc->capability) && 
has_capability("pubserver", our_capability))) {
     variant = 100;
+  } else if(!(has_capability("pubserver", pc->capability) && 
has_capability("pubserver", our_capability))) {
+    variant = 101;
   } else {
     die("unknown variant");
   }
@@ -4989,6 +6680,7 @@
 
   switch(pc->phs.variant[PACKET_GAME_INFO]) {
     case 100: return receive_packet_game_info_100(pc, type);
+    case 101: return receive_packet_game_info_101(pc, type);
     default: die("unknown variant"); return NULL;
   }
 }
@@ -5009,6 +6701,7 @@
 
   switch(pc->phs.variant[PACKET_GAME_INFO]) {
     case 100: return send_packet_game_info_100(pc, packet);
+    case 101: return send_packet_game_info_101(pc, packet);
     default: die("unknown variant"); return -1;
   }
 }
Index: common/packets_gen.h
===================================================================
--- common/packets_gen.h        (revision 11143)
+++ common/packets_gen.h        (working copy)
@@ -103,6 +103,7 @@
   int tech;
   int skill_level;
   int aifill;
+  char pubserver[MAX_LEN_NAME];
   bool is_new_game;
   float seconds_to_phasedone;
   int timeout;

[Prev in Thread] Current Thread [Next in Thread]
  • [Freeciv-Dev] (PR#13262) Include pubserver jobs v6, Per I. Mathisen <=