Response::ResponseCode Server_ProtocolHandler::processSessionCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
{
	Response::ResponseCode finalResponseCode = Response::RespOk;
	for (int i = cont.session_command_size() - 1; i >= 0; --i) {
		Response::ResponseCode resp = Response::RespInvalidCommand;
		const SessionCommand &sc = cont.session_command(i);
		const int num = getPbExtension(sc);
		if (num != SessionCommand::PING) { // don't log ping commands
			if (num == SessionCommand::LOGIN) { // log login commands, but hide passwords
				SessionCommand debugSc(sc);
				debugSc.MutableExtension(Command_Login::ext)->clear_password();
				logDebugMessage(QString::fromStdString(debugSc.ShortDebugString()));
			} else
				logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
		}
		switch ((SessionCommand::SessionCommandType) num) {
			case SessionCommand::PING: resp = cmdPing(sc.GetExtension(Command_Ping::ext), rc); break;
			case SessionCommand::LOGIN: resp = cmdLogin(sc.GetExtension(Command_Login::ext), rc); break;
			case SessionCommand::MESSAGE: resp = cmdMessage(sc.GetExtension(Command_Message::ext), rc); break;
			case SessionCommand::GET_GAMES_OF_USER: resp = cmdGetGamesOfUser(sc.GetExtension(Command_GetGamesOfUser::ext), rc); break;
			case SessionCommand::GET_USER_INFO: resp = cmdGetUserInfo(sc.GetExtension(Command_GetUserInfo::ext), rc); break;
			case SessionCommand::LIST_ROOMS: resp = cmdListRooms(sc.GetExtension(Command_ListRooms::ext), rc); break;
			case SessionCommand::JOIN_ROOM: resp = cmdJoinRoom(sc.GetExtension(Command_JoinRoom::ext), rc); break;
			case SessionCommand::LIST_USERS: resp = cmdListUsers(sc.GetExtension(Command_ListUsers::ext), rc); break;
			default: resp = processExtendedSessionCommand(num, sc, rc);
		}
		if (resp != Response::RespOk)
			finalResponseCode = resp;
	}
	return finalResponseCode;
}
示例#2
0
PendingCommand *AbstractClient::prepareAdminCommand(const ::google::protobuf::Message &cmd)
{
    CommandContainer cont;
    AdminCommand *c = cont.add_admin_command();
    c->GetReflection()->MutableMessage(c, cmd.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(cmd);
    return new PendingCommand(cont);
}
Response::ResponseCode Server_ProtocolHandler::processRoomCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
{
	if (authState == NotLoggedIn)
		return Response::RespLoginNeeded;

	QReadLocker locker(&server->roomsLock);
	Server_Room *room = rooms.value(cont.room_id(), 0);
	if (!room)
		return Response::RespNotInRoom;
	
	Response::ResponseCode finalResponseCode = Response::RespOk;
	for (int i = cont.room_command_size() - 1; i >= 0; --i) {
		Response::ResponseCode resp = Response::RespInvalidCommand;
		const RoomCommand &sc = cont.room_command(i);
		const int num = getPbExtension(sc);
		logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
		switch ((RoomCommand::RoomCommandType) num) {
			case RoomCommand::LEAVE_ROOM: resp = cmdLeaveRoom(sc.GetExtension(Command_LeaveRoom::ext), room, rc); break;
			case RoomCommand::ROOM_SAY: resp = cmdRoomSay(sc.GetExtension(Command_RoomSay::ext), room, rc); break;
			case RoomCommand::CREATE_GAME: resp = cmdCreateGame(sc.GetExtension(Command_CreateGame::ext), room, rc); break;
			case RoomCommand::JOIN_GAME: resp = cmdJoinGame(sc.GetExtension(Command_JoinGame::ext), room, rc); break;
		}
		if (resp != Response::RespOk)
			finalResponseCode = resp;
	}
	return finalResponseCode;
}
void ServerSocketInterface::processProtocolItem(ProtocolItem *item)
{
	CommandContainer *cont = qobject_cast<CommandContainer *>(item);
	if (!cont)
		sendProtocolItem(new ProtocolResponse(cont->getCmdId(), RespInvalidCommand));
	else
		processCommandContainer(cont);
}
示例#5
0
void IslInterface::processRoomCommand(const CommandContainer &cont, qint64 sessionId)
{
	for (int i = 0; i < cont.room_command_size(); ++i) {
		const RoomCommand &roomCommand = cont.room_command(i);
		switch (static_cast<RoomCommand::RoomCommandType>(getPbExtension(roomCommand))) {
			case RoomCommand::JOIN_GAME: roomCommand_JoinGame(roomCommand.GetExtension(Command_JoinGame::ext), cont.cmd_id(), cont.room_id(), sessionId);
			default: ;
		}
	}
}
示例#6
0
void Server::sendIsl_RoomCommand(const CommandContainer &item, int serverId, qint64 sessionId, int roomId)
{
    IslMessage msg;
    msg.set_message_type(IslMessage::ROOM_COMMAND_CONTAINER);
    msg.set_session_id(sessionId);

    CommandContainer *cont = msg.mutable_room_command();
    cont->CopyFrom(item);
    cont->set_room_id(roomId);

    emit sigSendIslMessage(msg, serverId);
}
示例#7
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;
	}
}
示例#8
0
void UserContextMenu::gamesOfUserReceived(const Response &resp, const CommandContainer &commandContainer)
{
    const Response_GetGamesOfUser &response = resp.GetExtension(Response_GetGamesOfUser::ext);
    const Command_GetGamesOfUser &cmd = commandContainer.session_command(0).GetExtension(Command_GetGamesOfUser::ext);

    QMap<int, GameTypeMap> gameTypeMap;
    QMap<int, QString> roomMap;
    const int roomListSize = response.room_list_size();
    for (int i = 0; i < roomListSize; ++i) {
        const ServerInfo_Room &roomInfo = response.room_list(i);
        roomMap.insert(roomInfo.room_id(), QString::fromStdString(roomInfo.name()));
        GameTypeMap tempMap;
        const int gameTypeListSize = roomInfo.gametype_list_size();
        for (int j = 0; j < gameTypeListSize; ++j) {
            const ServerInfo_GameType &gameTypeInfo = roomInfo.gametype_list(j);
            tempMap.insert(gameTypeInfo.game_type_id(), QString::fromStdString(gameTypeInfo.description()));
        }
        gameTypeMap.insert(roomInfo.room_id(), tempMap);
    }

    GameSelector *selector = new GameSelector(client, tabSupervisor, 0, roomMap, gameTypeMap, false, false);
    const int gameListSize = response.game_list_size();
    for (int i = 0; i < gameListSize; ++i)
        selector->processGameInfo(response.game_list(i));

    selector->setWindowTitle(tr("%1's games").arg(QString::fromStdString(cmd.user_name())));
    selector->setMinimumWidth(800);
    selector->setAttribute(Qt::WA_DeleteOnClose);
    selector->show();
}
示例#9
0
void RemoteClient::sendCommandContainer(const CommandContainer &cont)
{
    QByteArray buf;
    unsigned int size = cont.ByteSize();
#ifdef QT_DEBUG
    qDebug() << "OUT" << size << QString::fromStdString(cont.ShortDebugString());
#endif
    buf.resize(size + 4);
    cont.SerializeToArray(buf.data() + 4, size);
    buf.data()[3] = (unsigned char) size;
    buf.data()[2] = (unsigned char) (size >> 8);
    buf.data()[1] = (unsigned char) (size >> 16);
    buf.data()[0] = (unsigned char) (size >> 24);
    
    socket->write(buf);
}
示例#10
0
void TabReplays::deleteRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer)
{
    if (r.response_code() != Response::RespOk)
        return;
    
    const Command_ReplayDeleteMatch &cmd = commandContainer.session_command(0).GetExtension(Command_ReplayDeleteMatch::ext);
    serverDirView->removeMatchInfo(cmd.game_id());
}
void TabDeckStorage::newFolderFinished(const Response &response, const CommandContainer &commandContainer)
{
    if (response.response_code() != Response::RespOk)
        return;
    
    const Command_DeckNewDir &cmd = commandContainer.session_command(0).GetExtension(Command_DeckNewDir::ext);
    serverDirView->addFolderToTree(QString::fromStdString(cmd.dir_name()), serverDirView->getNodeByPath(QString::fromStdString(cmd.path())));
}
void Server_ProtocolHandler::processCommandContainer(const CommandContainer &cont)
{
	// Command processing must be disabled after prepareDestroy() has been called.
	if (deleted)
		return;
	
	lastDataReceived = timeRunning;
	
	ResponseContainer responseContainer(cont.has_cmd_id() ? cont.cmd_id() : -1);
	Response::ResponseCode finalResponseCode;
	
	if (cont.game_command_size())
		finalResponseCode = processGameCommandContainer(cont, responseContainer);
	else if (cont.room_command_size())
		finalResponseCode = processRoomCommandContainer(cont, responseContainer);
	else if (cont.session_command_size())
		finalResponseCode = processSessionCommandContainer(cont, responseContainer);
	else if (cont.moderator_command_size())
		finalResponseCode = processModeratorCommandContainer(cont, responseContainer);
	else if (cont.admin_command_size())
		finalResponseCode = processAdminCommandContainer(cont, responseContainer);
	else
		finalResponseCode = Response::RespInvalidCommand;
	
	if ((finalResponseCode != Response::RespNothing))
		sendResponseContainer(responseContainer, finalResponseCode);
}
示例#13
0
void Server::externalGameCommandContainerReceived(const CommandContainer &cont, int playerId, int serverId, qint64 sessionId)
{
    // This function is always called from the main thread via signal/slot.

    try {
        ResponseContainer responseContainer(cont.cmd_id());
        Response::ResponseCode finalResponseCode = Response::RespOk;

        QReadLocker roomsLocker(&roomsLock);
        Server_Room *room = rooms.value(cont.room_id());
        if (!room) {
            qDebug() << "externalGameCommandContainerReceived: room id=" << cont.room_id() << "not found";
            throw Response::RespNotInRoom;
        }

        QReadLocker roomGamesLocker(&room->gamesLock);
        Server_Game *game = room->getGames().value(cont.game_id());
        if (!game) {
            qDebug() << "externalGameCommandContainerReceived: game id=" << cont.game_id() << "not found";
            throw Response::RespNotInRoom;
        }

        QMutexLocker gameLocker(&game->gameMutex);
        Server_Player *player = game->getPlayers().value(playerId);
        if (!player) {
            qDebug() << "externalGameCommandContainerReceived: player id=" << playerId << "not found";
            throw Response::RespNotInRoom;
        }

        GameEventStorage ges;
        for (int i = cont.game_command_size() - 1; i >= 0; --i) {
            const GameCommand &sc = cont.game_command(i);
            qDebug() << "[ISL]" << QString::fromStdString(sc.ShortDebugString());

            Response::ResponseCode resp = player->processGameCommand(sc, responseContainer, ges);

            if (resp != Response::RespOk)
                finalResponseCode = resp;
        }
        ges.sendToGame(game);

        if (finalResponseCode != Response::RespNothing) {
            player->playerMutex.lock();
            player->getUserInterface()->sendResponseContainer(responseContainer, finalResponseCode);
            player->playerMutex.unlock();
        }
    } catch (Response::ResponseCode code) {
        Response response;
        response.set_cmd_id(cont.cmd_id());
        response.set_response_code(code);

        sendIsl_Response(response, serverId, sessionId);
    }
}
void TabDeckStorage::deleteFolderFinished(const Response &response, const CommandContainer &commandContainer)
{
    if (response.response_code() != Response::RespOk)
        return;
    
    const Command_DeckDelDir &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDelDir::ext);
    RemoteDeckList_TreeModel::Node *toDelete = serverDirView->getNodeByPath(QString::fromStdString(cmd.path()));
    if (toDelete)
        serverDirView->removeNode(toDelete);
}
void TabDeckStorage::deleteDeckFinished(const Response &response, const CommandContainer &commandContainer)
{
    if (response.response_code() != Response::RespOk)
        return;
    
    const Command_DeckDel &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDel::ext);
    RemoteDeckList_TreeModel::Node *toDelete = serverDirView->getNodeById(cmd.deck_id());
    if (toDelete)
        serverDirView->removeNode(toDelete);
}
void TabDeckStorage::uploadFinished(const Response &r, const CommandContainer &commandContainer)
{
    if (r.response_code() != Response::RespOk)
        return;
    
    const Response_DeckUpload &resp = r.GetExtension(Response_DeckUpload::ext);
    const Command_DeckUpload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckUpload::ext);
    
    serverDirView->addFileToTree(resp.new_file(), serverDirView->getNodeByPath(QString::fromStdString(cmd.path())));
}
Response::ResponseCode Server_ProtocolHandler::processAdminCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
{
	if (!userInfo)
		return Response::RespLoginNeeded;
	if (!(userInfo->user_level() & ServerInfo_User::IsAdmin))
		return Response::RespLoginNeeded;

	Response::ResponseCode finalResponseCode = Response::RespOk;
	for (int i = cont.admin_command_size() - 1; i >= 0; --i) {
		Response::ResponseCode resp = Response::RespInvalidCommand;
		const AdminCommand &sc = cont.admin_command(i);
		const int num = getPbExtension(sc);
		logDebugMessage(QString::fromStdString(sc.ShortDebugString()));
		
		resp = processExtendedAdminCommand(num, sc, rc);
		if (resp != Response::RespOk)
			finalResponseCode = resp;
	}
	return finalResponseCode;
}
示例#18
0
void TabReplays::keepRemoteReplayFinished(const Response &r, const CommandContainer &commandContainer)
{
    if (r.response_code() != Response::RespOk)
        return;
    
    const Command_ReplayModifyMatch &cmd = commandContainer.session_command(0).GetExtension(Command_ReplayModifyMatch::ext);
    
    ServerInfo_ReplayMatch temp;
    temp.set_do_not_hide(cmd.do_not_hide());
                    
    serverDirView->updateMatchInfo(cmd.game_id(), temp);
}
Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
{
	if (authState == NotLoggedIn)
		return Response::RespLoginNeeded;
	
	QMap<int, QPair<int, int> > gameMap = getGames();
	if (!gameMap.contains(cont.game_id()))
		return Response::RespNotInRoom;
	const QPair<int, int> roomIdAndPlayerId = gameMap.value(cont.game_id());
	
	QReadLocker roomsLocker(&server->roomsLock);
	Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first);
	if (!room)
		return Response::RespNotInRoom;
	
	QReadLocker roomGamesLocker(&room->gamesLock);
	Server_Game *game = room->getGames().value(cont.game_id());
	if (!game) {
		if (room->getExternalGames().contains(cont.game_id())) {
			server->sendIsl_GameCommand(cont,
			                            room->getExternalGames().value(cont.game_id()).server_id(),
			                            userInfo->session_id(),
			                            roomIdAndPlayerId.first,
			                            roomIdAndPlayerId.second
			                            );
			return Response::RespNothing;
		}
		return Response::RespNotInRoom;
	}
	
	QMutexLocker gameLocker(&game->gameMutex);
	Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second);
	if (!player)
		return Response::RespNotInRoom;
	
	GameEventStorage ges;
	Response::ResponseCode finalResponseCode = Response::RespOk;
	for (int i = cont.game_command_size() - 1; i >= 0; --i) {
		const GameCommand &sc = cont.game_command(i);
		logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString()));
		
		Response::ResponseCode resp = player->processGameCommand(sc, rc, ges);

		if (resp != Response::RespOk)
			finalResponseCode = resp;
	}
	ges.sendToGame(game);
	
	return finalResponseCode;
}
void TabDeckStorage::openRemoteDeckFinished(const Response &r, const CommandContainer &commandContainer)
{
    if (r.response_code() != Response::RespOk)
        return;
    
    const Response_DeckDownload &resp = r.GetExtension(Response_DeckDownload::ext);
    const Command_DeckDownload &cmd = commandContainer.session_command(0).GetExtension(Command_DeckDownload::ext);
    
    DeckLoader loader;
    if (!loader.loadFromRemote(QString::fromStdString(resp.deck()), cmd.deck_id()))
        return;
    
    emit openDeckEditor(&loader);
}
void ServerSocketInterface::readClient()
{
    QByteArray data = socket->readAll();
    servatrice->incRxBytes(data.size());
    inputBuffer.append(data);

    do {
        if (!messageInProgress) {
            if (inputBuffer.size() >= 4) {
                messageLength =   (((quint32) (unsigned char) inputBuffer[0]) << 24)
                                + (((quint32) (unsigned char) inputBuffer[1]) << 16)
                                + (((quint32) (unsigned char) inputBuffer[2]) << 8)
                                + ((quint32) (unsigned char) inputBuffer[3]);
                inputBuffer.remove(0, 4);
                messageInProgress = true;
            } else
                return;
        }
        if (inputBuffer.size() < messageLength)
            return;

        CommandContainer newCommandContainer;
        newCommandContainer.ParseFromArray(inputBuffer.data(), messageLength);
        inputBuffer.remove(0, messageLength);
        messageInProgress = false;

        // dirty hack to make v13 client display the correct error message
        if (handshakeStarted)
            processCommandContainer(newCommandContainer);
        else if (!newCommandContainer.has_cmd_id()) {
            handshakeStarted = true;
            if (!initSession())
                prepareDestroy();
        }
        // end of hack
    } while (!inputBuffer.isEmpty());
}
void ServerSocketInterface::readClient()
{
    QByteArray data = socket->readAll();
    servatrice->incRxBytes(data.size());
    inputBuffer.append(data);

    do {
        if (!messageInProgress) {
            if (inputBuffer.size() >= 4) {
                messageLength =   (((quint32) (unsigned char) inputBuffer[0]) << 24)
                                + (((quint32) (unsigned char) inputBuffer[1]) << 16)
                                + (((quint32) (unsigned char) inputBuffer[2]) << 8)
                                + ((quint32) (unsigned char) inputBuffer[3]);
                inputBuffer.remove(0, 4);
                messageInProgress = true;
            } else
                return;
        }
        if (inputBuffer.size() < messageLength)
            return;

        CommandContainer newCommandContainer;
        try {
            newCommandContainer.ParseFromArray(inputBuffer.data(), messageLength);
        }
        catch(std::exception &e) {
            qDebug() << "Caught std::exception in" << __FILE__ << __LINE__ << 
#ifdef _MSC_VER // Visual Studio
                __FUNCTION__;
#else
                __PRETTY_FUNCTION__;
#endif
            qDebug() << "Exception:" << e.what();
            qDebug() << "Message coming from:" << getAddress();
            qDebug() << "Message length:" << messageLength;
            qDebug() << "Message content:" << inputBuffer.toHex();
        }
        catch(...) {
            qDebug() << "Unhandled exception in" << __FILE__ << __LINE__ <<
#ifdef _MSC_VER // Visual Studio
                __FUNCTION__;
#else
                __PRETTY_FUNCTION__;
#endif
            qDebug() << "Message coming from:" << getAddress();
        }

        inputBuffer.remove(0, messageLength);
        messageInProgress = false;

        // dirty hack to make v13 client display the correct error message
        if (handshakeStarted)
            processCommandContainer(newCommandContainer);
        else if (!newCommandContainer.has_cmd_id()) {
            handshakeStarted = true;
            if (!initSession())
                prepareDestroy();
        }
        // end of hack
    } while (!inputBuffer.isEmpty());
}
Response::ResponseCode Server_ProtocolHandler::processGameCommandContainer(const CommandContainer &cont, ResponseContainer &rc)
{
    static QList<GameCommand::GameCommandType> antifloodCommandsWhiteList = QList<GameCommand::GameCommandType>()
        // draw/undo card draw (example: drawing 10 cards one by one from the deck)
        << GameCommand::DRAW_CARDS
        << GameCommand::UNDO_DRAW
        // create, delete arrows (example: targeting with 10 cards during an attack)
        << GameCommand::CREATE_ARROW
        << GameCommand::DELETE_ARROW
        // set card attributes (example: tapping 10 cards at once)
        << GameCommand::SET_CARD_ATTR
        // increment / decrement counter (example: -10 life points one by one)
        << GameCommand::INC_COUNTER
        // mulling lots of hands in a row
        << GameCommand::MULLIGAN
        // allows a user to sideboard without receiving flooding message
        << GameCommand::MOVE_CARD;

    if (authState == NotLoggedIn)
        return Response::RespLoginNeeded;

    QMap<int, QPair<int, int> > gameMap = getGames();
    if (!gameMap.contains(cont.game_id()))
        return Response::RespNotInRoom;
    const QPair<int, int> roomIdAndPlayerId = gameMap.value(cont.game_id());

    QReadLocker roomsLocker(&server->roomsLock);
    Server_Room *room = server->getRooms().value(roomIdAndPlayerId.first);
    if (!room)
        return Response::RespNotInRoom;

    QReadLocker roomGamesLocker(&room->gamesLock);
    Server_Game *game = room->getGames().value(cont.game_id());
    if (!game) {
        if (room->getExternalGames().contains(cont.game_id())) {
            server->sendIsl_GameCommand(cont,
                                        room->getExternalGames().value(cont.game_id()).server_id(),
                                        userInfo->session_id(),
                                        roomIdAndPlayerId.first,
                                        roomIdAndPlayerId.second
                                        );
            return Response::RespNothing;
        }
        return Response::RespNotInRoom;
    }

    QMutexLocker gameLocker(&game->gameMutex);
    Server_Player *player = game->getPlayers().value(roomIdAndPlayerId.second);
    if (!player)
        return Response::RespNotInRoom;

    int commandCountingInterval = server->getCommandCountingInterval();
    int maxCommandCountPerInterval = server->getMaxCommandCountPerInterval();
    GameEventStorage ges;
    Response::ResponseCode finalResponseCode = Response::RespOk;
    for (int i = cont.game_command_size() - 1; i >= 0; --i) {
        const GameCommand &sc = cont.game_command(i);
        logDebugMessage(QString("game %1 player %2: ").arg(cont.game_id()).arg(roomIdAndPlayerId.second) + QString::fromStdString(sc.ShortDebugString()));

        if (commandCountingInterval > 0) {
            int totalCount = 0;
            if (commandCountOverTime.isEmpty())
                commandCountOverTime.prepend(0);

            if(!antifloodCommandsWhiteList.contains((GameCommand::GameCommandType) getPbExtension(sc)))
                ++commandCountOverTime[0];

            for (int i = 0; i < commandCountOverTime.size(); ++i)
                totalCount += commandCountOverTime[i];

            if (totalCount > maxCommandCountPerInterval)
                return Response::RespChatFlood;
        }

        Response::ResponseCode resp = player->processGameCommand(sc, rc, ges);

        if (resp != Response::RespOk)
            finalResponseCode = resp;
    }
    ges.sendToGame(game);

    return finalResponseCode;
}