Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc)
{
	if (authState == NotLoggedIn)
		return Response::RespLoginNeeded;
	
	if (rooms.contains(cmd.room_id()))
		return Response::RespContextError;
	
	QReadLocker serverLocker(&server->roomsLock);
	Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
	if (!r)
		return Response::RespNameNotFound;
	
	r->addClient(this);
	rooms.insert(r->getId(), r);
	
	Event_RoomSay joinMessageEvent;
	joinMessageEvent.set_message(r->getJoinMessage().toStdString());
	rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent));
	
	Response_JoinRoom *re = new Response_JoinRoom;
	r->getInfo(*re->mutable_room_info(), true);
	
	rc.setResponseExtension(re);
	return Response::RespOk;
}
Response::ResponseCode Server_ProtocolHandler::cmdGetGamesOfUser(const Command_GetGamesOfUser &cmd, ResponseContainer &rc)
{
	if (authState == NotLoggedIn)
		return Response::RespLoginNeeded;
	
	// We don't need to check whether the user is logged in; persistent games should also work.
	// The client needs to deal with an empty result list.
	
	Response_GetGamesOfUser *re = new Response_GetGamesOfUser;
	server->roomsLock.lockForRead();
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext()) {
		Server_Room *room = roomIterator.next().value();
		room->gamesLock.lockForRead();
		room->getInfo(*re->add_room_list(), false, true);
		QListIterator<ServerInfo_Game> gameIterator(room->getGamesOfUser(QString::fromStdString(cmd.user_name())));
		while (gameIterator.hasNext())
			re->add_game_list()->CopyFrom(gameIterator.next());
		room->gamesLock.unlock();
	}
	server->roomsLock.unlock();
	
	rc.setResponseExtension(re);
	return Response::RespOk;
}
Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc)
{
    if (authState == NotLoggedIn)
        return Response::RespLoginNeeded;

    if (rooms.contains(cmd.room_id()))
        return Response::RespContextError;

    QReadLocker serverLocker(&server->roomsLock);
    Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
    if (!r)
        return Response::RespNameNotFound;

    QString roomPermission = r->getRoomPermission().toLower();
    if (roomPermission != "none"){
        if (roomPermission == "registered") {
            if (!(userInfo->user_level() & ServerInfo_User::IsRegistered))
                return Response::RespUserLevelTooLow;
        }

        if (roomPermission == "moderator"){
            if (!(userInfo->user_level() & ServerInfo_User::IsModerator))
                return Response::RespUserLevelTooLow;
        }

        if (roomPermission == "administrator"){
            if (!(userInfo->user_level() & ServerInfo_User::IsAdmin))
                return Response::RespUserLevelTooLow;
        }
    }

    r->addClient(this);
    rooms.insert(r->getId(), r);

    Event_RoomSay joinMessageEvent;
    joinMessageEvent.set_message(r->getJoinMessage().toStdString());
    joinMessageEvent.set_message_type(Event_RoomSay::Welcome);
    rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent));

    QReadLocker chatHistoryLocker(&r->historyLock);
    QList<ServerInfo_ChatMessage> chatHistory = r->getChatHistory();
    ServerInfo_ChatMessage chatMessage;
    for (int i = 0; i < chatHistory.size(); ++i) {
        chatMessage = chatHistory.at(i);
        qDebug() << QString::fromStdString(chatMessage.message()).simplified();
        Event_RoomSay roomChatHistory;
        roomChatHistory.set_message(chatMessage.sender_name() + ": " + chatMessage.message());
        roomChatHistory.set_message_type(Event_RoomSay::ChatHistory);
        roomChatHistory.set_time_of(QDateTime::fromString(QString::fromStdString(chatMessage.time())).toMSecsSinceEpoch());
        rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(roomChatHistory));
    }

    Response_JoinRoom *re = new Response_JoinRoom;
    r->getInfo(*re->mutable_room_info(), true);

    rc.setResponseExtension(re);
    return Response::RespOk;
}
Response::ResponseCode Server_ProtocolHandler::cmdJoinRoom(const Command_JoinRoom &cmd, ResponseContainer &rc)
{
    if (authState == NotLoggedIn)
        return Response::RespLoginNeeded;

    if (rooms.contains(cmd.room_id()))
        return Response::RespContextError;

    QReadLocker serverLocker(&server->roomsLock);
    Server_Room *r = server->getRooms().value(cmd.room_id(), 0);
    if (!r)
        return Response::RespNameNotFound;

    QString roomPermission = r->getRoomPermission().toLower();
    if (roomPermission != "none"){
        if (roomPermission == "registered") {
            if (!(userInfo->user_level() & ServerInfo_User::IsRegistered))
                return Response::RespUserLevelTooLow;
        }

        if (roomPermission == "moderator"){
            if (!(userInfo->user_level() & ServerInfo_User::IsModerator))
                return Response::RespUserLevelTooLow;
        }

        if (roomPermission == "administrator"){
            if (!(userInfo->user_level() & ServerInfo_User::IsAdmin))
                return Response::RespUserLevelTooLow;
        }
    }

    r->addClient(this);
    rooms.insert(r->getId(), r);

    Event_RoomSay joinMessageEvent;
    joinMessageEvent.set_message(r->getJoinMessage().toStdString());
    rc.enqueuePostResponseItem(ServerMessage::ROOM_EVENT, r->prepareRoomEvent(joinMessageEvent));

    Response_JoinRoom *re = new Response_JoinRoom;
    r->getInfo(*re->mutable_room_info(), true);

    rc.setResponseExtension(re);
    return Response::RespOk;
}
ResponseCode Server_ProtocolHandler::cmdJoinRoom(Command_JoinRoom *cmd, CommandContainer *cont)
{
	if (authState == PasswordWrong)
		return RespLoginNeeded;
	
	if (rooms.contains(cmd->getRoomId()))
		return RespContextError;
	
	Server_Room *r = server->getRooms().value(cmd->getRoomId(), 0);
	if (!r)
		return RespNameNotFound;

	r->addClient(this);
	rooms.insert(r->getId(), r);
	
	enqueueProtocolItem(new Event_RoomSay(r->getId(), QString(), r->getJoinMessage()));
	
	cont->setResponse(new Response_JoinRoom(cont->getCmdId(), RespOk, r->getInfo(true)));
	return RespNothing;
}
Esempio n. 6
0
void IslInterface::initServer()
{
	socket->setSocketDescriptor(socketDescriptor);
	
	logger->logMessage(QString("[ISL] incoming connection: %1").arg(socket->peerAddress().toString()));
	
	QList<ServerProperties> serverList = server->getServerList();
	int listIndex = -1;
	for (int i = 0; i < serverList.size(); ++i)
		if (serverList[i].address == socket->peerAddress()) {
			listIndex = i;
			break;
		}
	if (listIndex == -1) {
		logger->logMessage(QString("[ISL] address %1 unknown, terminating connection").arg(socket->peerAddress().toString()));
		deleteLater();
		return;
	}
	
	socket->startServerEncryption();
	if (!socket->waitForEncrypted(5000)) {
		QList<QSslError> sslErrors(socket->sslErrors());
		if (sslErrors.isEmpty())
			qDebug() << "[ISL] SSL handshake timeout, terminating connection";
		else
			qDebug() << "[ISL] SSL errors:" << sslErrors;
		deleteLater();
		return;
	}
	
	if (serverList[listIndex].cert == socket->peerCertificate())
		logger->logMessage(QString("[ISL] Peer authenticated as " + serverList[listIndex].hostname));
	else {
		logger->logMessage(QString("[ISL] Authentication failed, terminating connection"));
		deleteLater();
		return;
	}
	serverId = serverList[listIndex].id;
	
	Event_ServerCompleteList event;
	event.set_server_id(server->getServerId());
	
	server->clientsLock.lockForRead();
	QMapIterator<QString, Server_ProtocolHandler *> userIterator(server->getUsers());
	while (userIterator.hasNext())
		event.add_user_list()->CopyFrom(userIterator.next().value()->copyUserInfo(true, true));
	server->clientsLock.unlock();
	
	server->roomsLock.lockForRead();
	QMapIterator<int, Server_Room *> roomIterator(server->getRooms());
	while (roomIterator.hasNext()) {
		Server_Room *room = roomIterator.next().value();
		room->usersLock.lockForRead();
		room->gamesLock.lockForRead();
		room->getInfo(*event.add_room_list(), true, true, false, false);
	}
	
	IslMessage message;
	message.set_message_type(IslMessage::SESSION_EVENT);
	SessionEvent *sessionEvent = message.mutable_session_event();
	sessionEvent->GetReflection()->MutableMessage(sessionEvent, event.GetDescriptor()->FindExtensionByName("ext"))->CopyFrom(event);
	
	server->islLock.lockForWrite();
	if (server->islConnectionExists(serverId)) {
		qDebug() << "[ISL] Duplicate connection to #" << serverId << "terminating connection";
		deleteLater();
	} else {
		transmitMessage(message);
		server->addIslInterface(serverId, this);
	}
	server->islLock.unlock();
	
	roomIterator.toFront();
	while (roomIterator.hasNext()) {
		roomIterator.next();
		roomIterator.value()->gamesLock.unlock();
		roomIterator.value()->usersLock.unlock();
	}
	server->roomsLock.unlock();
}