[Freeciv-Dev] (PR#12432) separate timeouts per-player
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=12432 >
This patch implements separate timeouts for each player.
The timeout is tracked in the pplayer->server field instead of the game
field. It is initialized per-player and checked per-player. The
timeoutaddenemymove value only increases the timeout of the affected player.
When sending the info to the client however only one value is sent. We
could conceivably send a value for each player (using a player info
packet) and let the client do the logic. Instead the server does the
logic: for an active player their timeout is sent, for an inactive or
non-player the maximum timeout is sent.
-jason
Index: common/game.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/game.h,v
retrieving revision 1.175
diff -u -r1.175 game.h
--- common/game.h 5 Mar 2005 00:06:25 -0000 1.175
+++ common/game.h 5 Mar 2005 01:08:44 -0000
@@ -77,8 +77,6 @@
time_t last_ping;
int pingtimeout;
int pingtime;
- double seconds_to_phase_done; /* Set at start of each phase. */
- struct timer *phase_timer; /* Time since seconds_to_phase_done was set. */
int end_year;
int year;
int turn;
Index: common/player.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/common/player.h,v
retrieving revision 1.141
diff -u -r1.141 player.h
--- common/player.h 23 Feb 2005 03:34:06 -0000 1.141
+++ common/player.h 5 Mar 2005 01:08:44 -0000
@@ -228,6 +228,11 @@
void *data;
} attribute_block;
bv_debug debug;
+
+ struct {
+ double seconds_to_phase_done; /* Set at start of each phase. */
+ struct timer *phase_timer; /* Time since seconds_to_phase_done was set. */
+ } server;
};
void player_init(struct player *plr);
Index: server/gamehand.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.c,v
retrieving revision 1.154
diff -u -r1.154 gamehand.c
--- server/gamehand.c 5 Mar 2005 00:06:25 -0000 1.154
+++ server/gamehand.c 5 Mar 2005 01:08:45 -0000
@@ -304,6 +304,16 @@
{
struct packet_game_info ginfo;
int i;
+ double max_sec_to_phase_done = -1.0;
+
+ if (game.timeout != 0) {
+ phase_players_iterate(pplayer) {
+ double sec = pplayer->server.seconds_to_phase_done
+ - read_timer_seconds(pplayer->server.phase_timer);
+
+ max_sec_to_phase_done = MAX(max_sec_to_phase_done, sec);
+ } phase_players_iterate_end;
+ }
if (!dest) {
dest = game.game_connections;
@@ -343,19 +353,26 @@
ginfo.global_advances[i] = game.global_advances[i];
for (i = 0; i < B_LAST /*game.num_impr_types */ ; i++)
ginfo.great_wonders[i] = game.great_wonders[i];
+
/* the following values are computed every
time a packet_game_info packet is created */
- if (game.timeout != 0) {
- ginfo.seconds_to_phasedone
- = game.seconds_to_phase_done - read_timer_seconds(game.phase_timer);
- } else {
+ if (game.timeout == 0) {
/* unused but at least initialized */
ginfo.seconds_to_phasedone = -1.0;
}
conn_list_iterate(dest, pconn) {
- /* ? fixme: check for non-players: */
+ if (game.timeout != 0) {
+ if (pconn->player && is_player_phase(pconn->player, game.phase)) {
+ ginfo.seconds_to_phasedone
+ = (pconn->player->server.seconds_to_phase_done
+ - read_timer_seconds(pconn->player->server.phase_timer));
+ } else {
+ ginfo.seconds_to_phasedone = max_sec_to_phase_done;
+ }
+ }
ginfo.player_idx = (pconn->player ? pconn->player->player_no : -1);
+
send_packet_game_info(pconn, &ginfo);
}
conn_list_iterate_end;
@@ -421,14 +438,15 @@
theory there should be a separate timeout for each player and the
added time should only go onto the victim's timer.
**************************************************************************/
-void increase_timeout_because_unit_moved(void)
+void increase_timeout_because_unit_moved(struct player *pplayer)
{
if (game.timeout != 0 && game.timeoutaddenemymove > 0) {
- double maxsec = (read_timer_seconds(game.phase_timer)
+ double maxsec = (read_timer_seconds(pplayer->server.phase_timer)
+ (double)game.timeoutaddenemymove);
- if (maxsec > game.seconds_to_phase_done) {
- game.seconds_to_phase_done = maxsec;
+ assert(is_player_phase(pplayer, game.phase));
+ if (maxsec > pplayer->server.seconds_to_phase_done) {
+ pplayer->server.seconds_to_phase_done = maxsec;
send_game_info(NULL);
}
}
Index: server/gamehand.h
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/gamehand.h,v
retrieving revision 1.14
diff -u -r1.14 gamehand.h
--- server/gamehand.h 4 Mar 2005 18:48:08 -0000 1.14
+++ server/gamehand.h 5 Mar 2005 01:08:45 -0000
@@ -24,7 +24,7 @@
void send_start_phase_to_clients(void);
int update_timeout(void);
-void increase_timeout_because_unit_moved(void);
+void increase_timeout_because_unit_moved(struct player *pplayer);
const char *new_challenge_filename(struct connection *pc);
Index: server/sernet.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/sernet.c,v
retrieving revision 1.135
diff -u -r1.135 sernet.c
--- server/sernet.c 5 Mar 2005 00:06:26 -0000 1.135
+++ server/sernet.c 5 Mar 2005 01:08:45 -0000
@@ -323,6 +323,24 @@
}
}
+/****************************************************************************
+ Return TRUE if the timeout has expired for all players.
+****************************************************************************/
+static bool is_phase_timeout_expired(void)
+{
+ if (game.timeout == 0) {
+ return FALSE;
+ }
+ phase_players_iterate(pplayer) {
+ if (read_timer_seconds(pplayer->server.phase_timer)
+ < pplayer->server.seconds_to_phase_done) {
+ return FALSE;
+ }
+ } phase_players_iterate_end;
+
+ return TRUE;
+}
+
/*****************************************************************************
Get and handle:
- new connections,
@@ -499,9 +517,8 @@
if(select(max_desc+1, &readfs, &writefs, &exceptfs, &tv)==0) { /* timeout
*/
(void) send_server_info_to_metaserver(META_REFRESH);
- if (game.timeout != 0
- && read_timer_seconds(game.phase_timer) > game.seconds_to_phase_done
- && server_state == RUN_GAME_STATE) {
+ if (server_state == RUN_GAME_STATE
+ && is_phase_timeout_expired()) {
con_prompt_off();
return 0;
}
@@ -670,8 +687,7 @@
}
con_prompt_off();
- if (game.timeout != 0
- && read_timer_seconds(game.phase_timer) > game.seconds_to_phase_done) {
+ if (is_phase_timeout_expired()) {
return 0;
}
return 1;
Index: server/srv_main.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/srv_main.c,v
retrieving revision 1.231
diff -u -r1.231 srv_main.c
--- server/srv_main.c 5 Mar 2005 00:06:26 -0000 1.231
+++ server/srv_main.c 5 Mar 2005 01:08:45 -0000
@@ -566,9 +566,12 @@
sanity_check();
- game.seconds_to_phase_done = (double)game.timeout;
- game.phase_timer = renew_timer_start(game.phase_timer,
- TIMER_USER, TIMER_ACTIVE);
+ phase_players_iterate(pplayer) {
+ pplayer->server.seconds_to_phase_done = (double)game.timeout;
+ pplayer->server.phase_timer
+ = renew_timer_start(pplayer->server.phase_timer,
+ TIMER_USER, TIMER_ACTIVE);
+ } phase_players_iterate_end;
send_game_info(NULL);
}
Index: server/unittools.c
===================================================================
RCS file: /home/freeciv/CVS/freeciv/server/unittools.c,v
retrieving revision 1.324
diff -u -r1.324 unittools.c
--- server/unittools.c 4 Mar 2005 18:48:08 -0000 1.324
+++ server/unittools.c 5 Mar 2005 01:08:46 -0000
@@ -2921,8 +2921,6 @@
conn_list_do_unbuffer(pplayer->connections);
if (game.timeout != 0 && game.timeoutaddenemymove > 0) {
- bool new_information_for_enemy = FALSE;
-
phase_players_iterate(penemy) {
/* Increase the timeout if an enemy unit moves and the
* timeoutaddenemymove setting is in use. */
@@ -2930,14 +2928,9 @@
&& pplayer != penemy
&& pplayers_at_war(penemy, pplayer)
&& can_player_see_unit(penemy, punit)) {
- new_information_for_enemy = TRUE;
- break;
+ increase_timeout_because_unit_moved(penemy);
}
} phase_players_iterate_end;
-
- if (new_information_for_enemy) {
- increase_timeout_because_unit_moved();
- }
}
/* Note, an individual call to move_unit may leave things in an unstable
- [Freeciv-Dev] (PR#12432) separate timeouts per-player,
Jason Short <=
|
|