Looks good :)

Florian Köberle a écrit :
> 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();
>   


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

Répondre à