diff -Nur -Xfreeciv/diff_ignore freeciv/common/capstr.c test-timeout/common/capstr.c --- freeciv/common/capstr.c Fri Mar 22 15:13:55 2002 +++ test-timeout/common/capstr.c Sat Mar 30 13:27:35 2002 @@ -73,7 +73,7 @@ #define CAPABILITY "+1.11.6 conn_info pop_cost +turn +attributes"\ " new_bonus_tech fund_added +processing_packets angrycitizen +tile_trade"\ " init_techs short_worklists tech_cost_style +short_city_tile_trade"\ -" +trade_size +new_nation_selection" +" +trade_size +new_nation_selection u32timeout" /* "+1.11.6" is protocol for 1.11.6 beta release. @@ -120,6 +120,9 @@ "new_nation_selection" transfer array of used nations instead of bit mask + + "u32timeout" designates that game.timeout is packeted as a uint32 + instead of a uint16 */ void init_our_capability(void) diff -Nur -Xfreeciv/diff_ignore freeciv/common/game.c test-timeout/common/game.c --- freeciv/common/game.c Wed Mar 20 23:15:13 2002 +++ test-timeout/common/game.c Sat Mar 30 13:43:40 2002 @@ -649,6 +649,11 @@ game.tech = GAME_DEFAULT_TECHLEVEL; game.skill_level = GAME_DEFAULT_SKILL_LEVEL; game.timeout = GAME_DEFAULT_TIMEOUT; + game.timeoutint = GAME_DEFAULT_TIMEOUTINT; + game.timeoutintinc = GAME_DEFAULT_TIMEOUTINTINC; + game.timeoutinc = GAME_DEFAULT_TIMEOUTINC; + game.timeoutincmult= GAME_DEFAULT_TIMEOUTINCMULT; + game.timeoutcounter= 1; game.tcptimeout = GAME_DEFAULT_TCPTIMEOUT; game.netwait = GAME_DEFAULT_NETWAIT; game.last_ping = 0; diff -Nur -Xfreeciv/diff_ignore freeciv/common/game.h test-timeout/common/game.h --- freeciv/common/game.h Wed Mar 20 23:15:13 2002 +++ test-timeout/common/game.h Sat Mar 30 19:39:06 2002 @@ -60,6 +60,11 @@ int tech; int skill_level; int timeout; + int timeoutint; /* increase timeout every N turns... */ + int timeoutinc; /* ... by this amount ... */ + int timeoutincmult; /* ... and multiply timeoutinc by this amount ... */ + int timeoutintinc; /* ... and increase timeoutint by this amount */ + int timeoutcounter; /* timeoutcounter - timeoutint = turns to next inc. */ int tcptimeout; int netwait; time_t last_ping; @@ -361,6 +366,11 @@ #define GAME_DEFAULT_AUTO_AI_TOGGLE FALSE #define GAME_DEFAULT_TIMEOUT 0 +#define GAME_DEFAULT_TIMEOUTINT 0 +#define GAME_DEFAULT_TIMEOUTINTINC 0 +#define GAME_DEFAULT_TIMEOUTINC 0 +#define GAME_DEFAULT_TIMEOUTINCMULT 1 + #ifndef NDEBUG #define GAME_MIN_TIMEOUT -1 #else diff -Nur -Xfreeciv/diff_ignore freeciv/common/packets.c test-timeout/common/packets.c --- freeciv/common/packets.c Fri Mar 22 15:13:55 2002 +++ test-timeout/common/packets.c Sat Mar 30 13:27:35 2002 @@ -2052,9 +2052,12 @@ cptr=put_uint16(cptr, pinfo->gold); cptr=put_uint32(cptr, pinfo->tech); cptr=put_uint8(cptr, pinfo->researchcost); - cptr=put_uint32(cptr, pinfo->skill_level); - cptr=put_uint16(cptr, pinfo->timeout); + if (has_capability("u32timeout", pc->capability)) { + cptr=put_uint32(cptr, pinfo->timeout); + } else { + cptr=put_uint16(cptr, pinfo->timeout); + } cptr=put_uint32(cptr, pinfo->end_year); cptr=put_uint32(cptr, pinfo->year); cptr=put_uint8(cptr, pinfo->min_players); @@ -2111,7 +2114,11 @@ iget_uint32(&iter, &pinfo->tech); iget_uint8(&iter, &pinfo->researchcost); iget_uint32(&iter, &pinfo->skill_level); - iget_uint16(&iter, &pinfo->timeout); + if (has_capability("u32timeout", pc->capability)) { + iget_uint32(&iter, &pinfo->timeout); + } else { + iget_uint16(&iter, &pinfo->timeout); + } iget_uint32(&iter, &pinfo->end_year); iget_uint32(&iter, &pinfo->year); iget_uint8(&iter, &pinfo->min_players); diff -Nur -Xfreeciv/diff_ignore freeciv/server/gamehand.c test-timeout/server/gamehand.c --- freeciv/server/gamehand.c Wed Mar 6 23:23:04 2002 +++ test-timeout/server/gamehand.c Sat Mar 30 22:54:03 2002 @@ -196,7 +196,6 @@ lsend_packet_generic_integer(dest, PACKET_GAME_STATE, &pack); } - /************************************************************************** Send game_info packet; some server options and various stuff... dest==NULL means game.est_connections @@ -247,4 +246,56 @@ send_packet_game_info(pconn, &ginfo); } conn_list_iterate_end; +} + +/************************************************************************** + adjusts game.timeout based on various server options + + timeoutint: adjust game.timeout every timeoutint turns + timeoutinc: adjust game.timeout by adding timeoutinc to it. + timeoutintinc: every time we adjust game.timeout, we add timeoutintinc + to timeoutint. + timeoutincmult: every time we adjust game.timeout, we multiply timeoutinc + by timeoutincmult +**************************************************************************/ +int update_timeout(void) +{ + /* if there's no timer or we're doing autogame, do nothing */ + if (game.timeout < 1 || game.timeoutint == 0) { + return game.timeout; + } + + if (game.timeoutcounter >= game.timeoutint) { + game.timeout += game.timeoutinc; + game.timeoutinc *= game.timeoutincmult; + + game.timeoutcounter = 1; + game.timeoutint += game.timeoutintinc; + + if(game.timeout > GAME_MAX_TIMEOUT) { + notify_conn_ex(&game.est_connections, -1, -1, E_NOEVENT, + _("The turn timeout has exceeded its maximum value, " + "fixing at its maximum")); + freelog(LOG_DEBUG, "game.timeout exceeded maximum value"); + game.timeout = GAME_MAX_TIMEOUT; + game.timeoutint = 0; + game.timeoutinc = 0; + } else if (game.timeout < 0) { + notify_conn_ex(&game.est_connections, -1, -1, E_NOEVENT, + _("The turn timeout is smaller than zero, " + "fixing at zero.")); + freelog(LOG_DEBUG, "game.timeout less than zero"); + game.timeout = 0; + } + } else { + game.timeoutcounter++; + } + + freelog(LOG_DEBUG, "timeout=%d, inc=%d incmult=%d\n " + "int=%d, intinc=%d, turns till next=%d", + game.timeout, game.timeoutinc, game.timeoutincmult, + game.timeoutint, game.timeoutintinc, + game.timeoutint - game.timeoutcounter); + + return game.timeout; } diff -Nur -Xfreeciv/diff_ignore freeciv/server/gamehand.h test-timeout/server/gamehand.h --- freeciv/server/gamehand.h Thu Oct 18 11:45:34 2001 +++ test-timeout/server/gamehand.h Sat Mar 30 13:27:35 2002 @@ -22,4 +22,6 @@ void send_game_state(struct conn_list *dest, int state); void send_start_turn_to_clients(void); +int update_timeout(void); + #endif /* FC__GAMEHAND_H */ diff -Nur -Xfreeciv/diff_ignore freeciv/server/savegame.c test-timeout/server/savegame.c --- freeciv/server/savegame.c Wed Mar 20 23:15:13 2002 +++ test-timeout/server/savegame.c Sat Mar 30 14:05:54 2002 @@ -1703,7 +1703,19 @@ game.skill_level = secfile_lookup_int(file, "game.skill_level"); if (game.skill_level==0) game.skill_level = GAME_OLD_DEFAULT_SKILL_LEVEL; + game.timeout = secfile_lookup_int(file, "game.timeout"); + game.timeoutint = secfile_lookup_int_default(file, + GAME_DEFAULT_TIMEOUTINT, "game.timeoutint"); + game.timeoutintinc = secfile_lookup_int_default(file, + GAME_DEFAULT_TIMEOUTINTINC, "game.timeoutintinc"); + game.timeoutinc = secfile_lookup_int_default(file, + GAME_DEFAULT_TIMEOUTINC, "game.timeoutinc"); + game.timeoutincmult = secfile_lookup_int_default(file, + GAME_DEFAULT_TIMEOUTINCMULT, "game.timeoutincmult"); + game.timeoutcounter = secfile_lookup_int_default(file, 1, + "game.timeoutcounter"); + game.end_year = secfile_lookup_int(file, "game.end_year"); game.researchcost = secfile_lookup_int_default(file, 0, "game.researchcost"); if (game.researchcost == 0) @@ -2089,6 +2101,11 @@ secfile_insert_int(file, game.tech, "game.tech"); secfile_insert_int(file, game.skill_level, "game.skill_level"); secfile_insert_int(file, game.timeout, "game.timeout"); + secfile_insert_int(file, game.timeoutint, "game.timeoutint"); + secfile_insert_int(file, game.timeoutintinc, "game.timeoutintinc"); + secfile_insert_int(file, game.timeoutinc, "game.timeoutinc"); + secfile_insert_int(file, game.timeoutincmult, "game.timeoutincmult"); + secfile_insert_int(file, game.timeoutcounter, "game.timeoutcounter"); secfile_insert_int(file, game.end_year, "game.end_year"); secfile_insert_int(file, game.year, "game.year"); secfile_insert_int(file, game.turn, "game.turn"); diff -Nur -Xfreeciv/diff_ignore freeciv/server/sernet.c test-timeout/server/sernet.c --- freeciv/server/sernet.c Tue Mar 5 20:58:07 2002 +++ test-timeout/server/sernet.c Sat Mar 30 13:27:35 2002 @@ -63,6 +63,7 @@ #endif #include "fcintl.h" +#include "gamehand.h" #include "log.h" #include "mem.h" #include "netintf.h" @@ -619,9 +620,9 @@ } con_prompt_off(); - if(game.timeout != 0 - && (time(NULL)>game.turn_start + game.timeout)) + if(game.timeout != 0 && (time(NULL) > game.turn_start + game.timeout)) { return 0; + } return 1; } diff -Nur -Xfreeciv/diff_ignore freeciv/server/srv_main.c test-timeout/server/srv_main.c --- freeciv/server/srv_main.c Fri Mar 22 15:13:55 2002 +++ test-timeout/server/srv_main.c Sat Mar 30 23:08:44 2002 @@ -1724,6 +1724,8 @@ end_turn(); freelog(LOG_DEBUG, "Gamenextyear"); game_advance_year(); + freelog(LOG_DEBUG, "Updatetimeout"); + update_timeout(); check_spaceship_arrivals(); freelog(LOG_DEBUG, "Sendplayerinfo"); send_player_info(NULL, NULL); diff -Nur -Xfreeciv/diff_ignore freeciv/server/stdinhand.c test-timeout/server/stdinhand.c --- freeciv/server/stdinhand.c Wed Mar 20 23:15:13 2002 +++ test-timeout/server/stdinhand.c Sat Mar 30 23:01:51 2002 @@ -660,14 +660,16 @@ N_("If all players have not hit \"Turn Done\" before this " "time is up, then the turn ends automatically. Zero " "means there is no timeout. In DEBUG servers, a timeout " - "of -1 sets the autogame test mode."), NULL, + "of -1 sets the autogame test mode. Use this with the command " + "\"timeoutincrease\" to have a dynamic timer."), NULL, GAME_MIN_TIMEOUT, GAME_MAX_TIMEOUT, GAME_DEFAULT_TIMEOUT) #else GEN_INT( "timeout", game.timeout, SSET_META, SSET_TO_CLIENT, N_("Maximum seconds per turn"), N_("If all players have not hit \"Turn Done\" before this " "time is up, then the turn ends automatically. Zero " - "means there is no timeout."), NULL, + "means there is no timeout. Use this with the command " + "\"timeoutincrease\" to have a dynamic timer."), NULL, GAME_MIN_TIMEOUT, GAME_MAX_TIMEOUT, GAME_DEFAULT_TIMEOUT) #endif @@ -894,6 +896,7 @@ CMD_HARD, CMD_CMDLEVEL, CMD_FIRSTLEVEL, + CMD_TIMEOUT, /* potentially harmful: */ CMD_END_GAME, @@ -1105,10 +1108,14 @@ "firstlevel", N_("Grab the 'first come' command access level."), N_("If 'cmdlevel first come' has been used to set a special 'first come'\n" - "command access level, this is the command to grab it with." - ) + "command access level, this is the command to grab it with.") + }, + {"timeoutincrease", ALLOW_CTRL, "timeoutincrease " + "", N_("See \"help timeoutincrease\"."), + N_("Every turns, add to timeout timer, then add " + "to and multiply by . Use this command in " + "concert with the option \"timeout\".") }, - {"endgame", ALLOW_CTRL, "endgame", N_("End the game."), @@ -2199,6 +2206,73 @@ static const char *optname_accessor(int i) { return settings[i].name; } + +/************************************************************************** + Set timeout options. +**************************************************************************/ +static void timeout_command(struct connection *caller, char *str) +{ + char buf[MAX_LEN_CONSOLE_LINE]; + char *bptr = buf, *arg[4] = {NULL, NULL, NULL, NULL}; + int i = 0, noargs = 0, val[4]; + int *timeouts[4]; + + timeouts[0] = &game.timeoutint; + timeouts[1] = &game.timeoutintinc; + timeouts[2] = &game.timeoutinc; + timeouts[3] = &game.timeoutincmult; + + assert(str != NULL); + + sz_strlcpy(buf, str); + remove_trailing_spaces(buf); + + while(*bptr != '\0' && i < 4) { + /* skip intervening whitespace */ + while(*bptr == ' ' || *bptr == '\t') { + bptr++; + } + + arg[i++] = bptr; + + /* skip arg */ + while(*bptr != ' ' && *bptr != '\t' && *bptr != '\0') { + bptr++; + } + + if (*bptr == '\0') { + break; + } else { + *(bptr++) = '\0'; + } + } + + for(i = 0; i < 4; i++) { + if (arg[i] != NULL) { + if(sscanf(arg[i], "%d", &val[i]) != 1) { + cmd_reply(CMD_TIMEOUT, caller, C_FAIL, _("Invalid argument %d."), i+1); + } else { + *timeouts[i] = val[i]; + } + } else { + noargs++; + } + } + + if(noargs == 4) { + cmd_reply(CMD_TIMEOUT, caller, C_SYNTAX, + _("Usage: timeoutincrease .")); + } else { + cmd_reply(CMD_TIMEOUT, caller, C_OK, _("Dynamic timeout set to " + "%d %d %d %d"), + game.timeoutint, game.timeoutintinc, + game.timeoutinc, game.timeoutincmult); + + /* if we set anything here, reset the counter */ + game.timeoutcounter = 1; + } +} + /************************************************************************** Find option index by name. Return index (>=0) on success, -1 if no suitable options were found, -2 if several matches were found. @@ -2805,7 +2879,8 @@ **************************************************************************/ void handle_stdin_input(struct connection *caller, char *str) { - char command[MAX_LEN_CONSOLE_LINE], arg[MAX_LEN_CONSOLE_LINE], *cptr_s, *cptr_d; + char command[MAX_LEN_CONSOLE_LINE], arg[MAX_LEN_CONSOLE_LINE], + allargs[MAX_LEN_CONSOLE_LINE], *cptr_s, *cptr_d; int i; enum command_id cmd; @@ -2874,6 +2949,10 @@ cut_comment(arg); + /* keep this before we cut everything after a space */ + sz_strlcpy(allargs, cptr_s); + cut_comment(allargs); + i=strlen(arg)-1; while(i>0 && isspace(arg[i])) arg[i--]='\0'; @@ -2972,6 +3051,9 @@ break; case CMD_FIRSTLEVEL: firstlevel_command(caller); + break; + case CMD_TIMEOUT: + timeout_command(caller, allargs); break; case CMD_START_GAME: if (server_state==PRE_GAME_STATE) {