First pass idLib conversion from hex rays4.

This commit is contained in:
Justin Marshall
2026-08-08 13:54:26 -07:00
parent 3d01d735ce
commit 09a4cb91c3
120 changed files with 17718 additions and 0 deletions
+206
View File
@@ -0,0 +1,206 @@
#include "analysisclient.h"
#ifdef nullptr
#undef nullptr
#endif
#ifdef snprintf
#undef snprintf
#endif
#include <algorithm>
#include <cstdio>
#include <ctime>
idCVar mq_analysisReportRate(
"mq_analysisReportRate", "1", CVAR_INTEGER,
"Control the rate at which asserts and map stats get reported.");
idCVar mq_enable(
"mq_enable", "0", CVAR_BOOL,
"Enables the analysis client");
idAnalysisClient analysisClient;
namespace {
std::string CurrentTimestamp() {
std::time_t now = std::time(0);
std::tm utcTime = {};
gmtime_s(&utcTime, &now);
char buffer[32] = {};
std::strftime(buffer, sizeof(buffer), "%Y-%m-%dT%H:%M:%SZ", &utcTime);
return buffer;
}
std::string EventTimestamp(const char* timestamp) {
return timestamp == 0 || timestamp[0] == 0
? CurrentTimestamp() : std::string(timestamp);
}
int NextReportTime() {
const int seconds = std::max(1, mq_analysisReportRate.GetInteger());
return Sys_Milliseconds() + seconds * 1000;
}
} // namespace
idAnalysisClient::idAnalysisClient()
: idMQClientThread(), reportTime(0), channel(nullptr), currentMap(),
assertMutex(), mapLoadMutex(), viewNoteMutex(), pendingAsserts(),
pendingMapLoads(), pendingViewNotes() {
}
idAnalysisClient::~idAnalysisClient() {
StopThread(true);
}
void idAnalysisClient::StartMessageSystem() {
if (mq_enable.GetBool()) {
StartThread("AMQP idAnalysisClient >> Server");
}
}
void idAnalysisClient::StopMessageSystem() {
StopThread(true);
}
void idAnalysisClient::SetCurrentMap(const char* mapName) {
currentMap = mapName == nullptr ? "" : mapName;
}
void idAnalysisClient::QueueAssert(const idreports::AssertReport& report,
const char* timestamp) {
idScopedCriticalSection lock(assertMutex);
pendingEvent_t<idreports::AssertReport> event;
event.timestamp = EventTimestamp(timestamp);
event.message = report;
pendingAsserts.push_back(event);
}
void idAnalysisClient::QueueMapLoad(const idreports::MapReport& report,
const char* timestamp) {
idScopedCriticalSection lock(mapLoadMutex);
pendingEvent_t<idreports::MapReport> event;
event.timestamp = EventTimestamp(timestamp);
event.message = report;
pendingMapLoads.push_back(event);
}
void idAnalysisClient::QueueViewNote(const idreports::ViewNoteReport& report,
const char* timestamp) {
idScopedCriticalSection lock(viewNoteMutex);
pendingEvent_t<idreports::ViewNoteReport> event;
event.timestamp = EventTimestamp(timestamp);
event.message = report;
pendingViewNotes.push_back(event);
}
int idAnalysisClient::NumPendingAsserts() {
idScopedCriticalSection lock(assertMutex);
return static_cast<int>(pendingAsserts.size());
}
int idAnalysisClient::NumPendingMapLoads() {
idScopedCriticalSection lock(mapLoadMutex);
return static_cast<int>(pendingMapLoads.size());
}
int idAnalysisClient::NumPendingViewNotes() {
idScopedCriticalSection lock(viewNoteMutex);
return static_cast<int>(pendingViewNotes.size());
}
void idAnalysisClient::PreRun() {
channel = connection.GetChannel();
if (channel != nullptr) {
channel->ExchangeDeclare(idStr("idtech5"), idStr("topic"), true,
false);
}
reportTime = NextReportTime();
}
void PublishEvent(idreports::LogEvent& logEvent, const char* timestamp,
const idreports::LogEvent_Severity severity, const char* message,
google::protobuf::MessageLite& outgoing, const char* messageType,
idMQChannel* channel, const char* routingKey) {
logEvent.Clear();
logEvent.set_timestamp(timestamp == nullptr ? "" : timestamp);
logEvent.set_severity(severity);
logEvent.set_message(message == nullptr ? "" : message);
logEvent.set_datatype(messageType == nullptr ? "" : messageType);
std::string outgoingData;
outgoing.SerializePartialToString(&outgoingData);
logEvent.set_data(outgoingData.data(), outgoingData.size());
std::string envelope;
logEvent.SerializePartialToString(&envelope);
if (channel != nullptr) {
channel->BasicPublish(idStr("idtech5"),
idStr(routingKey == nullptr ? "" : routingKey), false, false,
envelope.data(), static_cast<unsigned int>(envelope.size()));
}
logEvent.Clear();
}
void idAnalysisClient::ThreadSlice() {
if (reportTime >= Sys_Milliseconds()) {
Sleep(25);
return;
}
std::vector<pendingEvent_t<idreports::AssertReport> > asserts;
std::vector<pendingEvent_t<idreports::MapReport> > mapLoads;
std::vector<pendingEvent_t<idreports::ViewNoteReport> > viewNotes;
{
idScopedCriticalSection lock(assertMutex);
asserts.swap(pendingAsserts);
}
{
idScopedCriticalSection lock(mapLoadMutex);
mapLoads.swap(pendingMapLoads);
}
{
idScopedCriticalSection lock(viewNoteMutex);
viewNotes.swap(pendingViewNotes);
}
idreports::LogEvent logEvent;
for (std::size_t index = 0; index < asserts.size(); ++index) {
char message[1200];
std::snprintf(message, sizeof(message), "Hit an assert in %s",
asserts[index].message.mapname().c_str());
PublishEvent(logEvent, asserts[index].timestamp.c_str(),
idreports::LogEvent_Severity_SEV_ERROR, message,
asserts[index].message, "AssertReport", channel,
"idtech5.events.assert_report");
}
for (std::size_t index = 0; index < mapLoads.size(); ++index) {
char message[1200];
std::snprintf(message, sizeof(message), "%s loaded the map %s",
mapLoads[index].message.username().c_str(),
mapLoads[index].message.mapname().c_str());
PublishEvent(logEvent, mapLoads[index].timestamp.c_str(),
idreports::LogEvent_Severity_SEV_WARNING, message,
mapLoads[index].message, "MapReport", channel,
"idtech5.events.map_load");
}
for (std::size_t index = 0; index < viewNotes.size(); ++index) {
char message[1200];
std::snprintf(message, sizeof(message),
"%s published a viewnote for %s",
viewNotes[index].message.username().c_str(),
viewNotes[index].message.mappath().c_str());
PublishEvent(logEvent, viewNotes[index].timestamp.c_str(),
idreports::LogEvent_Severity_SEV_INFO, message,
viewNotes[index].message, "ViewNoteReport", channel,
"idtech5.events.viewnote");
}
reportTime = NextReportTime();
Sleep(250);
}
void idAnalysisClient::OnThreadTerminate() {
channel = nullptr;
idLib::Printf("idAnalysisClient::OnThreadTerminate \n");
}