End of logger refactor

Changed all loggers to use the internal 'CoreMsg/CoreMsgV' functions. Significantly reduced duplicate code and CPU time. Code is also much more robust.

* Code now only acquires mutex lock when the actual logging part takes place.
* Code now only checks and strip ANSI rows if its enabled to begin with.
* Code now supports setting log levels, which ultimately could be tweaked with a cvar.
* Changed logger and file names to be more readable.

TODO:
* The RCON protocol has to be modified to accommodate these changes.
This commit is contained in:
Kawe Mazidjatari 2023-03-26 16:09:05 +02:00
parent 0f76c864fd
commit 793fcd62f2
19 changed files with 398 additions and 661 deletions

View File

@ -46,17 +46,24 @@ void SpdLog_Init(void)
* ROTATE LOGGER SETUP *
************************/
{
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sqvm_warn" , fmt::format("{:s}sqvm_warn.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sqvm_info" , fmt::format("{:s}sqvm_info.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk_info" , fmt::format("{:s}sdk_info.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk_warn" , fmt::format("{:s}sdk_warn.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk_error" , fmt::format("{:s}sdk_error.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("qhull_info", fmt::format("{:s}qhull_info.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("net_trace" , fmt::format("{:s}net_trace.log" , g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("squirrel_re(warning)"
, fmt::format("{:s}{:s}" , g_svLogSessionDirectory, "script_warning.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("squirrel_re"
, fmt::format("{:s}{:s}" , g_svLogSessionDirectory, "script.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(message)"
, fmt::format("{:s}{:s}" , g_svLogSessionDirectory, "message.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(warning)"
, fmt::format("{:s}{:s}" , g_svLogSessionDirectory, "warning.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("sdk(error)"
, fmt::format("{:s}{:s}" , g_svLogSessionDirectory, "error.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("net_trace"
, fmt::format("{:s}{:s}" , g_svLogSessionDirectory, "net_trace.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
#ifndef DEDICATED
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("net_con" , fmt::format("{:s}net_console.log", g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("netconsole"
, fmt::format("{:s}{:s}", g_svLogSessionDirectory, "netconsole.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
#endif // !DEDICATED
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("fs_warn" , fmt::format("{:s}fs_warn.log" ,g_svLogSessionDirectory), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
spdlog::rotating_logger_mt<spdlog::synchronous_factory>("filesystem"
, fmt::format("{:s}{:s}" ,g_svLogSessionDirectory, "filesystem.log"), SPDLOG_MAX_SIZE, SPDLOG_NUM_FILE)->set_pattern("[%Y-%m-%d %H:%M:%S.%e] %v");
}
spdlog::set_level(spdlog::level::trace);

View File

@ -269,7 +269,7 @@ void CRConClient::ProcessMessage(const sv_rcon::response& sv_response) const
}
case sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG:
{
NetMsg(static_cast<EGlobalContext_t>(sv_response.responseid()), PrintPercentageEscape(sv_response.responsebuf()).c_str());
NetMsg(static_cast<eDLL_T>(sv_response.responseid()), PrintPercentageEscape(sv_response.responsebuf()).c_str());
break;
}
default:

View File

@ -229,7 +229,7 @@ void CRConServer::Recv(void)
{//////////////////////////////////////////////
if (this->CheckForBan(pData))
{
this->Send(pData->m_hSocket, this->Serialize(s_pszBannedMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S)));
this->Send(pData->m_hSocket, this->Serialize(s_pszBannedMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)));
this->CloseConnection();
continue;
}
@ -337,7 +337,7 @@ void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNet
m_Socket.CloseListenSocket();
this->CloseNonAuthConnection();
this->Send(pData->m_hSocket, this->Serialize(s_pszAuthMessage, sv_rcon_sendlogs->GetString(), sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S)));
this->Send(pData->m_hSocket, this->Serialize(s_pszAuthMessage, sv_rcon_sendlogs->GetString(), sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)));
}
else // Bad password.
{
@ -347,7 +347,7 @@ void CRConServer::Authenticate(const cl_rcon::request& cl_request, CConnectedNet
DevMsg(eDLL_T::SERVER, "Bad RCON password attempt from '%s'\n", netAdr.ToString());
}
this->Send(pData->m_hSocket, this->Serialize(s_pszWrongPwMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S)));
this->Send(pData->m_hSocket, this->Serialize(s_pszWrongPwMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)));
pData->m_bAuthorized = false;
pData->m_bValidated = false;
@ -455,7 +455,7 @@ void CRConServer::ProcessMessage(const cl_rcon::request& cl_request)
&& cl_request.requesttype() != cl_rcon::request_t::SERVERDATA_REQUEST_AUTH)
{
// Notify net console that authentication is required.
this->Send(pData->m_hSocket, this->Serialize(s_pszNoAuthMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(EGlobalContext_t::NETCON_S)));
this->Send(pData->m_hSocket, this->Serialize(s_pszNoAuthMessage, "", sv_rcon::response_t::SERVERDATA_RESPONSE_AUTH, static_cast<int>(eDLL_T::NETCON)));
pData->m_bValidated = false;
pData->m_nIgnoredMessage++;

View File

@ -30,14 +30,15 @@
void _Error(char* fmt, ...)
{
char buf[4096];
{/////////////////////////////
va_list args;
va_start(args, fmt);
va_list args{};
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) -1] = 0;
va_end(args);
buf[sizeof(buf) - 1] = '\0';
va_end(args);
}/////////////////////////////
Error(eDLL_T::ENGINE, NO_ERROR, "%s", buf);
v_Error(buf);
@ -53,7 +54,7 @@ void _Warning(int level, char* fmt, ...)
{
char buf[10000];
{/////////////////////////////
va_list args{};
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
@ -81,7 +82,7 @@ void _Con_NPrintf(int pos, const char* fmt, ...)
{
char buf[MAXPRINTMSG];
{/////////////////////////////
va_list args{};
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);

View File

@ -15,40 +15,10 @@
//---------------------------------------------------------------------------------
void CBaseFileSystem::Warning(CBaseFileSystem* pFileSystem, FileWarningLevel_t level, const char* pFmt, ...)
{
if (fs_warning_level_sdk->GetInt() < static_cast<int>(level))
{
return;
}
static char szBuf[4096] = {};
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
static std::shared_ptr<spdlog::logger> fslogger = spdlog::get("fs_warn");
{/////////////////////////////
va_list args{};
va_start(args, pFmt);
vsnprintf(szBuf, sizeof(szBuf), pFmt, args);
szBuf[sizeof(szBuf) - 1] = '\0';
va_end(args);
}/////////////////////////////
fslogger->debug(szBuf);
if (fs_show_warning_output->GetBool())
{
wconsole->debug(szBuf);
#ifndef DEDICATED
iconsole->debug(szBuf);
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), ImVec4(1.00f, 1.00f, 0.00f, 1.00f)));
g_LogStream.str("");
g_LogStream.clear();
#endif // !DEDICATED
}
va_list args;
va_start(args, pFmt);
CoreMsgV(LogType_t::LOG_WARNING, static_cast<LogLevel_t>(fs_show_warnings->GetInt()), eDLL_T::FS, "filesystem", pFmt, args);
va_end(args);
}
//---------------------------------------------------------------------------------

View File

@ -28,7 +28,7 @@ void LogStub(const char* fmt, ...)
// Input : context -
// *fmt - ... -
//-----------------------------------------------------------------------------
void NetMsg(EGlobalContext_t context, const char* fmt, ...)
void NetMsg(eDLL_T context, const char* fmt, ...)
{
static char szBuf[4096] = {};

View File

@ -442,7 +442,7 @@ void CNetCon::ProcessMessage(const sv_rcon::response& sv_response) const
{
svOut.append(g_svReset);
}
NetMsg(EGlobalContext_t::GLOBAL_NONE, svOut.c_str());
NetMsg(eDLL_T::NONE, svOut.c_str());
break;
}
default:

View File

@ -1,5 +1,6 @@
#pragma once
#include "sqtype.h"
#include "sqvm.h"
extern bool g_bSQAuxError;
extern bool g_bSQAuxBadLogic;

View File

@ -31,7 +31,7 @@ enum class SQCONTEXT : SQInteger
NONE
};
const static string SQVM_TYPE_T[4] =
constexpr const char* s_SqContext[4] =
{
"SERVER",
"CLIENT",
@ -39,35 +39,11 @@ const static string SQVM_TYPE_T[4] =
"NONE"
};
const static string SQVM_LOG_T[4] =
constexpr const char* s_ScriptContext[4] =
{
"Script(S):",
"Script(C):",
"Script(U):",
"Script(X):"
};
const static string SQVM_ANSI_LOG_T[4] =
{
"\033[38;2;151;149;187mScript(S):",
"\033[38;2;151;149;163mScript(C):",
"\033[38;2;151;123;136mScript(U):",
"\033[38;2;151;149;163mScript(X):"
};
const static string SQVM_WARNING_ANSI_LOG_T[4] =
{
"\033[38;2;151;149;187mScript(S):\033[38;2;255;255;000m",
"\033[38;2;151;149;163mScript(C):\033[38;2;255;255;000m",
"\033[38;2;151;123;136mScript(U):\033[38;2;255;255;000m",
"\033[38;2;151;149;163mScript(X):\033[38;2;255;255;000m"
};
const static string SQVM_ERROR_ANSI_LOG_T[4] =
{
"\033[38;2;151;149;187mScript(S):\033[38;2;255;000;000m",
"\033[38;2;151;149;163mScript(C):\033[38;2;255;000;000m",
"\033[38;2;151;123;136mScript(U):\033[38;2;255;000;000m",
"\033[38;2;151;149;163mScript(X):\033[38;2;255;000;000m"
};
#endif // SQTYPE_H

View File

@ -32,180 +32,52 @@
//---------------------------------------------------------------------------------
SQRESULT SQVM_PrintFunc(HSQUIRRELVM v, SQChar* fmt, ...)
{
SQCONTEXT context;
int nResponseId;
eDLL_T remoteContext;
// We use the sqvm pointer as index for SDK usage as the function prototype has to match assembly.
switch (static_cast<SQCONTEXT>(reinterpret_cast<int>(v)))
{
case SQCONTEXT::SERVER:
context = SQCONTEXT::SERVER;
nResponseId = -3;
remoteContext = eDLL_T::SCRIPT_SERVER;
break;
case SQCONTEXT::CLIENT:
context = SQCONTEXT::CLIENT;
nResponseId = -2;
remoteContext = eDLL_T::SCRIPT_CLIENT;
break;
case SQCONTEXT::UI:
context = SQCONTEXT::UI;
nResponseId = -1;
remoteContext = eDLL_T::SCRIPT_UI;
break;
case SQCONTEXT::NONE:
context = SQCONTEXT::NONE;
nResponseId = -4;
remoteContext = eDLL_T::NONE;
break;
default:
context = v->GetContext();
switch (context)
SQCONTEXT scriptContext = v->GetContext();
switch (scriptContext)
{
case SQCONTEXT::SERVER:
nResponseId = -3;
remoteContext = eDLL_T::SCRIPT_SERVER;
break;
case SQCONTEXT::CLIENT:
nResponseId = -2;
remoteContext = eDLL_T::SCRIPT_CLIENT;
break;
case SQCONTEXT::UI:
nResponseId = -1;
break;
case SQCONTEXT::NONE:
nResponseId = -4;
remoteContext = eDLL_T::SCRIPT_UI;
break;
default:
nResponseId = -4;
remoteContext = eDLL_T::NONE;
break;
}
break;
}
static SQChar buf[4096] = {};
static std::string vmStr;
static std::regex rxAnsiExp("\\\033\\[.*?m");
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sqvm_info");
g_LogMutex.lock();
const char* pszUpTime = Plat_GetProcessUpTime();
{/////////////////////////////
va_list args{};
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) - 1] = '\0';
va_end(args);
}/////////////////////////////
vmStr = pszUpTime;
vmStr.append(SQVM_LOG_T[static_cast<SQInteger>(context)]);
vmStr.append(buf);
if (sq_showvmoutput->GetInt() > 0) {
sqlogger->debug(vmStr);
}
// Always show script errors.
bool bLogLevelOverride = (g_bSQAuxError || g_bSQAuxBadLogic && v == g_pErrorVM);
LogType_t type = bLogLevelOverride ? LogType_t::SQ_WARNING : LogType_t::SQ_INFO;
if (sq_showvmoutput->GetInt() > 1 || bLogLevelOverride)
{
bool bColorOverride = false;
bool bError = false;
va_list args;
va_start(args, fmt);
CoreMsgV(type, static_cast<LogLevel_t>(sq_showvmoutput->GetInt()), remoteContext, "squirrel_re", fmt, args);
va_end(args);
if (g_bSQAuxError)
{
bColorOverride = true;
if (strstr(buf, "SCRIPT ERROR:") || strstr(buf, " -> ")) {
bError = true;
}
}
if (g_bSQAuxBadLogic)
{
if (strstr(buf, "There was a problem processing game logic."))
{
bColorOverride = true;
bError = true;
g_bSQAuxBadLogic = false;
}
}
if (!g_bSpdLog_UseAnsiClr)
{
wconsole->debug(vmStr);
#ifndef CLIENT_DLL
RCONServer()->Send(vmStr, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, nResponseId);
#endif // !CLIENT_DLL
}
else // Use ANSI escape codes for the external console.
{
static std::string vmStrAnsi;
vmStrAnsi = pszUpTime;
if (bColorOverride)
{
if (bError) {
vmStrAnsi.append(SQVM_ERROR_ANSI_LOG_T[static_cast<SQInteger>(context)]);
}
else {
vmStrAnsi.append(SQVM_WARNING_ANSI_LOG_T[static_cast<SQInteger>(context)]);
}
}
else {
vmStrAnsi.append(SQVM_ANSI_LOG_T[static_cast<SQInteger>(context)]);
}
vmStrAnsi.append(buf);
wconsole->debug(vmStrAnsi);
#ifndef CLIENT_DLL
RCONServer()->Send(vmStrAnsi, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, nResponseId);
#endif // !CLIENT_DLL
}
#ifndef DEDICATED
vmStr = std::regex_replace(vmStr, rxAnsiExp, "");
iconsole->debug(vmStr);
if (sq_showvmoutput->GetInt() > 2 || bLogLevelOverride)
{
ImVec4 color;
if (bColorOverride)
{
if (bError) {
color = ImVec4(1.00f, 0.00f, 0.00f, 0.80f);
}
else {
color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f);
}
}
else
{
switch (context)
{
case SQCONTEXT::SERVER:
color = ImVec4(0.59f, 0.58f, 0.73f, 1.00f);
break;
case SQCONTEXT::CLIENT:
color = ImVec4(0.59f, 0.58f, 0.63f, 1.00f);
break;
case SQCONTEXT::UI:
color = ImVec4(0.59f, 0.48f, 0.53f, 1.00f);
break;
default:
color = ImVec4(0.59f, 0.58f, 0.63f, 1.00f);
break;
}
}
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), color));
g_pOverlay->AddLog(static_cast<EGlobalContext_t>(nResponseId), g_LogStream.str());
}
#endif // !DEDICATED
}
g_LogStream.str("");
g_LogStream.clear();
g_LogMutex.unlock();
return SQ_OK;
}
@ -220,84 +92,39 @@ SQRESULT SQVM_PrintFunc(HSQUIRRELVM v, SQChar* fmt, ...)
SQRESULT SQVM_WarningFunc(HSQUIRRELVM v, SQInteger a2, SQInteger a3, SQInteger* nStringSize, SQChar** ppString)
{
static void* retaddr = reinterpret_cast<void*>(p_SQVM_WarningCmd.Offset(0x10).FindPatternSelf("85 ?? ?? 99", CMemory::Direction::DOWN).GetPtr());
int nResponseId;
SQCONTEXT context;
eDLL_T remoteContext;
SQCONTEXT scriptContext;
SQRESULT result = v_SQVM_WarningFunc(v, a2, a3, nStringSize, ppString);
if (retaddr != _ReturnAddress() || !sq_showvmwarning->GetBool()) // Check if its SQVM_Warning calling.
if (retaddr != _ReturnAddress()) // Check if its SQVM_Warning calling.
{
return result;
}
g_LogMutex.lock();
const char* pszUpTime = Plat_GetProcessUpTime();
#ifdef GAMEDLL_S3
context = v->GetContext();
#else // Nothing equal to 'rdx + 18h' exist in the vm structs for anything below S3.
context = SQVM_GetContextIndex(v);
#endif
scriptContext = v->GetContext();
switch (context)
switch (scriptContext)
{
case SQCONTEXT::SERVER:
nResponseId = -3;
remoteContext = eDLL_T::SCRIPT_SERVER;
break;
case SQCONTEXT::CLIENT:
nResponseId = -2;
remoteContext = eDLL_T::SCRIPT_CLIENT;
break;
case SQCONTEXT::UI:
nResponseId = -1;
remoteContext = eDLL_T::SCRIPT_UI;
break;
case SQCONTEXT::NONE:
nResponseId = -4;
remoteContext = eDLL_T::NONE;
break;
default:
nResponseId = -4;
break;
}
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
static std::shared_ptr<spdlog::logger> sqlogger = spdlog::get("sqvm_warn");
std::string vmStr = pszUpTime;
vmStr.append(SQVM_LOG_T[static_cast<int>(context)]);
std::string svConstructor(*ppString, *nStringSize); // Get string from memory via std::string constructor.
vmStr.append(svConstructor);
CoreMsg(LogType_t::SQ_WARNING, static_cast<LogLevel_t>(sq_showvmwarning->GetInt()),
remoteContext, NO_ERROR, "squirrel_re(warning)", "%s", svConstructor.c_str());
sqlogger->debug(vmStr); // Emit to file.
if (sq_showvmwarning->GetInt() > 1)
{
if (!g_bSpdLog_UseAnsiClr)
{
wconsole->debug(vmStr);
#ifndef CLIENT_DLL
RCONServer()->Send(vmStr, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, nResponseId);
#endif // !CLIENT_DLL
}
else
{
std::string vmStrAnsi = pszUpTime;
vmStrAnsi.append(SQVM_WARNING_ANSI_LOG_T[static_cast<int>(context)]);
vmStrAnsi.append(svConstructor);
wconsole->debug(vmStrAnsi);
#ifndef CLIENT_DLL
RCONServer()->Send(vmStrAnsi, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, nResponseId);
#endif // !CLIENT_DLL
}
#ifndef DEDICATED
iconsole->debug(vmStr); // Emit to in-game console.
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), ImVec4(1.00f, 1.00f, 0.00f, 0.80f)));
g_pOverlay->AddLog(EGlobalContext_t::WARNING_C, g_LogStream.str());
#endif // !DEDICATED
}
g_LogStream.str("");
g_LogStream.clear();
g_LogMutex.unlock();
return result;
}
@ -314,12 +141,7 @@ void SQVM_CompileError(HSQUIRRELVM v, const SQChar* pszError, const SQChar* pszF
static SQCONTEXT context{};
static char szContextBuf[256]{};
#if !defined (GAMEDLL_S0) && !defined (GAMEDLL_S1) && !defined (GAMEDLL_S2)
context = v->GetContext();
#else // Nothing equal to 'rdx + 18h' exist in the vm structs for anything below S3.
context = SQVM_GetContextIndex(v);
#endif
v_SQVM_GetErrorLine(pszFile, nLine, szContextBuf, sizeof(szContextBuf) - 1);
Error(static_cast<eDLL_T>(context), NO_ERROR, "%s SCRIPT COMPILE ERROR: %s\n", SQVM_GetContextName(context), pszError);

View File

@ -23,6 +23,7 @@
#if defined( _X360 )
#include "xbox/xbox_console.h"
#endif
#include "squirrel/sqstdaux.h"
std::mutex g_LogMutex;
//-----------------------------------------------------------------------------
@ -90,341 +91,296 @@ PLATFORM_INTERFACE void AssertValidWStringPtr(const wchar_t* ptr, int maxchar/*
#endif
}
//-----------------------------------------------------------------------------
// Purpose: Netconsole log
// Input : context -
// *fmt - ... -
//-----------------------------------------------------------------------------
void NetMsg(EGlobalContext_t context, const char* fmt, ...)
{
#ifndef DEDICATED
static char szBuf[4096] = {};
static std::string svOut;
static const std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
static const std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
static const std::shared_ptr<spdlog::logger> ntlogger = spdlog::get("net_con");
switch (context)
ImVec4 CheckForWarnings(LogType_t type, eDLL_T context, const ImVec4& defaultCol)
{
ImVec4 color = defaultCol;
if (type == LogType_t::LOG_WARNING)
{
case EGlobalContext_t::GLOBAL_NONE:
case EGlobalContext_t::SCRIPT_SERVER:
case EGlobalContext_t::SCRIPT_CLIENT:
case EGlobalContext_t::SCRIPT_UI:
color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f);
}
else if (type == LogType_t::LOG_ERROR)
{
g_LogMutex.lock();
{/////////////////////////////
va_list args{};
va_start(args, fmt);
vsnprintf(szBuf, sizeof(szBuf), fmt, args);
szBuf[sizeof(szBuf) - 1] = '\0';
va_end(args);
}/////////////////////////////
svOut = szBuf;
if (svOut.back() != '\n')
{
svOut.append("\n");
}
ImVec4 color;
if (svOut.find("\033[38;2;255;255;000m") != std::string::npos)
{ // Warning.
color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f);
context = EGlobalContext_t::WARNING_C;
}
else if (svOut.find("\033[38;2;255;000;000m") != std::string::npos)
{ // Error.
color = ImVec4(1.00f, 0.00f, 0.00f, 0.80f);
context = EGlobalContext_t::ERROR_C;
}
else
{
switch (context)
{
case EGlobalContext_t::SCRIPT_SERVER: // [ SERVER ]
color = ImVec4(0.59f, 0.58f, 0.73f, 1.00f);
break;
case EGlobalContext_t::SCRIPT_CLIENT: // [ CLIENT ]
color = ImVec4(0.59f, 0.58f, 0.63f, 1.00f);
break;
case EGlobalContext_t::SCRIPT_UI: // [ UI ]
color = ImVec4(0.59f, 0.48f, 0.53f, 1.00f);
break;
default:
color = ImVec4(0.59f, 0.59f, 0.59f, 1.00f);
break;
}
}
if (g_bSpdLog_UseAnsiClr)
{
wconsole->debug(svOut);
svOut = std::regex_replace(svOut, rANSI_EXP, "");
}
else
{
svOut = std::regex_replace(svOut, rANSI_EXP, "");
wconsole->debug(svOut);
}
ntlogger->debug(svOut);
iconsole->debug(svOut);
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), color));
g_pOverlay->AddLog(static_cast<EGlobalContext_t>(context), g_LogStream.str());
g_LogStream.str("");
g_LogStream.clear();
g_LogMutex.unlock();
break;
color = ImVec4(1.00f, 0.00f, 0.00f, 0.80f);
}
case EGlobalContext_t::NATIVE_SERVER:
case EGlobalContext_t::NATIVE_CLIENT:
case EGlobalContext_t::NATIVE_UI:
case EGlobalContext_t::NATIVE_ENGINE:
case EGlobalContext_t::NATIVE_FS:
case EGlobalContext_t::NATIVE_RTECH:
case EGlobalContext_t::NATIVE_MS:
case EGlobalContext_t::NATIVE_AUDIO:
case EGlobalContext_t::NATIVE_VIDEO:
case EGlobalContext_t::NETCON_S:
case EGlobalContext_t::COMMON_C:
{
g_LogMutex.lock();
{/////////////////////////////
va_list args{};
va_start(args, fmt);
vsnprintf(szBuf, sizeof(szBuf), fmt, args);
szBuf[sizeof(szBuf) - 1] = '\0';
va_end(args);
}/////////////////////////////
svOut = szBuf;
if (svOut.back() != '\n')
{
svOut.append("\n");
}
ImVec4 color;
if (svOut.find("\033[38;2;255;255;000;") != std::string::npos)
{ // Warning.
color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f);
context = EGlobalContext_t::WARNING_C;
}
else if (svOut.find("\033[38;2;255;000;000;") != std::string::npos)
{ // Error.
color = ImVec4(1.00f, 0.00f, 0.00f, 0.80f);
context = EGlobalContext_t::ERROR_C;
}
else
{
switch (static_cast<eDLL_T>(context))
{
case eDLL_T::SERVER:
color = ImVec4(0.23f, 0.47f, 0.85f, 1.00f);
break;
case eDLL_T::CLIENT:
color = ImVec4(0.46f, 0.46f, 0.46f, 1.00f);
break;
case eDLL_T::UI:
color = ImVec4(0.59f, 0.35f, 0.46f, 1.00f);
break;
case eDLL_T::ENGINE:
color = ImVec4(0.70f, 0.70f, 0.70f, 1.00f);
break;
case eDLL_T::FS:
color = ImVec4(0.32f, 0.64f, 0.72f, 1.00f);
break;
case eDLL_T::RTECH:
color = ImVec4(0.36f, 0.70f, 0.35f, 1.00f);
break;
case eDLL_T::MS:
color = ImVec4(0.75f, 0.30f, 0.68f, 1.00f);
break;
case eDLL_T::AUDIO:
color = ImVec4(0.93f, 0.42f, 0.12f, 1.00f);
break;
case eDLL_T::VIDEO:
color = ImVec4(0.73f, 0.00f, 0.92f, 1.00f);
break;
case eDLL_T::NETCON:
color = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
break;
case eDLL_T::COMMON:
color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f);
break;
default:
color = ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
break;
}
}
if (g_bSpdLog_UseAnsiClr)
{
wconsole->debug(svOut);
svOut = std::regex_replace(svOut, rANSI_EXP, "");
}
else
{
svOut = std::regex_replace(svOut, rANSI_EXP, "");
wconsole->debug(svOut);
}
ntlogger->debug(svOut);
iconsole->info(svOut);
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), color));
g_pOverlay->AddLog(context, g_LogStream.str());
g_LogStream.str("");
g_LogStream.clear();
g_LogMutex.unlock();
break;
}
}
#endif // !DEDICATED
return color;
}
#ifndef DEDICATED
ImVec4 GetColorForContext(eDLL_T context)
ImVec4 GetColorForContext(LogType_t type, eDLL_T context)
{
switch (context)
{
case eDLL_T::SCRIPT_SERVER:
return CheckForWarnings(type, context, ImVec4(0.59f, 0.58f, 0.73f, 1.00f));
case eDLL_T::SCRIPT_CLIENT:
return CheckForWarnings(type, context, ImVec4(0.59f, 0.58f, 0.63f, 1.00f));
case eDLL_T::SCRIPT_UI:
return CheckForWarnings(type, context, ImVec4(0.59f, 0.48f, 0.53f, 1.00f));
case eDLL_T::SERVER:
return ImVec4(0.23f, 0.47f, 0.85f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.23f, 0.47f, 0.85f, 1.00f));
case eDLL_T::CLIENT:
return ImVec4(0.46f, 0.46f, 0.46f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.46f, 0.46f, 0.46f, 1.00f));
case eDLL_T::UI:
return ImVec4(0.59f, 0.35f, 0.46f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.59f, 0.35f, 0.46f, 1.00f));
case eDLL_T::ENGINE:
return ImVec4(0.70f, 0.70f, 0.70f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.70f, 0.70f, 0.70f, 1.00f));
case eDLL_T::FS:
return ImVec4(0.32f, 0.64f, 0.72f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.32f, 0.64f, 0.72f, 1.00f));
case eDLL_T::RTECH:
return ImVec4(0.36f, 0.70f, 0.35f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.36f, 0.70f, 0.35f, 1.00f));
case eDLL_T::MS:
return ImVec4(0.75f, 0.30f, 0.68f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.75f, 0.30f, 0.68f, 1.00f));
case eDLL_T::AUDIO:
return ImVec4(0.93f, 0.42f, 0.12f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.93f, 0.42f, 0.12f, 1.00f));
case eDLL_T::VIDEO:
return ImVec4(0.73f, 0.00f, 0.92f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.73f, 0.00f, 0.92f, 1.00f));
case eDLL_T::NETCON:
return ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.81f, 0.81f, 0.81f, 1.00f));
case eDLL_T::COMMON:
return ImVec4(1.00f, 0.80f, 0.60f, 1.00f);
return CheckForWarnings(type, context, ImVec4(1.00f, 0.80f, 0.60f, 1.00f));
default:
return ImVec4(0.81f, 0.81f, 0.81f, 1.00f);
return CheckForWarnings(type, context, ImVec4(0.81f, 0.81f, 0.81f, 1.00f));
}
}
#endif // !DEDICATED
string MsgInternal(LogType_t type, eDLL_T context, const char* fmt, va_list args, const UINT code = NULL)
const char* GetContextNameByIndex(eDLL_T context, const bool ansiColor = false)
{
std::lock_guard<std::mutex> lock(g_LogMutex);
int index = static_cast<int>(context);
const char* contextName = s_DefaultAnsiColor;
switch (context)
{
case eDLL_T::SCRIPT_SERVER:
contextName = s_ScriptAnsiColor[0];
break;
case eDLL_T::SCRIPT_CLIENT:
contextName = s_ScriptAnsiColor[1];
break;
case eDLL_T::SCRIPT_UI:
contextName = s_ScriptAnsiColor[2];
break;
case eDLL_T::SERVER:
case eDLL_T::CLIENT:
case eDLL_T::UI:
case eDLL_T::ENGINE:
case eDLL_T::FS:
case eDLL_T::RTECH:
case eDLL_T::MS:
case eDLL_T::AUDIO:
case eDLL_T::VIDEO:
case eDLL_T::NETCON:
case eDLL_T::COMMON:
contextName = s_DllAnsiColor[index];
break;
case eDLL_T::SYSTEM_WARNING:
case eDLL_T::SYSTEM_ERROR:
case eDLL_T::NONE:
default:
break;
}
if (!ansiColor)
{
// Shift # chars to skip ANSI row.
contextName += sizeof(s_DefaultAnsiColor)-1;
}
return contextName;
}
//-----------------------------------------------------------------------------
// Purpose: Show logs to all console interfaces (va_list version)
// Input : logType -
// logLevel -
// context -
// *pszLogger -
// *pszFormat -
// args -
// exitCode -
//-----------------------------------------------------------------------------
void CoreMsgV(LogType_t logType, LogLevel_t logLevel, eDLL_T context, const char* pszLogger,
const char* pszFormat, va_list args, const UINT exitCode /*= NO_ERROR*/)
{
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
static std::shared_ptr<spdlog::logger> ntlogger; // <-- Obtained by logger context.
std::shared_ptr<spdlog::logger> ntlogger = spdlog::get(pszLogger); // <-- Obtain by 'pszLogger'.
const char* pszUpTime = Plat_GetProcessUpTime();
string result = pszUpTime;
string message = g_bSpdLog_PostInit ? pszUpTime : "";
const char* pszContext = sANSI_DLL_T[static_cast<int>(context)];
if (!g_bSpdLog_UseAnsiClr)
{
// Shift # chars to skip ansi row.
pszContext += sizeof(s_DefaultAnsiColor)-1;
}
result.append(pszContext);
const bool bToConsole = (logLevel >= LogLevel_t::LEVEL_CONSOLE);
const bool bUseColor = (bToConsole && g_bSpdLog_UseAnsiClr);
const char* pszContext = GetContextNameByIndex(context, bUseColor);
message.append(pszContext);
#ifndef DEDICATED
ImVec4 color;
EGlobalContext_t tLog;
ImVec4 overlayColor = GetColorForContext(logType, context);
eDLL_T overlayContext = context;
#endif // !DEDICATED
switch (type)
bool bSquirrel = false;
bool bWarning = false;
bool bError = false;
//-------------------------------------------------------------------------
// Setup logger and context
//-------------------------------------------------------------------------
switch (logType)
{
case LogType_t::LOG_INFO:
#ifndef DEDICATED
color = GetColorForContext(context);
tLog = static_cast<EGlobalContext_t>(context);
#endif // !DEDICATED
ntlogger = spdlog::get("sdk_info");
break;
case LogType_t::LOG_WARNING:
#ifndef DEDICATED
color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f);
tLog = EGlobalContext_t::WARNING_C;
overlayContext = eDLL_T::SYSTEM_WARNING;
#endif // !DEDICATED
ntlogger = spdlog::get("sdk_warn");
if (g_bSpdLog_UseAnsiClr)
if (bUseColor)
{
result.append(g_svYellowF);
message.append(g_svYellowF);
}
break;
case LogType_t::LOG_ERROR:
#ifndef DEDICATED
color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f);
tLog = EGlobalContext_t::ERROR_C;
overlayContext = eDLL_T::SYSTEM_ERROR;
#endif // !DEDICATED
ntlogger = spdlog::get("sdk_error");
if (g_bSpdLog_UseAnsiClr)
if (bUseColor)
{
result.append(g_svRedF);
message.append(g_svRedF);
}
break;
case LogType_t::SQ_INFO:
bSquirrel = true;
break;
case LogType_t::SQ_WARNING:
#ifndef DEDICATED
overlayContext = eDLL_T::SYSTEM_WARNING;
overlayColor = ImVec4(1.00f, 1.00f, 0.00f, 0.80f);
#endif // !DEDICATED
bSquirrel = true;
bWarning = true;
break;
}
//-------------------------------------------------------------------------
// Format actual input
//-------------------------------------------------------------------------
va_list argsCopy;
va_copy(argsCopy, args);
result.append(FormatV(fmt, argsCopy));
const string formatted = FormatV(pszFormat, argsCopy);
va_end(argsCopy);
if (result.back() != '\n')
if (bUseColor && bSquirrel)
{
result.append("\n");
}
#ifndef CLIENT_DLL
RCONServer()->Send(result, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, static_cast<int>(context));
#endif // !CLIENT_DLL
wconsole->debug(result);
result = std::regex_replace(result, rANSI_EXP, "");
ntlogger->debug(result);
#ifndef DEDICATED
iconsole->debug(result);
if (g_bSpdLog_PostInit)
{
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), color));
g_pOverlay->AddLog(tLog, g_LogStream.str());
}
g_LogStream.str("");
g_LogStream.clear();
#endif // !DEDICATED
if (code) // Terminate the process if an exit code was passed.
{
if (MessageBoxA(NULL, Format("%s- %s", pszUpTime, result.c_str()).c_str(), "SDK Error", MB_ICONERROR | MB_OK))
if (bWarning && g_bSQAuxError)
{
TerminateProcess(GetCurrentProcess(), code);
if (formatted.find("SCRIPT ERROR:") != string::npos || formatted.find(" -> ") != string::npos)
{
bError = true;
}
}
else if (g_bSQAuxBadLogic)
{
if (formatted.find("There was a problem processing game logic.") != string::npos)
{
bError = true;
g_bSQAuxBadLogic = false;
}
}
// Append warning/error color before appending the formatted text,
// so that this gets marked as such while preserving context colors.
if (bError)
{
#ifndef DEDICATED
overlayContext = eDLL_T::SYSTEM_ERROR;
overlayColor = ImVec4(1.00f, 0.00f, 0.00f, 0.80f);
#endif // !DEDICATED
message.append(g_svRedF);
}
else if (bWarning)
{
message.append(g_svYellowF);
}
}
return result;
message.append(formatted);
if (!bSquirrel && message.back() != '\n')
{
message.append("\n");
}
std::lock_guard<std::mutex> lock(g_LogMutex);
//-------------------------------------------------------------------------
// Emit to all interfaces
//-------------------------------------------------------------------------
if (bToConsole)
{
wconsole->debug(message);
if (bUseColor)
{
// Remove ANSI rows before emitting to file or over wire.
message = std::regex_replace(message, s_AnsiRowRegex, "");
}
}
// Output is always logged to the file.
ntlogger->debug(message);
if (bToConsole)
{
#ifndef CLIENT_DLL
RCONServer()->Send(message, "", sv_rcon::response_t::SERVERDATA_RESPONSE_CONSOLE_LOG, static_cast<int>(context));
#endif // !CLIENT_DLL
#ifndef DEDICATED
iconsole->debug(message);
if (g_bSpdLog_PostInit)
{
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), overlayColor));
if (logLevel >= LogLevel_t::LEVEL_NOTIFY) // Draw to mini console.
{
g_pOverlay->AddLog(overlayContext, g_LogStream.str());
}
}
}
g_LogStream.str(string());
g_LogStream.clear();
#endif // !DEDICATED
if (exitCode) // Terminate the process if an exit code was passed.
{
if (MessageBoxA(NULL, Format("%s- %s", pszUpTime, message.c_str()).c_str(), "SDK Error", MB_ICONERROR | MB_OK))
{
TerminateProcess(GetCurrentProcess(), exitCode);
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Show logs to all console interfaces
// Input : logType -
// logLevel -
// context -
// exitCode -
// *pszLogger -
// *pszFormat -
// ... -
//-----------------------------------------------------------------------------
void CoreMsg(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
const UINT exitCode, const char* pszLogger, const char* pszFormat, ...)
{
va_list args;
va_start(args, pszFormat);
CoreMsgV(logType, logLevel, context, pszLogger, pszFormat, args, exitCode);
va_end(args);
}
//-----------------------------------------------------------------------------
// Purpose: Prints general debugging messages
// Input : context -
// *fmt - ... -
//-----------------------------------------------------------------------------
@ -432,10 +388,25 @@ void DevMsg(eDLL_T context, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
MsgInternal(LogType_t::LOG_INFO, context, fmt, args);
CoreMsgV(LogType_t::LOG_INFO, LogLevel_t::LEVEL_NOTIFY, context, "sdk(message)", fmt, args);
va_end(args);
}
//-----------------------------------------------------------------------------
// Purpose: Prints logs from remote console
// Input : context -
// *fmt - ... -
//-----------------------------------------------------------------------------
void NetMsg(eDLL_T context, const char* fmt, ...)
{
#ifndef DEDICATED
va_list args;
va_start(args, fmt);
CoreMsgV(LogType_t::LOG_NET, LogLevel_t::LEVEL_NOTIFY, context, "netconsole", fmt, args);
va_end(args);
#endif // !DEDICATED
}
//-----------------------------------------------------------------------------
// Purpose: Print engine and SDK warnings
// Input : context -
@ -445,7 +416,7 @@ void Warning(eDLL_T context, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
MsgInternal(LogType_t::LOG_WARNING, context, fmt, args);
CoreMsgV(LogType_t::LOG_WARNING, LogLevel_t::LEVEL_NOTIFY, context, "sdk(warning)", fmt, args);
va_end(args);
}
@ -459,6 +430,6 @@ void Error(eDLL_T context, const UINT code, const char* fmt, ...)
{
va_list args;
va_start(args, fmt);
MsgInternal(LogType_t::LOG_ERROR, context, fmt, args, code);
CoreMsgV(LogType_t::LOG_ERROR, LogLevel_t::LEVEL_NOTIFY, context, "sdk(error)", fmt, args, code);
va_end(args);
}

View File

@ -1,10 +1,10 @@
//===== Copyright (c) Valve Corporation, All rights reserved. ========//
//========== Copyright (c) Valve Corporation, All rights reserved. ==========//
//
// Purpose:
//
// $NoKeywords: $
//
//====================================================================//
//===========================================================================//
#ifndef DBG_H
#define DBG_H
#define AssertDbg assert
@ -13,30 +13,18 @@
bool HushAsserts();
//-----------------------------------------------------------------------------
enum class EGlobalContext_t : int
{
GLOBAL_NONE = -4,
SCRIPT_SERVER,
SCRIPT_CLIENT,
SCRIPT_UI,
NATIVE_SERVER,
NATIVE_CLIENT,
NATIVE_UI,
NATIVE_ENGINE,
NATIVE_FS,
NATIVE_RTECH,
NATIVE_MS,
NATIVE_AUDIO,
NATIVE_VIDEO,
NETCON_S,
COMMON_C,
WARNING_C,
ERROR_C,
NONE
};
enum class eDLL_T : int
{
//-------------------------------------------------------------------------
// Script enumerants
//-------------------------------------------------------------------------
SCRIPT_SERVER = -3,
SCRIPT_CLIENT = -2,
SCRIPT_UI = -1,
//-------------------------------------------------------------------------
// Native enumerants
//-------------------------------------------------------------------------
SERVER = 0, // server.dll (GameDLL)
CLIENT = 1, // client.dll (GameDLL)
UI = 2, // ui.dll (GameDLL)
@ -47,17 +35,33 @@ enum class eDLL_T : int
AUDIO = 7, // binkawin64/mileswin64.dll (AudioSystem API)
VIDEO = 8, // bink2w64 (VideoSystem API)
NETCON = 9, // netconsole impl (RCON wire)
COMMON = 10 // general (No specific subsystem)
};
//-------------------------------------------------------------------------
// Common enumerants
//-------------------------------------------------------------------------
COMMON = 10, // general (No specific subsystem)
SYSTEM_WARNING = 11, // general warning (No specific subsystem)
SYSTEM_ERROR = 12, // general error (No specific subsystem)
NONE = 13 // no context
};
//-----------------------------------------------------------------------------
enum class LogType_t
{
LOG_INFO = 0,
LOG_NET,
LOG_WARNING,
LOG_ERROR
LOG_ERROR,
SQ_INFO,
SQ_WARNING
};
//-----------------------------------------------------------------------------
enum class LogLevel_t
{
LEVEL_DISK_ONLY = 0,
LEVEL_CONSOLE, // Emit to console panels
LEVEL_NOTIFY // Emit to in-game mini console
};
//-----------------------------------------------------------------------------
static const char* sDLL_T[11] =
{
"Native(S):",
@ -72,9 +76,9 @@ static const char* sDLL_T[11] =
"Netcon(X):",
""
};
//-----------------------------------------------------------------------------
constexpr const char s_DefaultAnsiColor[] = "\033[38;2;255;204;153m";
constexpr const char* sANSI_DLL_T[11] =
constexpr const char* s_DllAnsiColor[11] =
{
"\033[38;2;059;120;218mNative(S):",
"\033[38;2;118;118;118mNative(C):",
@ -88,18 +92,30 @@ constexpr const char* sANSI_DLL_T[11] =
"\033[38;2;204;204;204mNetcon(X):",
s_DefaultAnsiColor
};
//-----------------------------------------------------------------------------
constexpr const char* s_ScriptAnsiColor[4] =
{
"\033[38;2;151;149;187mScript(S):",
"\033[38;2;151;149;163mScript(C):",
"\033[38;2;151;123;136mScript(U):",
"\033[38;2;151;149;163mScript(X):"
};
static const std::regex rANSI_EXP("\\\033\\[.*?m");
static const std::regex s_AnsiRowRegex("\\\033\\[.*?m");
extern std::mutex g_LogMutex;
//////////////////////////////////////////////////////////////////////////
// Legacy Logging System
//////////////////////////////////////////////////////////////////////////
void CoreMsgV(LogType_t logType, LogLevel_t logLevel, eDLL_T context, const char* pszLogger,
const char* pszFormat, va_list args, const UINT exitCode = NO_ERROR);
void CoreMsg(LogType_t logType, LogLevel_t logLevel, eDLL_T context,
const UINT exitCode, const char* pszLogger, const char* pszFormat, ...);
// These functions do not return.
PLATFORM_INTERFACE void NetMsg(EGlobalContext_t context, const char* fmt, ...) FMTFUNCTION(2, 3);
PLATFORM_INTERFACE void DevMsg(eDLL_T context, const char* fmt, ...) FMTFUNCTION(2, 3);
PLATFORM_INTERFACE void NetMsg(eDLL_T context, const char* fmt, ...) FMTFUNCTION(2, 3);
PLATFORM_INTERFACE void Warning(eDLL_T context, const char* fmt, ...) FMTFUNCTION(2, 3);
PLATFORM_INTERFACE void Error(eDLL_T context, const UINT code, const char* fmt, ...) FMTFUNCTION(3, 4);

View File

@ -200,8 +200,7 @@ void ConVar::Init(void)
#endif // !DEDICATED
//-------------------------------------------------------------------------
// FILESYSTEM |
fs_warning_level_sdk = ConVar::Create("fs_warning_level_sdk" , "0", FCVAR_DEVELOPMENTONLY, "Set the SDK FileSystem warning level.", false, 0.f, false, 0.f, nullptr, nullptr);
fs_show_warning_output = ConVar::Create("fs_show_warning_output" , "0", FCVAR_DEVELOPMENTONLY, "Logs the FileSystem warnings to the console, filtered by 'fs_warning_level_native' ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
fs_show_warnings = ConVar::Create("fs_show_warnings" , "0", FCVAR_DEVELOPMENTONLY, "Logs the FileSystem warnings to the console, filtered by 'fs_warning_level' ( !slower! ).", true, 0.f, true, 2.f, nullptr, "1 = log to console. 2 = 1 + log to notify.");
fs_packedstore_entryblock_stats = ConVar::Create("fs_packedstore_entryblock_stats" , "0", FCVAR_DEVELOPMENTONLY, "Logs the stats of each file entry in the VPK during decompression ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
fs_packedstore_workspace = ConVar::Create("fs_packedstore_workspace" , "platform/ship/", FCVAR_DEVELOPMENTONLY, "Determines the current VPK workspace.", false, 0.f, false, 0.f, nullptr, nullptr);
fs_packedstore_compression_level = ConVar::Create("fs_packedstore_compression_level", "default", FCVAR_DEVELOPMENTONLY, "Determines the VPK compression level.", false, 0.f, false, 0.f, nullptr, "fastest faster default better uber");
@ -216,8 +215,8 @@ void ConVar::Init(void)
// SQUIRREL |
sq_showrsonloading = ConVar::Create("sq_showrsonloading" , "0", FCVAR_DEVELOPMENTONLY, "Logs all RSON files loaded by the SQVM ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
sq_showscriptloading = ConVar::Create("sq_showscriptloading", "0", FCVAR_DEVELOPMENTONLY, "Logs all scripts loaded by the SQVM to be pre-compiled ( !slower! ).", false, 0.f, false, 0.f, nullptr, nullptr);
sq_showvmoutput = ConVar::Create("sq_showvmoutput" , "0", FCVAR_RELEASE, "Prints the VM output to the console ( !slower! ).", false, 0.f, false, 0.f, nullptr, "1 = Log to file. 2 = 1 + log to game console. 3 = 1 + 2 + log to overhead console.");
sq_showvmwarning = ConVar::Create("sq_showvmwarning" , "0", FCVAR_RELEASE, "Prints the VM warning output to the console ( !slower! ).", false, 0.f, false, 0.f, nullptr, "1 = Log to file. 2 = 1 + log to game console and overhead console.");
sq_showvmoutput = ConVar::Create("sq_showvmoutput" , "0", FCVAR_RELEASE, "Prints the VM output to the console ( !slower! ).", true, 0.f, true, 2.f, nullptr, "1 = log to console. 2 = 1 + log to notify.");
sq_showvmwarning = ConVar::Create("sq_showvmwarning" , "0", FCVAR_RELEASE, "Prints the VM warning output to the console ( !slower! ).", true, 0.f, true, 2.f, nullptr, "1 = log to console. 2 = 1 + log to notify.");
//-------------------------------------------------------------------------
// NETCHANNEL |
net_tracePayload = ConVar::Create("net_tracePayload" , "0", FCVAR_DEVELOPMENTONLY , "Log the payload of the send/recv datagram to a file on the disk.", false, 0.f, false, 0.f, nullptr, nullptr);

View File

@ -177,8 +177,7 @@ ConVar* origin_disconnectWhenOffline = nullptr;
#endif // !DEDICATED
//-----------------------------------------------------------------------------
// FILESYSTEM |
ConVar* fs_warning_level_sdk = nullptr;
ConVar* fs_show_warning_output = nullptr;
ConVar* fs_show_warnings = nullptr;
ConVar* fs_packedstore_entryblock_stats = nullptr;
ConVar* fs_packedstore_workspace = nullptr;
ConVar* fs_packedstore_compression_level = nullptr;

View File

@ -173,8 +173,7 @@ extern ConVar* origin_disconnectWhenOffline;
#endif // !DEDICATED
//-------------------------------------------------------------------------
// FILESYSTEM |
extern ConVar* fs_warning_level_sdk;
extern ConVar* fs_show_warning_output;
extern ConVar* fs_show_warnings;
extern ConVar* fs_packedstore_entryblock_stats;
extern ConVar* fs_packedstore_workspace;
extern ConVar* fs_packedstore_compression_level;

View File

@ -58,7 +58,7 @@ void CTextOverlay::Update(void)
//-----------------------------------------------------------------------------
// Purpose: add a log to the vector.
//-----------------------------------------------------------------------------
void CTextOverlay::AddLog(const EGlobalContext_t context, const string& svText)
void CTextOverlay::AddLog(const eDLL_T context, const string& svText)
{
if (!con_drawnotify->GetBool() || svText.empty())
{
@ -255,41 +255,41 @@ void CTextOverlay::DrawStreamOverlay(void) const
// Input : context -
// Output : Color
//-----------------------------------------------------------------------------
Color CTextOverlay::GetLogColorForType(const EGlobalContext_t context) const
Color CTextOverlay::GetLogColorForType(const eDLL_T context) const
{
switch (context)
{
case EGlobalContext_t::SCRIPT_SERVER:
case eDLL_T::SCRIPT_SERVER:
return { con_notify_script_server_clr->GetColor() };
case EGlobalContext_t::SCRIPT_CLIENT:
case eDLL_T::SCRIPT_CLIENT:
return { con_notify_script_client_clr->GetColor() };
case EGlobalContext_t::SCRIPT_UI:
case eDLL_T::SCRIPT_UI:
return { con_notify_script_ui_clr->GetColor() };
case EGlobalContext_t::NATIVE_SERVER:
case eDLL_T::SERVER:
return { con_notify_native_server_clr->GetColor() };
case EGlobalContext_t::NATIVE_CLIENT:
case eDLL_T::CLIENT:
return { con_notify_native_client_clr->GetColor() };
case EGlobalContext_t::NATIVE_UI:
case eDLL_T::UI:
return { con_notify_native_ui_clr->GetColor() };
case EGlobalContext_t::NATIVE_ENGINE:
case eDLL_T::ENGINE:
return { con_notify_native_engine_clr->GetColor() };
case EGlobalContext_t::NATIVE_FS:
case eDLL_T::FS:
return { con_notify_native_fs_clr->GetColor() };
case EGlobalContext_t::NATIVE_RTECH:
case eDLL_T::RTECH:
return { con_notify_native_rtech_clr->GetColor() };
case EGlobalContext_t::NATIVE_MS:
case eDLL_T::MS:
return { con_notify_native_ms_clr->GetColor() };
case EGlobalContext_t::NATIVE_AUDIO:
case eDLL_T::AUDIO:
return { con_notify_native_audio_clr->GetColor() };
case EGlobalContext_t::NATIVE_VIDEO:
case eDLL_T::VIDEO:
return { con_notify_native_video_clr->GetColor() };
case EGlobalContext_t::NETCON_S:
case eDLL_T::NETCON:
return { con_notify_netcon_clr->GetColor() };
case EGlobalContext_t::COMMON_C:
case eDLL_T::COMMON:
return { con_notify_common_clr->GetColor() };
case EGlobalContext_t::WARNING_C:
case eDLL_T::SYSTEM_WARNING:
return { con_notify_warning_clr->GetColor() };
case EGlobalContext_t::ERROR_C:
case eDLL_T::SYSTEM_ERROR:
return { con_notify_error_clr->GetColor() };
default:
return { con_notify_native_engine_clr->GetColor() };

View File

@ -4,15 +4,15 @@
struct CTextNotify
{
CTextNotify(const EGlobalContext_t type, const float nTime, const string& svMessage)
CTextNotify(const eDLL_T type, const float nTime, const string& svMessage)
{
this->m_svMessage = svMessage;
this->m_flLifeRemaining = nTime;
this->m_type = type;
}
EGlobalContext_t m_type = EGlobalContext_t::NONE;
float m_flLifeRemaining = 0.0f;
string m_svMessage = "";
eDLL_T m_type = eDLL_T::NONE;
float m_flLifeRemaining = 0.0f;
string m_svMessage = "";
};
class CTextOverlay
@ -26,7 +26,7 @@ public:
}
void Update(void);
void AddLog(const EGlobalContext_t context, const string& svText);
void AddLog(const eDLL_T context, const string& svText);
void DrawNotify(void);
void DrawFormat(const int x, const int y, const Color c, const char* pszFormat, ...) const;
void ShouldDraw(const float flFrameTime);
@ -38,7 +38,7 @@ public:
void Con_NPrintf(void);
private:
Color GetLogColorForType(const EGlobalContext_t type) const;
Color GetLogColorForType(const eDLL_T type) const;
vector<CTextNotify> m_vNotifyText;
int m_nFontHeight; // Hardcoded to 16 in this engine.

View File

@ -8,47 +8,23 @@
//-----------------------------------------------------------------------------
// Purpose: qhull error and debug prints
//-----------------------------------------------------------------------------
int HQHull_PrintFunc(const char* fmt, ...)
int QHull_PrintFunc(const char* fmt, ...)
{
static char buf[4096] = {};
va_list args;
va_start(args, fmt);
CoreMsgV(LogType_t::LOG_INFO, LogLevel_t::LEVEL_NOTIFY, eDLL_T::NONE, "message", fmt, args);
va_end(args);
static std::shared_ptr<spdlog::logger> iconsole = spdlog::get("game_console");
static std::shared_ptr<spdlog::logger> wconsole = spdlog::get("win_console");
static std::shared_ptr<spdlog::logger> qhlogger = spdlog::get("qhull_info");
g_LogMutex.lock();
{/////////////////////////////
va_list args{};
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) - 1] = '\0';
va_end(args);
}/////////////////////////////
qhlogger->debug(buf);
wconsole->debug(buf);
#ifndef DEDICATED
iconsole->debug(buf);
g_pConsole->AddLog(ConLog_t(g_LogStream.str(), ImVec4(0.81f, 0.81f, 0.81f, 1.00f)));
g_LogStream.str("");
g_LogStream.clear();
#endif // !DEDICATED
g_LogMutex.unlock();
return NULL;
}
///////////////////////////////////////////////////////////////////////////////
void VQHull::Attach() const
{
DetourAttach((LPVOID*)&QHull_PrintFunc, &HQHull_PrintFunc);
DetourAttach((LPVOID*)&v_QHull_PrintFunc, &QHull_PrintFunc);
}
void VQHull::Detach() const
{
DetourDetach((LPVOID*)&QHull_PrintFunc, &HQHull_PrintFunc);
DetourDetach((LPVOID*)&v_QHull_PrintFunc, &QHull_PrintFunc);
}

View File

@ -1,13 +1,13 @@
#pragma once
inline CMemory p_QHull_PrintFunc;
inline auto QHull_PrintFunc = p_QHull_PrintFunc.RCast<int (*)(const char* fmt, ...)>();
inline auto v_QHull_PrintFunc = p_QHull_PrintFunc.RCast<int (*)(const char* fmt, ...)>();
//inline CMemory p_speex_warning_int;
//inline auto speex_warning_int = p_speex_warning_int.RCast<int (*)(FILE* stream, const char* format, ...)>();
///////////////////////////////////////////////////////////////////////////////
int HQHull_PrintFunc(const char* fmt, ...);
int QHull_PrintFunc(const char* fmt, ...);
///////////////////////////////////////////////////////////////////////////////
class VQHull : public IDetour
@ -20,7 +20,7 @@ class VQHull : public IDetour
virtual void GetFun(void) const
{
p_QHull_PrintFunc = g_GameDll.FindPatternSIMD("48 89 4C 24 08 48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 53 B8 40 27 ?? ?? ?? ?? ?? ?? ?? 48");
QHull_PrintFunc = p_QHull_PrintFunc.RCast<int (*)(const char* fmt, ...)>(); /*48 89 4C 24 08 48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 53 B8 40 27 00 00 ?? ?? ?? ?? 00 48*/
v_QHull_PrintFunc = p_QHull_PrintFunc.RCast<int (*)(const char* fmt, ...)>(); /*48 89 4C 24 08 48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 53 B8 40 27 00 00 ?? ?? ?? ?? 00 48*/
//p_speex_warning_int = g_GameDll.FindPatternSIMD("48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 53 56 57 48 83 EC 30 48 8B FA 48 8D 74 24 60 48 8B");
//speex_warning_int = p_speex_warning_int.RCast<int (*)(FILE* stream, const char* format, ...)>(); /*48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 53 56 57 48 83 EC 30 48 8B FA 48 8D 74 24 60 48 8B*/