]> git.pond.sub.org Git - empserver/blobdiff - src/util/fairland.c
Fix PRNG seeding to resist guessing
[empserver] / src / util / fairland.c
index 38e1cae5a99f3c82f6b7551e0c96fecb2a93ba34..d95282f2c60e82ee872f093ba680e1dbe47ee670 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2010, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2013, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
@@ -14,8 +14,7 @@
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
@@ -30,6 +29,7 @@
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1998
+ *     Markus Armbruster, 2004-2012
  */
 
 #include <config.h>
@@ -55,7 +55,7 @@ static int quiet = 0;
 #define FERT_MAX   56
 
 /* raise OIL_MAX for more oil */
-#define OIL_MAX    33
+#define OIL_MAX           33
 
 /* lower IRON_MIN for more iron */
 #define IRON_MIN   22
@@ -71,11 +71,9 @@ static int quiet = 0;
 #include <stdarg.h>
 #include <stdio.h>
 #include <unistd.h>
+#include "chance.h"
 #include "file.h"
-#include "misc.h"
-#include "nat.h"
 #include "optlist.h"
-#include "power.h"
 #include "prototypes.h"
 #include "sect.h"
 #include "version.h"
@@ -103,7 +101,7 @@ static int DISTINCT_ISLANDS = 1;
 static char *program_name;
 
 #define STABLE_CYCLE 4         /* stability required for perterbed capitals */
-#define INFINITY        999    /* a number which means "BIG" */
+#define INFINITY       999     /* a number which means "BIG" */
 
 /* these defines prevent infinite loops:
 */
@@ -119,7 +117,6 @@ static char *program_name;
 
 #define new_x(newx) (((newx) + WORLD_X) % WORLD_X)
 #define new_y(newy) (((newy) + WORLD_Y) % WORLD_Y)
-#define rnd(x) (random() % (x))
 
 static int secs;               /* number of sectors grown */
 static int ctot;               /* total number of continents and islands grown */
@@ -153,7 +150,7 @@ static const char *numletter =
 static void help(char *);
 static void usage(void);
 static void parse_args(int argc, char *argv[]);
-static int allocate_memory(void);
+static void allocate_memory(void);
 static void init(void);
 static int drift(void);
 static void grow_continents(void);
@@ -182,9 +179,10 @@ main(int argc, char *argv[])
     int opt;
     char *config_file = NULL;
     int i = 0;
+    int seed_set = 0;
 
     program_name = argv[0];
-    rnd_seed = time(NULL);
+    rnd_seed = 0;
 
     while ((opt = getopt(argc, argv, "ae:hioqR:s:v")) != EOF) {
        switch (opt) {
@@ -205,6 +203,7 @@ main(int argc, char *argv[])
            break;
        case 'R':
            rnd_seed = strtoul(optarg, NULL, 10);
+           seed_set = 1;
            break;
        case 's':
            outfile = optarg;
@@ -222,14 +221,15 @@ main(int argc, char *argv[])
     }
     parse_args(argc - optind, argv + optind);
 
-    srandom(rnd_seed);
+    if (!seed_set)
+       rnd_seed = pick_seed();
+    seed_prng(rnd_seed);
     empfile_init();
     if (emp_config(config_file) < 0)
        exit(1);
     empfile_fixup();
 
-    if (allocate_memory() == -1)
-       exit(-1);
+    allocate_memory();
     print_vars();
 
     do {
@@ -262,14 +262,12 @@ main(int argc, char *argv[])
        fprintf(stderr, "Can't chdir to %s (%s)\n", gamedir, strerror(errno));
        exit(EXIT_FAILURE);
     }
-    if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME, WORLD_SZ())) {
-       perror("ef_open");
+    if (!ef_open(EF_SECTOR, EFF_MEM | EFF_NOTIME))
        exit(1);
-    }
     write_sects();
     qprint("writing to sectors file...\n");
     if (!ef_close(EF_SECTOR))
-       exit(-1);
+       exit(1);
 
     output();
     qprint("\n\nA script for adding all the countries can be found in \"%s\".\n",
@@ -375,8 +373,8 @@ parse_args(int argc, char *argv[])
        is = atoi(argv[3]);
     else
        is = sc / 2;
-    if (is < 0)
-       is = 0;
+    if (is < 1)
+       is = 1;
 
     if (argc > 4)
        sp = atoi(argv[4]);
@@ -431,7 +429,7 @@ parse_args(int argc, char *argv[])
   VARIABLE INITIALIZATION
 ****************************************************************************/
 
-static int
+static void
 allocate_memory(void)
 {
     int i;
@@ -464,7 +462,6 @@ allocate_memory(void)
        sectc[i] = calloc(is * 2, sizeof(int));
     }
 
-    return 0;
 }
 
 static void
@@ -566,7 +563,7 @@ fl_move(int j)
 {
     int i, n, newx, newy;
 
-    for (i = rnd(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
+    for (i = roll0(6), n = 0; n < 6; i = (i + 1) % 6, ++n) {
        newx = new_x(capx[j] + dirx[i]);
        newy = new_y(capy[j] + diry[i]);
        if (iso(j, newx, newy) >= iso(j, capx[j], capy[j])) {
@@ -683,7 +680,7 @@ new_try(int c)
        if (sectc[c][0])
            return 0;
     } else {
-       i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : rnd(secs);
+       i = starti = (spike && sectc[c][secs - 1]) ? secs - 1 : roll0(secs);
        do {
            if (sectc[c][i])
                return i;
@@ -703,7 +700,7 @@ grow_one_sector(int c)
 {
     int done, coast_search, try1, x, y, newx, newy, i, n, sx, sy;
 
-    spike = rnd(100) < sp;
+    spike = roll0(100) < sp;
     if ((try1 = new_try(c)) == -1)
        return 0;
     x = sx = sectx[c][try1];
@@ -712,7 +709,7 @@ grow_one_sector(int c)
     done = 0;
     do {
        if (spike) {
-           for (i = rnd(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
+           for (i = roll0(6), n = 0; n < 12 && !done; i = (i + 1) % 6, ++n) {
                newx = new_x(x + dirx[i]);
                newy = new_y(y + diry[i]);
                if (own[newx][newy] == -1 &&
@@ -723,7 +720,7 @@ grow_one_sector(int c)
                        done = 1;
            }
        } else
-           for (i = rnd(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
+           for (i = roll0(6), n = 0; n < 6 && !done; i = (i + 1) % 6, ++n) {
                newx = new_x(x + dirx[i]);
                newy = new_y(y + diry[i]);
                if (own[newx][newy] == -1)
@@ -782,8 +779,8 @@ static int
 place_island(int c, int *xp, int *yp)
 {
     int d, sx, sy;
-    int ssy = rnd(WORLD_Y);
-    int ssx = new_x(rnd(WORLD_X / 2) * 2 + ssy % 2);
+    int ssy = roll0(WORLD_Y);
+    int ssx = new_x(roll0(WORLD_X / 2) * 2 + ssy % 2);
 
     if (ssx > WORLD_X - 2)
        ssx = new_x(ssx + 2);
@@ -817,7 +814,7 @@ grow_islands(void)
        secs = 0;
        if (!place_island(c, &x, &y))
            return;
-       isiz = 1 + rnd(2 * is - 1);
+       isiz = roll(2 * is - 1);
        do {
            ++secs;
            find_coast(c);
@@ -903,7 +900,7 @@ elevate_land(void)
        for (k = nm, mountain_search = 0;
             k && mountain_search < MOUNTAIN_SEARCH_MAX;
             ++mountain_search) {
-           r = rnd(total);
+           r = roll0(total);
            for (i = 0; i < ns; ++i)
                if (r < weight[i] && ELEV == -INFINITY &&
                    (c >= nc ||
@@ -957,14 +954,14 @@ elevate_land(void)
        for (i = 0; i < ns; ++i) {
            if (ELEV == INFINITY) {
                if (dsea[i] == 1)
-                   ELEV = HILLMIN + rnd(PLATMIN - HILLMIN);
+                   ELEV = HILLMIN + roll0(PLATMIN - HILLMIN);
                else
-                   ELEV = HIGHMIN + rnd((256 - HIGHMIN) / 2) +
-                     rnd((256 - HIGHMIN) / 2);
-           } else if ((c < nc &&
-                       ((capx[c] == sectx[c][i] && capy[c] == secty[c][i]))) ||
-                      ((new_x(capx[c] + 2) == sectx[c][i] &&
-                        capy[c] == secty[c][i])))
+                   ELEV = HIGHMIN + roll0((256 - HIGHMIN) / 2) +
+                     roll0((256 - HIGHMIN) / 2);
+           } else if (c < nc &&
+                      (((capx[c] == sectx[c][i] && capy[c] == secty[c][i])) ||
+                       ((new_x(capx[c] + 2) == sectx[c][i] &&
+                         capy[c] == secty[c][i]))))
                ELEV = PLATMIN;
        }
     }
@@ -980,7 +977,7 @@ elevate_sea(void)
     for (y = 0; y < WORLD_Y; ++y) {
        for (x = y % 2; x < WORLD_X; x += 2) {
            if (elev[x][y] == -INFINITY)
-               elev[x][y] = -rnd((distance_to_land() * 20 + 27)) - 1;
+               elev[x][y] = -roll(distance_to_land() * 20 + 27);
        }
     }
 }
@@ -1007,7 +1004,7 @@ set_oil(int e)
 {
     int oil = 0;
     if (e < LANDMIN)
-       oil = (LANDMIN - e) * 2 + rnd(2);
+       oil = (LANDMIN - e) * 2 + roll0(2);
     else if (e <= OIL_MAX)
        oil = (120 * (OIL_MAX - e + 1)) / (OIL_MAX - LANDMIN + 1);
     if (oil > 100)
@@ -1158,12 +1155,12 @@ write_newcap_script(void)
     }
 
     for (c = 0; c < nc; ++c) {
-       fprintf(script, "add %d %d %d n i\n", c + 1, c + 1, c + 1);
+       fprintf(script, "add %d %d %d p\n", c + 1, c + 1, c + 1);
        if (AIRPORT_MARKER)
            fprintf(script, "des %d,%d -\n", capx[c], capy[c]);
        fprintf(script, "newcap %d %d,%d\n", c + 1, capx[c], capy[c]);
     }
-    fprintf(script, "add %d visitor visitor v i\n", c + 1);
+    fprintf(script, "add %d visitor visitor v\n", c + 1);
     fclose(script);
     return 0;
 }