|
|
|
@ -3,10 +3,16 @@
|
|
|
|
|
|
|
|
|
|
namespace Components
|
|
|
|
|
{
|
|
|
|
|
using namespace Utils::String;
|
|
|
|
|
|
|
|
|
|
std::mutex Logger::MessageMutex;
|
|
|
|
|
std::vector<std::string> Logger::MessageQueue;
|
|
|
|
|
|
|
|
|
|
std::mutex Logger::LoggingMutex;
|
|
|
|
|
std::vector<Network::Address> Logger::LoggingAddresses[2];
|
|
|
|
|
|
|
|
|
|
Dvar::Var Logger::IW4x_oneLog;
|
|
|
|
|
|
|
|
|
|
void(*Logger::PipeCallback)(const std::string&) = nullptr;;
|
|
|
|
|
|
|
|
|
|
bool Logger::IsConsoleReady()
|
|
|
|
@ -23,7 +29,7 @@ namespace Components
|
|
|
|
|
vsnprintf_s(buf, _TRUNCATE, message, va);
|
|
|
|
|
va_end(va);
|
|
|
|
|
|
|
|
|
|
MessagePrint(channel, {buf});
|
|
|
|
|
MessagePrint(channel, std::string{ buf });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Logger::MessagePrint(const int channel, const std::string& msg)
|
|
|
|
@ -145,6 +151,7 @@ namespace Components
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
for (const auto& addr : LoggingAddresses[gLog & 1])
|
|
|
|
|
{
|
|
|
|
|
Network::SendCommand(addr, "print", data);
|
|
|
|
@ -216,13 +223,13 @@ namespace Components
|
|
|
|
|
|
|
|
|
|
void Logger::RedirectOSPath(const char* file, char* folder)
|
|
|
|
|
{
|
|
|
|
|
if (Dvar::Var("g_log").get<std::string>() == file)
|
|
|
|
|
if (std::strcmp((*Game::g_log)->current.string, file) == 0)
|
|
|
|
|
{
|
|
|
|
|
if (folder != "userraw"s)
|
|
|
|
|
if (std::strcmp(folder, "userraw") != 0)
|
|
|
|
|
{
|
|
|
|
|
if (Dvar::Var("iw4x_onelog").get<bool>())
|
|
|
|
|
if (IW4x_oneLog.get<bool>())
|
|
|
|
|
{
|
|
|
|
|
strcpy_s(folder, 256, "userraw");
|
|
|
|
|
strncpy_s(folder, 256, "userraw", _TRUNCATE);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -234,11 +241,9 @@ namespace Components
|
|
|
|
|
{
|
|
|
|
|
pushad
|
|
|
|
|
|
|
|
|
|
push [esp + 28h]
|
|
|
|
|
push [esp + 30h]
|
|
|
|
|
|
|
|
|
|
push [esp + 20h + 8h]
|
|
|
|
|
push [esp + 20h + 10h]
|
|
|
|
|
call RedirectOSPath
|
|
|
|
|
|
|
|
|
|
add esp, 8h
|
|
|
|
|
|
|
|
|
|
popad
|
|
|
|
@ -253,14 +258,25 @@ namespace Components
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Logger::LSP_LogString_Stub([[maybe_unused]] int localControllerIndex, const char* string)
|
|
|
|
|
{
|
|
|
|
|
NetworkLog(string, false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Logger::LSP_LogStringAboutUser_Stub([[maybe_unused]] int localControllerIndex, std::uint64_t xuid, const char* string)
|
|
|
|
|
{
|
|
|
|
|
NetworkLog(VA("%" PRIx64 ";%s", xuid, string), false);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Logger::AddServerCommands()
|
|
|
|
|
{
|
|
|
|
|
Command::AddSV("log_add", [](Command::Params* params)
|
|
|
|
|
{
|
|
|
|
|
if (params->size() < 2) return;
|
|
|
|
|
|
|
|
|
|
Network::Address addr(params->get(1));
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
|
|
|
|
|
Network::Address addr(params->get(1));
|
|
|
|
|
if (std::find(LoggingAddresses[0].begin(), LoggingAddresses[0].end(), addr) == LoggingAddresses[0].end())
|
|
|
|
|
{
|
|
|
|
|
LoggingAddresses[0].push_back(addr);
|
|
|
|
@ -271,8 +287,10 @@ namespace Components
|
|
|
|
|
{
|
|
|
|
|
if (params->size() < 2) return;
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
|
|
|
|
|
const auto num = std::atoi(params->get(1));
|
|
|
|
|
if (!std::strcmp(Utils::String::VA("%i", num), params->get(1)) && static_cast<unsigned int>(num) < LoggingAddresses[0].size())
|
|
|
|
|
if (!std::strcmp(VA("%i", num), params->get(1)) && static_cast<unsigned int>(num) < LoggingAddresses[0].size())
|
|
|
|
|
{
|
|
|
|
|
auto addr = Logger::LoggingAddresses[0].begin() + num;
|
|
|
|
|
Print("Address {} removed\n", addr->getString());
|
|
|
|
@ -300,6 +318,8 @@ namespace Components
|
|
|
|
|
Print("# ID: Address\n");
|
|
|
|
|
Print("-------------\n");
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0; i < LoggingAddresses[0].size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Print("#{:03d}: {}\n", i, LoggingAddresses[0][i].getString());
|
|
|
|
@ -310,8 +330,9 @@ namespace Components
|
|
|
|
|
{
|
|
|
|
|
if (params->size() < 2) return;
|
|
|
|
|
|
|
|
|
|
const Network::Address addr(params->get(1));
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
|
|
|
|
|
const Network::Address addr(params->get(1));
|
|
|
|
|
if (std::find(LoggingAddresses[1].begin(), LoggingAddresses[1].end(), addr) == LoggingAddresses[1].end())
|
|
|
|
|
{
|
|
|
|
|
LoggingAddresses[1].push_back(addr);
|
|
|
|
@ -322,8 +343,10 @@ namespace Components
|
|
|
|
|
{
|
|
|
|
|
if (params->size() < 2) return;
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
|
|
|
|
|
const auto num = std::atoi(params->get(1));
|
|
|
|
|
if (!std::strcmp(Utils::String::VA("%i", num), params->get(1)) && static_cast<unsigned int>(num) < LoggingAddresses[1].size())
|
|
|
|
|
if (!std::strcmp(VA("%i", num), params->get(1)) && static_cast<unsigned int>(num) < LoggingAddresses[1].size())
|
|
|
|
|
{
|
|
|
|
|
const auto addr = LoggingAddresses[1].begin() + num;
|
|
|
|
|
Print("Address {} removed\n", addr->getString());
|
|
|
|
@ -332,7 +355,6 @@ namespace Components
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
const Network::Address addr(params->get(1));
|
|
|
|
|
|
|
|
|
|
const auto i = std::ranges::find(LoggingAddresses[1].begin(), LoggingAddresses[1].end(), addr);
|
|
|
|
|
if (i != LoggingAddresses[1].end())
|
|
|
|
|
{
|
|
|
|
@ -351,6 +373,7 @@ namespace Components
|
|
|
|
|
Print("# ID: Address\n");
|
|
|
|
|
Print("-------------\n");
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(LoggingMutex);
|
|
|
|
|
for (std::size_t i = 0; i < LoggingAddresses[1].size(); ++i)
|
|
|
|
|
{
|
|
|
|
|
Print("#{:03d}: {}\n", i, LoggingAddresses[1][i].getString());
|
|
|
|
@ -360,7 +383,7 @@ namespace Components
|
|
|
|
|
|
|
|
|
|
Logger::Logger()
|
|
|
|
|
{
|
|
|
|
|
Dvar::Register<bool>("iw4x_onelog", false, Game::DVAR_LATCH | Game::DVAR_ARCHIVE, "Only write the game log to the 'userraw' OS folder");
|
|
|
|
|
IW4x_oneLog = Dvar::Register<bool>("iw4x_onelog", false, Game::DVAR_LATCH, "Only write the game log to the 'userraw' OS folder");
|
|
|
|
|
Utils::Hook(0x642139, BuildOSPath_Stub, HOOK_JUMP).install()->quick();
|
|
|
|
|
|
|
|
|
|
Scheduler::Loop(Frame, Scheduler::Pipeline::SERVER);
|
|
|
|
@ -368,6 +391,9 @@ namespace Components
|
|
|
|
|
Utils::Hook(Game::G_LogPrintf, G_LogPrintf_Hk, HOOK_JUMP).install()->quick();
|
|
|
|
|
Utils::Hook(Game::Com_PrintMessage, PrintMessage_Stub, HOOK_JUMP).install()->quick();
|
|
|
|
|
|
|
|
|
|
Utils::Hook(0x5F67AE, LSP_LogString_Stub, HOOK_CALL).install()->quick(); // Scr_LogString
|
|
|
|
|
Utils::Hook(0x5F67EE, LSP_LogStringAboutUser_Stub, HOOK_CALL).install()->quick(); // ScrCmd_LogString_Stub
|
|
|
|
|
|
|
|
|
|
if (Loader::IsPerformingUnitTests())
|
|
|
|
|
{
|
|
|
|
|
Utils::Hook(Game::Com_Printf, Print_Stub, HOOK_JUMP).install()->quick();
|
|
|
|
@ -378,12 +404,12 @@ namespace Components
|
|
|
|
|
|
|
|
|
|
Logger::~Logger()
|
|
|
|
|
{
|
|
|
|
|
std::unique_lock lock_logging(LoggingMutex);
|
|
|
|
|
LoggingAddresses[0].clear();
|
|
|
|
|
LoggingAddresses[1].clear();
|
|
|
|
|
|
|
|
|
|
std::unique_lock lock(MessageMutex);
|
|
|
|
|
std::unique_lock lock_message(MessageMutex);
|
|
|
|
|
MessageQueue.clear();
|
|
|
|
|
lock.unlock();
|
|
|
|
|
|
|
|
|
|
// Flush the console log
|
|
|
|
|
if (*Game::logfile)
|
|
|
|
|