diff --git a/dDashboardServer/routes/SettingsCatalog.cpp b/dDashboardServer/routes/SettingsCatalog.cpp index fee2eb9a7..fb927ea4e 100644 --- a/dDashboardServer/routes/SettingsCatalog.cpp +++ b/dDashboardServer/routes/SettingsCatalog.cpp @@ -251,6 +251,9 @@ namespace { c.Add(List(AUTH, "rewardcodes", "Reward codes", "Given to every account at login. 4 opens LEGO Club; 30 stops bricks being used up in build mode. Codes with an item mail it once.", eListOf::REWARD_CODE, "4,30")); c.Add(Bool(AUTH, "log_login_addresses", "Remember login addresses", "Keep the network address each account logs in to the game from, so staff see accounts that share one. " "Addresses are personal data: they're only shown as links between accounts, and deleted after log_login_address_days.", true)); + c.Add(Bool(AUTH, "log_client_sysinfo", "Remember client system info", "Keep the system description the client sends when it logs in (Windows version, video card, " + "processor count, memory), as the client reported it, for staff with client_sysinfo. The client's old Windows calls often report " + "compatibility values, not the real hardware. Deleted after log_client_sysinfo_days.", true)); c.AddSection("Moderation"); c.Add(Bool(SHARED, "mute_restrict_mail", "Muted players can't send mail", "", false)); diff --git a/dNet/AuthPackets.cpp b/dNet/AuthPackets.cpp index 6bde1b3e5..3843c1667 100644 --- a/dNet/AuthPackets.cpp +++ b/dNet/AuthPackets.cpp @@ -27,6 +27,7 @@ #include "MessageType/Master.h" #include "eGameMasterLevel.h" #include "StringifiedEnum.h" +#include "ClientSysInfo.h" #include #include @@ -238,6 +239,31 @@ void AuthPackets::LoginRequest::Handle() { stamps.Add(eStamps::PASSPORT_AUTH_DB_INSERT_FINISH, 1); } + // The system description the client sent, as it sent it (log_client_sysinfo, on by default). Only the address + // follows log_login_addresses. One row per account while nothing but the memory in use changes. + if (Game::config->GetValue("log_client_sysinfo") != "0") { + const auto memoryText = memoryStats.GetAsString(); + const auto memory = ClientSysInfo::ParseMemoryStats(memoryText); + IClientSysInfo::SysInfoRow info; + info.accountId = accountInfo->id; + info.firstSeen = info.lastSeen = static_cast(std::time(nullptr)); + if (Game::config->GetValue("log_login_addresses") != "0") info.ip = system.ToString(false); + info.clientOs = static_cast(clientOS); + info.memoryStats = memoryText; + info.memoryTotalKb = memory.totalPhysKb && *memory.totalPhysKb > 0 ? static_cast(*memory.totalPhysKb) : 0; + info.videoCard = videoCard.GetAsString(); + info.numberOfProcessors = numberOfProcessors; + info.processorType = processorType; + info.processorLevel = processorLevel; + info.processorRevision = processorRevision; + info.osVersionInfoSize = osVersionInfoSize; + info.majorVersion = majorVersion; + info.minorVersion = minorVersion; + info.buildNumber = buildNumber; + info.platformId = platformID; + Database::Get()->RecordClientSysInfo(info); + } + if (!server->GetIsConnectedToMaster()) { stamps.Add(eStamps::PASSPORT_AUTH_WORLD_DISCONNECT, 1); AuthPackets::SendLoginResponse(server, system, eLoginResponse::GENERAL_FAILED, "", "", 0, username, stamps); diff --git a/resources/authconfig.ini b/resources/authconfig.ini index 66df3cc16..286073997 100644 --- a/resources/authconfig.ini +++ b/resources/authconfig.ini @@ -20,3 +20,7 @@ closed_to_non_devs=0 # share one. Addresses are personal data: they're only shown as links between accounts, and deleted after # log_login_address_days. log_login_addresses=1 +# Remember client system info: Keep the system description the client sends when it logs in (Windows version, video +# card, processor count, memory), as the client reported it, for staff with client_sysinfo. The client's old Windows calls +# often report compatibility values, not the real hardware. Deleted after log_client_sysinfo_days. +log_client_sysinfo=1