void Server::removeClient(Server_ProtocolHandler *client) { QWriteLocker locker(&clientsLock); clients.removeAt(clients.indexOf(client)); ServerInfo_User *data = client->getUserInfo(); if (data) { Event_UserLeft event; event.set_name(data->name()); SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); for (int i = 0; i < clients.size(); ++i) if (clients[i]->getAcceptsUserListChanges()) clients[i]->sendProtocolItem(*se); sendIsl_SessionEvent(*se); delete se; users.remove(QString::fromStdString(data->name())); qDebug() << "Server::removeClient: name=" << QString::fromStdString(data->name()); if (data->has_session_id()) { const qint64 sessionId = data->session_id(); usersBySessionId.remove(sessionId); emit endSession(sessionId); qDebug() << "closed session id:" << sessionId; } } qDebug() << "Server::removeClient: removed" << (void *) client << ";" << clients.size() << "clients; " << users.size() << "users left"; }
void Server::broadcastRoomUpdate(const ServerInfo_Room &roomInfo, bool sendToIsl) { // This function is always called from the main thread via signal/slot. Event_ListRooms event; event.add_room_list()->CopyFrom(roomInfo); SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); clientsLock.lockForRead(); for (int i = 0; i < clients.size(); ++i) if (clients[i]->getAcceptsRoomListChanges()) clients[i]->sendProtocolItem(*se); clientsLock.unlock(); if (sendToIsl) sendIsl_SessionEvent(*se); delete se; }
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft, QString &clientid, QString &clientVersion, QString & /* connectionType */) { if (name.size() > 35) name = name.left(35); Server_DatabaseInterface *databaseInterface = getDatabaseInterface(); AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, clientid, reasonStr, secondsLeft); if (authState == NotLoggedIn || authState == UserIsBanned || authState == UsernameInvalid || authState == UserIsInactive) return authState; ServerInfo_User data = databaseInterface->getUserData(name, true); data.set_address(session->getAddress().toStdString()); name = QString::fromStdString(data.name()); // Compensate for case indifference if (authState == PasswordRight) { if (users.contains(name) || databaseInterface->userSessionExists(name)) { if (users.contains(name)) { qDebug("Session already logged in, logging old session out"); Event_ConnectionClosed event; event.set_reason(Event_ConnectionClosed::LOGGEDINELSEWERE); event.set_reason_str("You have been logged out due to logging in at another location."); event.set_end_time(QDateTime::currentDateTime().toTime_t()); SessionEvent *se = users.value(name)->prepareSessionEvent(event); users.value(name)->sendProtocolItem(*se); delete se; users.value(name)->prepareDestroy(); } else { qDebug() << "Active session and sessions table inconsistent, please validate session table information for user " << name; } } } else if (authState == UnknownUser) { // Change user name so that no two users have the same names, // don't interfere with registered user names though. if (getRegOnlyServerEnabled()) { qDebug("Login denied: registration required"); databaseInterface->unlockSessionTables(); return RegistrationRequired; } QString tempName = name; int i = 0; while (users.contains(tempName) || databaseInterface->activeUserExists(tempName) || databaseInterface->userSessionExists(tempName)) tempName = name + "_" + QString::number(++i); name = tempName; data.set_name(name.toStdString()); } QWriteLocker locker(&clientsLock); databaseInterface->lockSessionTables(); users.insert(name, session); qDebug() << "Server::loginUser:"******"name=" << name; data.set_session_id(databaseInterface->startSession(name, session->getAddress(), clientid, session->getConnectionType())); databaseInterface->unlockSessionTables(); usersBySessionId.insert(data.session_id(), session); qDebug() << "session id:" << data.session_id(); session->setUserInfo(data); Event_UserJoined event; event.mutable_user_info()->CopyFrom(session->copyUserInfo(false)); SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); for (int i = 0; i < clients.size(); ++i) if (clients[i]->getAcceptsUserListChanges()) clients[i]->sendProtocolItem(*se); delete se; event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); locker.unlock(); if (clientid.isEmpty()){ // client id is empty, either out dated client or client has been modified if (getClientIDRequiredEnabled()) return ClientIdRequired; } else { // update users database table with client id databaseInterface->updateUsersClientID(name, clientid); } databaseInterface->updateUsersLastLoginData(name, clientVersion); se = Server_ProtocolHandler::prepareSessionEvent(event); sendIsl_SessionEvent(*se); delete se; return authState; }
AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft) { if (name.size() > 35) name = name.left(35); Server_DatabaseInterface *databaseInterface = getDatabaseInterface(); QWriteLocker locker(&clientsLock); AuthenticationResult authState = databaseInterface->checkUserPassword(session, name, password, reasonStr, secondsLeft); if ((authState == NotLoggedIn) || (authState == UserIsBanned || authState == UsernameInvalid)) return authState; ServerInfo_User data = databaseInterface->getUserData(name, true); data.set_address(session->getAddress().toStdString()); name = QString::fromStdString(data.name()); // Compensate for case indifference databaseInterface->lockSessionTables(); if (authState == PasswordRight) { if (users.contains(name) || databaseInterface->userSessionExists(name)) { qDebug("Login denied: would overwrite old session"); databaseInterface->unlockSessionTables(); return WouldOverwriteOldSession; } } else if (authState == UnknownUser) { // Change user name so that no two users have the same names, // don't interfere with registered user names though. QSettings settings("servatrice.ini", QSettings::IniFormat); bool requireReg = settings.value("authentication/regonly", 0).toBool(); if (requireReg) { qDebug("Login denied: registration required"); databaseInterface->unlockSessionTables(); return RegistrationRequired; } QString tempName = name; int i = 0; while (users.contains(tempName) || databaseInterface->userExists(tempName) || databaseInterface->userSessionExists(tempName)) tempName = name + "_" + QString::number(++i); name = tempName; data.set_name(name.toStdString()); } users.insert(name, session); qDebug() << "Server::loginUser:"******"name=" << name; data.set_session_id(databaseInterface->startSession(name, session->getAddress())); databaseInterface->unlockSessionTables(); usersBySessionId.insert(data.session_id(), session); qDebug() << "session id:" << data.session_id(); session->setUserInfo(data); Event_UserJoined event; event.mutable_user_info()->CopyFrom(session->copyUserInfo(false)); SessionEvent *se = Server_ProtocolHandler::prepareSessionEvent(event); for (int i = 0; i < clients.size(); ++i) if (clients[i]->getAcceptsUserListChanges()) clients[i]->sendProtocolItem(*se); delete se; event.mutable_user_info()->CopyFrom(session->copyUserInfo(true, true, true)); locker.unlock(); se = Server_ProtocolHandler::prepareSessionEvent(event); sendIsl_SessionEvent(*se); delete se; return authState; }