diff --git a/cockatrice/src/localserver.h b/cockatrice/src/localserver.h index cf24b438..36838cc6 100644 --- a/cockatrice/src/localserver.h +++ b/cockatrice/src/localserver.h @@ -20,6 +20,8 @@ public: LocalServerInterface *newConnection(); protected: + int startSession(const QString & /*userName*/, const QString & /*address*/) { return -1; } + void endSession(int /*sessionId*/) { } bool userExists(const QString & /*name*/) { return false; } ServerInfo_User *getUserData(const QString &name); QMap getBuddyList(const QString & /*name*/) { return QMap(); } diff --git a/common/server.cpp b/common/server.cpp index d9e83a06..4a37dadc 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -82,6 +82,9 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString users.insert(name, session); qDebug() << "Server::loginUser: name=" << name; + session->setSessionId(startSession(name, session->getAddress())); + qDebug() << "session id:" << session->getSessionId(); + Event_UserJoined *event = new Event_UserJoined(new ServerInfo_User(data, false)); for (int i = 0; i < clients.size(); ++i) if (clients[i]->getAcceptsUserListChanges()) @@ -111,6 +114,10 @@ void Server::removeClient(Server_ProtocolHandler *client) users.remove(data->getName()); qDebug() << "Server::removeClient: name=" << data->getName(); + + if (client->getSessionId() != -1) + endSession(client->getSessionId()); + qDebug() << "closed session id:" << client->getSessionId(); } qDebug() << "Server::removeClient:" << clients.size() << "clients; " << users.size() << "users left"; } diff --git a/common/server.h b/common/server.h index de8dd2a5..467642f6 100644 --- a/common/server.h +++ b/common/server.h @@ -50,6 +50,8 @@ protected: QMap users; QMap rooms; + virtual int startSession(const QString &userName, const QString &address) = 0; + virtual void endSession(int sessionId) = 0; virtual bool userExists(const QString &user) = 0; virtual AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password) = 0; virtual ServerInfo_User *getUserData(const QString &name) = 0; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 7bd1e99f..bdb887c8 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -14,7 +14,7 @@ #include Server_ProtocolHandler::Server_ProtocolHandler(Server *_server, QObject *parent) - : QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive) + : QObject(parent), server(_server), authState(PasswordWrong), acceptsUserListChanges(false), acceptsRoomListChanges(false), userInfo(0), sessionId(-1), timeRunning(0), lastDataReceived(0), gameListMutex(QMutex::Recursive) { connect(server, SIGNAL(pingClockTimeout()), this, SLOT(pingClockTimeout())); } diff --git a/common/server_protocolhandler.h b/common/server_protocolhandler.h index c95f5094..05b07ce2 100644 --- a/common/server_protocolhandler.h +++ b/common/server_protocolhandler.h @@ -31,6 +31,7 @@ protected: void prepareDestroy(); virtual bool getCompressionSupport() const = 0; + int sessionId; private: QList itemQueue; QList messageSizeOverTime, messageCountOverTime; @@ -110,6 +111,8 @@ public: void setUserInfo(ServerInfo_User *_userInfo) { userInfo = _userInfo; } const QMap &getBuddyList() const { return buddyList; } const QMap &getIgnoreList() const { return ignoreList; } + int getSessionId() const { return sessionId; } + void setSessionId(int _sessionId) { sessionId = _sessionId; } int getLastCommandTime() const { return timeRunning - lastDataReceived; } void processCommandContainer(CommandContainer *cont); diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 4bbd6c84..b2362e6a 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -149,7 +149,7 @@ CREATE TABLE `cockatrice_buddylist` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8; CREATE TABLE `cockatrice_bans` ( - `user_name` varchar(255) unsigned zerofill NOT NULL, + `user_name` varchar(255) NOT NULL, `ip_address` varchar(255) NOT NULL, `id_admin` int(7) unsigned zerofill NOT NULL, `time_from` datetime NOT NULL, @@ -159,3 +159,12 @@ CREATE TABLE `cockatrice_bans` ( KEY `time_from` (`time_from`,`ip_address`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE `cockatrice_sessions` ( + `id` int(9) NOT NULL AUTO_INCREMENT, + `user_name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, + `ip_address` char(15) COLLATE utf8_unicode_ci NOT NULL, + `start_time` datetime NOT NULL, + `end_time` datetime DEFAULT NULL, + PRIMARY KEY (`id`), + KEY `username` (`user_name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; diff --git a/servatrice/src/servatrice.cpp b/servatrice/src/servatrice.cpp index 890aedc4..344d05e3 100644 --- a/servatrice/src/servatrice.cpp +++ b/servatrice/src/servatrice.cpp @@ -300,6 +300,31 @@ int Servatrice::getUsersWithAddress(const QHostAddress &address) const return result; } +int Servatrice::startSession(const QString &userName, const QString &address) +{ + QMutexLocker locker(&dbMutex); + checkSql(); + + QSqlQuery query; + query.prepare("insert into " + dbPrefix + "_sessions (user_name, ip_address, start_time) values(:user_name, :ip_address, NOW())"); + query.bindValue(":user_name", userName); + query.bindValue(":ip_address", address); + if (execSqlQuery(query)) + return query.lastInsertId().toInt(); + return -1; +} + +void Servatrice::endSession(int sessionId) +{ + QMutexLocker locker(&dbMutex); + checkSql(); + + QSqlQuery query; + query.prepare("update " + dbPrefix + "_sessions set end_time=NOW() where id = :id_session"); + query.bindValue(":id_session", sessionId); + execSqlQuery(query); +} + QMap Servatrice::getBuddyList(const QString &name) { QMutexLocker locker(&dbMutex); diff --git a/servatrice/src/servatrice.h b/servatrice/src/servatrice.h index 8b397d1b..53faa70a 100644 --- a/servatrice/src/servatrice.h +++ b/servatrice/src/servatrice.h @@ -76,6 +76,8 @@ public: QMap getIgnoreList(const QString &name); void scheduleShutdown(const QString &reason, int minutes); protected: + int startSession(const QString &userName, const QString &address); + void endSession(int sessionId); bool userExists(const QString &user); AuthenticationResult checkUserPassword(Server_ProtocolHandler *handler, const QString &user, const QString &password); private: