diff --git a/common/server.cpp b/common/server.cpp index ff49a6dc..4b65739b 100644 --- a/common/server.cpp +++ b/common/server.cpp @@ -345,6 +345,8 @@ void Server::externalRoomSay(int roomId, const QString &userName, const QString return; } room->say(userName, message, false); + + getDatabaseInterface()->logMessage(0, userName, "ISL", message, Server_DatabaseInterface::MessageTargetIslRoom, room->getId(), room->getName()); } void Server::externalRoomGameListChanged(int roomId, const ServerInfo_Game &gameInfo) diff --git a/common/server_database_interface.h b/common/server_database_interface.h index a08e9526..f3ffed6d 100644 --- a/common/server_database_interface.h +++ b/common/server_database_interface.h @@ -35,6 +35,9 @@ public: virtual bool userSessionExists(const QString & /* userName */) { return false; } virtual bool getRequireRegistration() { return false; } + + 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) { }; }; #endif diff --git a/common/server_game.cpp b/common/server_game.cpp index 647aa22e..58725742 100644 --- a/common/server_game.cpp +++ b/common/server_game.cpp @@ -436,7 +436,7 @@ void Server_Game::addPlayer(Server_AbstractUserInterface *userInterface, Respons { QMutexLocker locker(&gameMutex); - Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true), spectator, userInterface); + Server_Player *newPlayer = new Server_Player(this, nextPlayerId++, userInterface->copyUserInfo(true, true, true), spectator, userInterface); newPlayer->moveToThread(thread()); Event_Join joinEvent; diff --git a/common/server_player.cpp b/common/server_player.cpp index b9277a2d..f6d7ffce 100644 --- a/common/server_player.cpp +++ b/common/server_player.cpp @@ -767,6 +767,8 @@ Response::ResponseCode Server_Player::cmdGameSay(const Command_GameSay &cmd, Res Event_GameSay event; event.set_message(cmd.message()); ges.enqueueGameEvent(event, playerId); + + game->getRoom()->getServer()->getDatabaseInterface()->logMessage(userInfo->id(), QString::fromStdString(userInfo->name()), QString::fromStdString(userInfo->address()), QString::fromStdString(cmd.message()), Server_DatabaseInterface::MessageTargetGame, game->getGameId(), game->getDescription()); return Response::RespOk; } diff --git a/common/server_protocolhandler.cpp b/common/server_protocolhandler.cpp index 2ca3902a..07f3fd0f 100644 --- a/common/server_protocolhandler.cpp +++ b/common/server_protocolhandler.cpp @@ -395,7 +395,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdMessage(const Command_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; } @@ -543,6 +545,9 @@ Response::ResponseCode Server_ProtocolHandler::cmdRoomSay(const Command_RoomSay msg.replace(QChar('\n'), QChar(' ')); room->say(QString::fromStdString(userInfo->name()), msg); + + databaseInterface->logMessage(userInfo->id(), QString::fromStdString(userInfo->name()), QString::fromStdString(userInfo->address()), msg, Server_DatabaseInterface::MessageTargetRoom, room->getId(), room->getName()); + return Response::RespOk; } diff --git a/servatrice/servatrice.ini.example b/servatrice/servatrice.ini.example index b3e431a1..c4454745 100644 --- a/servatrice/servatrice.ini.example +++ b/servatrice/servatrice.ini.example @@ -79,7 +79,7 @@ password=foobar [rooms] -; A servtrice server can expose to the users different "rooms" to chat and create games. Rooms can be defined +; A servatrice server can expose to the users different "rooms" to chat and create games. Rooms can be defined ; with two different methods: ; config: rooms are defined in this configuration (see the following example) ; sql: rooms are defined in the "rooms" table of the database @@ -144,6 +144,24 @@ max_message_count_per_interval=10 max_games_per_user=5 +[logging] + +; Servatrice can log user messages to the database table cockatrice_log. +; These messages can come from different sources; each source can be enabled separately. + +; Log user messages inside chat rooms +log_user_msg_room=false + +; Log user messages inside games +log_user_msg_game=false + +; Log user messages in private chats +log_user_msg_chat=false + +; Log user messages coming from other servers in the network +log_user_msg_isl=false + + ; EXPERIMENTAL - NOT WORKING YET ; The following settings are relative to the server network functionality, that is not yet complete. ; Avoid enabling it unless you are willing to test it and help its development. diff --git a/servatrice/servatrice.sql b/servatrice/servatrice.sql index 22ba4cf5..9d733176 100644 --- a/servatrice/servatrice.sql +++ b/servatrice/servatrice.sql @@ -223,3 +223,18 @@ CREATE TABLE IF NOT EXISTS `cockatrice_rooms_gametypes` ( PRIMARY KEY (`name`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE IF NOT EXISTS `cockatrice_log` ( + `log_time` datetime NOT NULL, + `sender_id` int(7) unsigned NULL, + `sender_name` varchar(35) NOT NULL, + `sender_ip` varchar(255) NOT NULL, + `log_message` text NOT NULL, + `target_type` ENUM('room', 'game', 'chat'), + `target_id` int(7) NULL, + `target_name` varchar(50) NOT NULL, + KEY `sender_name` (`sender_name`), + KEY `sender_ip` (`sender_ip`), + KEY `target_type` (`target_type`), + KEY `target_id` (`target_id`), + KEY `target_name` (`target_name`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; diff --git a/servatrice/src/servatrice_database_interface.cpp b/servatrice/src/servatrice_database_interface.cpp index a8c27e09..156c600c 100644 --- a/servatrice/src/servatrice_database_interface.cpp +++ b/servatrice/src/servatrice_database_interface.cpp @@ -538,3 +538,44 @@ DeckList *Servatrice_DatabaseInterface::getDeckFromDatabase(int deckId, int user return deck; } + +void Servatrice_DatabaseInterface::logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName) +{ + QSqlQuery query(sqlDatabase); + QString targetTypeString; + switch(targetType) + { + case MessageTargetRoom: + if(!settingsCache->value("logging/log_user_msg_room", 0).toBool()) + return; + targetTypeString = "room"; + break; + case MessageTargetGame: + if(!settingsCache->value("logging/log_user_msg_game", 0).toBool()) + return; + targetTypeString = "game"; + break; + case MessageTargetChat: + if(!settingsCache->value("logging/log_user_msg_chat", 0).toBool()) + return; + targetTypeString = "chat"; + break; + case MessageTargetIslRoom: + if(!settingsCache->value("logging/log_user_msg_isl", 0).toBool()) + return; + targetTypeString = "room"; + break; + default: + return; + } + + query.prepare("insert into " + server->getDbPrefix() + "_log (log_time, sender_id, sender_name, sender_ip, log_message, target_type, target_id, target_name) values (now(), :sender_id, :sender_name, :sender_ip, :log_message, :target_type, :target_id, :target_name)"); + query.bindValue(":sender_id", senderId < 1 ? QVariant() : senderId); + query.bindValue(":sender_name", senderName); + query.bindValue(":sender_ip", senderIp); + query.bindValue(":log_message", logMessage); + query.bindValue(":target_type", targetTypeString); + query.bindValue(":target_id", (targetType == MessageTargetChat && targetId < 1) ? QVariant() : targetId); + query.bindValue(":target_name", targetName); + execSqlQuery(query); +} diff --git a/servatrice/src/servatrice_database_interface.h b/servatrice/src/servatrice_database_interface.h index 8e8ab5c6..9488ded8 100644 --- a/servatrice/src/servatrice_database_interface.h +++ b/servatrice/src/servatrice_database_interface.h @@ -52,6 +52,8 @@ public: bool userSessionExists(const QString &userName); bool getRequireRegistration(); + + void logMessage(const int senderId, const QString &senderName, const QString &senderIp, const QString &logMessage, LogMessage_TargetType targetType, const int targetId, const QString &targetName); }; #endif