コード例 #1
0
// Scenario 1: Player is idle and gets suspended -- no other players in game
static void doScenario1(GamePair &gamePair)
{
   ClientGame *clientGame = gamePair.getClient(0);
   ServerGame *serverGame = gamePair.server;

   // Idle for a while -- ship should become spawn delayed.  GameConnection::SPAWN_DELAY_TIME is measured in ms.
   gamePair.idle(10, GameConnection::SPAWN_DELAY_TIME / 10);

   ASSERT_TRUE(serverGame->getClientInfo(0)->isPlayerInactive());    // No input from player, should be flagged as inactive
   // Note that spawn delay does not get set until the delayed ship tries to spawn, even if player is marked as inactive

   // Kill the ship again -- should be delayed when it tries to respawn because client has been inactive
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   EXPECT_EQ(1, fillVector.size());    // Should only be one ship

   Ship *ship = static_cast<Ship *>(fillVector[0]);      // Server's copy of the ship

   killShip(ship);

   gamePair.idle(10, GameType::RespawnDelay / 10 + 5);
   // Since server has received no input from client for GameConnection::SPAWN_DELAY_TIME ms, and ship has attempted to respawn, should be spawn-delayed
   ASSERT_TRUE(serverGame->getClientInfo(0)->isSpawnDelayed());
   ASSERT_TRUE(clientGame->isSpawnDelayed());      // Status should have propagated to client by now

   // At this point, client and server are both aware that the spawn is delayed due to player inactivity

   gamePair.idle(10, 10);              // Idle 10x
   // If spawn were not delayed, ship would have respawned.  Check for it on the server.
   // (Dead ship may linger on client while exploding, so we won't check there.)
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(0, fillVector.size());                   // Ship is spawn delayed and won't spawn... hence no ships
   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());      // No returnToGamePenalty in this scenario
   ASSERT_EQ(0, clientGame->getReturnToGameDelay());
   ASSERT_FALSE(static_cast<FullClientInfo *>(serverGame->getClientInfo(0))->hasReturnToGamePenalty());   // No penalty in the works

   // Undelay spawn
   clientGame->undelaySpawn();         // This is what gets run when player presses a key
   gamePair.idle(10, 5);               // Idle 5x; give things time to propagate

   ASSERT_FALSE(serverGame->getClientInfo(0)->isSpawnDelayed());     // Player should no longer be spawn delayed
   ASSERT_FALSE(clientGame->inReturnToGameCountdown());
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());    // Ship should have spawned and be available on client and server
   fillVector.clear();
   clientGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());    // Ship should have spawned and be available on client and server
}
コード例 #2
0
// Scenario 3, 4 -- Player enters /idle command, no other players, so server suspends itself
// In this case, no returnToGame penalty should be levied
// In this scenario 3, player un-idles during the suspend game timer countdown (there is a 2 second delay after all players are idle)
// In scenario 4, player enters full suspend mode before unidling
static void doScenario34(GamePair &gamePair, bool letGameSlipIntoFullSuspendMode)
{
   ClientGame *clientGame = gamePair.getClient(0);
   ServerGame *serverGame = gamePair.server;

   // Make sure we start off in a "normal" state
   ASSERT_FALSE(serverGame->isOrIsAboutToBeSuspended());
   ASSERT_FALSE(clientGame->isSpawnDelayed());         

   gamePair.idle(Ship::KillDeleteDelay / 15, 20);     // Idle; give things time to propagate
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());                   // Now that player 2 has left, should only be one ship
   fillVector.clear();
   clientGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());

   Vector<string> words;
   ChatCommands::idleHandler(clientGame, words);
   gamePair.idle(10, 10);     // Idle; give things time to propagate, timers to time out, etc.
   ASSERT_TRUE(serverGame->getClientInfo(0)->isSpawnDelayed());
   ASSERT_TRUE(serverGame->isOrIsAboutToBeSuspended());
   EXPECT_FALSE(serverGame->isSuspended());
   ASSERT_TRUE(clientGame->isSpawnDelayed());         // Status should have propagated to client by now
   EXPECT_FALSE(clientGame->isSuspended());

   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(0, fillVector.size());                   // No ships remaining in game -- don't check client as it may have exploding ship there
   fillVector.clear();

   // ReturnToGame penalty has been set, but won't start to count down until ship attempts to spawn
   ASSERT_FALSE(clientGame->inReturnToGameCountdown());
   ASSERT_TRUE(static_cast<FullClientInfo *>(serverGame->getClientInfo(0))->hasReturnToGamePenalty()); // Penalty has been primed
   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());

   if(letGameSlipIntoFullSuspendMode)
		gamePair.idle(ServerGame::PreSuspendSettlingPeriod / 20, 25);

   // Player presses a key to rejoin the game; since game was suspended, player can resume without penalty
   ASSERT_TRUE(serverGame->isOrIsAboutToBeSuspended()) << "Game should be suspended";

   if(letGameSlipIntoFullSuspendMode)
   {
      // In here, game is suspended

      EXPECT_TRUE(serverGame->isSuspended());
      EXPECT_TRUE(clientGame->isSuspended());

      // Check if server clocks are still counting down... should be stopped
      S32 snow = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 cnow = clientGame->getGameType()->getRemainingGameTimeInMs();
      gamePair.idle(10, 10);
      S32 slater = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 clater = clientGame->getGameType()->getRemainingGameTimeInMs();
      EXPECT_EQ(snow, slater) << "Looks like server clock is still running (should be stopped)!";
      EXPECT_EQ(cnow, clater) << "Looks like client clock is still running (should be stopped)!";
   }
   else
   {
      // In here, game is not (yet) suspended, but is in the 2 second cooldown period that comes after 
      // all players have left or are idle, but before full suspension

      EXPECT_FALSE(serverGame->isSuspended());
      EXPECT_FALSE(clientGame->isSuspended());

      // Check if clocks are still counting down... should be still running
      S32 snow = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 cnow = clientGame->getGameType()->getRemainingGameTimeInMs();
      gamePair.idle(10, 10);
      S32 slater = serverGame->getGameType()->getRemainingGameTimeInMs();
      S32 clater = clientGame->getGameType()->getRemainingGameTimeInMs();
      EXPECT_NE(snow, slater) << "Looks like server clock is stopped (should be running)!";
      EXPECT_NE(cnow, clater) << "Looks like client clock is stopped (should be running)!";
   }

   clientGame->undelaySpawn();                                          // Simulate effects of key press
   gamePair.idle(10, 5);                                                // Idle; give things time to propagate
   ASSERT_FALSE(serverGame->isOrIsAboutToBeSuspended());

   ASSERT_EQ(0, serverGame->getClientInfo(0)->getReturnToGameTime());   // No returnToGame penalty
   ASSERT_FALSE(clientGame->inReturnToGameCountdown());

   gamePair.idle(Ship::KillDeleteDelay / 15, 20);     // Idle; give dead ships time to be cleaned up

   // Check to ensure ship spawned
   fillVector.clear();
   serverGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());   
   fillVector.clear();
   clientGame->getLevel()->findObjects(PlayerShipTypeNumber, fillVector);
   ASSERT_EQ(1, fillVector.size());

   ASSERT_FALSE(serverGame->isOrIsAboutToBeSuspended());
   ASSERT_FALSE(clientGame->isSpawnDelayed());         
}