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