Generated from galaxyng.c with ROBODoc v3.2.2 on Sun Aug 27 19:47:33 2000

TABLE OF CONTENTS

  1. Galaxy/GalaxyNG
  2. GalaxyNG/CMD_check
  3. GalaxyNG/CMD_checkFile
  4. GalaxyNG/CMD_create
  5. GalaxyNG/CMD_dump
  6. GalaxyNG/CMD_graph
  7. GalaxyNG/CMD_mail0
  8. GalaxyNG/CMD_relay
  9. GalaxyNG/CMD_report
  10. GalaxyNG/CMD_run
  11. GalaxyNG/CMD_score
  12. GalaxyNG/CMD_selftest
  13. GalaxyNG/CMD_template
  14. GalaxyNG/CMD_test
  15. GalaxyNG/checkTime
  16. GalaxyNG/galaxynghome
  17. GalaxyNG/lineBuffer
  18. GalaxyNG/logFile
  19. GalaxyNG/logLevel
  20. GalaxyNG/main
  21. GalaxyNG/options
  22. GalaxyNG/productname
  23. GalaxyNG/relayMessage
  24. GalaxyNG/tempdir
  25. GalaxyNG/usage

Galaxy/GalaxyNG

NAME
    galaxyng -- Server for the play-by-email game GalaxyNG
SYNOPSIS
    galaxyng [command [options]]
FUNCTION
    Checks incomming orders, runs the turn, and sends out the turn
    reports. 

    The code is divided into a number of modules:
     List     -- (list.c list.h) functions for manipulating lists.
     Util     -- (util.c util.h) frequently used functions.
     Phase    -- (phase.c phase.h) code for the various phases in the game.
     Process  -- (process.c process.h ) code for order checking, 
                 order processing, and running a turn.
     Report   -- (report.c report.h) 
                 Code to generate the turn reports.
     Battle   -- (battle.c battle.h) code that performs the battles.
     Loadgame -- saves a turn to disk
     Savegame -- load a turn from disk
     GalaxyNG -- glues it all together.
AUTHOR
    Created by:  
    o Frans Slothouber (fslothouber@acm.org) 
    o Christophe  Barbier 
    o Jacco van Weert 
    o Tommy Lindqvist       
    o Rogerio Fung
    o Ken Weinert

    This code contains parts of the the orginal Galaxy code which was
    created by Russell Wallace (RWALLACE@vax1.tcd.ie), and updated by the
    Galaxy PBeM Development Group which include 
    o Russell Wallace (RWALLACE@vax1.tcd.ie) 
    o Tim Myers (tmyers@unlinfo.unl.edu), 
    o Robert Stone (stone@athena.cs.uga.edu), 
    o Mayan Moudgill (moudgill@cs.cornell.edu), 
    o Graeme Griffiths (graeme@abekrd.co.uk), 
    o K Pankhurst (k.pankhurst@ic.ac.uk).
CREATION DATE
    4-Jan-1997
COPYRIGHT
    This program may be freely distributed, and used to run _free_
    games over electronic media.  It may not be sold or used
    commercially without prior written permission from me Frans
    Slothouber.  fslothouber@acm.org.  In no case may it be used to
    run commercial games.
NOTES
    This is not the most pretty code around. It is a product of many
    years and many people. The code hosts a lot of global variables
    and many not very descriptively named function. The code is
    pretty stable however.
BUGS


GalaxyNG/CMD_check

NAME
   CMD_check -- check in comming orders.
FUNCTION
   Check incomming orders and create a forecast of the
   situation at the next turn.
INPUTS
   Orders come in via stdin. The forecast is mailed directy to the player.
   Orders are assumed to have a proper mailheader, that is start with:
      To: <player>@theaddress
      Subject:  orders [turn number]
   This header can be produced with formail (see .procmailrc file).
RESULT
   Orders are stored in
   $GALAXYNGHOME/orders/<game name>/<nation name>.<turn number>
   Forecast is mailed to the player.
   A log is kept of all order processing in log/orders_processed.txt
SOURCE
    int
    CMD_check(int argc, char **argv, int kind)
    {
      int             result;
      char           *logName;
    
      logLevel = LBRIEF;
      result = EXIT_FAILURE;
    
      logName = createString("%s/log/orders_processed.txt", galaxynghome);
      openLog(logName, "a");
      free(logName);
    
      plogtime(LBRIEF);
      if (argc >= 2) {
        char           *forecastName, *returnAddress, *nationName, *password;
        int             resNumber, theTurnNumber;
        game           *aGame;
        FILE           *forecast;
    
        forecastName = createString("%s/NGforecast", tempdir);
        if ((forecast = GOS_fopen(forecastName, "w"))) {
          envelope       *anEnvelope;
    
          anEnvelope = createEnvelope();
          returnAddress = getReturnAddress(stdin);
          theTurnNumber = getTurnNumber(stdin);
          nationName = NULL;
          password = NULL;
          aGame = NULL;
          resNumber = areValidOrders(stdin, &aGame, &nationName,
                                     &password, theTurnNumber);
          plog(LBRIEF, "game %s\n", aGame->name);
          setHeader(anEnvelope, MAILHEADER_TO, "%s", returnAddress);
          plog(LBRIEF, "Orders from %s\n", returnAddress);
          if (resNumber eq RES_OK) {
            if ((theTurnNumber eq LG_CURRENT_TURN) ||
                (theTurnNumber eq(aGame->turn) + 1)) {
              copyOrders(aGame, stdin, nationName, password, (aGame->turn) + 1);
              setHeader(anEnvelope, MAILHEADER_SUBJECT,
                        "Galaxy HQ, %s turn %d forecast for %s",
                        aGame->name, (aGame->turn) + 1, nationName);
              plog(LBRIEF, "%s turn %d orders checked for %s.\n",
                   aGame->name, (aGame->turn) + 1, nationName);
              checkOrders(aGame, nationName, forecast);
            }
            else {
              copyOrders(aGame, stdin, nationName, password, theTurnNumber);
              setHeader(anEnvelope, MAILHEADER_SUBJECT,
                        "Galaxy HQ, %s advance orders received for %s.",
                        aGame->name, nationName);
              plog(LBRIEF, "%s advance orders received for %s.\n",
                   aGame->name, nationName);
              fprintf(forecast, "O wise leader your orders for turn %d "
                      "have been received and stored.\n", theTurnNumber);
            }
          }
          else {
            setHeader(anEnvelope, MAILHEADER_SUBJECT, "Galaxy HQ, major trouble");
            plog(LBRIEF, "major trouble %d\n", resNumber);
            generateErrorMessage(resNumber, aGame, nationName,
                                 theTurnNumber, forecast);
          }
          fprintf(forecast, "\n\n%s\n", vcid);
          fclose(forecast);
          result = 0;
          if (kind == CMD_CHECK_REAL) {
            result |= eMail(aGame, anEnvelope, forecastName);
          }
          else {
            char           *forecastFile;
    
            forecastFile =
                createString("%s/forecasts/%s",
                             galaxynghome, argv[2], returnAddress);
            GOS_copy(forecastName, forecastFile);
          }
          if (nationName)
            free(nationName);
          if (password)
            free(password);
          destroyEnvelope(anEnvelope);
          result |= GOS_delete(forecastName);
          result = (result) ? EXIT_FAILURE : EXIT_SUCCESS;
        }
        else {
          fprintf(stderr, "Can't open \"%s\".\n", forecastName);
        }
        free(forecastName);
      }
      else {
        usage();
      }
      closeLog();
      return result;
    }    

GalaxyNG/CMD_checkFile

NAME
   CMD_checkFile --
 NOTE
   This should be merged with CMD_check(). 

GalaxyNG/CMD_create

NAME
   CMD_create -- create a new galaxy and game.
SYNOPSIS
   galaxyng -create <game specification file>
FUNCTION
   Creates a new game based on the specification found in
   the specification file.
INPUTS
   specificationfile -- file with the dimensions of the galaxy
     and the addresses of all the players. (.glx file).
 SEE 
   CMD_mail0(), CMD_template()  
SOURCE
    int
    CMD_create(int argc, char **argv)
    {
      gamespecification *gspec;
      game           *aGame;
      int             result;
      FILE           *specfile;
    
      result = EXIT_FAILURE;
      if (argc == 3) {
        if ((specfile = GOS_fopen(argv[2], "r"))) {
          gspec = readGameSpec(specfile);
          fclose(specfile);
          printGameSpecs(gspec);
          if ((aGame = creategame(gspec))) {
            struct fielddef fields;
    
            fields.destination = stdout;
            checkIntegrity(aGame);
            savegame(aGame);
            reportMap(aGame, aGame->players, &fields);
            printf("Number of planets: %d\n", numberOfElements(aGame->planets));
            result = EXIT_SUCCESS;
          }
          else {
            fprintf(stderr, "Can't create the game\n");
          }
        }
        else {
          fprintf(stderr, "Can't open specification file \"%s\"\n", argv[2]);
        }
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/CMD_dump

NAME
    CMD_dump -- dump game data.
SYNOPSIS
     ./galaxyng -players     <game> [turn]
     ./galaxyng -lastorders  <game> [turn]
     ./galaxyng -map         <game> [turn]

     CMD_dump(int argc, char **argv, int kind) 
FUNCTION
    Dump game information.
SWITCHES
    kind:
      CMD_DUMP_LASTORDERS
         show turn when players last send in orders.
      CMD_DUMP_MAP
         show a map of the galaxy
      CMD_DUMP_PLAYERS
         show password and address of players
      CMD_DUMP_HALL
         show information for use in the hall of fame.
SOURCE
    int
    CMD_dump(int argc, char **argv, int kind)
    {
      game           *aGame;
      int             result;
      int             turn;
    
      result = EXIT_FAILURE;
      if (argc >= 3) {
        if (argc == 3) {
          turn = LG_CURRENT_TURN;
        }
        else {
          turn = atoi(argv[3]);
        }
        if ((aGame = loadgame(argv[2], turn))) {
          player         *aDummyPlayer;
          struct fielddef fields;
    
          fields.destination = stdout;
    
          loadConfig(aGame);
          switch (kind) {
          case CMD_DUMP_MAP:{
              aDummyPlayer = allocStruct(player);
    
              setName(aDummyPlayer, "DummyDummy");
              aDummyPlayer->msize = aGame->galaxysize;
              reportMap(aGame, aDummyPlayer, &fields);
              break;
            }
          case CMD_DUMP_LASTORDERS:{
              reportLastOrders(aGame->players, &fields);
              break;
            }
          case CMD_DUMP_PLAYERS:{
              reportPlayers(aGame->players, &fields);
              break;
            }
          case CMD_DUMP_PSCORE:{
              scorePercent(aGame, &fields);
              break;
            }
          case CMD_DUMP_HALL:{
              reportHall(aGame, &fields);
              break;
            }
          case CMD_DUMP_MAILHEADER:{
              createMailToAllHeader(aGame);
              break;
            }
            result = EXIT_SUCCESS;
          }
          freegame(aGame);
        }
        else {
          fprintf(stderr, "Could not load game \"%s\".\n", argv[2]);
        }
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/CMD_graph

NAME
   CMD_graph -- create a data dump for a graph of a game.
NOTES
   Experimental. See Tools/graphscore.tcl
SOURCE
    int
    CMD_graph(int argc, char **argv)
    {
      game           *aGame;
      int             result;
    
      result = EXIT_FAILURE;
      if (argc == 4) {
        if ((aGame = loadgame(argv[2], atoi(argv[3])))) {
          player         *aPlayer;
          int             number;
    
          nationStatus(aGame);
          for (number = 0, aPlayer = aGame->players;
               aPlayer;
               aPlayer = aPlayer->next, number++) {
            printf("%d %d %s %f\n", aGame->turn, number, aPlayer->name,
                   effectiveIndustry(aPlayer->totPop, aPlayer->totInd));
          }
        }
        else {
          fprintf(stderr, "Could not load game \"%s\" turn %s\n",
                  argv[2], argv[3]);
        }
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/CMD_mail0

NAME
   CMD_mail0 -- mail the turn 0 reports.
SYNOPSIS
   ./galaxyng -mail0 <Game Name>
   int CMD_mail0(int argc, char **argv) 
FUNCTION
   Mail the turn 0 reports to the players. 
   To be run after a new game is created.
SOURCE
    int
    CMD_mail0(int argc, char **argv, int kind)
    {
      game           *aGame;
      int             result;
    
      result = EXIT_FAILURE;
      if (argc == 3) {
        if ((aGame = loadgame(argv[2], LG_CURRENT_TURN))) {
          player         *aPlayer;
    
          loadConfig(aGame);
          checkIntegrity(aGame);
          for (aPlayer = aGame->players;
               aPlayer;
               aPlayer = aPlayer->next) {
            aPlayer->pswdstate = 1;
            if (kind == CMD_CHECK_REAL) {
              mailTurnReport(aGame, aPlayer, 0);
            }
            if ((aGame->gameOptions & GAME_SAVECOPY) | (kind == CMD_CHECK_DUMMY)) {
              saveTurnReport(aGame, aPlayer, 0);
            }
            if (aPlayer->flags & F_XMLREPORT) {
              if (kind == CMD_CHECK_DUMMY) {
                saveTurnReport(aGame, aPlayer, F_XMLREPORT);
              }
              else {
                mailTurnReport(aGame, aPlayer, F_XMLREPORT);
              }
            }
            if (aPlayer->flags & F_MACHINEREPORT) {
              if (kind == CMD_CHECK_DUMMY) {
                saveTurnReport(aGame, aPlayer, F_MACHINEREPORT);
              }
              else {
                mailTurnReport(aGame, aPlayer, F_MACHINEREPORT);
              }
            }
          }
          result = EXIT_SUCCESS;
        }
        else {
          fprintf(stderr, "Could not load game \"%s\"\n", argv[2]);
        }
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/CMD_relay

NAME
   CMD_relay -- relay a message from one nation to another.
FUNCTION

GalaxyNG/CMD_report

NAME
   CMD_report -- send a copy of a turn report.
SYNOPSIS
   ./galaxyng -check < file_with_email
   int CMD_report(int argc, char **argv) 
FUNCTION
   Recreate a turn report of a given turn. Send it to the player
   that requested it.
BUGS
   Does not send XML nor machine reports.
SOURCE
    int
    CMD_report(int argc, char **argv)
    {
      int             result;
      char           *logName;
    
      logName = createString("%s/log/orders_processed.txt", galaxynghome);
      openLog(logName, "a");
      free(logName);
      logLevel = LBRIEF;
      plogtime(LBRIEF);
      result = EXIT_FAILURE;
      if (argc >= 2) {
        char           *returnAddress, *nationName, *password;
        int             resNumber, theTurnNumber;
        game           *aGame;
        FILE           *report;
        char           *reportName;
    
        reportName = createString("%s/temp_report_copy", tempdir);
        if ((report = GOS_fopen(reportName, "w"))) {
          envelope       *anEnvelope;
    
          anEnvelope = createEnvelope();
          returnAddress = getReturnAddress(stdin);
          setHeader(anEnvelope, MAILHEADER_TO, "%s", returnAddress);
          plog(LBRIEF, "Report request from %s.\n", returnAddress);
          theTurnNumber = getTurnNumber(stdin);
          nationName = NULL;
          password = NULL;
          aGame = NULL;
          resNumber =
              areValidOrders(stdin, &aGame, &nationName, &password, theTurnNumber);
          if ((resNumber eq RES_TURNRAN) ||
              ((resNumber eq RES_OK) && (theTurnNumber eq LG_CURRENT_TURN))) {
            game           *aGame2;
    
            if (theTurnNumber > 0) {
              aGame2 = loadgame(aGame->name, theTurnNumber - 1);
            }
            else if (theTurnNumber == LG_CURRENT_TURN) {
              theTurnNumber = aGame->turn;
              aGame2 = loadgame(aGame->name, theTurnNumber - 1);
            }
            else {
              aGame2 = loadgame(aGame->name, 0);
            }
            if (aGame2) {
              player         *aPlayer;
              int             index;
    
              setHeader(anEnvelope, MAILHEADER_SUBJECT,
                        "Galaxy HQ, Copy of turn %d report",
                        theTurnNumber);
              if (theTurnNumber > 0) {      /* Rerun the turn */
                char           *ordersName;
    
                ordersName =
                    createString("%s/orders/%s/%d.all",
                                 galaxynghome, aGame2->name, theTurnNumber);
                runTurn(aGame2, ordersName);
                free(ordersName);
              }
    /* Translate the current nation name into the name used during the turn *
     * * * that is requested */
              aPlayer = findElement(player, aGame->players, nationName);
    
              index = ptonum(aGame->players, aPlayer);
              aPlayer = numtop(aGame2->players, index);
    
              if (theTurnNumber == 0)
                aPlayer->pswdstate = 1;
              highScoreList(aGame2);
              createTurnReport(aGame2, aPlayer, report, 0);
            }
            else {
              setHeader(anEnvelope, MAILHEADER_SUBJECT,
                        "Galaxy HQ, Copy of turn report request.");
              fprintf(report, "\n\nThe turn you requested is no longer available...\n");
            }
          }
          else if (resNumber eq RES_OK) {
            setHeader(anEnvelope, MAILHEADER_SUBJECT,
                      "Galaxy HQ, Major Trouble");
            fprintf(report, "You can not request a report for the next turn\n");
            fprintf(report, "or any following turns,"
                    " I can not see into the future!\n");
          }
          else {
            setHeader(anEnvelope, MAILHEADER_SUBJECT,
                      "Galaxy HQ, Major Trouble");
            generateErrorMessage(
                        resNumber, aGame, nationName, theTurnNumber, report);
          }
          fclose(report);
          result = eMail(aGame, anEnvelope, reportName);
          destroyEnvelope(anEnvelope);
          result |= ssystem("rm %s", reportName);
          result = (result) ? EXIT_FAILURE : EXIT_SUCCESS;
          if (nationName)
            free(nationName);
          if (password)
            free(password);
        }
        else {
          fprintf(stderr, "Can't open \"%s\"\n", reportName);
        }
        free(reportName);
      }
      else {
        usage();
      }
      closeLog();
      return result;
    }    

GalaxyNG/CMD_run

NAME
   CMD_run -- run turn and send turn reports
SYNOPSIS
   ./galaxyng -run <game name> <file with all orders>
FUNCTION
   Run an turn, Compute the highscore list, and send the turn reports 
   to all players. The GM is send a status report. If the option
   SaveReportCopy is specified in the .galaxyngrc file, a copy of each
   turn report is also saved in reports/

   This function is also run for: 
     ./galaxyng -dummyrun <game name> <file with all orders>
   In this case the run is a dummy run, and the turn reports are stored 
   in reports/. Nothing is mailed. This is used to debug the server code.
 
OUTPUT
   Turn reports are send out to the players and the turn is saved
   to disk. The GM is sent a status report. A log can be found in
   log/<game name>.
DIAGNOSTICS
   Message to stderr in case of an error.
   (Game does not exist, not the right time to run the game,
    game structure is corrupted).
RESULT
   EXIT_FAILURE  or  EXIT_SUCCESS
SOURCE
    int
    CMD_run(int argc, char **argv, int kind)
    {
      int             result;
    
      result = EXIT_FAILURE;
      if (argc >= 4) {
        game           *aGame;
        int             turn;
        char           *logName;
    
        logLevel = LPART;
    
        logName = createString("%s/log/%s", galaxynghome, argv[2]);
        openLog(logName, "w");
        free(logName);
    
        plogtime(LPART);
        plog(LPART, "Trying to run Game \"%s\".\n", argv[2]);
    
        aGame = NULL;
        turn = (argc == 4) ? LG_CURRENT_TURN : atoi(argv[4]) - 1;
    
        if ((aGame = loadgame(argv[2], turn))) {
          player         *aPlayer;
    
          loadConfig(aGame);
          if (checkTime(aGame) || (kind == CMD_RUN_DUMMY)) {
            checkIntegrity(aGame);
            if (runTurn(aGame, argv[3])) {
              highScoreList(aGame);
              result = 0;
              for (aPlayer = aGame->players; aPlayer; aPlayer = aPlayer->next) {
                if (kind == CMD_RUN_REAL) {
                  result |= mailTurnReport(aGame, aPlayer, 0);
                  if (aGame->gameOptions & GAME_SAVECOPY) {
                    saveTurnReport(aGame, aPlayer, 0);
                  }
                }
                else {
                  saveTurnReport(aGame, aPlayer, 0);
                }
                if (aPlayer->flags & F_XMLREPORT) {
                  if (kind == CMD_RUN_REAL) {
                    result |= mailTurnReport(aGame, aPlayer, F_XMLREPORT);
                  }
                  else {
                    saveTurnReport(aGame, aPlayer, F_XMLREPORT);
                  }
                }
                if (aPlayer->flags & F_MACHINEREPORT) {
                  if (kind == CMD_RUN_REAL) {
                    result |= mailTurnReport(aGame, aPlayer, F_MACHINEREPORT);
                  }
                  else {
                    saveTurnReport(aGame, aPlayer, F_MACHINEREPORT);
                  }
                }
              }
              savegame(aGame);
            }
            else {
              fprintf(stderr,
                      "The server has detected an error in the game data structure. The run\n"
                      "of the turn has been aborted. No turn reports have been send. Please\n"
                      "contact Frans Slothouber at fslothouber@acm.org for a solution to this\n"
                      "problem.\n");
              result = 1;
            }
            plogtime(LPART);
            plog(LPART, "Run is completed.\n");
            result = (result) ? EXIT_FAILURE : EXIT_SUCCESS;
          }
          else {
            plog(LBRIEF, "Error, attempt to run the game \"%s\" at the"
                 " wrong time.\n"
               "You specified a starttime of %s in your .galaxyngrc file.\n",
                 argv[2], aGame->starttime);
            fprintf(stderr,
                 "Error, attempt to run the game \"%s\" at the wrong time.\n"
               "You specified a starttime of %s in your .galaxyngrc file.\n",
                    argv[2], aGame->starttime);
          }
          closeLog();
          if (kind == CMD_RUN_REAL) {
            mailGMReport(aGame, argv[2]);
          }
          freegame(aGame);
        }
        else {
          plog(LBRIEF, "Game \"%s\" does not exist.\n", argv[2]);
          fprintf(stderr, "Game \"%s\" does not exist.\n", argv[2]);
        }
      }
      else {
        usage();
      }
      closeLog();
      return result;
    }    

GalaxyNG/CMD_score

NAME
   CMD_score -- Show highscore list.
FUNCTION
   Write a HTML-ized version of the highscore list to stdout.
SOURCE
    int
    CMD_score(int argc, char **argv)
    {
      int             result;
      game           *aGameThisTurn;
      game           *aGamePrevTurn;
    
      result = EXIT_FAILURE;
      if (argc == 3) {
        if ((aGameThisTurn = loadgame(argv[2], LG_CURRENT_TURN))) {
          if ((aGamePrevTurn =
               loadgame(aGameThisTurn->name, aGameThisTurn->turn - 1))) {
            score(aGamePrevTurn, aGameThisTurn, TRUE, stdout);
            result = EXIT_SUCCESS;
          }
          else {
            fprintf(stderr, "Could not load game \"%s\"\n", argv[2]);
          }
        }
        else {
          fprintf(stderr, "Could not load game \"%s\" turn %d\n", argv[2],
                  aGameThisTurn->turn - 1);
        }
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/CMD_selftest

NAME
   CMD_selftest -- run a series of selftests
FUNCTION
   Run a series of selftest.  Used for debug purposes.

GalaxyNG/CMD_template

NAME
   CMD_template -- Create a template .glx file that the GM can edit.
SYNOPSIS
   ./galaxyng <name> <number of players>
FUNCTION
   Creates a template .glx file.
   All parameters are given some sensible default values.

   The number of players is used to determine the size of the galaxy,
   using the following formule
      42 * ceil (sqrt(number of players))
   For games with very few players this size is sometimes too small.
SOURCE
    int
    CMD_template(int argc, char **argv)
    {
      int             result = EXIT_FAILURE;
    
      if (argc == 4) {
        FILE           *glxfile;
        char           *glxname;
        int             numberOfPlayers;
    
        glxname = createString("%s.glx", argv[2]);
        numberOfPlayers = atoi(argv[3]);
        if ((glxfile = GOS_fopen(glxname, "w"))) {
          int             i;
          int             gsize;
    
          fprintf(glxfile, "\n\nname %s\n\n", argv[2]);
          gsize = (int) (42.0 * ceil(sqrt((double) numberOfPlayers)));
          gsize /= 10;
          gsize *= 10;
          fprintf(glxfile,
                  "; The following size is only approximately right.\n"
                  "; You probably want to experiment with different sizes to get a galaxy\n"
                  "; that looks right. It should not be too crowded nor too sparse.\n\n");
          fprintf(glxfile, "size %d\n", gsize);
          fprintf(glxfile,
                  "\n"
                  "; The engine will make sure that distance between any of primary home\n"
                  "; planets is atleast 30.0 light years.\n"
                  "\n"
                  "nation_spacing 30.0\n"
                  "\n"
                  "; The sizes of the core home planets for each nation.\n"
            "; The following would give each nation 3 homeplanets of sizes\n"
                "; 1000 250 350. The first one is the primary home planet.\n"
          "; You have to define these before any of the player definitions.\n"
                  "\n"
                  "core_sizes 1000 250 350\n"
                  "\n"
                  "; Within a radius [2,r] from the primary home world the engine allocates\n"
                  "; a number of empty planets for the nation to colonize.\n"
                  "; The following two parameters define how many there are per nation,\n"
               "; and in within what radius. A number between 4 and 10 and\n"
                  "; a radius of  nation_spacing/2.0  is a good guess.\n"
                  "\n"
                  "empty_planets 6\n"
                  "empty_radius 15\n"
                  "\n"
                  "; It is possible to add a number of 'stuff' planets. These are useless\n"
                  "; planets, all of size 50 or less, that are use to fill up the empty\n"
                  "; space between the home worlds. They make it possible for a players to\n"
                  "; approach (attack) other players by different routes. The following\n"
                  "; parameter specifies how many there are per nation.\n"
                  "\n"
                  "stuff_planets 8\n"
                  ";\n"
             "; The list of the players, you can add here the mail address\n"
                  "; of each player that enrolled in your game.\n"
                  ";\n"
                  "\n");
          for (i = 1; i <= numberOfPlayers; i++) {
            fprintf(glxfile, "player  player%d@itsaddress.somehwere\n", i);
          }
          fprintf(glxfile,
                  ";\n"
                  "; You can override the core size for a player by adding the sizes.\n"
             "; For instance the following player will get one home planet\n"
                  "; of size 1600.0\n"
                  "\n"
                  "; player player3@itsaddress.somewhere 1600.0\n"
                  "\n"
                "; While the following player gets 3 home planets of sizes\n"
                  "; 500.0, 100.0, and 1000.0\n"
                  "\n"
             "; player player4@itsaddress.somewhere 500.0 100.0 1000.0\n\n");
          fclose(glxfile);
        }
        else {
          fprintf(stderr, "Can't open \"%s\".\n", glxname);
        }
        printf("Created the file \"%s\".\n", glxname);
        free(glxname);
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/CMD_test

NAME
   CMD_test -- check the integrity of a game.
FUNCTION
   Check if a GAME is OK by running checkIntegrity() on it.

GalaxyNG/checkTime

NAME
   checkTime -- check if it is really time to run a turn.
SYNOPSIS
   int checkTime(game *aGame)
FUNCTION
   Does a sanity check to see if a turn really has to be run.  On
   some systems, after a reboot, crontab goes bezerk and executes a
   whole bunch of entries in your crontab file for no good reason.
   This will cause turns to be run prematurely.

   This function checks if the current time is equal to the time a
   game is supposed to be run.  The GM has to put this time in a
   game specific .galaxyngrc file, using the starttime key.

EXAMPLE
   You want to make sure a game runs at 13:00. Add the entry

     starttime 13:00 

   to the .galaxyngrc file. The a turn will then only run, if and
   only if, it is started by between 13:00 and 13:09.  Add starttime
   13:10, and it will only run if started between 13:10 and 13:19.
RESULT
   TRUE  -- the game is allowed to run.
   FALSE -- the game is not allowed to run.
SOURCE
    int
    checkTime(game *aGame)
    {
      int             runGame;
    
      assert(aGame != NULL);
    
      runGame = FALSE;
      if (aGame->starttime) {
        char            timeBuffer[255];
        time_t          ttp;
    
        time(&ttp);
        strftime(timeBuffer, 255, "%H:%M", localtime(&ttp));
        if (strncmp(timeBuffer, aGame->starttime, 4) == 0) {
          runGame = TRUE;
        }
      }
      else {
        runGame = TRUE;
      }
      return runGame;
    }    

GalaxyNG/galaxynghome

NAME
   galaxynghome -- path to all data files
SOURCE
    char           *galaxynghome = NULL;    

GalaxyNG/lineBuffer

NAME
   lineBuffer -- global line buffer.
NOTES
   2 is there to prevent buffer overflows.
SOURCE
    char            lineBuffer[2 * LINE_BUFFER_SIZE];    

GalaxyNG/logFile

NAME
   logFile -- 
SOURCE
    FILE           *logFile = NULL;    

GalaxyNG/logLevel

NAME
   logLevel -- specifies the level of detail in log files.
SOURCE
    int             logLevel = LFULL;    

GalaxyNG/main

NAME
   main -- the start of it all.
RESULT
   Reports any errors that occur back to the environment.
SOURCE
    int
    main(int argc, char **argv)
    {
      char           *value;
      int             result;
    
    /* Some initializations */
      resetErnie(197162622);
      nbrProducts = sizeof(productname) / sizeof(char *);
    
    /* This should be a function */
      if ((value = getenv("GALAXYNGHOME"))) {
        galaxynghome = strdup(value);
      }
      else if ((value = getenv("HOME"))) {
        sprintf(lineBuffer, "%s/Games", value);
        galaxynghome = strdup(lineBuffer);
      }
      else {
        galaxynghome = strdup("/please/set/your/HOME/or/GALAXYNGHOME/variable");
      }
    
    #ifdef WIN32
    /* This should be a function */
      if ((value = getenv("TEMP"))) {
        tempdir = strdup(value);
      }
      else if ((value = getenv("TMP"))) {
        tempdir = strdup(value);
      }
      else {
        tempdir = strdup("c:\temp");
      }
    #else
      tempdir = strdup("/tmp");
    #endif
    
      if (argc <= 1) {
        usage();
      }
      else if (strstr(argv[1], "create")) {
        result = CMD_create(argc, argv);
      }
      else if (strstr(argv[1], "dummymail0")) {
        result = CMD_mail0(argc, argv, CMD_CHECK_DUMMY);
      }
      else if (strstr(argv[1], "mail0")) {
        result = CMD_mail0(argc, argv, CMD_CHECK_REAL);
      }
      else if (strstr(argv[1], "filecheck")) {
        result = CMD_checkFile(argc, argv, CMD_CHECK_DUMMY);
      }
      else if (strstr(argv[1], "dummycheck")) {
        result = CMD_check(argc, argv, CMD_CHECK_DUMMY);
      }
      else if (strstr(argv[1], "check")) {
        result = CMD_check(argc, argv, CMD_CHECK_REAL);
      }
      else if (strstr(argv[1], "dummyrun")) {
        result = CMD_run(argc, argv, CMD_RUN_DUMMY);
      }
      else if (strstr(argv[1], "run")) {
        result = CMD_run(argc, argv, CMD_RUN_REAL);
      }
      else if (strstr(argv[1], "selftest")) {       /* experimental */
        result = CMD_selftest();
      }
      else if (strstr(argv[1], "battletest")) {     /* experimental */
        result = CMD_battletest(argc, argv);
      }
      else if (strstr(argv[1], "test")) {   /* experimental */
        result = CMD_test(argc, argv);
      }
      else if (strstr(argv[1], "report")) {
        result = CMD_report(argc, argv);
      }
      else if (strstr(argv[1], "relay")) {
        result = CMD_relay(argc, argv);
      }
      else if (strstr(argv[1], "pscore")) {         /* experimental */
        result = CMD_dump(argc, argv, CMD_DUMP_PSCORE);
      }
      else if (strstr(argv[1], "score")) {
        result = CMD_score(argc, argv);
      }
      else if (strstr(argv[1], "graph")) {  /* experimental */
        result = CMD_graph(argc, argv);
      }
      else if (strstr(argv[1], "template")) {
        result = CMD_template(argc, argv);
      }
      else if (strstr(argv[1], "map")) {
        result = CMD_dump(argc, argv, CMD_DUMP_MAP);
      }
      else if (strstr(argv[1], "hall")) {
        result = CMD_dump(argc, argv, CMD_DUMP_HALL);
      }
      else if (strstr(argv[1], "lastorders")) {
        result = CMD_dump(argc, argv, CMD_DUMP_LASTORDERS);
      }
      else if (strstr(argv[1], "players")) {
        result = CMD_dump(argc, argv, CMD_DUMP_PLAYERS);
      }
      else if (strstr(argv[1], "toall")) {
        result = CMD_dump(argc, argv, CMD_DUMP_MAILHEADER);
      }
      else {
        usage();
      }
      return result;
    }    

GalaxyNG/options

NAME
   options -- options available to players. 
FUNCTION
   Associative array to look-up option flag by option names. 
SOURCE
    struct option   options[] =
    {
      {"Anonymous", F_ANONYMOUS},
      {"AutoUnload", F_AUTOUNLOAD},
      {"ProdTable", F_PRODTABLE},
      {"SortGroups", F_SORTGROUPS},
      {"GroupForeCast", F_GROUPFORECAST},
      {"PlanetForeCast", F_PLANETFORECAST},
      {"ShipTypeForecast", F_SHIPTYPEFORECAST},
      {"RoutesForecast", F_ROUTESFORECAST},
      {"Compress", F_COMPRESS},
      {"Gplus", F_GPLUS},
      {"MachineReport", F_MACHINEREPORT},   /* CB 1998 - Experimental */
      {"BattleProtocol", F_BATTLEPROTOCOL},
      {"XMLReport", F_XMLREPORT},   /* KDW 1999 - experimental */
      {NULL, 0}
    };    

GalaxyNG/productname

NAME
   productname -- things a planet can produce.
SOURCE
    char           *productname[] =
    {
      "CAP", "MAT", 0, "Drive", "Weapons", "Shields", "Cargo",
    };    

GalaxyNG/relayMessage

NAME
   relayMessage --

GalaxyNG/tempdir

NAME
   tempdir -- path to the directory used to store temporary files.
SOURCE
    char           *tempdir = NULL;    

GalaxyNG/usage

NAME
   usage -- print usage info.