diff --git a/common/server.cpp b/common/server.cpp index e0a015ec..873944b0 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -105,7 +105,7 @@ Server_DatabaseInterface *Server::getDatabaseInterface() const return databaseInterfaces.value(QThread::currentThread()); } -AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft, QString &clientid) +AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reasonStr, int &secondsLeft, QString &clientid, QString &clientVersion) { if (name.size() > 35) name = name.left(35); @@ -190,7 +190,7 @@ AuthenticationResult Server::loginUser(Server_ProtocolHandler *session, QString databaseInterface->updateUsersClientID(name, clientid); } - databaseInterface->updateUsersLastLoginTime(name); + databaseInterface->updateUsersLastLoginData(name, clientVersion); se = Server_ProtocolHandler::prepareSessionEvent(event); sendIsl_SessionEvent(*se); delete se; diff --git a/common/server.h b/common/server.h index e4b635e0..f1228b94 100644 --- a/common/server.h +++ b/common/server.h @@ -44,7 +44,7 @@ public: Server(bool _threaded, QObject *parent = 0); ~Server(); void setThreaded(bool _threaded) { threaded = _threaded; } - AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft, QString &clientid); + AuthenticationResult loginUser(Server_ProtocolHandler *session, QString &name, const QString &password, QString &reason, int &secondsLeft, QString &clientid, QString &clientVersion); const QMap &getRooms() { return rooms; } diff --git a/common/server_database_interface.h b/common/server_database_interface.h index f6ab7945..2923b311 100644 --- a/common/server_database_interface.h +++ b/common/server_database_interface.h @@ -40,7 +40,7 @@ public: virtual bool registerUser(const QString & /* userName */, const QString & /* realName */, ServerInfo_User_Gender const & /* gender */, const QString & /* password */, const QString & /* emailAddress */, const QString & /* country */, bool /* active = false */) { return false; } virtual bool activateUser(const QString & /* userName */, const QString & /* token */) { return false; } virtual void updateUsersClientID(const QString & /* userName */, const QString & /* userClientID */) { } - virtual void updateUsersLastLoginTime(const QString & /* userName */) { } + virtual void updateUsersLastLoginData(const QString & /* userName */, const QString & /* clientVersion */) { } enum LogMessage_TargetType { MessageTargetRoom, MessageTargetGame, MessageTargetChat, MessageTargetIslRoom }; virtual void logMessage(const int /* senderId */, const QString & /* senderName */, const QString & /* senderIp */, const QString & /* logMessage */, LogMessage_TargetType /* targetType */, const int /* targetId */, const QString & /* targetName */) { }; diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 775b204f..cb8515f3 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -384,6 +384,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd { QString userName = QString::fromStdString(cmd.user_name()).simplified(); QString clientId = QString::fromStdString(cmd.clientid()).simplified(); + QString clientVersion = QString::fromStdString(cmd.clientver()).simplified(); if (userName.isEmpty() || (userInfo != 0)) return Response::RespContextError; @@ -412,7 +413,7 @@ Response::ResponseCode Server_ProtocolHandler::cmdLogin(const Command_Login &cmd QString reasonStr; int banSecondsLeft = 0; - AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft, clientId); + AuthenticationResult res = server->loginUser(this, userName, QString::fromStdString(cmd.password()), reasonStr, banSecondsLeft, clientId, clientVersion); switch (res) { case UserIsBanned: { Response_Login *re = new Response_Login; diff --git a/servatrice/migrations/servatrice_0007_to_0008.sql b/servatrice/migrations/servatrice_0007_to_0008.sql new file mode 100644 index 00000000..0b2c1566 --- /dev/null +++ b/servatrice/migrations/servatrice_0007_to_0008.sql @@ -0,0 +1,16 @@ +-- Servatrice db migration from version 7 to version 8 + +CREATE TABLE IF NOT EXISTS `cockatrice_user_analytics` ( + `id` int(7) unsigned zerofill NOT NULL, + `client_ver` varchar(35) NOT NULL, + `last_login` datetime NOT NULL, + `notes` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +INSERT INTO `cockatrice_user_analytics` (id, last_login) SELECT id, last_login FROM `cockatrice_users` WHERE last_login != ''; + +ALTER TABLE `cockatrice_users` + DROP COLUMN last_login; + +UPDATE cockatrice_schema_version SET version=8 WHERE version=7; diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 9a6173a5..2c4d0b67 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_schema_version` ( PRIMARY KEY (`version`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; -INSERT INTO cockatrice_schema_version VALUES(7); +INSERT INTO cockatrice_schema_version VALUES(8); CREATE TABLE IF NOT EXISTS `cockatrice_decklist_files` ( `id` int(7) unsigned zerofill NOT NULL auto_increment, @@ -84,7 +84,6 @@ CREATE TABLE IF NOT EXISTS `cockatrice_users` ( `active` tinyint(1) NOT NULL, `token` binary(16) NOT NULL, `clientid` varchar(15) NOT NULL, - `last_login` datetime NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `name` (`name`), KEY `token` (`token`), @@ -214,3 +213,11 @@ CREATE TABLE IF NOT EXISTS `cockatrice_log` ( CREATE TABLE IF NOT EXISTS `cockatrice_activation_emails` ( `name` varchar(35) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +CREATE TABLE IF NOT EXISTS `cockatrice_user_analytics` ( + `id` int(7) unsigned zerofill NOT NULL, + `client_ver` varchar(35) NOT NULL, + `last_login` datetime NOT NULL, + `notes` varchar(255) NOT NULL, + PRIMARY KEY (`id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index ae8279fa..f10e841f 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -881,13 +881,45 @@ void Servatrice_DatabaseInterface::updateUsersClientID(const QString &userName, } -void Servatrice_DatabaseInterface::updateUsersLastLoginTime(const QString &userName) -{ +void Servatrice_DatabaseInterface::updateUsersLastLoginData(const QString &userName, const QString &clientVersion) { + if (!checkSql()) return; - QSqlQuery *query = prepareQuery("update {prefix}_users set last_login = NOW() where name = :user_name"); - query->bindValue(":user_name", userName); - execSqlQuery(query); + int usersID; + QSqlQuery *query = prepareQuery("select id from {prefix}_users where name = :user_name"); + query->bindValue(":user_name", userName); + if (!execSqlQuery(query)) { + qDebug("Failed to locate user id when updating users last login data: SQL Error"); + return; + } + + if (query->next()) { + usersID = query->value(0).toInt(); + } + + if (usersID) { + int userCount; + query = prepareQuery("select count(id) from {prefix}_user_analytics where id = :user_id"); + query->bindValue(":user_id", usersID); + if (!execSqlQuery(query)) + return; + + if (query->next()) { + userCount = query->value(0).toInt(); + } + + if (!userCount) { + query = prepareQuery("insert into {prefix}_user_analytics (id,client_ver,last_login) values (:user_id,:client_ver,NOW())"); + query->bindValue(":user_id", usersID); + query->bindValue(":client_ver", clientVersion); + execSqlQuery(query); + } else { + query = prepareQuery("update {prefix}_user_analytics set last_login = NOW(), client_ver = :client_ver where id = :user_id"); + query->bindValue(":client_ver", clientVersion); + query->bindValue(":user_id", usersID); + execSqlQuery(query); + } + } } diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index 0ca48440..99630c4e 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -9,7 +9,7 @@ #include "server.h" #include "server_database_interface.h" -#define DATABASE_SCHEMA_VERSION 7 +#define DATABASE_SCHEMA_VERSION 8 class Servatrice; @@ -73,7 +73,7 @@ public: const QString &password, const QString &emailAddress, const QString &country, QString &token, bool active = false); bool activateUser(const QString &userName, const QString &token); void updateUsersClientID(const QString &userName, const QString &userClientID); - void updateUsersLastLoginTime(const QString &userName); + void updateUsersLastLoginData(const QString &userName, const QString &clientVersion); void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName); bool changeUserPassword(const QString &user, const QString &oldPassword, const QString &newPassword);