This patch makes it easier to remove the action  ACTION_GAMELOOP_SET_STATE at a 
later stage.
Additionally it's easier now to move the check to another location in the code.
---
 lib/wormux/include/WORMUX_action.h |    1 +
 src/game/game.cpp                  |   13 +++++++++----
 src/include/action_handler.cpp     |   25 ++++++++++++++-----------
 src/network/randomsync.cpp         |   13 +++++++++++++
 src/network/randomsync.h           |    1 +
 5 files changed, 38 insertions(+), 15 deletions(-)

diff --git a/lib/wormux/include/WORMUX_action.h 
b/lib/wormux/include/WORMUX_action.h
index b423346..a64a515 100644
--- a/lib/wormux/include/WORMUX_action.h
+++ b/lib/wormux/include/WORMUX_action.h
@@ -109,6 +109,7 @@ public:
     ACTION_EXPLOSION,
     ACTION_WIND,
     ACTION_NETWORK_PING,
+    ACTION_NETWORK_VERIFY_RANDOM_SYNC,
     // ########################################################
   } Action_t;
 
diff --git a/src/game/game.cpp b/src/game/game.cpp
index af266bb..f62dbb6 100644
--- a/src/game/game.cpp
+++ b/src/game/game.cpp
@@ -664,6 +664,15 @@ void Game::SetState(game_loop_state_t new_state, bool 
begin_game) const
   // already in good state, nothing to do
   if ((state == new_state) && !begin_game) return;
 
+
+  // The action which verifys the random seed must be the first action 
sheduled!
+  // Otherwise the following could happen:
+  // 1. Action C gets sheduled which draws values from the random source.
+  // 2. Action V gets sheduled which verifies that random seed is X.
+  // 3. Action C gets executed: As a result the random seed has changed to 
another value Y.
+  // 4. Action V gets executed: It fails as the random seed is no longer X but 
Y.
+  RandomSync().Verify();
+
   // Send information about energy and position of every characters
   // ONLY at the beginning of a new turn!
   // (else you can send unstable information of a character which is moving)
@@ -672,11 +681,7 @@ void Game::SetState(game_loop_state_t new_state, bool 
begin_game) const
     SyncCharacters();
 
   MSG_DEBUG("game", "Ask for state %d", new_state);
-
-  MSG_DEBUG("random.get", "Game::SetState(...): %d");
   Action *a = new Action(Action::ACTION_GAMELOOP_SET_STATE);
-  uint seed = RandomSync().GetSeed();
-  a->Push((int)seed);
   a->Push(new_state);
   ActionHandler::GetInstance()->NewAction(a);
 }
diff --git a/src/include/action_handler.cpp b/src/include/action_handler.cpp
index 3c1ff0b..1e747e3 100644
--- a/src/include/action_handler.cpp
+++ b/src/include/action_handler.cpp
@@ -346,17 +346,6 @@ static void Action_DropBonusBox (Action *a)
 
 static void Action_Game_SetState (Action *a)
 {
-  // to re-synchronize random number generator
-  uint seed = (uint)(a->PopInt());
-#ifdef DEBUG
-  if (IsLOGGING("random")) {
-    uint nb = RandomSync().GetSeed();
-    MSG_DEBUG("random.get", "Action_Game_SetState(...): %d", nb);
-    ASSERT(nb == seed);
-  }
-#endif
-  RandomSync().SetSeed(seed);
-
   Game::game_loop_state_t state = Game::game_loop_state_t(a->PopInt());
   Game::GetInstance()->Really_SetState(state);
 }
@@ -799,6 +788,19 @@ static void Action_Network_RandomInit (Action *a)
   RandomSync().SetSeed(a->PopInt());
 }
 
+static void Action_Network_VerifyRandomSync(Action *a)
+{
+  uint local_seed = RandomSync().GetSeed();
+  uint remote_seed = (uint)(a->PopInt());
+  MSG_DEBUG("random.verify","Verify seed: %d (local) == %d (remote)", 
local_seed, remote_seed);
+
+  if (IsLOGGING("random"))
+    ASSERT(remote_seed == local_seed);
+
+  if (local_seed != remote_seed)
+    RandomSync().SetSeed(remote_seed);
+}
+
 // Nothing to do here. Just for time synchronisation
 static void Action_Network_Ping(Action */*a*/)
 {
@@ -1059,6 +1061,7 @@ void Action_Handler_Init()
   ActionHandler::GetInstance()->Register (Action::ACTION_EXPLOSION, 
"explosion", &Action_Explosion);
   ActionHandler::GetInstance()->Register (Action::ACTION_WIND, "wind", 
&Action_Wind);
   ActionHandler::GetInstance()->Register (Action::ACTION_NETWORK_RANDOM_INIT, 
"NETWORK_random_init", &Action_Network_RandomInit);
+  ActionHandler::GetInstance()->Register 
(Action::ACTION_NETWORK_VERIFY_RANDOM_SYNC, "NETWORK_verify_random_sync", 
&Action_Network_VerifyRandomSync);
   ActionHandler::GetInstance()->Register 
(Action::ACTION_INFO_CLIENT_DISCONNECT, "INFO_client_disconnect", 
&Action_Info_ClientDisconnect);
   ActionHandler::GetInstance()->Register (Action::ACTION_INFO_CLIENT_CONNECT, 
"INFO_client_connect", &Action_Info_ClientConnect);
 
diff --git a/src/network/randomsync.cpp b/src/network/randomsync.cpp
index e86f8df..fb0f412 100644
--- a/src/network/randomsync.cpp
+++ b/src/network/randomsync.cpp
@@ -66,6 +66,19 @@ void RandomSyncGen::SetRand(uint seed)
   RandomGenerator::SetRand(seed);
 }
 
+void RandomSyncGen::Verify()
+{
+  MSG_DEBUG("random.verify","Verify seed (%d)", GetSeed());
+  bool turn_master = Network::GetInstance()->IsTurnMaster();
+  ASSERT(turn_master);
+  if (!turn_master)
+    return;
+  uint seed = GetSeed();
+  Action* action = new Action(Action::ACTION_NETWORK_VERIFY_RANDOM_SYNC);
+  action->Push((int)seed);
+  ActionHandler::GetInstance()->NewAction(action);
+}
+
 RandomSyncGen& RandomSync()
 {
   return (*RandomSyncGen::GetInstance());
diff --git a/src/network/randomsync.h b/src/network/randomsync.h
index efb0397..181ed2b 100644
--- a/src/network/randomsync.h
+++ b/src/network/randomsync.h
@@ -36,6 +36,7 @@ protected:
   virtual void SetRand(uint seed);
 public:
   virtual void InitRandom();
+  void Verify();
 };
 
 RandomSyncGen& RandomSync();
-- 
1.6.0.4


_______________________________________________
Wormux-dev mailing list
Wormux-dev@gna.org
https://mail.gna.org/listinfo/wormux-dev

Répondre à