iw4x-client/src/Components/Modules/Logger.cpp

148 lines
2.6 KiB
C++
Raw Normal View History

#include "STDInclude.hpp"
2015-12-23 16:21:03 -05:00
namespace Components
{
std::mutex Logger::MessageMutex;
std::vector<std::string> Logger::MessageQueue;
2016-02-17 16:21:42 -05:00
void(*Logger::PipeCallback)(std::string) = nullptr;
2015-12-23 16:21:03 -05:00
bool Logger::IsConsoleReady()
{
return (IsWindow(*reinterpret_cast<HWND*>(0x64A3288)) != FALSE || (Dedicated::IsDedicated() && !Flags::HasFlag("console")));
2015-12-23 16:21:03 -05:00
}
void Logger::Print(const char* message, ...)
{
char buffer[0x1000] = { 0 };
va_list ap;
va_start(ap, message);
vsprintf_s(buffer, message, ap);
va_end(ap);
if (Logger::IsConsoleReady())
{
if (!Game::Sys_IsMainThread())
{
Logger::EnqueueMessage(buffer);
}
else
{
Game::Com_PrintMessage(0, buffer, 0);
}
2015-12-23 16:21:03 -05:00
}
else
{
2016-02-04 17:19:20 -05:00
// Only print to stdout, when doing unit tests
if (Loader::PerformingUnitTests())
{
printf("%s", buffer);
}
2015-12-23 16:21:03 -05:00
OutputDebugStringA(buffer);
}
}
void Logger::Error(const char* message, ...)
{
char buffer[0x1000] = { 0 };
va_list ap;
va_start(ap, message);
vsprintf_s(buffer, message, ap);
va_end(ap);
Game::Com_Error(0, "%s", buffer);
}
void Logger::SoftError(const char* message, ...)
{
char buffer[0x1000] = { 0 };
va_list ap;
va_start(ap, message);
vsprintf_s(buffer, message, ap);
va_end(ap);
Game::Com_Error(2, "%s", buffer);
}
void Logger::Frame()
{
Logger::MessageMutex.lock();
2016-01-24 13:58:13 -05:00
for (unsigned int i = 0; i < Logger::MessageQueue.size(); ++i)
{
if (Logger::IsConsoleReady())
{
Game::Com_PrintMessage(0, Logger::MessageQueue[i].data(), 0);
}
else
{
OutputDebugStringA(Logger::MessageQueue[i].data());
}
}
Logger::MessageQueue.clear();
Logger::MessageMutex.unlock();
}
2016-02-17 16:21:42 -05:00
void Logger::PipeOutput(void(*callback)(std::string))
{
Logger::PipeCallback = callback;
}
void Logger::PrintMessagePipe(const char* data)
{
if (Logger::PipeCallback)
{
Logger::PipeCallback(data);
}
}
void __declspec(naked) Logger::PrintMessageStub()
{
__asm
{
mov eax, Logger::PipeCallback
test eax, eax
2016-02-17 16:40:02 -05:00
jz returnPrint
2016-02-17 16:21:42 -05:00
push [esp + 8h]
call Logger::PrintMessagePipe
add esp, 4h
retn
returnPrint:
push esi
mov esi, [esp + 0Ch]
mov eax, 4AA835h
jmp eax
}
}
void Logger::EnqueueMessage(std::string message)
{
Logger::MessageMutex.lock();
Logger::MessageQueue.push_back(message);
Logger::MessageMutex.unlock();
}
2015-12-23 16:21:03 -05:00
Logger::Logger()
{
2016-02-17 16:21:42 -05:00
Logger::PipeOutput(nullptr);
2016-03-01 07:37:51 -05:00
QuickPatch::OnFrame(Logger::Frame);
2016-02-17 16:21:42 -05:00
Utils::Hook(Game::Com_PrintMessage, Logger::PrintMessageStub, HOOK_JUMP).Install()->Quick();
}
2015-12-23 16:21:03 -05:00
Logger::~Logger()
{
Logger::MessageMutex.lock();
Logger::MessageQueue.clear();
Logger::MessageMutex.unlock();
2015-12-23 16:21:03 -05:00
}
}