Skip to content

Commit

Permalink
Add optional logging to chat ability
Browse files Browse the repository at this point in the history
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
  • Loading branch information
povargek committed Sep 15, 2024
1 parent cd52bec commit 3bf9f81
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 25 deletions.
2 changes: 0 additions & 2 deletions .github/workflows/win32-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ name: win32-build
on:
push:
branches: [ "main" ]
tags:
- 'v*.*.*'
pull_request:
branches: [ "main" ]

Expand Down
63 changes: 57 additions & 6 deletions src/Plugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,21 @@
#include <iomanip>
#include <sstream>


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;
Expand All @@ -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();
Expand All @@ -35,17 +50,27 @@ 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()();
}

void Plugin::CMessages_AddBigMessageHooked(const decltype(hookCMessages_AddBigMessageHooked)& hook,
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;
}
Expand Down Expand Up @@ -80,6 +105,26 @@ void Plugin::MemSet(LPVOID lpAddr, int iVal, size_t dwSize)
/// <summary>
/// DEBUG Helpers
/// </summary>
///
///
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<LPBYTE>(&nResult),
&dwBufferSize);
if (ERROR_SUCCESS == nError)
{
nValue = nResult;
}
return nError;
}


void Plugin::PrintBin(std::string str)
{
Expand All @@ -91,17 +136,24 @@ void Plugin::PrintBin(std::string str)
}

/// <summary>
/// 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
/// </summary>
/// <param name="dwLevel">Message Log Level</param>
/// <param name="dwColor">Message Color</param>
/// <param name="sFmtMessage">Message to format</param>
/// <param name="">Args...</param>
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));
Expand All @@ -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
}
16 changes: 15 additions & 1 deletion src/Plugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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<CTimerProto> hookCTimerUpdate{ reinterpret_cast<void*>(0x561B10) };
Expand All @@ -31,6 +43,8 @@ class Plugin {
/// Debug helpers
/// </summary>

LONG GetDWORDRegKey(HKEY hKey, const std::string& strValueName, DWORD& nValue, DWORD nDefaultValue);

void PrintBin(std::string str);

inline void InitConsole()
Expand Down
46 changes: 30 additions & 16 deletions src/PluginRPC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@

#include "misc.h"


template <typename T>
std::string readWithSize(RakNet::BitStream& bs, size_t max = 0) {
T size;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -97,15 +97,17 @@ bool PluginRPC::ApplyAnimation(unsigned char& id, RakNet::BitStream* bs) {
std::string sAnimLib = readWithSize<uint8_t>(*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;
}

std::string sAnimName = readWithSize<uint8_t>(*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;
}
Expand All @@ -128,15 +130,17 @@ bool PluginRPC::ApplyActorAnimation(unsigned char& id, RakNet::BitStream* bs) {
std::string sAnimLib = readWithSize<uint8_t>(*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;
}

std::string sAnimName = readWithSize<uint8_t>(*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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -231,21 +237,24 @@ 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;
}

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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
Binary file modified src/Resource.rc
Binary file not shown.

0 comments on commit 3bf9f81

Please sign in to comment.