Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
	}
}
Пример #4
0
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);
}
Пример #6
0
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);
}