Push SQVM output to in-game console

* Upgrade to spdlog for SQVM_PrintFunc
* Improve in-game console window
* Add print hook for signonstate debug on the client
This commit is contained in:
Amos 2021-08-05 03:28:03 -07:00
parent 8cd970b6bd
commit d0e77c42f2
18 changed files with 306 additions and 169 deletions

View File

@ -55,7 +55,7 @@
///////////////////////////////////////////////////////////////////////////////
// Uncomment to override default eol ("\n" or "\r\n" under Linux/Windows)
//
#define SPDLOG_EOL "\n"
#define SPDLOG_EOL ""
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////

View File

@ -69,7 +69,7 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
///////////////////////////////////////////////////////////////////////
// Engine toggles
if (sCommand == "toggle net") { Hooks::ToggleNetHooks(); continue; }
if (sCommand == "toggle net") { Hooks::ToggleNetTrace(); continue; }
if (sCommand == "toggle dev") { Hooks::ToggleDevCommands(); continue; }
if (sCommand == "toggle fal") { g_bReturnAllFalse = !g_bReturnAllFalse; continue; }
///////////////////////////////////////////////////////////////////////

View File

@ -43,6 +43,11 @@ void Hooks::InstallHooks()
MH_EnableHook(addr_CHLClient_FrameStageNotify);
MH_EnableHook(addr_CVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Enable ConVar | ConCommand hooks
MH_EnableHook(addr_ConVar_IsFlagSet);
MH_EnableHook(addr_ConCommand_IsFlagSet);
///////////////////////////////////////////////////////////////////////////////
// Enabled Utility hooks
MH_EnableHook(addr_MSG_EngineError);
@ -115,7 +120,7 @@ void Hooks::ToggleDevCommands()
bDev = !bDev;
}
void Hooks::ToggleNetHooks()
void Hooks::ToggleNetTrace()
{
static bool bNet = true;

View File

@ -131,6 +131,6 @@ namespace Hooks
void InstallHooks();
void RemoveHooks();
void ToggleNetHooks();
void ToggleNetTrace();
void ToggleDevCommands();
}

View File

@ -34,9 +34,8 @@ struct __declspec(align(8)) netpacket_t
};
//-----------------------------------------------------------------------------
// Hook and log the receive datagram
// Purpose: hook and log the receive datagram
//-----------------------------------------------------------------------------
bool Hooks::NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{
bool result = originalNET_ReceiveDatagram(sock, inpacket, raw);
@ -54,9 +53,8 @@ bool Hooks::NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
}
//-----------------------------------------------------------------------------
// Hook and log send datagram
// Purpose: hook and log send datagram
//-----------------------------------------------------------------------------
unsigned int Hooks::NET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{
unsigned int result = originalNET_SendDatagram(s, buf, len, flags);

View File

@ -24,6 +24,8 @@
#include "spdlog.h"
#include "sinks/basic_file_sink.h"
#include "sinks/stdout_sinks.h"
#include "sinks/ostream_sink.h"
#include "utility.h"
//#include "httplib.h"
//#include "json.hpp"

View File

@ -8,23 +8,39 @@ namespace Hooks
}
//---------------------------------------------------------------------------------
// Print the output of the VM.
// TODO: separate SV CL and UI
// Purpose: prints the output of each VM to the console
//---------------------------------------------------------------------------------
void* Hooks::SQVM_Print(void* sqvm, char* fmt, ...)
{
int vmIdx = *(int*)((std::uintptr_t)sqvm + 0x18);
static char buf[1024];
static std::string vmType[3] = { "Script(S):", "Script(C):", "Script(U):" };
static auto wconsole = spdlog::stdout_logger_mt("sqvm_wconsole"); // windows console
std::string vmStr = vmType[vmIdx].c_str();
wconsole->set_pattern("[%S.%e] %v");
wconsole->set_level(spdlog::level::debug);
va_list args;
va_start(args, fmt);
vprintf(fmt, args);
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) - 1] = 0;
va_end(args);
vmStr.append(buf);
wconsole->debug(vmStr);
return NULL;
}
//---------------------------------------------------------------------------------
// Load the include file from the mods directory
// Purpose: loads the include file from the mods directory
//---------------------------------------------------------------------------------
__int64 Hooks::SQVM_LoadRson(const char* rson_name)
{
char filepath[MAX_PATH] = { 0 };
@ -63,9 +79,8 @@ __int64 Hooks::SQVM_LoadRson(const char* rson_name)
}
//---------------------------------------------------------------------------------
// Load the script file from the mods directory
// Purpose: loads the script file from the mods directory
//---------------------------------------------------------------------------------
bool Hooks::SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
{
char filepath[MAX_PATH] = { 0 };

View File

@ -41,6 +41,10 @@ namespace Hooks
#pragma region NetChannel
bool NET_ReceiveDatagram(int sock, void* inpacket, bool raw);
unsigned int NET_SendDatagram(SOCKET s, const char* buf, int len, int flags);
void NET_PrintFunc(const char* fmt, ...);
using NET_PrintFuncFn = void(*)(const char* fmt, ...);
extern NET_PrintFuncFn originalNET_PrintFunc;
using NET_ReceiveDatagramFn = bool(*)(int, void*, bool);
extern NET_ReceiveDatagramFn originalNET_ReceiveDatagram;
@ -82,8 +86,8 @@ namespace Hooks
void InstallHooks();
void RemoveHooks();
void ToggleNetHooks();
extern bool bToggledNetHooks;
void ToggleNetTrace();
extern bool bToggledNetTrace;
void ToggleDevCommands();
extern bool bToggledDevFlags;
}

View File

@ -31,6 +31,9 @@ namespace
#pragma endregion
#pragma region NetChannel
/*0x1402655F0*/
FUNC_AT_ADDRESS(addr_NET_PrintFunc, bool(*)(int, void*, bool), r5_patterns.PatternSearch("48 89 54 24 10 4C 89 44 24 18 4C 89 4C 24 20 C3 48").GetPtr());
/*0x1402655F0*/
FUNC_AT_ADDRESS(addr_NET_ReceiveDatagram, bool(*)(int, void*, bool), r5_patterns.PatternSearch("48 89 74 24 18 48 89 7C 24 20 55 41 54 41 55 41 56 41 57 48 8D AC 24 50 EB").GetPtr());
@ -64,6 +67,7 @@ namespace
PRINT_ADDRESS("SQVM_Print", addr_SQVM_Print);
PRINT_ADDRESS("SQVM_LoadScript", addr_SQVM_LoadScript);
PRINT_ADDRESS("SQVM_LoadRson", addr_SQVM_LoadRson);
PRINT_ADDRESS("NET_PrintFunc", addr_NET_PrintFunc);
PRINT_ADDRESS("NET_ReceiveDatagram", addr_NET_ReceiveDatagram);
PRINT_ADDRESS("NET_SendDatagram ", addr_NET_SendDatagram);
PRINT_ADDRESS("CHLClient::FrameStageNotify", addr_CHLClient_FrameStageNotify);

View File

@ -27,6 +27,8 @@
#include "imgui_impl_win32.h"
#include "spdlog.h"
#include "sinks/basic_file_sink.h"
#include "sinks/stdout_sinks.h"
#include "sinks/ostream_sink.h"
#include "utility.h"
#include "httplib.h"
#include "json.hpp"

View File

@ -71,7 +71,7 @@ DWORD __stdcall ProcessConsoleWorker(LPVOID)
///////////////////////////////////////////////////////////////////////
// Engine toggles
if (sCommand == "toggle net") { Hooks::ToggleNetHooks(); continue; }
if (sCommand == "toggle net") { Hooks::ToggleNetTrace(); continue; }
if (sCommand == "toggle dev") { Hooks::ToggleDevCommands(); continue; }
if (sCommand == "toggle fal") { g_bReturnAllFalse = !g_bReturnAllFalse; continue; }
///////////////////////////////////////////////////////////////////////

View File

@ -5,8 +5,8 @@ bool g_bBlockInput = false;
namespace Hooks
{
bool bToggledDevFlags = false;
bool bToggledNetHooks = false;
bool bToggledDevFlags = true;
bool bToggledNetTrace = false;
}
void Hooks::InstallHooks()
@ -28,6 +28,7 @@ void Hooks::InstallHooks()
///////////////////////////////////////////////////////////////////////////////
// Hook Netchan functions
MH_CreateHook(addr_NET_PrintFunc, &Hooks::NET_PrintFunc, reinterpret_cast<void**>(&originalNET_PrintFunc));
MH_CreateHook(addr_NET_ReceiveDatagram, &Hooks::NET_ReceiveDatagram, reinterpret_cast<void**>(&originalNET_ReceiveDatagram));
MH_CreateHook(addr_NET_SendDatagram, &Hooks::NET_SendDatagram, reinterpret_cast<void**>(&originalNET_SendDatagram));
@ -36,23 +37,34 @@ void Hooks::InstallHooks()
MH_CreateHook(addr_ConVar_IsFlagSet, &Hooks::ConVar_IsFlagSet, NULL);
MH_CreateHook(addr_ConCommand_IsFlagSet, &Hooks::ConCommand_IsFlagSet, NULL);
///////////////////////////////////////////////////////////////////////////////
// Hook WinAPI
HMODULE user32dll = GetModuleHandleA("user32.dll");
void* SetCursorPosPtr = GetProcAddress(user32dll, "SetCursorPos");
void* ClipCursorPtr = GetProcAddress(user32dll, "ClipCursor");
void* GetCursorPosPtr = GetProcAddress(user32dll, "GetCursorPos");
void* ShowCursorPtr = GetProcAddress(user32dll, "ShowCursor");
MH_CreateHook(SetCursorPosPtr, &Hooks::SetCursorPos, reinterpret_cast<void**>(&originalSetCursorPos));
MH_CreateHook(ClipCursorPtr, &Hooks::ClipCursor, reinterpret_cast<void**>(&originalClipCursor));
MH_CreateHook(GetCursorPosPtr, &Hooks::GetCursorPos, reinterpret_cast<void**>(&originalGetCursorPos));
MH_CreateHook(ShowCursorPtr, &Hooks::ShowCursor, reinterpret_cast<void**>(&originalShowCursor));
///////////////////////////////////////////////////////////////////////////////
// Hook Utility functions
MH_CreateHook(addr_MSG_EngineError, &Hooks::MSG_EngineError, reinterpret_cast<void**>(&originalMSG_EngineError));
///////////////////////////////////////////////////////////////////////////////
// Hook WinAPI
HMODULE user32dll = GetModuleHandleA("user32.dll");
if (user32dll)
{
void* SetCursorPosPtr = GetProcAddress(user32dll, "SetCursorPos");
void* ClipCursorPtr = GetProcAddress(user32dll, "ClipCursor");
void* GetCursorPosPtr = GetProcAddress(user32dll, "GetCursorPos");
void* ShowCursorPtr = GetProcAddress(user32dll, "ShowCursor");
MH_CreateHook(SetCursorPosPtr, &Hooks::SetCursorPos, reinterpret_cast<void**>(&originalSetCursorPos));
MH_CreateHook(ClipCursorPtr, &Hooks::ClipCursor, reinterpret_cast<void**>(&originalClipCursor));
MH_CreateHook(GetCursorPosPtr, &Hooks::GetCursorPos, reinterpret_cast<void**>(&originalGetCursorPos));
MH_CreateHook(ShowCursorPtr, &Hooks::ShowCursor, reinterpret_cast<void**>(&originalShowCursor));
///////////////////////////////////////////////////////////////////////////
// Enable WinAPI hooks
MH_EnableHook(SetCursorPosPtr);
MH_EnableHook(ClipCursorPtr);
MH_EnableHook(GetCursorPosPtr);
MH_EnableHook(ShowCursorPtr);
}
///////////////////////////////////////////////////////////////////////////////
// Enable Squirrel hooks
MH_EnableHook(addr_SQVM_Print);
@ -65,15 +77,13 @@ void Hooks::InstallHooks()
MH_EnableHook(addr_CVEngineServer_IsPersistenceDataAvailable);
///////////////////////////////////////////////////////////////////////////////
// Enable ConVar | ConCommand hooks
ToggleDevCommands();
// Enable Netchan hooks
MH_EnableHook(addr_NET_PrintFunc);
///////////////////////////////////////////////////////////////////////////////
// Enable WinAPI hooks
MH_EnableHook(SetCursorPosPtr);
MH_EnableHook(ClipCursorPtr);
MH_EnableHook(GetCursorPosPtr);
MH_EnableHook(ShowCursorPtr);
// Enable ConVar | ConCommand hooks
MH_EnableHook(addr_ConVar_IsFlagSet);
MH_EnableHook(addr_ConCommand_IsFlagSet);
///////////////////////////////////////////////////////////////////////////////
// Enabled Utility hooks
@ -95,6 +105,7 @@ void Hooks::RemoveHooks()
///////////////////////////////////////////////////////////////////////////////
// Unhook Netchan functions
MH_RemoveHook(addr_NET_PrintFunc);
MH_RemoveHook(addr_NET_ReceiveDatagram);
MH_RemoveHook(addr_NET_SendDatagram);
@ -106,15 +117,19 @@ void Hooks::RemoveHooks()
///////////////////////////////////////////////////////////////////////////////
// Unhook WinAPI
HMODULE user32dll = GetModuleHandleA("user32.dll");
void* SetCursorPosPtr = GetProcAddress(user32dll, "SetCursorPos");
void* ClipCursorPtr = GetProcAddress(user32dll, "ClipCursor");
void* GetCursorPosPtr = GetProcAddress(user32dll, "GetCursorPos");
void* ShowCursorPtr = GetProcAddress(user32dll, "ShowCursor");
MH_RemoveHook(SetCursorPosPtr);
MH_RemoveHook(ClipCursorPtr);
MH_RemoveHook(GetCursorPosPtr);
MH_RemoveHook(ShowCursorPtr);
if (user32dll)
{
void* SetCursorPosPtr = GetProcAddress(user32dll, "SetCursorPos");
void* ClipCursorPtr = GetProcAddress(user32dll, "ClipCursor");
void* GetCursorPosPtr = GetProcAddress(user32dll, "GetCursorPos");
void* ShowCursorPtr = GetProcAddress(user32dll, "ShowCursor");
MH_RemoveHook(SetCursorPosPtr);
MH_RemoveHook(ClipCursorPtr);
MH_RemoveHook(GetCursorPosPtr);
MH_RemoveHook(ShowCursorPtr);
}
///////////////////////////////////////////////////////////////////////////////
// Unhook Utility functions
@ -125,9 +140,9 @@ void Hooks::RemoveHooks()
MH_Uninitialize();
}
void Hooks::ToggleNetHooks()
void Hooks::ToggleNetTrace()
{
if (!bToggledNetHooks)
if (!bToggledNetTrace)
{
MH_EnableHook(addr_NET_ReceiveDatagram);
MH_EnableHook(addr_NET_SendDatagram);
@ -147,7 +162,7 @@ void Hooks::ToggleNetHooks()
printf("+--------------------------------------------------------+\n");
printf("\n");
}
bToggledNetHooks = !bToggledNetHooks;
bToggledNetTrace = !bToggledNetTrace;
}
void Hooks::ToggleDevCommands()

View File

@ -3,10 +3,50 @@
namespace Hooks
{
NET_PrintFuncFn originalNET_PrintFunc = nullptr;
NET_ReceiveDatagramFn originalNET_ReceiveDatagram = nullptr;
NET_SendDatagramFn originalNET_SendDatagram = nullptr;
}
//-----------------------------------------------------------------------------
// Purpose: log the clients signonstate to the console
//-----------------------------------------------------------------------------
void Hooks::NET_PrintFunc(const char* fmt, ...)
{
static char buf[1024];
static auto iconsole = spdlog::stdout_logger_mt("net_iconsole"); // in-game console
static auto wconsole = spdlog::stdout_logger_mt("net_wconsole"); // windows console
std::ostringstream oss;
auto ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(oss);
iconsole = std::make_shared<spdlog::logger>("ostream", ostream_sink);
iconsole->set_pattern("[%S.%e] %v");
iconsole->set_level(spdlog::level::debug);
wconsole->set_pattern("[%S.%e] %v");
wconsole->set_level(spdlog::level::debug);
va_list args;
va_start(args, fmt);
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) - 1] = 0;
va_end(args);
iconsole->debug(buf);
wconsole->debug(buf);
std::string s = oss.str();
const char* c = s.c_str();
Items.push_back(Strdup((const char*)c));
}
//-----------------------------------------------------------------------------
// Purpose: hook and log the receive datagram
//-----------------------------------------------------------------------------
bool Hooks::NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
{
bool result = originalNET_ReceiveDatagram(sock, inpacket, raw);
@ -23,6 +63,9 @@ bool Hooks::NET_ReceiveDatagram(int sock, void* inpacket, bool raw)
return result;
}
//-----------------------------------------------------------------------------
// Purpose: hook and log the send datagram
//-----------------------------------------------------------------------------
unsigned int Hooks::NET_SendDatagram(SOCKET s, const char* buf, int len, int flags)
{
unsigned int result = originalNET_SendDatagram(s, buf, len, flags);

View File

@ -7,29 +7,52 @@ namespace Hooks
SQVM_LoadScriptFn originalSQVM_LoadScript = nullptr;
}
std::string prefixes[3] = { "Script(S)", "Script(C)", "Script(U)" };
//---------------------------------------------------------------------------------
// Purpose: prints the output of each VM to the console
//---------------------------------------------------------------------------------
void* Hooks::SQVM_Print(void* sqvm, char* fmt, ...)
{
int vmIdx = *(int*)((std::uintptr_t)sqvm + 0x18);
char buf[1024];
static char buf[1024];
static std::string vmType[3] = { "Script(S):", "Script(C):", "Script(U):" };
static auto iconsole = spdlog::stdout_logger_mt("sqvm_iconsole"); // in-game console
static auto wconsole = spdlog::stdout_logger_mt("sqvm_wconsole"); // windows console
std::string vmStr = vmType[vmIdx].c_str();
std::ostringstream oss;
auto ostream_sink = std::make_shared<spdlog::sinks::ostream_sink_st>(oss);
iconsole = std::make_shared<spdlog::logger>("ostream", ostream_sink);
iconsole->set_pattern("[%S.%e] %v");
iconsole->set_level(spdlog::level::debug);
wconsole->set_pattern("[%S.%e] %v");
wconsole->set_level(spdlog::level::debug);
va_list args;
va_start(args, fmt);
// external console
printf("%s:", prefixes[vmIdx].c_str());
vprintf(fmt, args);
// imgui console
vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args);
buf[IM_ARRAYSIZE(buf) - 1] = 0;
vsnprintf(buf, sizeof(buf), fmt, args);
buf[sizeof(buf) - 1] = 0;
va_end(args);
Items.push_back(Strdup(buf));
vmStr.append(buf);
iconsole->debug(vmStr);
wconsole->debug(vmStr);
std::string s = oss.str();
const char* c = s.c_str();
Items.push_back(Strdup((const char*)c));
return NULL;
}
//---------------------------------------------------------------------------------
// Purpose: loads the include file from the mods directory
//---------------------------------------------------------------------------------
__int64 Hooks::SQVM_LoadRson(const char* rson_name)
{
char filepath[MAX_PATH] = { 0 };
@ -67,6 +90,9 @@ __int64 Hooks::SQVM_LoadRson(const char* rson_name)
return originalSQVM_LoadRson(rson_name);
}
//---------------------------------------------------------------------------------
// Purpose: loads the script file from the mods directory
//---------------------------------------------------------------------------------
bool Hooks::SQVM_LoadScript(void* sqvm, const char* script_path, const char* script_name, int flag)
{
char filepath[MAX_PATH] = { 0 };

View File

@ -408,6 +408,58 @@ HRESULT __stdcall Present(IDXGISwapChain* pSwapChain, UINT nSyncInterval, UINT n
return originalPresent(pSwapChain, nSyncInterval, nFlags);
}
bool LoadTextureFromByteArray(unsigned char* image_data, const int& image_width, const int& image_height, ID3D11ShaderResourceView** out_srv)
{
// Load from disk into a raw RGBA buffer
//int image_width = 0;
//int image_height = 0;
//unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
if (image_data == NULL)
{
return false;
}
// Create texture
D3D11_TEXTURE2D_DESC desc;
ID3D11Texture2D* pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource;
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = image_width;
desc.Height = image_height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
subResource.pSysMem = image_data;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
g_pDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
if (pTexture)
{
g_pDevice->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
}
pTexture->Release();
//stbi_image_free(image_data);
return true;
}
//#################################################################################
// MANAGEMENT
//#################################################################################
@ -416,8 +468,11 @@ void InstallDXHooks()
{
HMODULE user32dll = GetModuleHandleA("user32.dll");
IPostMessageA PostMessageA = (IPostMessageA)GetProcAddress(user32dll, "PostMessageA");
IPostMessageW PostMessageW = (IPostMessageW)GetProcAddress(user32dll, "PostMessageW");
if (user32dll)
{
IPostMessageA PostMessageA = (IPostMessageA)GetProcAddress(user32dll, "PostMessageA");
IPostMessageW PostMessageW = (IPostMessageW)GetProcAddress(user32dll, "PostMessageW");
}
///////////////////////////////////////////////////////////////////////////////
// Hook PostMessage
@ -441,8 +496,11 @@ void RemoveDXHooks()
{
HMODULE user32dll = GetModuleHandleA("user32.dll");
IPostMessageA PostMessageA = (IPostMessageA)GetProcAddress(user32dll, "PostMessageA");
IPostMessageW PostMessageW = (IPostMessageW)GetProcAddress(user32dll, "PostMessageW");
if (user32dll)
{
IPostMessageA PostMessageA = (IPostMessageA)GetProcAddress(user32dll, "PostMessageA");
IPostMessageW PostMessageW = (IPostMessageW)GetProcAddress(user32dll, "PostMessageW");
}
///////////////////////////////////////////////////////////////////////////////
// Unhook PostMessage
@ -498,47 +556,4 @@ void SetupDXSwapChain()
//#################################################################################
// UTILS
//#################################################################################
bool LoadTextureFromByteArray(unsigned char* image_data, const int &image_width, const int &image_height, ID3D11ShaderResourceView** out_srv)
{
// Load from disk into a raw RGBA buffer
//int image_width = 0;
//int image_height = 0;
//unsigned char* image_data = stbi_load(filename, &image_width, &image_height, NULL, 4);
if (image_data == NULL)
return false;
// Create texture
D3D11_TEXTURE2D_DESC desc;
ZeroMemory(&desc, sizeof(desc));
desc.Width = image_width;
desc.Height = image_height;
desc.MipLevels = 1;
desc.ArraySize = 1;
desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
desc.SampleDesc.Count = 1;
desc.Usage = D3D11_USAGE_DEFAULT;
desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
desc.CPUAccessFlags = 0;
ID3D11Texture2D* pTexture = NULL;
D3D11_SUBRESOURCE_DATA subResource;
subResource.pSysMem = image_data;
subResource.SysMemPitch = desc.Width * 4;
subResource.SysMemSlicePitch = 0;
g_pDevice->CreateTexture2D(&desc, &subResource, &pTexture);
// Create texture view
D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
ZeroMemory(&srvDesc, sizeof(srvDesc));
srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
srvDesc.Texture2D.MipLevels = desc.MipLevels;
srvDesc.Texture2D.MostDetailedMip = 0;
g_pDevice->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
pTexture->Release();
//stbi_image_free(image_data);
return true;
}
//#################################################################################

View File

@ -8,7 +8,7 @@
void InstallOpcodes() /* .TEXT */
{
//-------------------------------------------------------------------------
// JNZ --> JMP | Prevent OriginSDK from initializing on the client
// JNZ --> JMP | Prevent OriginSDK from initializing
//Origin_Init.Offset(0x0B).Patch({ 0xE9, 0x63, 0x02, 0x00, 0x00, 0x00 });
//Origin_SetState.Offset(0x0E).Patch({ 0xE9, 0xCB, 0x03, 0x00, 0x00 });
//-------------------------------------------------------------------------

View File

@ -48,6 +48,8 @@ CGameConsole::~CGameConsole()
void CGameConsole::Draw(const char* title)
{
bool copy_to_clipboard = false;
if (!ThemeSet)
{
SetStyleVar();
@ -56,7 +58,7 @@ void CGameConsole::Draw(const char* title)
//ImGui::ShowStyleEditor();
ImGui::SetNextWindowSize(ImVec2(840, 600), ImGuiCond_FirstUseEver);
ImGui::SetNextWindowSize(ImVec2(1000, 600), ImGuiCond_FirstUseEver);
ImGui::SetWindowPos(ImVec2(-1000, 50), ImGuiCond_FirstUseEver);
if (!ImGui::Begin(title, NULL)) // Passing a bool only causes problems if you Begin a new window. I would not suggest to use it.
@ -64,58 +66,59 @@ void CGameConsole::Draw(const char* title)
ImGui::End(); return;
}
///////////////////////////////////////////////////////////////////////
// If bToggledDevFlags is true, override text color to be green, if its false red.
Hooks::bToggledDevFlags ? ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0, 255, 0, 255)) : ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 0, 0, 255));
if (ImGui::SmallButton("Developer mode"))
{
Hooks::ToggleDevCommands();
AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n");
ProcessCommand("exec autoexec");
}
ImGui::PopStyleColor(); // Pop color override.
ImGui::SameLine();
// Do the same for bToggledNetHooks.
Hooks::bToggledNetHooks ? ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0, 255, 0, 255)) : ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 0, 0, 255));
if (ImGui::SmallButton("Netchannel Trace"))
{
Hooks::ToggleNetHooks();
AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n");
ProcessCommand("exec netchan");
}
ImGui::PopStyleColor(); // Pop color override.
// Reserve enough left-over height and width for 1 separator + 1 input text
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
const float footer_width_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetWindowWidth();
///////////////////////////////////////////////////////////////////////
ImGui::SameLine();
if (ImGui::SmallButton("Clear"))
{
ClearLog();
}
ImGui::SameLine();
bool copy_to_clipboard = ImGui::SmallButton("Copy");
ImGui::Separator();
if (ImGui::BeginPopup("Options"))
{
ImGui::Checkbox("Auto-scroll", &AutoScroll); ImGui::EndPopup();
ImGui::Checkbox("Auto-scroll", &AutoScroll);
if (ImGui::SmallButton("Clear"))
{
ClearLog();
}
copy_to_clipboard = ImGui::SmallButton("Copy");
ImGui::EndPopup();
}
if (ImGui::Button("Options"))
{
ImGui::OpenPopup("Options");
}
ImGui::SameLine();
Filter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", 265);
if (ImGui::BeginPopup("Tools"))
{
Hooks::bToggledDevFlags ? ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0, 255, 0, 255)) : ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 0, 0, 255));
if (ImGui::SmallButton("Developer Mode"))
{
Hooks::ToggleDevCommands();
AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| DEVONLY COMMANDS TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n");
ProcessCommand("exec autoexec");
}
ImGui::PopStyleColor(); // Pop color override.
Hooks::bToggledNetTrace ? ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(0, 255, 0, 255)) : ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(255, 0, 0, 255));
if (ImGui::SmallButton("Netchannel Trace"))
{
Hooks::ToggleNetTrace();
AddLog("+--------------------------------------------------------+\n");
AddLog("|>>>>>>>>>>>>>>| NETCHANNEL TRACE TOGGLED |<<<<<<<<<<<<<<|\n");
AddLog("+--------------------------------------------------------+\n");
ProcessCommand("exec netchan");
}
ImGui::PopStyleColor(); // Pop color override.
ImGui::EndPopup();
}
if (ImGui::Button("Tools"))
{
ImGui::OpenPopup("Tools");
}
ImGui::SameLine();
Filter.Draw("Filter [\"-incl,-excl\"] [\"error\"]", footer_width_to_reserve - 500);
ImGui::Separator();
// Reserve enough left-over height for 1 separator + 1 input text
const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
///////////////////////////////////////////////////////////////////////
ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), true, ImGuiWindowFlags_AlwaysVerticalScrollbar);
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2{ 4.f, 6.f });
@ -136,15 +139,21 @@ void CGameConsole::Draw(const char* title)
///////////////////////////////////////////////////////////////////
// General
if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "[DEBUG]")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; }
if (strstr(item, "[INFO]")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
if (strstr(item, "[ERROR]")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "[DEBUG]")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "[WARNING]")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strncmp(item, "# ", 2) == 0) { color = ImVec4(1.00f, 0.80f, 0.60f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Virtual machines
if (strstr(item, "Script(S):")) { color = ImVec4(0.59f, 0.58f, 0.73f, 1.00f); has_color = true; }
if (strstr(item, "Script(C):")) { color = ImVec4(0.59f, 0.58f, 0.63f, 1.00f); has_color = true; }
if (strstr(item, "Script(U):")) { color = ImVec4(0.59f, 0.48f, 0.53f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Callbacks
if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
//if (strstr(item, "CodeCallback_")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Script errors
@ -157,21 +166,20 @@ void CGameConsole::Draw(const char* title)
if (strstr(item, "SCRIPT COMPILE")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, ".gnut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, ".nut #")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, " -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
if (strstr(item, "): -> ")) { color = ImVec4(1.00f, 0.00f, 0.00f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Script debug
if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "<><>GRX<><>")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "CALLSTACK")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "LOCALS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "*FUNCTION")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, "DIAGPRINTS")) { color = ImVec4(1.00f, 1.00f, 0.00f, 0.80f); has_color = true; }
if (strstr(item, " File : ")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
if (strstr(item, "<><>GRX<><>")) { color = ImVec4(0.00f, 0.30f, 1.00f, 1.00f); has_color = true; }
///////////////////////////////////////////////////////////////////
// Filters
if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
///////////////////////////////////////////////////////////////////
//if (strstr(item, ") -> ")) { color = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); has_color = true; }
if (has_color) { ImGui::PushStyleColor(ImGuiCol_Text, color); }
ImGui::TextWrapped(item);
@ -190,7 +198,7 @@ void CGameConsole::Draw(const char* title)
///////////////////////////////////////////////////////////////////////
// Console
bool reclaim_focus = false;
ImGui::PushItemWidth(750);
ImGui::PushItemWidth(footer_width_to_reserve - 80);
if (ImGui::IsWindowAppearing()) { ImGui::SetKeyboardFocusHere(); }
ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory;

View File

@ -133,7 +133,7 @@ void HexDump(const char* szHeader, int nFunc, const void* pData, int nSize)
// Add timestamp
logger->set_level(spdlog::level::trace);
logger->set_pattern("%v [%H:%M:%S.%f]");
logger->set_pattern("%v [%H:%M:%S.%f]\n");
logger->trace("---------------------------------------------------------");
// Disable EOL and create block header