mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-09-21 17:15:09 -07:00
[Server/Client/Protocol] Add developer staff role
Introduce a Developer staff level (proto flag 32, DB admin bit 8) that sits between admin and moderator: no kick/ban/warn/report/admin powers, but gets server log access via a new developer command container family (GET_SERVER_STATS, VIEWLOG_HISTORY) and an idle-timeout exemption. - Protocol: IsDeveloper flag, developer_commands.proto envelope, Command_GetServerStats/Command_GetLogHistory, Response_GetServerStats, Command_AdjustMod.should_be_developer - Servatrice: fail-closed developer dispatcher, uptime snapshot handler, shared log history handler reuse, bit-8 DB mapping - Client: burgundy pawn/badge/labels/sort order, prepareDeveloperCommand, minimal Developer stats tab, log tab access, promote/demote actions Took 24 minutes Took 18 seconds
This commit is contained in:
parent
7d867b9745
commit
1ff7ffcaa4
31 changed files with 515 additions and 23 deletions
|
|
@ -47,6 +47,8 @@
|
|||
#include <libcockatrice/protocol/pb/command_deck_list.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_new_dir.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_deck_upload.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_get_log_history.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_get_server_stats.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_replay_delete_match.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_replay_download.pb.h>
|
||||
#include <libcockatrice/protocol/pb/command_replay_download_by_game_id.pb.h>
|
||||
|
|
@ -80,6 +82,7 @@
|
|||
#include <libcockatrice/protocol/pb/response_deck_upload.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_forgotpasswordrequest.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_admin_notes.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_get_server_stats.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_moderator_last_logins.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_password_salt.pb.h>
|
||||
#include <libcockatrice/protocol/pb/response_register.pb.h>
|
||||
|
|
@ -337,6 +340,38 @@ AbstractServerSocketInterface::processExtendedAdminCommand(int cmdType, const Ad
|
|||
}
|
||||
}
|
||||
|
||||
// DEVELOPER FUNCTIONS.
|
||||
// Permission is checked by processDeveloperCommandContainer. Only stats-style
|
||||
// queries live here, never community moderation or server administration.
|
||||
Response::ResponseCode AbstractServerSocketInterface::processExtendedDeveloperCommand(int cmdType,
|
||||
const DeveloperCommand &cmd,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
switch ((DeveloperCommand::DeveloperCommandType)cmdType) {
|
||||
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);
|
||||
}
|
||||
default:
|
||||
return Response::RespFunctionNotAllowed;
|
||||
}
|
||||
}
|
||||
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdAddToList(const Command_AddToList &cmd, ResponseContainer &rc)
|
||||
{
|
||||
if (authState != PasswordRight) {
|
||||
|
|
@ -1643,6 +1678,38 @@ Response::ResponseCode AbstractServerSocketInterface::cmdReportUserInfo(const Co
|
|||
return Response::RespOk;
|
||||
}
|
||||
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdGetServerStats(const Command_GetServerStats & /*cmd */,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
if (!sqlInterface->checkSql()) {
|
||||
return Response::RespInternalError;
|
||||
}
|
||||
|
||||
// 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)) {
|
||||
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());
|
||||
}
|
||||
|
||||
rc.setResponseExtension(re);
|
||||
return Response::RespOk;
|
||||
}
|
||||
|
||||
Response::ResponseCode AbstractServerSocketInterface::cmdReportStats(const Command_ReportStats & /*cmd */,
|
||||
ResponseContainer &rc)
|
||||
{
|
||||
|
|
@ -3215,7 +3282,7 @@ bool AbstractServerSocketInterface::removeAdminFlagFromUser(const QString &userN
|
|||
if (user) {
|
||||
Event_ConnectionClosed event;
|
||||
event.set_reason(Event_ConnectionClosed::DEMOTED);
|
||||
event.set_reason_str("Your moderator and/or judge status has been revoked.");
|
||||
event.set_reason_str("Your moderator, judge, and/or developer status has been revoked.");
|
||||
event.set_end_time(QDateTime::currentDateTime().toSecsSinceEpoch());
|
||||
|
||||
SessionEvent *se = user->prepareSessionEvent(event);
|
||||
|
|
@ -3257,6 +3324,18 @@ Response::ResponseCode AbstractServerSocketInterface::cmdAdjustMod(const Command
|
|||
}
|
||||
}
|
||||
|
||||
if (cmd.has_should_be_developer()) {
|
||||
if (cmd.should_be_developer()) {
|
||||
if (!addAdminFlagToUser(userName, 8)) {
|
||||
return Response::RespInternalError;
|
||||
}
|
||||
} else {
|
||||
if (!removeAdminFlagFromUser(userName, 8)) {
|
||||
return Response::RespInternalError;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Response::RespOk;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue