mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 09:05:10 -07:00
[Server/Client/Protocol] Address developer role review feedback
Address ZeizaZach's review of the developer staff role: - Nudge the developer log query to exclude private chat and sender IPs (the ModeratorCommand path still sees everything). - Deduplicate Command_GetLogHistory into Command_ViewLogHistory, which now extends both ModeratorCommand (ext) and DeveloperCommand (dev_ext); the client picks the DeveloperCommand-scoped extension by extendee, and the server reads it via the extension number. - Pull the uptime snapshot SQL into Servatrice_DatabaseInterface as getLatestUptimeSnapshot() and widen the reported counters to 64-bit. - Document the admin bitfield (1 admin, 2 moderator, 4 judge, 8 developer) and add a server-side test for the developer command path.
This commit is contained in:
parent
1ff7ffcaa4
commit
1dc20176b3
14 changed files with 251 additions and 76 deletions
|
|
@ -25,6 +25,9 @@ INSERT INTO cockatrice_schema_version VALUES(36);
|
|||
-- users and user data tables
|
||||
CREATE TABLE IF NOT EXISTS `cockatrice_users` (
|
||||
`id` int(7) unsigned zerofill NOT NULL auto_increment,
|
||||
-- Bitfield of staff levels: 1 = admin (implies moderator), 2 = moderator,
|
||||
-- 4 = judge, 8 = developer. Operators set these by hand with
|
||||
-- "UPDATE cockatrice_users SET admin = ...".
|
||||
`admin` tinyint(1) NOT NULL,
|
||||
`name` varchar(35) NOT NULL,
|
||||
`realname` varchar(255) NOT NULL,
|
||||
|
|
|
|||
|
|
@ -1487,6 +1487,38 @@ QList<ServerInfo_ModeratorLogin> Servatrice_DatabaseInterface::getModeratorLastL
|
|||
return results;
|
||||
}
|
||||
|
||||
Servatrice_DatabaseInterface::UptimeSnapshot Servatrice_DatabaseInterface::getLatestUptimeSnapshot(int serverId)
|
||||
{
|
||||
UptimeSnapshot snapshot;
|
||||
|
||||
if (!checkSql()) {
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
QSqlQuery *query = prepareQuery("SELECT users_count, mods_count, games_count, tx_bytes, rx_bytes, uptime, "
|
||||
"UNIX_TIMESTAMP(timest) FROM {prefix}_uptime "
|
||||
"WHERE id_server = :id_server ORDER BY timest DESC LIMIT 1");
|
||||
query->bindValue(":id_server", serverId);
|
||||
|
||||
if (!execSqlQuery(query)) {
|
||||
qCWarning(DatabaseInterfaceLog) << "Failed to collect server stats snapshot: SQL Error";
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
if (query->next()) {
|
||||
snapshot.valid = true;
|
||||
snapshot.usersCount = query->value(0).toULongLong();
|
||||
snapshot.modsCount = query->value(1).toULongLong();
|
||||
snapshot.gamesCount = query->value(2).toULongLong();
|
||||
snapshot.txBytes = query->value(3).toULongLong();
|
||||
snapshot.rxBytes = query->value(4).toULongLong();
|
||||
snapshot.uptimeSecs = query->value(5).toULongLong();
|
||||
snapshot.timest = query->value(6).toULongLong();
|
||||
}
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
bool Servatrice_DatabaseInterface::removeUserAvatar(const QString &userName)
|
||||
{
|
||||
if (!checkSql()) {
|
||||
|
|
|
|||
|
|
@ -140,6 +140,21 @@ public:
|
|||
QList<ServerInfo_UserSession> getUserSessions(const QString &userName, int limit);
|
||||
QList<ServerInfo_UserAlt> getUserAlts(const QString &userName);
|
||||
QList<ServerInfo_ModeratorLogin> getModeratorLastLogins();
|
||||
|
||||
// Uptime snapshot as recorded by Servatrice::statusUpdate() into the
|
||||
// {prefix}_uptime table. valid is false when no snapshot exists yet.
|
||||
struct UptimeSnapshot
|
||||
{
|
||||
bool valid = false;
|
||||
quint64 usersCount = 0;
|
||||
quint64 modsCount = 0;
|
||||
quint64 gamesCount = 0;
|
||||
quint64 txBytes = 0;
|
||||
quint64 rxBytes = 0;
|
||||
quint64 uptimeSecs = 0;
|
||||
quint64 timest = 0;
|
||||
};
|
||||
UptimeSnapshot getLatestUptimeSnapshot(int serverId);
|
||||
bool removeUserAvatar(const QString &userName);
|
||||
bool addForgotPassword(const QString &user);
|
||||
bool removeForgotPassword(const QString &user) override;
|
||||
|
|
|
|||
|
|
@ -287,7 +287,7 @@ Response::ResponseCode AbstractServerSocketInterface::processExtendedModeratorCo
|
|||
case ModeratorCommand::REPORT_RESOLVE:
|
||||
return cmdReportResolve(cmd.GetExtension(Command_ReportResolve::ext), rc);
|
||||
case ModeratorCommand::VIEWLOG_HISTORY:
|
||||
return cmdGetLogHistory(cmd.GetExtension(Command_ViewLogHistory::ext), rc);
|
||||
return cmdGetLogHistory(cmd.GetExtension(Command_ViewLogHistory::ext), rc, true);
|
||||
case ModeratorCommand::GRANT_REPLAY_ACCESS:
|
||||
return cmdGrantReplayAccess(cmd.GetExtension(Command_GrantReplayAccess::ext), rc);
|
||||
case ModeratorCommand::REPLAY_DOWNLOAD_BY_GAME_ID:
|
||||
|
|
@ -351,21 +351,9 @@ Response::ResponseCode AbstractServerSocketInterface::processExtendedDeveloperCo
|
|||
case DeveloperCommand::GET_SERVER_STATS:
|
||||
return cmdGetServerStats(cmd.GetExtension(Command_GetServerStats::ext), rc);
|
||||
case DeveloperCommand::VIEWLOG_HISTORY: {
|
||||
// Same query as the moderator log view, just carried by the
|
||||
// developer command family.
|
||||
const Command_GetLogHistory &devCmd = cmd.GetExtension(Command_GetLogHistory::ext);
|
||||
Command_ViewLogHistory modCmd;
|
||||
modCmd.set_user_name(devCmd.user_name());
|
||||
modCmd.set_ip_address(devCmd.ip_address());
|
||||
modCmd.set_game_name(devCmd.game_name());
|
||||
modCmd.set_game_id(devCmd.game_id());
|
||||
modCmd.set_message(devCmd.message());
|
||||
for (int i = 0; i < devCmd.log_location_size(); ++i) {
|
||||
modCmd.add_log_location(devCmd.log_location(i));
|
||||
}
|
||||
modCmd.set_date_range(devCmd.date_range());
|
||||
modCmd.set_maximum_results(devCmd.maximum_results());
|
||||
return cmdGetLogHistory(modCmd, rc);
|
||||
// Same query as the moderator log view, carried by the developer
|
||||
// command family, but narrows out private chats and sender IPs.
|
||||
return cmdGetLogHistory(cmd.GetExtension(Command_ViewLogHistory::dev_ext), rc, false);
|
||||
}
|
||||
default:
|
||||
return Response::RespFunctionNotAllowed;
|
||||
|
|
@ -1055,12 +1043,13 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReplaySubmitCode(const
|
|||
// MODERATOR FUNCTIONS.
|
||||
// May be called by admins and moderators. Permission is checked by the calling function.
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdGetLogHistory(const Command_ViewLogHistory &cmd,
|
||||
ResponseContainer &rc)
|
||||
ResponseContainer &rc,
|
||||
bool allowPrivateChat)
|
||||
{
|
||||
|
||||
QList<ServerInfo_ChatMessage> messageList;
|
||||
QString userName = nameFromStdString(cmd.user_name());
|
||||
QString ipAddress = nameFromStdString(cmd.ip_address());
|
||||
QString ipAddress = allowPrivateChat ? nameFromStdString(cmd.ip_address()) : QString();
|
||||
QString gameName = nameFromStdString(cmd.game_name());
|
||||
QString gameID = nameFromStdString(cmd.game_id());
|
||||
QString message = textFromStdString(cmd.message());
|
||||
|
|
@ -1075,7 +1064,7 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetLogHistory(const Com
|
|||
if (nameFromStdString(cmd.log_location(i)).simplified() == "game") {
|
||||
gameType = true;
|
||||
}
|
||||
if (nameFromStdString(cmd.log_location(i)).simplified() == "chat") {
|
||||
if (nameFromStdString(cmd.log_location(i)).simplified() == "chat" && allowPrivateChat) {
|
||||
chatType = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1089,7 +1078,11 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetLogHistory(const Com
|
|||
QListIterator<ServerInfo_ChatMessage> messageIterator(sqlInterface->getMessageLogHistory(
|
||||
userName, ipAddress, gameName, gameID, message, chatType, gameType, roomType, dateRange, maximumResults));
|
||||
while (messageIterator.hasNext()) {
|
||||
re->add_log_message()->CopyFrom(messageIterator.next());
|
||||
ServerInfo_ChatMessage chatMessage = messageIterator.next();
|
||||
if (!allowPrivateChat) {
|
||||
chatMessage.clear_sender_ip();
|
||||
}
|
||||
re->add_log_message()->CopyFrom(chatMessage);
|
||||
}
|
||||
} else {
|
||||
ServerInfo_ChatMessage chatMessage;
|
||||
|
|
@ -1687,24 +1680,20 @@ Response::ResponseCode AbstractServerSocketInterface::cmdGetServerStats(const Co
|
|||
|
||||
// Servatrice::statusUpdate() periodically snapshots server health into the
|
||||
// uptime table. Serve the freshest snapshot for this server.
|
||||
QSqlQuery *query = sqlInterface->prepareQuery(
|
||||
"SELECT users_count, mods_count, games_count, tx_bytes, rx_bytes, uptime, UNIX_TIMESTAMP(timest) "
|
||||
"FROM {prefix}_uptime WHERE id_server = :id_server ORDER BY timest DESC LIMIT 1");
|
||||
query->bindValue(":id_server", servatrice->getServerID());
|
||||
if (!sqlInterface->execSqlQuery(query)) {
|
||||
const auto snapshot = sqlInterface->getLatestUptimeSnapshot(servatrice->getServerID());
|
||||
if (!snapshot.valid) {
|
||||
// No snapshot yet (fresh server, or statusUpdate() has not ticked).
|
||||
return Response::RespInternalError;
|
||||
}
|
||||
|
||||
auto *re = new Response_GetServerStats;
|
||||
if (query->next()) {
|
||||
re->set_users_count(query->value(0).toUInt());
|
||||
re->set_mods_count(query->value(1).toUInt());
|
||||
re->set_games_count(query->value(2).toUInt());
|
||||
re->set_tx_bytes(query->value(3).toUInt());
|
||||
re->set_rx_bytes(query->value(4).toUInt());
|
||||
re->set_uptime_secs(query->value(5).toUInt());
|
||||
re->set_timest(query->value(6).toUInt());
|
||||
}
|
||||
re->set_users_count(snapshot.usersCount);
|
||||
re->set_mods_count(snapshot.modsCount);
|
||||
re->set_games_count(snapshot.gamesCount);
|
||||
re->set_tx_bytes(snapshot.txBytes);
|
||||
re->set_rx_bytes(snapshot.rxBytes);
|
||||
re->set_uptime_secs(snapshot.uptimeSecs);
|
||||
re->set_timest(snapshot.timest);
|
||||
|
||||
rc.setResponseExtension(re);
|
||||
return Response::RespOk;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ private:
|
|||
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
|
||||
cmdGetLogHistory(const Command_ViewLogHistory &cmd, ResponseContainer &rc, bool allowPrivateChat);
|
||||
Response::ResponseCode cmdGetBanHistory(const Command_GetBanHistory &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetWarnList(const Command_GetWarnList &cmd, ResponseContainer &rc);
|
||||
Response::ResponseCode cmdGetWarnHistory(const Command_GetWarnHistory &cmd, ResponseContainer &rc);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue