Replace IPanel::PaintTraverse hook with IEngineVGui::Paint.

* Add example watermark text in bottom-right corner.

Signed-off-by: aixxe <me@aixxe.net>
This commit is contained in:
aixxe 2016-12-23 12:13:39 +00:00
parent f94aaad6c3
commit c1738ce42b
6 changed files with 90 additions and 22 deletions

View File

@ -0,0 +1,26 @@
#pragma once
enum VGuiPanel_t {
PANEL_ROOT = 0,
PANEL_GAMEUIDLL,
PANEL_CLIENTDLL,
PANEL_TOOLS,
PANEL_INGAMESCREENS,
PANEL_GAMEDLL,
PANEL_CLIENTDLL_TOOLS
};
enum PaintMode_t {
PAINT_UIPANELS = (1 << 0),
PAINT_INGAMEPANELS = (1 << 1),
PAINT_CURSOR = (1 << 2)
};
class IEngineVGui {
public:
virtual ~IEngineVGui(void) {};
virtual VPANEL GetPanel(VGuiPanel_t type) = 0;
virtual bool IsGameUIVisible() = 0;
};
extern IEngineVGui* enginevgui;

View File

@ -31,6 +31,7 @@
#include "Interfaces/ICvar.h"
#include "Interfaces/IPanel.h"
#include "Interfaces/ISurface.h"
#include "Interfaces/IEngineVGui.h"
#include "Interfaces/IVModelInfo.h"
#include "Interfaces/ILauncherMgr.h"
#include "Interfaces/IInputSystem.h"

View File

@ -24,6 +24,7 @@
ICvar* cvar = nullptr;
IPanel* panel = nullptr;
ISurface* matsurface = nullptr;
IEngineVGui* enginevgui = nullptr;
IVModelInfoClient* modelinfo = nullptr;
ILauncherMgr* launchermgr = nullptr;
IInputSystem* inputsystem = nullptr;
@ -41,9 +42,12 @@ CGlobalVarsBase* globalvars = nullptr;
CRC32_ProcessBufferFn CRC32_ProcessBuffer = NULL;
StartDrawing_t StartDrawing = NULL;
FinishDrawing_t FinishDrawing = NULL;
std::unique_ptr<VMTHook> sdl_hook;
std::unique_ptr<VMTHook> panel_hook;
std::unique_ptr<VMTHook> clientdll_hook;
std::unique_ptr<VMTHook> enginevgui_hook;
std::unique_ptr<VMTHook> modelrender_hook;
std::unique_ptr<VMTHook> inputinternal_hook;
@ -52,6 +56,7 @@ extern "C" void __attribute__((constructor)) css_basehook_open() {
cvar = GetInterface<ICvar>("bin/libvstdlib.so", "VEngineCvar0");
panel = GetInterface<IPanel>("bin/vgui2.so", "VGUI_Panel0");
matsurface = GetInterface<ISurface>("bin/vguimatsurface.so", "VGUI_Surface0");
enginevgui = GetInterface<IEngineVGui>("bin/engine.so", "VEngineVGui0");
modelinfo = GetInterface<IVModelInfoClient>("bin/engine.so", "VModelInfoClient0");
inputsystem = GetInterface<IInputSystem>("bin/inputsystem.so", "InputSystemVersion0");
inputinternal = GetInterface<IInputInternal>("bin/vgui2.so", "VGUI_InputInternal0");
@ -73,9 +78,18 @@ extern "C" void __attribute__((constructor)) css_basehook_open() {
clientdll_hook->HookFunction(reinterpret_cast<void*>(Hooks::CreateMove), 21);
clientdll_hook->HookFunction(reinterpret_cast<void*>(Hooks::FrameStageNotify), 35);
// Hook 'PaintTraverse' from IPanel.
panel_hook = std::make_unique<VMTHook>(panel);
panel_hook->HookFunction(reinterpret_cast<void*>(Hooks::PaintTraverse), 42);
// Scan for 'StartDrawing' and 'FinishDrawing' from CMatSystemSurface.
StartDrawing = reinterpret_cast<StartDrawing_t>(
FindPattern("bin/vguimatsurface.so", "\x55\x89\xE5\x53\x83\xEC\x74\x80\x3D\x00\x00\x00\x00\x00", "xxxxxxxxx????x")
);
FinishDrawing = reinterpret_cast<FinishDrawing_t>(
FindPattern("bin/vguimatsurface.so", "\x55\x89\xE5\x53\x83\xEC\x24\xC7\x04\x00\x00\x00\x00\x00\xE8\x00\x00\x00\x00\xA1", "xxxxxxxxx????xx????x")
);
// Hook 'Paint' from IEngineVGui.
enginevgui_hook = std::make_unique<VMTHook>(enginevgui);
enginevgui_hook->HookFunction(reinterpret_cast<void*>(Hooks::Paint), 14);
// Hook 'DrawModelExecute' from IVModelRender.
modelrender_hook = std::make_unique<VMTHook>(modelrender);

View File

@ -3,20 +3,24 @@
#include "../Basehook.h"
#include "../GUI/GUI.h"
// Extra functions neccessary for proper engine drawing.
typedef void (*StartDrawing_t) (ISurface*);
typedef void (*FinishDrawing_t) (ISurface*);
namespace Hooks {
// ILauncherMgr
void PumpWindowsMessageLoop(ILauncherMgr*);
void ShowPixels(ILauncherMgr*, CShowPixelsParams*);
// IBaseClientDLL
void CreateMove(IBaseClientDLL*, int, float, bool);
void FrameStageNotify(IBaseClientDLL*, ClientFrameStage_t);
// IPanel
void PaintTraverse(IPanel*, VPANEL, bool, bool);
// IEngineVGui
void Paint(IEngineVGui*, PaintMode_t);
// IVModelRender
void DrawModelExecute(IVModelRender*, DrawModelState_t const&, ModelRenderInfo_t const&, matrix3x4_t*);
// ILauncherMgr
void PumpWindowsMessageLoop(ILauncherMgr*);
void ShowPixels(ILauncherMgr*, CShowPixelsParams*);
// IInputInternal
void SetKeyCodeState(IInputInternal*, KeyCode, bool);
@ -24,7 +28,7 @@ namespace Hooks {
}
extern std::unique_ptr<VMTHook> sdl_hook;
extern std::unique_ptr<VMTHook> panel_hook;
extern std::unique_ptr<VMTHook> clientdll_hook;
extern std::unique_ptr<VMTHook> enginevgui_hook;
extern std::unique_ptr<VMTHook> modelrender_hook;
extern std::unique_ptr<VMTHook> inputinternal_hook;

34
src/Hooks/Paint.cpp Normal file
View File

@ -0,0 +1,34 @@
#include "Hooks.h"
extern StartDrawing_t StartDrawing;
extern FinishDrawing_t FinishDrawing;
typedef void (*Paint_t) (IEngineVGui*, PaintMode_t);
void Hooks::Paint(IEngineVGui* thisptr, PaintMode_t mode) {
// Get the original function and store it statically.
static Paint_t oPaint = enginevgui_hook->GetOriginalFunction<Paint_t>(14);
// Call original 'IEngineVGui::Paint'.
oPaint(thisptr, mode);
if (mode & PaintMode_t::PAINT_UIPANELS) {
StartDrawing(matsurface);
// Set watermark text.
const wchar_t* watermark = L"cstrike-basehook-linux";
// Set position of watermark text. (bottom-right)
int width = 0, height = 0, wide = 0, tall = 0;
engine->GetScreenSize(width, height);
matsurface->GetTextSize(37, watermark, wide, tall);
// Do stuff here then call FinishDrawing.
matsurface->DrawSetTextColor(Color(150, 150, 255));
matsurface->DrawSetTextPos((width - wide) - 15, (height - tall) - 15);
matsurface->DrawSetTextFont(37);
matsurface->DrawPrintText(L"cstrike-basehook-linux", 23);
FinishDrawing(matsurface);
}
}

View File

@ -1,11 +0,0 @@
#include "Hooks.h"
typedef void (*PaintTraverse_t) (IPanel*, VPANEL, bool, bool);
void Hooks::PaintTraverse(IPanel* thisptr, VPANEL vpanel, bool force_repaint, bool allow_force) {
// Get the original function and store it statically.
static PaintTraverse_t oPaintTraverse = panel_hook->GetOriginalFunction<PaintTraverse_t>(42);
// Call original 'IPanel::PaintTraverse'.
oPaintTraverse(thisptr, vpanel, force_repaint, allow_force);
}