Example #1
0
void Server::externalUserLeft(const QString &userName)
{
    // This function is always called from the main thread via signal/slot.

    clientsLock.lockForWrite();
    Server_AbstractUserInterface *user = externalUsers.take(userName);
    externalUsersBySessionId.remove(user->getUserInfo()->session_id());
    clientsLock.unlock();

    QMap<int, QPair<int, int> > userGames(user->getGames());
    QMapIterator<int, QPair<int, int> > userGamesIterator(userGames);
    roomsLock.lockForRead();
    while (userGamesIterator.hasNext()) {
        userGamesIterator.next();
        Server_Room *room = rooms.value(userGamesIterator.value().first);
        if (!room)
            continue;

        QReadLocker roomGamesLocker(&room->gamesLock);
        Server_Game *game = room->getGames().value(userGamesIterator.key());
        if (!game)
            continue;

        QMutexLocker gameLocker(&game->gameMutex);
        Server_Player *player = game->getPlayers().value(userGamesIterator.value().second);
        if (!player)
            continue;

        player->disconnectClient();
    }
    roomsLock.unlock();

    delete user;

    Event_UserLeft event;
    event.set_name(userName.toStdString());

    SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event);
    clientsLock.lockForRead();
    for (int i = 0; i < clients.size(); ++i)
        if (clients[i]->getAcceptsUserListChanges())
            clients[i]->sendProtocolItem(*se);
    clientsLock.unlock();
    delete se;
}
Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_Message &cmd, ResponseContainer &rc)
{
    if (authState == NotLoggedIn)
        return Response::RespLoginNeeded;

    QReadLocker locker(&server->clientsLock);

    QString receiver = QString::fromStdString(cmd.user_name());
    Server_AbstractUserInterface *userInterface = server->findUser(receiver);
    if (!userInterface)
        return Response::RespNameNotFound;
    if (databaseInterface->isInIgnoreList(receiver, QString::fromStdString(userInfo->name())))
        return Response::RespInIgnoreList;

    Event_UserMessage event;
    event.set_sender_name(userInfo->name());
    event.set_receiver_name(cmd.user_name());
    event.set_message(cmd.message());

    SessionEvent *se = prepareSessionEvent(event);
    userInterface->sendProtocolItem(*se);
    rc.enqueuePreResponseItem(ServerMessage::SESSION_EVENT, se);

    databaseInterface->logMessage(userInfo->id(), QString::fromStdString(userInfo->name()), QString::fromStdString(userInfo->address()), QString::fromStdString(cmd.message()), Server_DatabaseInterface::MessageTargetChat, userInterface->getUserInfo()->id(), receiver);

    return Response::RespOk;
}