void Server_Game::sendGameStateToPlayers() { // game state information for replay and omniscient spectators Event_GameStateChanged omniscientEvent; createGameStateChangedEvent(&omniscientEvent, 0, true, false); GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); replayCont->set_seconds_elapsed(secondsElapsed - startTimeOfThisGame); replayCont->clear_game_id(); currentReplay->add_event_list()->CopyFrom(*replayCont); delete replayCont; // If spectators are not omniscient, we need an additional createGameStateChangedEvent call, otherwise we can use the data we used for the replay. // All spectators are equal, so we don't need to make a createGameStateChangedEvent call for each one. Event_GameStateChanged spectatorEvent; if (spectatorsSeeEverything) spectatorEvent = omniscientEvent; else createGameStateChangedEvent(&spectatorEvent, 0, false, false); // send game state info to clients according to their role in the game QMapIterator<int, Server_Player *> playerIterator(players); while (playerIterator.hasNext()) { Server_Player *player = playerIterator.next().value(); GameEventContainer *gec; if (player->getSpectator()) gec = prepareGameEvent(spectatorEvent, -1); else { Event_GameStateChanged event; createGameStateChangedEvent(&event, player, false, false); gec = prepareGameEvent(event, -1); } player->sendGameEvent(*gec); delete gec; } }
void Server_Game::doStartGameIfReady() { Server_DatabaseInterface *databaseInterface = room->getServer()->getDatabaseInterface(); QMutexLocker locker(&gameMutex); if (getPlayerCount() < maxPlayers) return; QMapIterator<int, Server_Player *> playerIterator(players); while (playerIterator.hasNext()) { Server_Player *p = playerIterator.next().value(); if (!p->getReadyStart() && !p->getSpectator()) return; } playerIterator.toFront(); while (playerIterator.hasNext()) { Server_Player *p = playerIterator.next().value(); if (!p->getSpectator()) p->setupZones(); } gameStarted = true; playerIterator.toFront(); while (playerIterator.hasNext()) { Server_Player *player = playerIterator.next().value(); player->setConceded(false); player->setReadyStart(false); } if (firstGameStarted) { currentReplay->set_duration_seconds(secondsElapsed - startTimeOfThisGame); replayList.append(currentReplay); currentReplay = new GameReplay; currentReplay->set_replay_id(databaseInterface->getNextReplayId()); ServerInfo_Game *gameInfo = currentReplay->mutable_game_info(); getInfo(*gameInfo); gameInfo->set_started(false); Event_GameStateChanged omniscientEvent; createGameStateChangedEvent(&omniscientEvent, 0, true, true); GameEventContainer *replayCont = prepareGameEvent(omniscientEvent, -1); replayCont->set_seconds_elapsed(0); replayCont->clear_game_id(); currentReplay->add_event_list()->CopyFrom(*replayCont); delete replayCont; startTimeOfThisGame = secondsElapsed; } else firstGameStarted = true; sendGameStateToPlayers(); activePlayer = -1; nextTurn(); locker.unlock(); ServerInfo_Game gameInfo; gameInfo.set_room_id(room->getId()); gameInfo.set_game_id(gameId); gameInfo.set_started(true); emit gameInfoChanged(gameInfo); }