From 3bf9f81c62060efc14b890e7213b536bc01b75d9 Mon Sep 17 00:00:00 2001 From: Alex Golubev <9640178+povargek@users.noreply.github.com> Date: Sun, 15 Sep 2024 23:02:16 +0300 Subject: [PATCH] Add optional logging to chat ability Displayed ONLY IF you add a registry key: HKEY_CURRENT_USER\SOFTWARE\SAMP Key 'MiNotifyLevelFlags' DWORD LogLevel::Disabled - Logging disabled (default) LogLevel::InitNotify - Show only message about plugin loaded LogLevel::DetectNotify - Log all detections --- .github/workflows/win32-build.yml | 2 - src/Plugin.cpp | 63 +++++++++++++++++++++++++++--- src/Plugin.h | 16 +++++++- src/PluginRPC.cpp | 46 ++++++++++++++-------- src/Resource.rc | Bin 4654 -> 4654 bytes 5 files changed, 102 insertions(+), 25 deletions(-) diff --git a/.github/workflows/win32-build.yml b/.github/workflows/win32-build.yml index a6bcb75..4bea9c3 100644 --- a/.github/workflows/win32-build.yml +++ b/.github/workflows/win32-build.yml @@ -3,8 +3,6 @@ name: win32-build on: push: branches: [ "main" ] - tags: - - 'v*.*.*' pull_request: branches: [ "main" ] diff --git a/src/Plugin.cpp b/src/Plugin.cpp index e7429aa..6725f2f 100644 --- a/src/Plugin.cpp +++ b/src/Plugin.cpp @@ -6,9 +6,21 @@ #include #include - +extern DWORD Debug::dwLogLevel; Plugin::Plugin(HMODULE hndl) : hModule(hndl) { + HKEY hKey; + LONG lRes = RegOpenKeyExA(HKEY_CURRENT_USER, REG_CONFIG_TREE, 0, KEY_READ, &hKey); + + if (SUCCEEDED(lRes)) { + + DWORD dwNotifyFlagsRaw; + + if (SUCCEEDED(GetDWORDRegKey(hKey, REG_CONFIG_KEY, dwNotifyFlagsRaw, 0))) { + Debug::dwLogLevel = dwNotifyFlagsRaw; // Set log level + } + } + InitConsole(); using namespace std::placeholders; @@ -21,6 +33,9 @@ Plugin::Plugin(HMODULE hndl) : hModule(hndl) { void Plugin::mainloop(const decltype(hookCTimerUpdate)& hook) { static bool inited = false; + static bool msgShow = false; + static DWORD64 dwTickShow = 0; + if (!inited && rakhook::initialize()) { // GTA SA Patches what required SA:MP InstallPatchAddHospitalRestartPoint(); @@ -35,9 +50,19 @@ void Plugin::mainloop(const decltype(hookCTimerUpdate)& hook) { rakhook::on_receive_rpc += std::bind(&PluginRPC::ShowPlayerDialog, &RPC, _1, _2); rakhook::on_receive_rpc += std::bind(&PluginRPC::InitMenu, &RPC, _1, _2); + dwTickShow = GetTickCount64(); inited = true; } + + if (inited && GetTickCount64() > (dwTickShow + 3000) && !msgShow) { // dirty hack. Can't emulate RPC when not connected + Plugin::AddChatMessageDebug(Debug::LogLevel::InitNotify, 0xFFFFFFFF, "MiTurboFix by ? inited. THIS MESSAGE CAN BE DISABLED. You need remove registry key:"); + Plugin::AddChatMessageDebug(Debug::LogLevel::InitNotify, 0xFFFFFFFF, "HKEY_CURRENT_USER//%s key '%s'", REG_CONFIG_TREE, REG_CONFIG_KEY); + + msgShow = true; + } + + return hook.get_trampoline()(); } @@ -45,7 +70,7 @@ void Plugin::CMessages_AddBigMessageHooked(const decltype(hookCMessages_AddBigMe char* text, uint32_t duration, uint16_t style) { if (style > 6) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": GameText bad style = %d, strlen = %d", style, strlen(text)); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, 0xFFFFFFFF, __FUNCTION__ ": GameText bad style = %d, strlen = %d", style, strlen(text)); return; } @@ -80,6 +105,26 @@ void Plugin::MemSet(LPVOID lpAddr, int iVal, size_t dwSize) /// /// DEBUG Helpers /// +/// +/// +LONG Plugin::GetDWORDRegKey(HKEY hKey, const std::string& strValueName, DWORD& nValue, DWORD nDefaultValue) +{ + nValue = nDefaultValue; + DWORD dwBufferSize(sizeof(DWORD)); + DWORD nResult(0); + LONG nError = ::RegQueryValueExA(hKey, + strValueName.c_str(), + 0, + NULL, + reinterpret_cast(&nResult), + &dwBufferSize); + if (ERROR_SUCCESS == nError) + { + nValue = nResult; + } + return nError; +} + void Plugin::PrintBin(std::string str) { @@ -91,17 +136,24 @@ void Plugin::PrintBin(std::string str) } /// -/// Add a debug chat message + WinDbg Message. Displayed ONLY IF you compile a DEBUG build +/// Add a debug chat message + WinDbg Message. Displayed ONLY IF you add a registry key: +/// HKEY_CURRENT_USER\SOFTWARE\SAMP Key 'MiNotifyLevelFlags' DWORD +/// LogLevel::Disabled - Logging disabled +/// LogLevel::InitNotify - Show only message about plugin loaded +/// LogLevel::DetectNotify - Log all detections /// +/// Message Log Level /// Message Color /// Message to format /// Args... -void Plugin::AddChatMessageDebug(std::uint32_t dwColor, std::string sFmtMessage, ...) +void Plugin::AddChatMessageDebug(Debug::LogLevel dwLevel, std::uint32_t dwColor, std::string sFmtMessage, ...) { -#ifdef _DEBUG if (!rakhook::initialized) return; + if (!(dwLevel & Debug::dwLogLevel)) + return; + char szBuffer[144]; memset(szBuffer, 0x0, sizeof(szBuffer)); @@ -120,5 +172,4 @@ void Plugin::AddChatMessageDebug(std::uint32_t dwColor, std::string sFmtMessage, rakhook::emul_rpc(ScriptRPC::ClientMessage, bs); OutputDebugStringA(std::string(std::string("[MiTurboFix] ") + sMessage).data()); -#endif } diff --git a/src/Plugin.h b/src/Plugin.h index 82b08e1..5149a66 100644 --- a/src/Plugin.h +++ b/src/Plugin.h @@ -7,6 +7,18 @@ using CTimerProto = void( __cdecl* )(); using CMessagesProto = void(__cdecl*)(char* text, uint32_t duration, uint16_t style); +constexpr auto REG_CONFIG_TREE = "SOFTWARE\\SAMP"; +constexpr auto REG_CONFIG_KEY = "MiNotifyLevelFlags"; + +namespace Debug { + enum LogLevel { + Disabled = 0, // default + InitNotify = 1 << 0, + DetectNotify = 1 << 1, + }; + + static DWORD dwLogLevel; +}; class Plugin { public: @@ -17,7 +29,7 @@ class Plugin { void MemSet(LPVOID lpAddr, int iVal, size_t dwSize); - static void AddChatMessageDebug(std::uint32_t dwColor, std::string sFmrMessage, ...); // DEBUG + static void AddChatMessageDebug(Debug::LogLevel dwLevel, std::uint32_t dwColor, std::string sFmtMessage, ...); // DEBUG private: PluginRPC RPC; kthook::kthook_simple hookCTimerUpdate{ reinterpret_cast(0x561B10) }; @@ -31,6 +43,8 @@ class Plugin { /// Debug helpers /// + LONG GetDWORDRegKey(HKEY hKey, const std::string& strValueName, DWORD& nValue, DWORD nDefaultValue); + void PrintBin(std::string str); inline void InitConsole() diff --git a/src/PluginRPC.cpp b/src/PluginRPC.cpp index 51eb9e4..85b85a5 100644 --- a/src/PluginRPC.cpp +++ b/src/PluginRPC.cpp @@ -13,7 +13,6 @@ #include "misc.h" - template std::string readWithSize(RakNet::BitStream& bs, size_t max = 0) { T size; @@ -46,7 +45,8 @@ bool BitStreamIgnoreString(RakNet::BitStream& bs, size_t max = 0) { size_t tokenLen = (maxLineLen > 0 && token.length() > maxLineLen) ? maxLineLen : token.length(); if (maxLineLen > 0 && token.length() > maxLineLen) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad listitem len = %d", token.length()); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad listitem len = %d", token.length()); } return token.substr(0, tokenLen); @@ -97,7 +97,8 @@ bool PluginRPC::ApplyAnimation(unsigned char& id, RakNet::BitStream* bs) { std::string sAnimLib = readWithSize(*bs, iAnimLibMaxLen); if (sAnimLib.length() < 1 || sAnimLib.length() > iAnimLibMaxLen) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad bAnimLibLength = %d", iAnimLibMaxLen); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad bAnimLibLength = %d", iAnimLibMaxLen); return false; } @@ -105,7 +106,8 @@ bool PluginRPC::ApplyAnimation(unsigned char& id, RakNet::BitStream* bs) { std::string sAnimName = readWithSize(*bs, iAnimNameMaxLen); if (sAnimName.length() < 1 || sAnimName.length() > iAnimNameMaxLen) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad bAnimNameLength = %d", iAnimNameMaxLen); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad bAnimNameLength = %d", iAnimNameMaxLen); return false; } @@ -128,7 +130,8 @@ bool PluginRPC::ApplyActorAnimation(unsigned char& id, RakNet::BitStream* bs) { std::string sAnimLib = readWithSize(*bs, iAnimLibMaxLen); if (sAnimLib.length() < 1 || sAnimLib.length() > iAnimLibMaxLen) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad bAnimLibLength = %d", iAnimLibMaxLen); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad bAnimLibLength = %d", iAnimLibMaxLen); return false; } @@ -136,7 +139,8 @@ bool PluginRPC::ApplyActorAnimation(unsigned char& id, RakNet::BitStream* bs) { std::string sAnimName = readWithSize(*bs, iAnimNameMaxLen); if (sAnimName.length() < 1 || sAnimName.length() > iAnimNameMaxLen) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad bAnimNameLength = %d", iAnimNameMaxLen); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad bAnimNameLength = %d", iAnimNameMaxLen); return false; } @@ -202,7 +206,8 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { bs->Read(bMenuID); if (bMenuID >= Menu::MAX_MENUS) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad bMenuID = %d", bMenuID); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad bMenuID = %d", bMenuID); return false; } @@ -211,7 +216,8 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { bs->Read(szText, Menu::MAX_MENU_LINE); if (!String::ValidateLen(szText, Menu::MAX_MENU_LINE)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuTitle length = %d", strnlen_s(szText, Menu::MAX_MENU_LINE)); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuTitle length = %d", strnlen_s(szText, Menu::MAX_MENU_LINE)); return false; } @@ -231,7 +237,8 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { bs->Read(szText, Menu::MAX_MENU_LINE); if (!String::ValidateLen(szText, Menu::MAX_MENU_LINE)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuHeaderCol1 length = %d", strnlen_s(szText, Menu::MAX_MENU_LINE)); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuHeaderCol1 length = %d", strnlen_s(szText, Menu::MAX_MENU_LINE)); return false; } @@ -239,13 +246,15 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { unsigned char byteRowCount; if (!bs->Read(byteRowCount)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad can't read MenuRowCountCol1"); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad can't read MenuRowCountCol1"); return false; } if (byteRowCount > Menu::MAX_MENU_ITEMS) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCountCol1 = %d", byteRowCount); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCountCol1 = %d", byteRowCount); return false; } @@ -254,7 +263,8 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { bs->Read(szText, Menu::MAX_MENU_LINE); if (!String::ValidateLen(szText, Menu::MAX_MENU_LINE)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCol1(%d) length = %d", i, strnlen_s(szText, Menu::MAX_MENU_LINE)); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCol1(%d) length = %d", i, strnlen_s(szText, Menu::MAX_MENU_LINE)); return false; } @@ -264,19 +274,22 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { bs->Read(szText, Menu::MAX_MENU_LINE); if (!String::ValidateLen(szText, Menu::MAX_MENU_LINE)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuHeaderCol2 length = %d", strnlen_s(szText, Menu::MAX_MENU_LINE)); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuHeaderCol2 length = %d", strnlen_s(szText, Menu::MAX_MENU_LINE)); return false; } if (!bs->Read(byteRowCount)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad can't read MenuRowCountCol1"); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad can't read MenuRowCountCol1"); return false; } if (byteRowCount > Menu::MAX_MENU_ITEMS) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCountCol2 = %d", byteRowCount); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCountCol2 = %d", byteRowCount); return false; } @@ -285,7 +298,8 @@ bool PluginRPC::InitMenu(unsigned char& id, RakNet::BitStream* bs) { bs->Read(szText, Menu::MAX_MENU_LINE); if (!String::ValidateLen(szText, Menu::MAX_MENU_LINE)) { - Plugin::AddChatMessageDebug(0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCol2(%d) length = %d", i, strnlen_s(szText, Menu::MAX_MENU_LINE)); + Plugin::AddChatMessageDebug(Debug::LogLevel::DetectNotify, + 0xFFFFFFFF, __FUNCTION__ ": bad MenuRowCol2(%d) length = %d", i, strnlen_s(szText, Menu::MAX_MENU_LINE)); return false; } diff --git a/src/Resource.rc b/src/Resource.rc index 07be688c9709b4a338b9e77c5336f2fd0c6b7382..7a7e9283dab687e8705dd2a6fd2afb42e6eaae5b 100644 GIT binary patch delta 42 vcmZ3dvQA}#8waE5WOoijM$^re9O2AB>LPb76HrW%OMG$#pU~zCzHQ6^39t+t delta 42 vcmZ3dvQA}#8waDwWOoijMw88z9O2AB>LPb76HrW%OMG$#pU~zCzHQ6^2~P|d