Complete.Org: Mailing Lists: Archives: freeciv-dev: March 2005:
[Freeciv-Dev] (PR#12432) separate timeouts per-player
Home

[Freeciv-Dev] (PR#12432) separate timeouts per-player

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#12432) separate timeouts per-player
From: "Jason Short" <jdorje@xxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 4 Mar 2005 17:11:37 -0800
Reply-to: bugs@xxxxxxxxxxx

<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

[Prev in Thread] Current Thread [Next in Thread]