home *** CD-ROM | disk | FTP | other *** search
/ Amiga Times / AmigaTimes.iso / spiele / FreeCiv / src / freeciv-1.7.0 / server / stdinhand.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-06  |  19.1 KB  |  599 lines

  1. /********************************************************************** 
  2.  Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
  3.    This program is free software; you can redistribute it and/or modify
  4.    it under the terms of the GNU General Public License as published by
  5.    the Free Software Foundation; either version 2, or (at your option)
  6.    any later version.
  7.  
  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.
  12. ***********************************************************************/
  13. #include <stdio.h>
  14. #include <string.h>
  15. #include <ctype.h>
  16. #include <stdlib.h>
  17. #include <assert.h>
  18.  
  19. #include <game.h>
  20. #include <gamehand.h>
  21. #include <player.h>
  22. #include <civserver.h>
  23. #include <log.h>
  24. #include <sernet.h>
  25. #include <map.h>
  26. #include <mapgen.h>
  27. #include <registry.h>
  28. #include <plrhand.h>
  29. extern char metaserver_info_line[256];
  30.  
  31. void cut_player_connection(char *playername);
  32. void quit_game(void);
  33. void show_help(void);
  34. void show_players(void);
  35.  
  36. struct proto_settings {
  37.   char *name;
  38.   char *help;
  39.   int *value;
  40.   int afterstart;
  41.   int min_value, max_value, default_value;
  42. };
  43.  
  44. struct proto_settings settings[] = {
  45.   { "xsize", "Width of map in squares", 
  46.     &map.xsize, 0,  
  47.     MAP_MIN_WIDTH, MAP_MAX_HEIGHT, MAP_DEFAULT_WIDTH},
  48.  
  49.   { "ysize", "Height of map in squares", 
  50.     &map.ysize, 0,
  51.     MAP_MIN_HEIGHT, MAP_MAX_HEIGHT, MAP_DEFAULT_HEIGHT},
  52.  
  53.   { "seed", "This single number defines the random sequence that generate the map\nSame seed will always produce same map.", 
  54.     &map.seed, 0,
  55.     MAP_MIN_SEED,MAP_MAX_SEED, MAP_DEFAULT_SEED},
  56.   
  57.   { "landmass", "This number defines the percentage of the map that becomes land.", 
  58.     &map.landpercent, 0,
  59.     MAP_MIN_LANDMASS, MAP_MAX_LANDMASS, MAP_DEFAULT_LANDMASS},
  60.  
  61.   { "specials", "This number donates a percentage chance that a square is special.",
  62.     &map.riches, 0,
  63.     MAP_MIN_RICHES, MAP_MAX_RICHES, MAP_DEFAULT_RICHES},
  64.  
  65.   { "swamps", "How many swamps to create on the map.",
  66.     &map.swampsize, 0,
  67.     MAP_MIN_SWAMPS, MAP_MAX_SWAMPS, MAP_DEFAULT_SWAMPS},
  68.  
  69.   { "settlers", "How many settlers each player starts with.",
  70.     &game.settlers, 0,
  71.     GAME_MIN_SETTLERS, GAME_MAX_SETTLERS, GAME_DEFAULT_SETTLERS},
  72.  
  73.   { "explorer", "How many explorer units the player starts with.",
  74.     &game.explorer, 0,
  75.     GAME_MIN_EXPLORER, GAME_MAX_EXPLORER, GAME_DEFAULT_EXPLORER},
  76.  
  77.   { "deserts", "How many deserts to create on the map.",
  78.     &map.deserts, 0,
  79.     MAP_MIN_DESERTS, MAP_MAX_DESERTS, MAP_DEFAULT_DESERTS},
  80.  
  81.   { "rivers", "Denotes the total length of the rivers on the map.",
  82.     &map.riverlength, 0,
  83.     MAP_MIN_RIVERS, MAP_MAX_RIVERS, MAP_DEFAULT_RIVERS},
  84.  
  85.   { "mountains", "How flat/high is the map, higher values give more mountains.", 
  86.     &map.mountains, 0,
  87.     MAP_MIN_MOUNTAINS, MAP_MAX_MOUNTAINS, MAP_DEFAULT_MOUNTAINS},
  88.  
  89.   { "forests", "How much forest to create, higher values give more forest.", 
  90.     &map.forestsize, 0,
  91.     MAP_MIN_FORESTS, MAP_MAX_FORESTS, MAP_DEFAULT_FORESTS},
  92.  
  93.   { "huts", "how many 'bonus huts' should be created.",
  94.     &map.huts, 0,
  95.     MAP_MIN_HUTS, MAP_MAX_HUTS, MAP_DEFAULT_HUTS},
  96.  
  97.   { "generator", "made a more fair mapgenerator (2), but it only supports 7 players, and works on 80x50 maps only", 
  98.     &map.generator, 0,
  99.     MAP_MIN_GENERATOR, MAP_MAX_GENERATOR, MAP_DEFAULT_GENERATOR}, 
  100.  
  101.   { "gold", "how much gold does each players start with.",
  102.     &game.gold, 0,
  103.     GAME_MIN_GOLD, GAME_MAX_GOLD, GAME_DEFAULT_GOLD},
  104.  
  105.   { "techlevel", "How many initial advances does each player have.",
  106.     &game.tech, 0,
  107.     GAME_MIN_TECHLEVEL, GAME_MAX_TECHLEVEL, GAME_DEFAULT_TECHLEVEL},
  108.  
  109.   { "researchspeed", "How fast do players gain technology.",
  110.     &game.techlevel, 0,
  111.     GAME_MIN_RESEARCHLEVEL, GAME_MAX_RESEARCHLEVEL, GAME_DEFAULT_RESEARCHLEVEL},
  112.  
  113.   { "diplcost", "How many % of the price of researching a tech, does a tech cost when you exchange it in a diplomatic treaty.",
  114.     &game.diplcost, 0,
  115.     GAME_MIN_DIPLCOST, GAME_MAX_DIPLCOST, GAME_DEFAULT_DIPLCOST},
  116.  
  117.   { "diplchance", "The 1:n chance of a diplomat/spy defeating a resident diplomat/spy while subverting or sabotaging a city.  Also the chance of a Spy returning from a sucessful mission",
  118.     &game.diplchance, 1,
  119.     GAME_MIN_DIPLCHANCE, GAME_MAX_DIPLCHANCE, GAME_DEFAULT_DIPLCHANCE},
  120.  
  121.   { "freecost", "How many % of the price of researching a tech, does a tech cost when you get it for free.",
  122.     &game.freecost, 0,
  123.     GAME_MIN_FREECOST, GAME_MAX_FREECOST, GAME_DEFAULT_FREECOST},
  124.  
  125.   { "conquercost", "How many % of the price of researching a tech, does a tech cost when you get it by military force.",
  126.     &game.conquercost, 0,
  127.     GAME_MIN_CONQUERCOST, GAME_MAX_CONQUERCOST, GAME_DEFAULT_CONQUERCOST},
  128.   
  129.   { "unhappysize", "When do people get angry in a city.",
  130.     &game.unhappysize, 0,
  131.     GAME_MIN_UNHAPPYSIZE, GAME_MAX_UNHAPPYSIZE, GAME_DEFAULT_UNHAPPYSIZE},
  132.  
  133.   { "cityfactor", "How many cities will it take to increase unhappy faces in cities.",
  134.     &game.cityfactor, 0,
  135.     GAME_MIN_CITYFACTOR, GAME_MAX_CITYFACTOR, GAME_DEFAULT_CITYFACTOR},
  136.   { "railfood", "How many % railroads modifies food production.",
  137.      &game.rail_food, 0,
  138.      GAME_MIN_RAILFOOD, GAME_MAX_RAILFOOD, GAME_DEFAULT_RAILFOOD},
  139.  
  140.    { "railprod", "How many % railroads modifies shield production.",
  141.      &game.rail_prod, 0,
  142.      GAME_MIN_RAILPROD, GAME_MAX_RAILPROD, GAME_DEFAULT_RAILPROD},
  143.  
  144.    { "railtrade", "How many % railroads modifies trade production.",
  145.      &game.rail_trade, 0,
  146.      GAME_MIN_RAILTRADE, GAME_MAX_RAILTRADE, GAME_DEFAULT_RAILTRADE},
  147.   { "foodbox", "Size * this parameter is what it takes for a city to grow by 1"
  148.     ,&game.foodbox, 0,
  149.     GAME_MIN_FOODBOX, GAME_MAX_FOODBOX, GAME_DEFAULT_FOODBOX},
  150.   { "techpenalty", "% penalty if you change tech default it's 100%",
  151.     &game.techpenalty, 0,
  152.     GAME_MIN_TECHPENALTY, GAME_MAX_TECHPENALTY, GAME_DEFAULT_TECHPENALTY},
  153.   { "razechance", "% chance that each building in town is destroyed when conquered",
  154.     &game.razechance, 0,
  155.     GAME_MIN_RAZECHANCE, GAME_MAX_RAZECHANCE, GAME_DEFAULT_RAZECHANCE},
  156.  
  157.   { "civstyle", "1= civ 1 (units, techs, buildings), 2= civ 2 style",
  158.     &game.civstyle, 0,
  159.     GAME_MIN_CIVSTYLE, GAME_MAX_CIVSTYLE, GAME_DEFAULT_CIVSTYLE},
  160.  
  161.   { "endyear", "In what year is the game over.", 
  162.     &game.end_year, 1,
  163.     GAME_MIN_END_YEAR, GAME_MAX_END_YEAR, GAME_DEFAULT_END_YEAR},
  164.  
  165.   { "minplayers", "How many players are needed to start the game.",
  166.     &game.min_players, 1,
  167.     GAME_MIN_MIN_PLAYERS, GAME_MAX_MIN_PLAYERS, GAME_DEFAULT_MIN_PLAYERS},
  168.   
  169.   { "maxplayers", "How many players are maximally wanted in game.",
  170.     &game.max_players, 1,
  171.     GAME_MIN_MAX_PLAYERS, GAME_MAX_MAX_PLAYERS, GAME_DEFAULT_MAX_PLAYERS},
  172.  
  173.   { "saveturns", "How many turns between when the game is saved.",
  174.     &game.save_nturns, 1,
  175.     0, 200, 10},
  176.   { "timeout", "How many seconds can a turn max take (0 is no timeout).",
  177.     &game.timeout, 1,
  178.     0, 999, GAME_DEFAULT_TIMEOUT},
  179.  
  180.   { "aifill", "Maximum number of AI players to create when game starts",
  181.     &game.aifill, 1,
  182.     GAME_MIN_AIFILL, GAME_MAX_AIFILL, GAME_DEFAULT_AIFILL},
  183.  
  184.   { NULL, NULL, NULL, 0, 0, 0}
  185. };
  186.  
  187.  
  188. /**************************************************************************
  189. ...
  190. **************************************************************************/
  191. void meta_command(char *arg)
  192. {
  193.   strncpy(metaserver_info_line, arg, 256);
  194.   metaserver_info_line[256-1]='\0';
  195.   send_server_info_to_metaserver(1);
  196. }
  197.  
  198. /**************************************************************************
  199. ...
  200. **************************************************************************/
  201. void save_command(char *arg)
  202. {
  203.   struct section_file file;
  204.   
  205.   if (server_state==SELECT_RACES_STATE || 
  206.       (server_state == PRE_GAME_STATE && !map_is_empty()))
  207.     {
  208.       printf("Please wait until the game has started to save.\n");
  209.       return;
  210.     }
  211.  
  212.   section_file_init(&file);
  213.   
  214.   game_save(&file);
  215.  
  216.   if(!section_file_save(&file, arg))
  217.     printf("Failed saving game as %s\n", arg);
  218.   else
  219.     printf("Game saved as %s\n", arg);
  220. }
  221.  
  222. /**************************************************************************
  223. ...
  224. **************************************************************************/
  225. void toggle_ai_player(char *arg)
  226. {
  227.   struct player *pplayer=find_player_by_name(arg);
  228.   if (!pplayer) {
  229.     puts("No player by that name.");
  230.     return;
  231.   }
  232.   pplayer->ai.control = !pplayer->ai.control;
  233.   if (pplayer->ai.control) {
  234.     notify_player(0, "Option: %s is AI-controlled.", pplayer->name);
  235.     printf("%s is now under AI control.\n",pplayer->name);
  236.   } else {
  237.     notify_player(0, "Option: %s is human.", pplayer->name);
  238.     printf("%s is now under human control.\n",pplayer->name);
  239.   }
  240.   send_player_info(pplayer,0);
  241. }
  242.  
  243. /**************************************************************************
  244. ...
  245. **************************************************************************/
  246. void create_ai_player(char *arg)
  247. {
  248.   struct player *pplayer;
  249.    
  250.   if (server_state==PRE_GAME_STATE) {
  251.      if(game.nplayers==game.max_players) 
  252.        puts ("Can't add more players, server is full.");
  253.      else if ((pplayer=find_player_by_name(arg))) 
  254.        puts("A player already exists by that name.");
  255.      else {
  256.     accept_new_player(arg, NULL);
  257.     pplayer = find_player_by_name(arg);
  258.     if (!pplayer) 
  259.       printf ("Error creating new ai player: %s\n", arg);
  260.     else {
  261.        pplayer->ai.control = !pplayer->ai.control;
  262.        pplayer->is_connected=0;
  263.        notify_player(0, "Option: %s has been added as an AI-controlled.",
  264.              pplayer->name);
  265.     }
  266.      }
  267.   } else
  268.      puts ("Can't add AI players once the game has begun.");
  269. }
  270.  
  271.  
  272. /**************************************************************************
  273. ...
  274. **************************************************************************/
  275. void remove_player(char *arg)
  276. {
  277.   struct player *pplayer=find_player_by_name(arg);
  278.   
  279.   if(!pplayer) {
  280.     puts("No player by that name.");
  281.     return;
  282.   }
  283.  
  284.   server_remove_player(pplayer);
  285. }
  286.  
  287. int lookup_cmd(char *find)
  288. {
  289.   int i;
  290.   for (i=0;settings[i].name!=NULL;i++) 
  291.     if (!strcmp(find, settings[i].name)) return i;
  292.   
  293.   return -1;
  294. }
  295.  
  296. void help_command(char *str)
  297. {
  298.   char command[512], *cptr_s, *cptr_d;
  299.   int cmd,i;
  300.  
  301.   for(cptr_s=str; *cptr_s && !isalnum(*cptr_s); cptr_s++);
  302.   for(cptr_d=command; *cptr_s && isalnum(*cptr_s); cptr_s++, cptr_d++)
  303.     *cptr_d=*cptr_s;
  304.   *cptr_d='\0';
  305.  
  306.   if (*command) {
  307.     cmd=lookup_cmd(command);
  308.     if (cmd==-1) {
  309.       puts("No help on that (yet).");
  310.       return;
  311.     }
  312.     printf("%s: is set to %d\nEffect: %s\nMinimum %d, Maximum %d, Default %d\n"
  313.        , settings[cmd].name, *settings[cmd].value, settings[cmd].help, 
  314.        settings[cmd].min_value, settings[cmd].max_value, 
  315.        settings[cmd].default_value);
  316.   } else {
  317.   puts("------------------------------------------------------------------------------");
  318.       puts("Help are defined on the following variables:");
  319.   puts("------------------------------------------------------------------------------");
  320.     for (i=0;settings[i].name;i++) {
  321.       printf("%-19s%c",settings[i].name, ((i+1)%4) ? ' ' : '\n'); 
  322.     }
  323.     if ((i)%4!=0) puts("");
  324.   puts("------------------------------------------------------------------------------");
  325.   }
  326. }
  327.   
  328. void report_server_options(struct player *pplayer)
  329. {
  330.   int i;
  331.   char buffer[4096];
  332.   char buf2[4096];
  333.   char title[128];
  334.   buffer[0]=0;
  335.   sprintf(title, "%-20svalue  (min , max)\n", "Variable");
  336.  
  337.   for (i=0;settings[i].name;i++) {
  338.     sprintf(buf2, "%-20s%c%-6d (%d,%d)\n", settings[i].name,(*settings[i].value==settings[i].default_value) ? '*' : ' ',  *settings[i].value, settings[i].min_value, settings[i].max_value);
  339.     strcat(buffer, buf2);
  340.   }
  341.   page_player(pplayer, title, buffer);
  342.   
  343. }
  344.  
  345. void set_ai_level(char *arg, int level)
  346. {
  347.   struct player *pplayer=find_player_by_name(arg);
  348.   char *nm[11] = { "NONE", "NONE", "NONE", "easy", "NONE",
  349.                  "normal", "NONE", "hard", "NONE", "NONE", "NONE" };
  350.   int h[11] = { 0, 0, 0, H_RATES+H_TARGETS+H_HUTS, 0,
  351.                 H_RATES+H_TARGETS+H_HUTS, 0, 0, 0, 0, 0 };
  352.   int i;
  353.  
  354.   if (pplayer) {
  355.     if (pplayer->ai.control) {
  356.       pplayer->ai.handicap = h[level];
  357.       printf("%s is now %s.\n", pplayer->name, nm[level]);
  358.     } else {
  359.       printf("%s is not controlled by the AI.\n", pplayer->name);
  360.     }
  361.   } else {
  362.     for (i = 0; i < game.nplayers; i++) {
  363.       pplayer = get_player(i);
  364.       if (pplayer->ai.control) {
  365.         pplayer->ai.handicap = h[level];
  366.         printf("%s is now %s.\n", pplayer->name, nm[level]);
  367.       }
  368.     }
  369.   }
  370. }
  371.  
  372. void crash_and_burn(void)
  373. {
  374.   printf("Crashing and burning.\n");
  375.   assert(0);
  376. }
  377.  
  378. void show_command(char *str)
  379. {
  380.   int i;
  381.   puts("------------------------------------------------------------------------------");
  382.   printf("%-20svalue  (min , max)\n", "Variable");
  383.   puts("------------------------------------------------------------------------------");
  384.   for (i=0;settings[i].name;i++) {
  385.     printf("%-20s%c%-6d (%d,%d)\n", settings[i].name,(*settings[i].value==settings[i].default_value) ? '*' : ' ',  *settings[i].value, settings[i].min_value, settings[i].max_value);
  386.   }
  387.   puts("------------------------------------------------------------------------------");
  388.   puts("* means that it's the default for the variable");
  389.   puts("------------------------------------------------------------------------------");
  390. }
  391.  
  392. void set_command(char *str) 
  393. {
  394.   char command[512], arg[512], *cptr_s, *cptr_d;
  395.   int val, cmd;
  396.   for(cptr_s=str; *cptr_s && !isalnum(*cptr_s); cptr_s++);
  397.  
  398.   for(cptr_d=command; *cptr_s && isalnum(*cptr_s); cptr_s++, cptr_d++)
  399.     *cptr_d=*cptr_s;
  400.   *cptr_d='\0';
  401.   
  402.   for(; *cptr_s && (*cptr_s != '-' && !isalnum(*cptr_s)); cptr_s++);
  403.  
  404.   for(cptr_d=arg; *cptr_s && (*cptr_s == '-' || isalnum(*cptr_s)); cptr_s++ , cptr_d++)
  405.     *cptr_d=*cptr_s;
  406.   *cptr_d='\0';
  407.  
  408.   cmd=lookup_cmd(command);
  409.   if (cmd==-1) {
  410.     puts("Undefined argument. Usage: set <variable> <value>.");
  411.     return;
  412.   }
  413.   if (!settings[cmd].afterstart && !map_is_empty()) {
  414.     puts("This setting can't be modified after game has started");
  415.     return;
  416.   }
  417.  
  418.   val=atoi(arg);
  419.   if (val>=settings[cmd].min_value && val<=settings[cmd].max_value) {
  420.     *(settings[cmd].value)=val;
  421.     notify_player(0, "Option: %s", str);
  422.   } else
  423.     puts("Value out of range. Usage: set <variable> <value>.");
  424. }
  425.  
  426. /**************************************************************************
  427. ...
  428. **************************************************************************/
  429. void handle_stdin_input(char *str)
  430. {
  431.   char command[512], arg[512], *cptr_s, *cptr_d;
  432.   int i;
  433.  
  434.   for(cptr_s=str; *cptr_s && !isalnum(*cptr_s); cptr_s++);
  435.  
  436.   for(cptr_d=command; *cptr_s && isalnum(*cptr_s); cptr_s++, cptr_d++)
  437.     *cptr_d=*cptr_s;
  438.   *cptr_d='\0';
  439.  
  440.   for(; *cptr_s && !isalnum(*cptr_s); cptr_s++);
  441.   strncpy(arg, cptr_s, 511);
  442.   arg[511]='\0';
  443.  
  444.   i=strlen(arg)-1;
  445.   while(i>0 && isspace(arg[i]))
  446.     arg[i--]='\0';
  447.   
  448.   if(!strcmp("remove", command))
  449.     remove_player(arg);
  450.   else if(!strcmp("save", command))
  451.     save_command(arg);
  452.   else if(!strcmp("meta", command))
  453.     meta_command(arg);
  454.   else if(!strcmp("h", command))
  455.     show_help();
  456.   else if(!strcmp("l", command))
  457.     show_players();
  458.   else if (!strcmp("ai", command))
  459.     toggle_ai_player(arg);
  460.   else if (!strcmp("create", command))
  461.     create_ai_player(arg);
  462.   else if (!strcmp("crash", command))
  463.     crash_and_burn();
  464. /*  else if (!strcmp("easy", command))
  465.     set_ai_level(arg, 3);               not fair to tease people like this -- Syela */
  466.   else if (!strcmp("normal", command))
  467.     set_ai_level(arg, 5);
  468.   else if (!strcmp("hard", command))
  469.     set_ai_level(arg, 7);
  470.   else if(!strcmp("q", command))
  471.     quit_game();
  472.   else if(!strcmp("c", command))
  473.     cut_player_connection(arg);
  474.   else if (!strcmp("show",command)) 
  475.     show_command(arg);
  476.   else if (!strcmp("help",command)) 
  477.     help_command(arg);
  478.   else if (!strcmp("set", command)) 
  479.     set_command(arg);
  480.   else if(!strcmp("score", command)) {
  481.     if(server_state==RUN_GAME_STATE)
  482.       show_ending();
  483.     else
  484.       printf("The game must be running, before you can see the score.\n");
  485.   }
  486.   else if(server_state==PRE_GAME_STATE) {
  487.     int plrs=0;
  488.     int i;
  489.     if(!strcmp("s", command)) {
  490.       for (i=0;i<game.nplayers;i++) {
  491.     if (game.players[i].conn || game.players[i].ai.control) plrs++ ;
  492.       }
  493.       if (plrs<game.min_players) 
  494.     printf("Not enough players, game will not start.\n");
  495.       else 
  496.     start_game();
  497.     }
  498.     else
  499.       printf("Unknown Command, try 'h' for help.\n");
  500.   }
  501.   else
  502.     printf("Unknown Command, try 'h' for help.\n");  
  503.   
  504.   printf(">");
  505.   fflush(stdout);
  506. }
  507.  
  508. /**************************************************************************
  509. ...
  510. **************************************************************************/
  511. void cut_player_connection(char *playername)
  512. {
  513.   struct player *pplayer;
  514.  
  515.   pplayer=find_player_by_name(playername);
  516.   if(pplayer && pplayer->conn) {
  517.     log(LOG_NORMAL, "cutting connection to %s", playername);
  518.     close_connection(pplayer->conn);
  519.     pplayer->conn=NULL;
  520.   }
  521.   else
  522.     puts("uh, no such player connected");
  523. }
  524.  
  525. /**************************************************************************
  526. ...
  527. **************************************************************************/
  528. void quit_game(void)
  529. {
  530.   int i;
  531.   struct packet_generic_message gen_packet;
  532.   gen_packet.message[0]='\0';
  533.   
  534.   for(i=0; i<game.nplayers; i++)
  535.     send_packet_generic_message(game.players[i].conn, PACKET_SERVER_SHUTDOWN,
  536.                 &gen_packet);
  537.   close_connections_and_socket();
  538.   
  539.   exit(1);
  540. }
  541.  
  542. /**************************************************************************
  543. ...
  544. **************************************************************************/
  545. void show_help(void)
  546. {
  547.   puts("Available commands: (P=player, M=message, F=file)");
  548.   puts("-------------------------------------");
  549.   puts("c P      - cut connection to player");
  550.   puts("h        - this help");
  551.   puts("l        - list players");
  552.   puts("q        - quit game and shutdown server");
  553.   puts("remove P - fully remove player from game");
  554.   puts("score    - show current score");
  555.   puts("save F   - save game as file F");
  556.   puts("show     - list server options");
  557.   puts("help     - help on server options");
  558.   puts("meta T   - Set meta-server infoline to T");
  559.   puts("ai P     - toggles AI on player");
  560.   puts("create P - creates an AI player");
  561. /*  puts("easy P   - AI player will be easy");
  562.   puts("easy     - All AI players will be easy"); */
  563.   puts("normal P - AI player will be normal");
  564.   puts("normal   - All AI players will be normal");
  565.   puts("hard P   - AI player will be hard");
  566.   puts("hard     - All AI players will be hard");
  567.   if(server_state==PRE_GAME_STATE) {
  568.     puts("set      - set options");
  569.     puts("s        - start game");
  570.   }
  571.   else {
  572.     
  573.   }
  574. }
  575.  
  576. /**************************************************************************
  577. ...
  578. **************************************************************************/
  579. void show_players(void)
  580. {
  581.   int i;
  582.   char aichar;
  583.   
  584.   puts("List of players:");
  585.   puts("-------------------------------------");
  586.  
  587.   for(i=0; i<game.nplayers; i++) {
  588.     if (game.players[i].ai.control) 
  589.       aichar = '*';
  590.     else
  591.       aichar = ' ';
  592.     printf("%c%s ", aichar, game.players[i].name);
  593.     if(game.players[i].conn)
  594.       printf("is connected from %s\n", game.players[i].addr); 
  595.     else
  596.       printf("is not connected\n");
  597.   }
  598. }
  599.