mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2026-10-20 11:42:49 +00:00
feat(dashboard): client system info, as reported by the client
Account pages get a Client system info (as reported) card (client_sysinfo): every description the account's client sent at login, newest first, with the raw values, the memory text split into numbers and each field's caveat. The address is only shown with logs_audit. The Client System Info page (Logs & Health) shows the spread across players from each account's newest report: Windows version, video card, memory buckets, processor count and client build, marked as client-reported and approximate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
40
dDashboardServer/routes/ClientSysInfoRoutes.cpp
Normal file
40
dDashboardServer/routes/ClientSysInfoRoutes.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "ClientSysInfoRoutes.h"
|
||||
|
||||
#include "ClientSysInfoView.h"
|
||||
#include "Database.h"
|
||||
#include "RouteUtils.h"
|
||||
#include "eHTTPMethod.h"
|
||||
|
||||
using namespace RouteUtils;
|
||||
|
||||
namespace {
|
||||
constexpr uint32_t HISTORY_ROWS = 200;
|
||||
constexpr uint32_t SPREAD_ACCOUNTS = 100000;
|
||||
}
|
||||
|
||||
void ClientSysInfoRoutes::RegisterRoutes() {
|
||||
Route(eHTTPMethod::GET, "/client_sysinfo", Perm("client_sysinfo"), "Client system info: the spread across players, as reported by the client",
|
||||
[](HTTPReply& reply, const HTTPContext& context) {
|
||||
RenderPage(reply, context, "client_sysinfo.jinja2", "client_sysinfo");
|
||||
});
|
||||
|
||||
Route(eHTTPMethod::GET, "/api/accounts/:id/client_sysinfo", Perm("client_sysinfo"),
|
||||
"The system info an account's client sent at login, as reported by the client (compatibility values from old Windows calls, not "
|
||||
"necessarily the real hardware): {rows: [...] newest first (at most 200), caveats: {field: text}, showsIp}. ip only with logs_audit",
|
||||
[](HTTPReply& reply, const HTTPContext& context) {
|
||||
const auto accountId = PathId<uint32_t>(context.path, 2);
|
||||
if (!accountId) return JsonError(reply, eHTTPStatusCode::BAD_REQUEST, "Invalid account");
|
||||
const bool showIp = Can(context, "logs_audit");
|
||||
nlohmann::json rows = nlohmann::json::array();
|
||||
for (const auto& row : Database::Get()->GetClientSysInfo(*accountId, HISTORY_ROWS)) rows.push_back(ClientSysInfoView::RowJson(row, showIp));
|
||||
JsonSuccess(reply, { {"rows", rows}, {"caveats", ClientSysInfoView::Caveats()}, {"showsIp", showIp} });
|
||||
});
|
||||
|
||||
Route(eHTTPMethod::GET, "/api/client_sysinfo/spread", Perm("client_sysinfo"),
|
||||
"How the system info clients report is spread across players, from each account's newest row (approximate: as reported by the "
|
||||
"client): {spread: {accounts, os, video, memory, processors, clientOs: [{label, count}]}, caveats}",
|
||||
[](HTTPReply& reply, const HTTPContext&) {
|
||||
JsonSuccess(reply, { {"spread", ClientSysInfoView::Spread(Database::Get()->GetLatestClientSysInfo(SPREAD_ACCOUNTS))},
|
||||
{"caveats", ClientSysInfoView::Caveats()} });
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user