Skip to content

Commit

Permalink
Fix MsgBox for GameUI.
Browse files Browse the repository at this point in the history
  • Loading branch information
hzqst committed Feb 5, 2024
1 parent f882b9b commit 9e2bb28
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 1 deletion.
Binary file modified Build/svencoop_schinese/resource/gameui_english.txt
Binary file not shown.
172 changes: 171 additions & 1 deletion Plugins/VGUI2Extension/GameUI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,17 @@ void __fastcall GameUI_Panel_Init(vgui::Panel* pthis, int dummy, int x, int y, i
}
}

void __fastcall GameUI_MessageBox_ApplySchemeSettings_Panel_SetSize(vgui::Panel* pthis, int dummy, int width, int height)
{
int basewidth = width - 100;
int baseheight = height - 100;

width = basewidth + g_pVGuiSchemeManager2->GetProportionalScaledValue(100);
height = baseheight + g_pVGuiSchemeManager2->GetProportionalScaledValue(100);

gPrivateFuncs.GameUI_Panel_SetSize(pthis, 0, width, height);
}

/*
====================================================================
GameUI inline hook
Expand Down Expand Up @@ -2615,6 +2626,166 @@ void GameUI_FillAddress(void)
gPrivateFuncs.GameUI_PropertySheet_HasHotkey = (decltype(gPrivateFuncs.GameUI_PropertySheet_HasHotkey))gPrivateFuncs.Sheet_vftable[73];
}

if (1)
{
const char sigs1[] = "MessageBoxText";
auto MessageBoxText_String = g_pMetaHookAPI->SearchPattern(GameUIRdataBase, GameUIRdataSize, sigs1, sizeof(sigs1) - 1);
if (!MessageBoxText_String)
{
MessageBoxText_String = g_pMetaHookAPI->SearchPattern(GameUIDataBase, GameUIDataSize, sigs1, sizeof(sigs1) - 1);
}
Sig_VarNotFound(MessageBoxText_String);
char pattern[] = "\x68\x2A\x2A\x2A\x2A\x68\x2A\x2A\x2A\x2A";
*(DWORD*)(pattern + 1) = (DWORD)MessageBoxText_String;
auto MessageBoxText_PushString = g_pMetaHookAPI->SearchPattern(GameUITextBase, GameUITextSize, pattern, sizeof(pattern) - 1);
Sig_VarNotFound(MessageBoxText_PushString);

g_pMetaHookAPI->DisasmRanges(MessageBoxText_PushString, 0x80, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) {

auto pinst = (cs_insn*)inst;

if (address[0] == 0xE8 && instCount <= 8)
{
gPrivateFuncs.MessageBox_ctor = (decltype(gPrivateFuncs.MessageBox_ctor))GetCallAddress(address);

return TRUE;
}

if (address[0] == 0xCC)
return TRUE;

if (pinst->id == X86_INS_RET)
return TRUE;

return FALSE;

}, 0, NULL);

Sig_FuncNotFound(MessageBox_ctor);

typedef struct
{
PVOID GameUIRdataBase;
ULONG GameUIRdataSize;

PVOID GameUITextBase;
ULONG GameUITextSize;

}MessageBoxSearchContext;

MessageBoxSearchContext ctx = { 0 };

ctx.GameUIRdataBase = GameUIRdataBase;
ctx.GameUIRdataSize = GameUIRdataSize;

ctx.GameUITextBase = GameUITextBase;
ctx.GameUITextSize = GameUITextSize;

g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.MessageBox_ctor, 0x300, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) {

auto pinst = (cs_insn*)inst;
auto ctx = (MessageBoxSearchContext*)context;

if (!gPrivateFuncs.MessageBox_vftable)
{
if (pinst->id == X86_INS_MOV &&
pinst->detail->x86.op_count == 2 &&
pinst->detail->x86.operands[0].type == X86_OP_MEM &&
pinst->detail->x86.operands[0].mem.disp == 0 &&
pinst->detail->x86.operands[1].type == X86_OP_IMM &&
((PUCHAR)pinst->detail->x86.operands[1].imm > (PUCHAR)ctx->GameUIRdataBase &&
(PUCHAR)pinst->detail->x86.operands[1].imm < (PUCHAR)ctx->GameUIRdataBase + ctx->GameUIRdataSize))
{
auto candidate = (PVOID*)pinst->detail->x86.operands[1].imm;
if (candidate[0] >= (PUCHAR)ctx->GameUITextBase && candidate[0] < (PUCHAR)ctx->GameUITextBase + ctx->GameUITextSize)
{
gPrivateFuncs.MessageBox_vftable = candidate;
}
}
}

if (gPrivateFuncs.MessageBox_vftable)
return TRUE;

if (address[0] == 0xCC)
return TRUE;

if (pinst->id == X86_INS_RET)
return TRUE;

return FALSE;

}, 0, & ctx);

Sig_FuncNotFound(MessageBox_vftable);

gPrivateFuncs.MessageBox_ApplySchemeSettings = (decltype(gPrivateFuncs.MessageBox_ApplySchemeSettings))gPrivateFuncs.MessageBox_vftable[0x13C/4];
}

if (g_iEngineType != ENGINE_GOLDSRC_HL25)
{
typedef struct
{
std::set<PVOID> insnSets_SetSize;

int instCount_Add64h;

}MessageBox_ApplySchemeSettings_SearchContext;

MessageBox_ApplySchemeSettings_SearchContext ctx = { };

g_pMetaHookAPI->DisasmRanges(gPrivateFuncs.MessageBox_ApplySchemeSettings, 0x300, [](void* inst, PUCHAR address, size_t instLen, int instCount, int depth, PVOID context) {

auto pinst = (cs_insn*)inst;
auto ctx = (MessageBox_ApplySchemeSettings_SearchContext*)context;

if (!ctx->instCount_Add64h &&
pinst->id == X86_INS_ADD &&
pinst->detail->x86.op_count == 2 &&
pinst->detail->x86.operands[0].type == X86_OP_REG &&
pinst->detail->x86.operands[1].type == X86_OP_IMM &&
pinst->detail->x86.operands[1].imm == 0x64)
{
ctx->instCount_Add64h = instCount;
}

if (address[0] == 0xE8 && ctx->instCount_Add64h && instCount > ctx->instCount_Add64h && instCount < ctx->instCount_Add64h + 10)
{
auto Candidate = GetCallAddress(address);

if (gPrivateFuncs.GameUI_Panel_SetSize == Candidate)
{
ctx->insnSets_SetSize.emplace(address);
}
else if (!gPrivateFuncs.GameUI_Panel_SetSize && VGUI2_IsPanelSetSize(Candidate))
{
gPrivateFuncs.GameUI_Panel_SetSize = (decltype(gPrivateFuncs.GameUI_Panel_SetSize))Candidate;
ctx->insnSets_SetSize.emplace(address);
}

return TRUE;
}

if (address[0] == 0xCC)
return TRUE;

if (pinst->id == X86_INS_RET)
return TRUE;

return FALSE;

}, 0, & ctx);

Sig_FuncNotFound(GameUI_Panel_SetSize);

for (auto insn : ctx.insnSets_SetSize)
{
auto addr = (PUCHAR)insn;
int rva = (PUCHAR)GameUI_MessageBox_ApplySchemeSettings_Panel_SetSize - (addr + 5);
g_pMetaHookAPI->WriteMemory(addr + 1, &rva, 4);
}
}

if (1)
{
const char sigs1[] = "GameMenuButton\0";
Expand Down Expand Up @@ -2977,7 +3148,6 @@ void GameUI_InstallHooks(void)
{
Install_InlineHook(GameUI_FocusNavGroup_GetCurrentFocus);
}

}

void GameUI_UninstallHooks(void)
Expand Down
4 changes: 4 additions & 0 deletions Plugins/VGUI2Extension/privatefuncs.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ typedef struct
void*(__fastcall* GameUI_KeyValues_ctor)(void* pthis, int dummy, const char* name);
void** GameUI_KeyValues_vftable;
bool(__fastcall* GameUI_KeyValues_LoadFromFile)(void* pthis, int dummy, IFileSystem* pFileSystem, const char* resourceName, const char* pathId);
void(__fastcall* GameUI_Panel_SetSize)(void* pthis, int dummy, int width, int height);
void *(__fastcall* Sheet_ctor)(void* pthis, int dummy, void* parent, const char *panelName);
void** Sheet_vftable;
int offset_propertySheet;
//void *(__fastcall*QueryBox_ctor)(void* pthis, int dummy, const char* title, const char* queryText, void* parent);
void *(__fastcall*MessageBox_ctor)(void* pthis, int dummy, const char *title, const char *text, void *parent);
void (__fastcall*MessageBox_ApplySchemeSettings)(void* pthis, int dummy, void *pScheme);
void** MessageBox_vftable;
void *(__fastcall*CCreateMultiplayerGameDialog_ctor)(void* pthis, int dummy, void* parent);
void *(__fastcall*CGameConsoleDialog_ctor)(void* pthis, int dummy);
void *(__fastcall*COptionsDialog_ctor)(void *pthis, int dummy, void *parent);
Expand Down

0 comments on commit 9e2bb28

Please sign in to comment.