GameEventContainer *Server_Game::prepareGameEvent(const ::google::protobuf::Message &gameEvent, int playerId, GameEventContext *context) { GameEventContainer *cont = new GameEventContainer; cont->set_game_id(gameId); if (context) cont->mutable_context()->CopyFrom(*context); GameEvent *event = cont->add_event_list(); if (playerId != -1) event->set_player_id(playerId); event->GetReflection()->MutableMessage(event, gameEvent.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(gameEvent); return cont; }
void Server_ProtocolHandler::processCommandContainer(CommandContainer *cont) { const QList<Command *> &cmdList = cont->getCommandList(); ResponseCode finalResponseCode = RespOk; for (int i = 0; i < cmdList.size(); ++i) { ResponseCode resp = processCommandHelper(cmdList[i], cont); if ((resp != RespOk) && (resp != RespNothing)) finalResponseCode = resp; } ProtocolResponse *pr = cont->getResponse(); if (!pr) pr = new ProtocolResponse(cont->getCmdId(), finalResponseCode); GameEventContainer *gQPublic = cont->getGameEventQueuePublic(); if (gQPublic) { Server_Game *game = games.value(gQPublic->getGameId()).first; Server_Player *player = games.value(gQPublic->getGameId()).second; GameEventContainer *gQPrivate = cont->getGameEventQueuePrivate(); GameEventContainer *gQOmniscient = cont->getGameEventQueueOmniscient(); if (gQPrivate) { int privatePlayerId = cont->getPrivatePlayerId(); Server_Player *privatePlayer; if (privatePlayerId == -1) privatePlayer = player; else privatePlayer = game->getPlayer(privatePlayerId); if (gQOmniscient) { game->sendGameEventContainer(gQPublic, privatePlayer, true); game->sendGameEventContainerOmniscient(gQOmniscient, privatePlayer); } else game->sendGameEventContainer(gQPublic, privatePlayer); privatePlayer->sendProtocolItem(gQPrivate); } else game->sendGameEventContainer(gQPublic); } const QList<ProtocolItem *> &iQ = cont->getItemQueue(); for (int i = 0; i < iQ.size(); ++i) sendProtocolItem(iQ[i]); sendProtocolItem(pr); while (!itemQueue.isEmpty()) sendProtocolItem(itemQueue.takeFirst()); if (cont->getReceiverMayDelete()) delete cont; }
void AbstractClient::processProtocolItem(ProtocolItem *item) { ProtocolResponse *response = qobject_cast<ProtocolResponse *>(item); if (response) { CommandContainer *cmdCont = pendingCommands.value(response->getCmdId(), 0); if (!cmdCont) return; pendingCommands.remove(cmdCont->getCmdId()); cmdCont->processResponse(response); if (response->getReceiverMayDelete()) delete response; cmdCont->deleteLater(); return; } GenericEvent *genericEvent = qobject_cast<GenericEvent *>(item); if (genericEvent) { switch (genericEvent->getItemId()) { case ItemId_Event_UserJoined: emit userJoinedEventReceived(qobject_cast<Event_UserJoined *>(item)); break; case ItemId_Event_UserLeft: emit userLeftEventReceived(qobject_cast<Event_UserLeft *>(item)); break; case ItemId_Event_ServerMessage: emit serverMessageEventReceived(qobject_cast<Event_ServerMessage *>(item)); break; case ItemId_Event_ListRooms: emit listRoomsEventReceived(qobject_cast<Event_ListRooms *>(item)); break; case ItemId_Event_GameJoined: emit gameJoinedEventReceived(qobject_cast<Event_GameJoined *>(item)); break; case ItemId_Event_Message: emit messageEventReceived(qobject_cast<Event_Message *>(item)); break; } if (genericEvent->getReceiverMayDelete()) delete genericEvent; return; } GameEventContainer *gameEventContainer = qobject_cast<GameEventContainer *>(item); if (gameEventContainer) { emit gameEventContainerReceived(gameEventContainer); if (gameEventContainer->getReceiverMayDelete()) delete gameEventContainer; return; } RoomEvent *roomEvent = qobject_cast<RoomEvent *>(item); if (roomEvent) { emit roomEventReceived(roomEvent); if (roomEvent->getReceiverMayDelete()) delete roomEvent; return; } }
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 GameEventStorage::sendToGame(Server_Game *game) { if (gameEventList.isEmpty()) return; GameEventContainer *contPrivate = new GameEventContainer; GameEventContainer *contOthers = new GameEventContainer; for (int i = 0; i < gameEventList.size(); ++i) { const GameEvent &event = gameEventList[i]->getGameEvent(); const GameEventStorageItem::EventRecipients recipients = gameEventList[i]->getRecipients(); if (recipients.testFlag(GameEventStorageItem::SendToPrivate)) contPrivate->add_event_list()->CopyFrom(event); if (recipients.testFlag(GameEventStorageItem::SendToOthers)) contOthers->add_event_list()->CopyFrom(event); } if (gameEventContext) { contPrivate->mutable_context()->CopyFrom(*gameEventContext); contOthers->mutable_context()->CopyFrom(*gameEventContext); } game->sendGameEventContainer(contPrivate, GameEventStorageItem::SendToPrivate, privatePlayerId); game->sendGameEventContainer(contOthers, GameEventStorageItem::SendToOthers, privatePlayerId); }
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); }