mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-29 09:22:18 -07:00
[Server/Client/Protocol] Reporting users + moderation queue functionality
Took 6 minutes Took 3 minutes Took 8 seconds Took 11 minutes Took 12 minutes Took 7 minutes Took 15 seconds Took 2 minutes Took 1 minute Took 30 seconds Took 16 seconds
This commit is contained in:
parent
9eafd90a91
commit
b8a70c48a4
58 changed files with 3364 additions and 17 deletions
47
servatrice/migrations/servatrice_0035_to_0036.sql
Normal file
47
servatrice/migrations/servatrice_0035_to_0036.sql
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
-- Servatrice db migration from version 35 to version 36
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_reports` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`reporter_id` int(7) unsigned NULL,
|
||||
`reporter_name` varchar(35) NOT NULL,
|
||||
`reported_user_id` int(7) unsigned NULL,
|
||||
`reported_user_name` varchar(35) NOT NULL,
|
||||
`game_id` int(7) unsigned NULL,
|
||||
`room_id` int(7) unsigned NULL,
|
||||
`category` varchar(255) NOT NULL,
|
||||
`description` text NOT NULL,
|
||||
`chat_log` mediumtext NULL,
|
||||
`created_at` datetime NOT NULL,
|
||||
`resolution_time` datetime NULL,
|
||||
`status` enum('open','assigned','resolved','dismissed') NOT NULL DEFAULT 'open',
|
||||
`assigned_to` int(7) unsigned NULL,
|
||||
`resolution_note` text,
|
||||
`notified` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_created` (`created_at`),
|
||||
INDEX `idx_reporter_id_created` (`reporter_id`, `created_at`),
|
||||
INDEX `idx_reported_user_name` (`reported_user_name`),
|
||||
INDEX `idx_status_created` (`status`, `created_at`),
|
||||
FOREIGN KEY (`reporter_id`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`reported_user_id`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`assigned_to`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_report_comments` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`report_id` int(11) unsigned NOT NULL,
|
||||
`author_name` varchar(35) NOT NULL,
|
||||
`author_id` int(7) unsigned NULL,
|
||||
`comment_text` text NOT NULL,
|
||||
`created_at` datetime NOT NULL,
|
||||
`is_moderator` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`notified` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_report_id` (`report_id`),
|
||||
INDEX `idx_notified` (`notified`),
|
||||
FOREIGN KEY (`report_id`) REFERENCES `cockatrice_reports`(`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`author_id`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
UPDATE cockatrice_schema_version SET version=36 WHERE version=35;
|
||||
|
|
@ -373,6 +373,13 @@ command_counting_interval=10
|
|||
; Maximum number of game commands in an interval before new commands gets dropped; default is 20
|
||||
max_command_count_per_interval=20
|
||||
|
||||
[reporting]
|
||||
; Maximum number of user reports a single user can file per day; default is 10; set to 0 to disable the limit
|
||||
max_reports_per_day=10
|
||||
|
||||
; Maximum number of report comments a single user can post per hour; default is 30; set to 0 to disable the limit
|
||||
max_comments_per_hour=30
|
||||
|
||||
[logging]
|
||||
; Admin/Moderators can query the stored logs for information when looking up reports by various players. This
|
||||
; option can allow or disallow them from doing so.
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ CREATE TABLE IF NOT EXISTS `cockatrice_schema_version` (
|
|||
PRIMARY KEY (`version`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
INSERT INTO cockatrice_schema_version VALUES(35);
|
||||
INSERT INTO cockatrice_schema_version VALUES(36);
|
||||
|
||||
-- users and user data tables
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_users` (
|
||||
|
|
@ -233,6 +233,50 @@ CREATE TABLE IF NOT EXISTS `cockatrice_warnings` (
|
|||
INDEX `idx_user_name` (`user_name`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_reports` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`reporter_id` int(7) unsigned NULL,
|
||||
`reporter_name` varchar(35) NOT NULL,
|
||||
`reported_user_id` int(7) unsigned NULL,
|
||||
`reported_user_name` varchar(35) NOT NULL,
|
||||
`game_id` int(7) unsigned NULL,
|
||||
`room_id` int(7) unsigned NULL,
|
||||
`category` varchar(255) NOT NULL,
|
||||
`description` text NOT NULL,
|
||||
`chat_log` mediumtext NULL,
|
||||
`created_at` datetime NOT NULL,
|
||||
`resolution_time` datetime NULL,
|
||||
`status` enum('open','assigned','resolved','dismissed') NOT NULL DEFAULT 'open',
|
||||
`assigned_to` int(7) unsigned NULL,
|
||||
`resolution_note` text,
|
||||
`notified` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_created` (`created_at`),
|
||||
INDEX `idx_reporter_id_created` (`reporter_id`, `created_at`),
|
||||
INDEX `idx_reported_user_name` (`reported_user_name`),
|
||||
INDEX `idx_status_created` (`status`, `created_at`),
|
||||
FOREIGN KEY (`reporter_id`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`reported_user_id`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`assigned_to`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_report_comments` (
|
||||
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
||||
`report_id` int(11) unsigned NOT NULL,
|
||||
`author_name` varchar(35) NOT NULL,
|
||||
`author_id` int(7) unsigned NULL,
|
||||
`comment_text` text NOT NULL,
|
||||
`created_at` datetime NOT NULL,
|
||||
`is_moderator` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`notified` tinyint(1) NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (`id`),
|
||||
INDEX `idx_report_id` (`report_id`),
|
||||
INDEX `idx_notified` (`notified`),
|
||||
FOREIGN KEY (`report_id`) REFERENCES `cockatrice_reports`(`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
FOREIGN KEY (`author_id`) REFERENCES `cockatrice_users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 DEFAULT COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_log` (
|
||||
`log_time` datetime NOT NULL,
|
||||
`sender_id` int(7) unsigned NULL,
|
||||
|
|
|
|||
|
|
@ -514,6 +514,23 @@ QList<ServerProperties> Servatrice::getServerList() const
|
|||
return result;
|
||||
}
|
||||
|
||||
std::shared_ptr<const Response_ReportStats> Servatrice::getCachedReportStats() const
|
||||
{
|
||||
QMutexLocker locker(&reportStatsMutex);
|
||||
if (!reportStatsTimestamp.isValid() ||
|
||||
reportStatsTimestamp.secsTo(QDateTime::currentDateTime()) >= reportStatsCacheTtlSeconds) {
|
||||
return nullptr;
|
||||
}
|
||||
return reportStatsCache;
|
||||
}
|
||||
|
||||
void Servatrice::cacheReportStats(const Response_ReportStats &stats)
|
||||
{
|
||||
QMutexLocker locker(&reportStatsMutex);
|
||||
reportStatsCache = std::make_shared<const Response_ReportStats>(stats);
|
||||
reportStatsTimestamp = QDateTime::currentDateTime();
|
||||
}
|
||||
|
||||
int Servatrice::getUsersWithAddress(const QHostAddress &address) const
|
||||
{
|
||||
int result = 0;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#ifndef SERVATRICE_H
|
||||
#define SERVATRICE_H
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QHostAddress>
|
||||
#include <QMetaType>
|
||||
#include <QMutex>
|
||||
|
|
@ -29,6 +30,8 @@
|
|||
#include <QSslKey>
|
||||
#include <QTcpServer>
|
||||
#include <QWebSocketServer>
|
||||
#include <libcockatrice/protocol/pb/response_report_stats.pb.h>
|
||||
#include <memory>
|
||||
#include <server.h>
|
||||
#include <utility>
|
||||
|
||||
|
|
@ -173,6 +176,11 @@ private:
|
|||
int nextShutdownMessageMinutes;
|
||||
QTimer *shutdownTimer;
|
||||
|
||||
mutable QMutex reportStatsMutex;
|
||||
QDateTime reportStatsTimestamp;
|
||||
std::shared_ptr<const Response_ReportStats> reportStatsCache;
|
||||
static constexpr int reportStatsCacheTtlSeconds = 60;
|
||||
|
||||
mutable QMutex serverListMutex;
|
||||
QList<ServerProperties> serverList;
|
||||
void updateServerList();
|
||||
|
|
@ -283,6 +291,11 @@ public:
|
|||
void removeIslInterface(int _serverId);
|
||||
QReadWriteLock islLock;
|
||||
|
||||
// The moderation queue statistics are shared between all connected moderators and
|
||||
// cached briefly to avoid re-running several full-table queries on every refresh.
|
||||
std::shared_ptr<const Response_ReportStats> getCachedReportStats() const;
|
||||
void cacheReportStats(const Response_ReportStats &stats);
|
||||
|
||||
QList<ServerProperties> getServerList() const;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
#include <server.h>
|
||||
#include <server_database_interface.h>
|
||||
|
||||
#define DATABASE_SCHEMA_VERSION 35
|
||||
#define DATABASE_SCHEMA_VERSION 36
|
||||
|
||||
class Servatrice;
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -24,6 +24,16 @@
|
|||
#include <QMutex>
|
||||
#include <QTcpSocket>
|
||||
#include <QWebSocket>
|
||||
#include <libcockatrice/protocol/pb/command_replay_download_by_game_id.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_add_comment.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_assign.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_details.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_my_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_resolve.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_stats.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_report_user_info.pb.h>
|
||||
#include <server_protocolhandler.h>
|
||||
|
||||
class Servatrice;
|
||||
|
|
@ -50,6 +60,7 @@ class Command_BanFromServer;
|
|||
class Command_UpdateServerMessage;
|
||||
class Command_ShutdownServer;
|
||||
class Command_ReloadConfig;
|
||||
class Command_ReplayDownloadByGameId;
|
||||
|
||||
class Command_AccountEdit;
|
||||
class Command_AccountImage;
|
||||
|
|
@ -102,6 +113,7 @@ private:
|
|||
Response::ResponseCode cmdReplayGetCode(const Command_ReplayGetCode &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplaySubmitCode(const Command_ReplaySubmitCode &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdBanFromServer(const Command_BanFromServer &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReportList(const Command_ReportList &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdWarnUser(const Command_WarnUser &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetLogHistory(const Command_ViewLogHistory &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetBanHistory(const Command_GetBanHistory &cmd, ResponseContainer &rc);
|
||||
|
|
@ -109,6 +121,10 @@ private:
|
|||
Response::ResponseCode cmdGetWarnHistory(const Command_GetWarnHistory &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdShutdownServer(const Command_ShutdownServer &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdUpdateServerMessage(const Command_UpdateServerMessage &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReportAssign(const Command_ReportAssign &cmd, ResponseContainer &);
|
||||
Response::ResponseCode cmdReportResolve(const Command_ReportResolve &cmd, ResponseContainer &);
|
||||
Response::ResponseCode cmdReportUserInfo(const Command_ReportUserInfo &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReportStats(const Command_ReportStats &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdRegisterAccount(const Command_Register &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdActivateAccount(const Command_Activate &cmd, ResponseContainer & /* rc */);
|
||||
Response::ResponseCode cmdReloadConfig(const Command_ReloadConfig & /* cmd */, ResponseContainer & /*rc*/);
|
||||
|
|
@ -122,6 +138,13 @@ private:
|
|||
Response::ResponseCode cmdForgotPasswordChallenge(const Command_ForgotPasswordChallenge &cmd,
|
||||
ResponseContainer &rc);
|
||||
Response::ResponseCode cmdRequestPasswordSalt(const Command_RequestPasswordSalt &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReport(const Command_Report &cmd, ResponseContainer &);
|
||||
Response::ResponseCode cmdReportMyList(const Command_ReportMyList &cmd, ResponseContainer &rc);
|
||||
void sendPendingReportNotifications(ResponseContainer &rc);
|
||||
void onLogin(ResponseContainer &rc) override;
|
||||
Response::ResponseCode cmdReportDetails(const Command_ReportDetails &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReportAddComment(const Command_ReportAddComment &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdReplayDownloadByGameId(const Command_ReplayDownloadByGameId &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode processExtendedSessionCommand(int cmdType, const SessionCommand &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode
|
||||
processExtendedModeratorCommand(int cmdType, const ModeratorCommand &cmd, ResponseContainer &rc);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue