diff --git a/Client/common/include/Exceptions.h b/Client/common/include/Exceptions.h new file mode 100644 index 0000000..ce51df3 --- /dev/null +++ b/Client/common/include/Exceptions.h @@ -0,0 +1,126 @@ +#ifndef COMMON_EXCEPTIONS_H +#define COMMON_EXCEPTIONS_H + +#include +#include + +namespace Exceptions { + + namespace Core { + + namespace Exceptions { + class RuntimeException : public std::runtime_error + { + public: + explicit RuntimeException(const std::string &msg) : + std::runtime_error(msg.c_str()) + { } + + explicit RuntimeException(const char *msg) : + std::runtime_error(msg) + { } + }; + + class DetourException : public RuntimeException + { + public: + explicit DetourException(const std::string &msg) : + RuntimeException(msg.c_str()) + { } + + explicit DetourException(const char *msg) : + RuntimeException(msg) + { } + }; + + class GenericWinAPIException : public std::runtime_error + { + DWORD last_error_; + + public: + explicit GenericWinAPIException(const std::string &msg) : + std::runtime_error(msg.c_str()), last_error_(GetLastError()) + { } + + explicit GenericWinAPIException(const char *msg) : + std::runtime_error(msg), last_error_(GetLastError()) + { } + + virtual DWORD get_last_error() const + { + return last_error_; + } + }; + + class ModuleNotFoundException : public GenericWinAPIException + { + public: + explicit ModuleNotFoundException(const std::string &msg) : + GenericWinAPIException(msg) + { } + + explicit ModuleNotFoundException(const char *msg) : + GenericWinAPIException(msg) + { } + }; + + class ProcAddressNotFoundException : public GenericWinAPIException + { + public: + explicit ProcAddressNotFoundException(const std::string &msg) : + GenericWinAPIException(msg) + { } + + explicit ProcAddressNotFoundException(const char *msg) : + GenericWinAPIException(msg) + { } + }; + + class COMInterfaceException : public RuntimeException + { + HRESULT hresult_; + + public: + explicit COMInterfaceException(const std::string &msg, HRESULT result) : + RuntimeException(msg), hresult_(result) + { } + + explicit COMInterfaceException(const char *msg, HRESULT result) : + RuntimeException(msg), hresult_(result) + { } + + HRESULT hresult() const + { + return hresult_; + } + }; + + class DXAPIException : public COMInterfaceException + { + public: + explicit DXAPIException(const std::string &msg, HRESULT result) : + COMInterfaceException(msg, result) + { } + + explicit DXAPIException(const char *msg, HRESULT result) : + COMInterfaceException(msg, result) + { } + }; + + class ARCException : public COMInterfaceException + { + public: + explicit ARCException(const std::string &msg, HRESULT result) : + COMInterfaceException(msg, result) + { } + + explicit ARCException(const char *msg, HRESULT result) : + COMInterfaceException(msg, result) + { } + }; + }; + + }; + +}; +#endif \ No newline at end of file diff --git a/Client/common/include/Types.h b/Client/common/include/Types.h new file mode 100644 index 0000000..8c33616 --- /dev/null +++ b/Client/common/include/Types.h @@ -0,0 +1,25 @@ +#ifndef COMMON_TYPES_H +#define COMMON_TYPES_H + +namespace Types { + // Enteros sin signo (Unsigned) + typedef unsigned char UInt8; // 1 byte + typedef unsigned short UInt16; // 2 bytes + typedef unsigned int UInt32; // 4 bytes (Cambiado long por int para asegurar 32bits) + typedef unsigned long long UInt64; // 8 bytes + + // Enteros con signo (Signed) + typedef signed char SInt8; + typedef signed short SInt16; + typedef signed int SInt32; + typedef signed long long SInt64; + + // Números de coma flotante + typedef float Float32; + typedef double Float64; + + // Alias útiles para punteros de memoria + typedef uintptr_t RawAddr; +} + +#endif \ No newline at end of file diff --git a/Client/src/DirectXHook.h b/Client/src/DirectXHook.h new file mode 100644 index 0000000..0c4da50 --- /dev/null +++ b/Client/src/DirectXHook.h @@ -0,0 +1,45 @@ +#ifndef H_DIRECT3D11 +#define H_DIRECT3D11 + +#include +#include + +namespace hDirect3D11 { + class Direct3D11 { + public: + std::vector vtable_methods; + + Direct3D11() { + ID3D11Device* pDevice = nullptr; + ID3D11DeviceContext* pContext = nullptr; + IDXGISwapChain* pSwapChain = nullptr; + + D3D_FEATURE_LEVEL featureLevel = D3D_FEATURE_LEVEL_11_0; + DXGI_SWAP_CHAIN_DESC scd = {}; + scd.BufferCount = 1; + scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; + scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + scd.OutputWindow = GetForegroundWindow(); + scd.SampleDesc.Count = 1; + scd.Windowed = TRUE; + scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; + + if (SUCCEEDED(D3D11CreateDeviceAndSwapChain(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, 0, &featureLevel, 1, D3D11_SDK_VERSION, &scd, &pSwapChain, &pDevice, nullptr, &pContext))) { + uintptr_t* vtable = *(uintptr_t**)pSwapChain; + for (int i = 0; i < 150; i++) { + vtable_methods.push_back(vtable[i]); + } + pSwapChain->Release(); + pDevice->Release(); + pContext->Release(); + } + } + + uintptr_t* vtable() { return vtable_methods.data(); } + }; +} + +namespace hDXGI { + enum Index { Present = 8 }; +} +#endif \ No newline at end of file diff --git a/Client/src/Hooks/Direct3D11.h b/Client/src/Hooks/Direct3D11.h new file mode 100644 index 0000000..4dd22a6 --- /dev/null +++ b/Client/src/Hooks/Direct3D11.h @@ -0,0 +1,83 @@ +#include "DirectXHook.h" +#include + +// Definición de variables globales +HWND g_windowHandle = NULL; +ID3D11Device* g_d3d11Device = NULL; +ID3D11DeviceContext* g_d3d11Context = NULL; +IDXGISwapChain* g_d3d11SwapChain = NULL; +ID3D11RenderTargetView* g_mainRenderTargetView = NULL; +bool g_ShowMenu = false; +bool g_Initialized = false; + +namespace Hooks { + namespace DirectX { + + void Init() { + try { + auto d3d11 = std::make_unique(); + uintptr_t* vtable = d3d11->vtable(); + + spdlog::info("[F4MP] Hooking DXGI Present..."); + + swapChainPresent11Hook.apply(vtable[hDXGI::Present], [](IDXGISwapChain* chain, UINT SyncInterval, UINT Flags) -> HRESULT { + static std::once_flag flag; + std::call_once(flag, [&chain]() { + g_d3d11SwapChain = chain; + if (SUCCEEDED(chain->GetDevice(__uuidof(ID3D11Device), (void**)&g_d3d11Device))) { + Pre_Render(chain); + g_Initialized = true; + } + }); + + Render(); + return swapChainPresent11Hook.call_orig(chain, SyncInterval, Flags); + }); + } + catch (const std::exception& e) { + spdlog::error("[F4MP] DX11 Hook Error: {}", e.what()); + } + } + + void Pre_Render(IDXGISwapChain* swapChain) { + swapChain->GetDevice(__uuidof(ID3D11Device), (void**)&g_d3d11Device); + g_d3d11Device->GetImmediateContext(&g_d3d11Context); + + DXGI_SWAP_CHAIN_DESC sd; + swapChain->GetDesc(&sd); + g_windowHandle = sd.OutputWindow; + + // Hook al WndProc para el ratón + OriginalWndProcHandler = (WNDPROC)SetWindowLongPtr(g_windowHandle, GWLP_WNDPROC, (LONG_PTR)hWndProc); + + ImGui::CreateContext(); + ImGui_ImplWin32_Init(g_windowHandle); + ImGui_ImplDX11_Init(g_d3d11Device, g_d3d11Context); + + ID3D11Texture2D* pBackBuffer; + swapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer); + g_d3d11Device->CreateRenderTargetView(pBackBuffer, NULL, &g_mainRenderTargetView); + pBackBuffer->Release(); + } + + void Render() { + if (!g_Initialized) return; + + ImGui_ImplDX11_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + if (g_ShowMenu) { + ImGui::Begin("F4MP Next-Gen Console", &g_ShowMenu); + ImGui::Text("F4MP Experimental Multiplayer Mod"); + ImGui::Separator(); + if (ImGui::Button("Unload Mod")) { /* Lógica de salida */ } + ImGui::End(); + } + + ImGui::Render(); + g_d3d11Context->OMSetRenderTargets(1, &g_mainRenderTargetView, NULL); + ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData()); + } + } +} \ No newline at end of file