diff --git a/Entity.cpp b/Entity.cpp new file mode 100644 index 0000000..cb179d1 --- /dev/null +++ b/Entity.cpp @@ -0,0 +1,53 @@ +#include "Entity.h" + +template +bool GetDataAddressWithOffset(const DWORD64& Address, DWORD Offset, T& Data) +{ + if (Address == 0) + return false; + + if (!ProcessMgr.ReadMemory(Address + Offset, Data)) + return false; + + return true; +} + +bool CEntity::UpdateController(const DWORD64& PlayerControllerAddress) +{ + if (PlayerControllerAddress == 0) + return false; + this->Controller.Address = PlayerControllerAddress; + + this->Pawn.Address = this->Controller.GetPlayerPawnAddress(); + + return true; +} + +bool CEntity::UpdatePawn(const DWORD64& PlayerPawnAddress) +{ + if (PlayerPawnAddress == 0) + return false; + this->Pawn.Address = PlayerPawnAddress; + + return true; +} + +DWORD64 PlayerController::GetPlayerPawnAddress() +{ + DWORD64 EntityPawnListEntry = 0; + DWORD64 EntityPawnAddress = 0; + + if (!GetDataAddressWithOffset(Address, Offset::Entity.PlayerPawn, this->Pawn)) + return 0; + + if (!ProcessMgr.ReadMemory(gGame.GetEntityListAddress(), EntityPawnListEntry)) + return 0; + + if (!ProcessMgr.ReadMemory(EntityPawnListEntry + 0x10 + 8 * ((Pawn & 0x7FFF) >> 9), EntityPawnListEntry)) + return 0; + + if (!ProcessMgr.ReadMemory(EntityPawnListEntry + 0x78 * (Pawn & 0x1FF), EntityPawnAddress)) + return 0; + + return EntityPawnAddress; +} \ No newline at end of file diff --git a/Entity.h b/Entity.h new file mode 100644 index 0000000..769df7a --- /dev/null +++ b/Entity.h @@ -0,0 +1,34 @@ +#pragma once +#include "Game.h" + +struct C_UTL_VECTOR +{ + DWORD64 Count = 0; + DWORD64 Data = 0; +}; + +class PlayerController +{ +public: + DWORD64 Address = 0; + DWORD Pawn = 0; +public: + DWORD64 GetPlayerPawnAddress(); +}; + +class PlayerPawn +{ +public: + + DWORD64 Address = 0; +}; + +class CEntity +{ +public: + PlayerController Controller; + PlayerPawn Pawn; +public: + bool UpdateController(const DWORD64& PlayerControllerAddress); + bool UpdatePawn(const DWORD64& PlayerPawnAddress); +}; \ No newline at end of file diff --git a/Game.cpp b/Game.cpp new file mode 100644 index 0000000..db43a01 --- /dev/null +++ b/Game.cpp @@ -0,0 +1,50 @@ +#include "Game.h" + +bool CGame::InitAddress() +{ + this->Address.ClientDLL = reinterpret_cast(ProcessMgr.GetProcessModuleHandle("client.dll")); + + this->Address.EntityList = GetClientDLLAddress() + Offset::EntityList; + this->Address.LocalController = GetClientDLLAddress() + Offset::LocalPlayerController; + this->Address.LocalPawn = GetClientDLLAddress() + Offset::LocalPlayerPawn; + + return this->Address.ClientDLL != 0; +} + +DWORD64 CGame::GetClientDLLAddress() +{ + return this->Address.ClientDLL; +} + +DWORD64 CGame::GetEntityListAddress() +{ + return this->Address.EntityList; +} + +DWORD64 CGame::GetEntityListEntry() +{ + return this->Address.EntityListEntry; +} + +DWORD64 CGame::GetLocalControllerAddress() +{ + return this->Address.LocalController; +} + +DWORD64 CGame::GetLocalPawnAddress() +{ + return this->Address.LocalPawn; +} + +bool CGame::UpdateEntityListEntry() +{ + DWORD64 EntityListEntry = 0; + if (!ProcessMgr.ReadMemory(gGame.GetEntityListAddress(), EntityListEntry)) + return false; + if (!ProcessMgr.ReadMemory(EntityListEntry + 0x10, EntityListEntry)) + return false; + + this->Address.EntityListEntry = EntityListEntry; + + return this->Address.EntityListEntry != 0; +} \ No newline at end of file diff --git a/Game.h b/Game.h new file mode 100644 index 0000000..19276db --- /dev/null +++ b/Game.h @@ -0,0 +1,38 @@ +#pragma once +#include +#include "ProcessManager.hpp" +#include "Offsets.h" + +class CGame +{ +private: + struct + { + DWORD64 ClientDLL; + DWORD64 EntityList; + DWORD64 Matrix; + DWORD64 ViewAngle; + DWORD64 EntityListEntry; + DWORD64 LocalController; + DWORD64 LocalPawn; + DWORD64 ForceJump; + }Address; + +public: + + bool InitAddress(); + + DWORD64 GetClientDLLAddress(); + + DWORD64 GetEntityListAddress(); + + DWORD64 GetEntityListEntry(); + + DWORD64 GetLocalControllerAddress(); + + DWORD64 GetLocalPawnAddress(); + + bool UpdateEntityListEntry(); +}; + +inline CGame gGame; \ No newline at end of file diff --git a/MemorySearch.cpp b/MemorySearch.cpp new file mode 100644 index 0000000..efb8000 --- /dev/null +++ b/MemorySearch.cpp @@ -0,0 +1,105 @@ +#include "ProcessManager.hpp" + +#define BLOCKMAXSIZE 409600 +BYTE* MemoryData; +short Next[260]; + +WORD GetSignatureArray(std::string Signature, WORD* SignatureArray) +{ + int len = 0; + WORD Length = Signature.length() / 3 + 1; + + for (int i = 0; i < Signature.length(); ) + { + char num[2]; + num[0] = Signature[i++]; + num[1] = Signature[i++]; + i++; + if (num[0] != '?' && num[1] != '?') + { + int sum = 0; + WORD a[2]; + for (int i = 0; i < 2; i++) + { + if (num[i] >= '0' && num[i] <= '9') + a[i] = num[i] - '0'; + else if (num[i] >= 'a' && num[i] <= 'z') + a[i] = num[i] - 87; + else if (num[i] >= 'A' && num[i] <= 'Z') + a[i] = num[i] - 55; + } + sum = a[0] * 16 + a[1]; + SignatureArray[len++] = sum; + } + else + SignatureArray[len++] = 256; + } + return Length; +} + +void GetNext(short* next, WORD* Signature, WORD SignatureLength) +{ + for (int i = 0; i < 260; i++) + next[i] = -1; + for (int i = 0; i < SignatureLength; i++) + next[Signature[i]] = i; +} + +void SearchMemoryBlock(HANDLE hProcess, WORD* Signature, WORD SignatureLength, DWORD64 StartAddress, DWORD size, std::vector& ResultArray) +{ + if (!ReadProcessMemory(hProcess, (LPCVOID)StartAddress, MemoryData, size, NULL)) + return; + + for (int i = 0, j, k; i < size;) + { + j = i; k = 0; + + for (; k < SignatureLength && j < size && (Signature[k] == MemoryData[j] || Signature[k] == 256); k++, j++); + + if (k == SignatureLength) + ResultArray.push_back(StartAddress + i); + + if ((i + SignatureLength) >= size) + return; + + int num = Next[MemoryData[i + SignatureLength]]; + if (num == -1) + i += (SignatureLength - Next[256]); + else + i += (SignatureLength - num); + } +} + + +std::vector ProcessManager::SearchMemory(std::string Signature, DWORD64 StartAddress, DWORD64 EndAddress) +{ + MemoryData = new BYTE[BLOCKMAXSIZE]; + int i = 0; + unsigned long BlockSize; + MEMORY_BASIC_INFORMATION mbi; + WORD SignatureLength = Signature.length() / 3 + 1; + WORD* SignatureArray = new WORD[SignatureLength]; + std::vectorResultArray; + GetSignatureArray(Signature, SignatureArray); + GetNext(Next, SignatureArray, SignatureLength); + + while (VirtualQueryEx(hProcess, (LPCVOID)StartAddress, &mbi, sizeof(mbi)) != 0) + { + i = 0; + BlockSize = mbi.RegionSize; + while (BlockSize >= BLOCKMAXSIZE) + { + SearchMemoryBlock(hProcess, SignatureArray, SignatureLength, StartAddress + (BLOCKMAXSIZE * i), BLOCKMAXSIZE, ResultArray); + BlockSize -= BLOCKMAXSIZE; i++; + } + SearchMemoryBlock(hProcess, SignatureArray, SignatureLength, StartAddress + (BLOCKMAXSIZE * i), BlockSize, ResultArray); + + StartAddress += mbi.RegionSize; + + if (EndAddress != 0 && StartAddress > EndAddress) + return ResultArray; + } + delete[] MemoryData; + delete[] SignatureArray; + return ResultArray; +} diff --git a/Offsets.cpp b/Offsets.cpp new file mode 100644 index 0000000..5f885c0 --- /dev/null +++ b/Offsets.cpp @@ -0,0 +1,48 @@ +#include "Offsets.h" + +DWORD64 SearchOffsets(std::string Signature, DWORD64 ModuleAddress) +{ + std::vector TempAddressList; + DWORD64 Address = 0; + DWORD Offsets = 0; + + TempAddressList = ProcessMgr.SearchMemory(Signature, ModuleAddress, ModuleAddress + 0x4000000); + + if (TempAddressList.size() <= 0) + return 0; + + if (!ProcessMgr.ReadMemory(TempAddressList.at(0) + 3, Offsets)) + return 0; + + Address = TempAddressList.at(0) + Offsets + 7; + return Address; +} + +bool Offset::UpdateOffsets() +{ + DWORD64 ClientDLL = reinterpret_cast(ProcessMgr.GetProcessModuleHandle("client.dll")); + if (ClientDLL == 0) + return false; + + DWORD64 TempAddress = 0; + + TempAddress = SearchOffsets(Offset::Signatures::EntityList, ClientDLL); + if (TempAddress == 0) + return false; + + Offset::EntityList = TempAddress - ClientDLL; + + TempAddress = SearchOffsets(Offset::Signatures::LocalPlayerController, ClientDLL); + if (TempAddress == 0) + return false; + + Offset::LocalPlayerController = TempAddress - ClientDLL; + + TempAddress = SearchOffsets(Offset::Signatures::LocalPlayerPawn, ClientDLL); + if (TempAddress == 0) + return false; + + Offset::LocalPlayerPawn = TempAddress + 0x138 - ClientDLL; + + return true; +} \ No newline at end of file diff --git a/Offsets.h b/Offsets.h new file mode 100644 index 0000000..fd89d2e --- /dev/null +++ b/Offsets.h @@ -0,0 +1,27 @@ +#pragma once +#include +#include "ProcessManager.hpp" + +namespace Offset +{ + inline DWORD EntityList; + inline DWORD LocalPlayerController; + inline DWORD LocalPlayerPawn; + + // https://github.com/a2x/cs2-dumper/blob/main/generated/client.dll.hpp + struct + { + DWORD PlayerPawn = 0x60C; // CBasePlayerController -> m_hPawn + DWORD EnemySensor = 0x13DC; // m_flDetectedByEnemySensorTime + } Entity; + + // https://github.com/a2x/cs2-dumper/blob/main/config.json + namespace Signatures + { + const std::string EntityList = "48 8B 0D ?? ?? ?? ?? 48 89 7C 24 ?? 8B FA C1"; + const std::string LocalPlayerController = "48 8B 05 ?? ?? ?? ?? 48 85 C0 74 4F"; + const std::string LocalPlayerPawn = "48 8D 05 ?? ?? ?? ?? C3 CC CC CC CC CC CC CC CC 48 83 EC ?? 8B 0D"; + } + + bool UpdateOffsets(); +} \ No newline at end of file diff --git a/ProcessManager.hpp b/ProcessManager.hpp new file mode 100644 index 0000000..061a561 --- /dev/null +++ b/ProcessManager.hpp @@ -0,0 +1,178 @@ +#pragma once +#include +#include +#include +#include +#include +#define _is_invalid(v) if(v==NULL) return false +#define _is_invalid(v,n) if(v==NULL) return n + +enum StatusCode +{ + SUCCEED, + FAILE_PROCESSID, + FAILE_HPROCESS, + FAILE_MODULE, +}; + +class ProcessManager +{ +private: + + bool Attached = false; + +public: + + HANDLE hProcess = 0; + DWORD ProcessID = 0; + DWORD64 ModuleAddress = 0; + +public: + ~ProcessManager() + { + //if (hProcess) + //CloseHandle(hProcess); + } + + StatusCode Attach(std::string ProcessName) + { + ProcessID = this->GetProcessID(ProcessName); + _is_invalid(ProcessID, FAILE_PROCESSID); + + hProcess = OpenProcess(PROCESS_ALL_ACCESS | PROCESS_CREATE_THREAD, TRUE, ProcessID); + _is_invalid(hProcess, FAILE_HPROCESS); + + ModuleAddress = reinterpret_cast(this->GetProcessModuleHandle(ProcessName)); + _is_invalid(ModuleAddress, FAILE_MODULE); + + Attached = true; + + return SUCCEED; + } + + void Detach() + { + if (hProcess) + CloseHandle(hProcess); + hProcess = 0; + ProcessID = 0; + ModuleAddress = 0; + Attached = false; + } + + bool IsActive() + { + if (!Attached) + return false; + DWORD ExitCode{}; + GetExitCodeProcess(hProcess, &ExitCode); + return ExitCode == STILL_ACTIVE; + } + + template + bool ReadMemory(DWORD64 Address, ReadType& Value, int Size) + { + _is_invalid(hProcess,false); + _is_invalid(ProcessID, false); + + if (ReadProcessMemory(hProcess, reinterpret_cast(Address), &Value, Size, 0)) + return true; + return false; + } + + template + bool ReadMemory(DWORD64 Address, ReadType& Value) + { + _is_invalid(hProcess, false); + _is_invalid(ProcessID, false); + + if (ReadProcessMemory(hProcess, reinterpret_cast(Address), &Value, sizeof(ReadType), 0)) + return true; + return false; + } + + template + bool WriteMemory(DWORD64 Address, ReadType& Value, int Size) + { + _is_invalid(hProcess, false); + _is_invalid(ProcessID, false); + + if (WriteProcessMemory(hProcess, reinterpret_cast(Address), &Value, Size, 0)) + return true; + return false; + } + + template + bool WriteMemory(DWORD64 Address, ReadType& Value) + { + _is_invalid(hProcess, false); + _is_invalid(ProcessID, false); + + if (WriteProcessMemory(hProcess, reinterpret_cast(Address), &Value, sizeof(ReadType), 0)) + return true; + return false; + } + + std::vector SearchMemory(std::string Signature, DWORD64 StartAddress, DWORD64 EndAddress); + + DWORD64 TraceAddress(DWORD64 BaseAddress, std::vector Offsets) + { + _is_invalid(hProcess,0); + _is_invalid(ProcessID,0); + DWORD64 Address = 0; + + if (Offsets.size() == 0) + return BaseAddress; + + if (!ReadMemory(BaseAddress, Address)) + return 0; + + for (int i = 0; i < Offsets.size() - 1; i++) + { + if (!ReadMemory(Address + Offsets[i], Address)) + return 0; + } + return Address == 0 ? 0 : Address + Offsets[Offsets.size() - 1]; + } + +public: + + DWORD GetProcessID(std::string ProcessName) + { + PROCESSENTRY32 ProcessInfoPE; + ProcessInfoPE.dwSize = sizeof(PROCESSENTRY32); + HANDLE hSnapshot = CreateToolhelp32Snapshot(15, 0); + Process32First(hSnapshot, &ProcessInfoPE); + USES_CONVERSION; + do { + if (strcmp(W2A(ProcessInfoPE.szExeFile), ProcessName.c_str()) == 0) + { + CloseHandle(hSnapshot); + return ProcessInfoPE.th32ProcessID; + } + } while (Process32Next(hSnapshot, &ProcessInfoPE)); + CloseHandle(hSnapshot); + return 0; + } + + HMODULE GetProcessModuleHandle(std::string ModuleName) + { + MODULEENTRY32 ModuleInfoPE; + ModuleInfoPE.dwSize = sizeof(MODULEENTRY32); + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, this->ProcessID); + Module32First(hSnapshot, &ModuleInfoPE); + USES_CONVERSION; + do { + if (strcmp(W2A(ModuleInfoPE.szModule), ModuleName.c_str()) == 0) + { + CloseHandle(hSnapshot); + return ModuleInfoPE.hModule; + } + } while (Module32Next(hSnapshot, &ModuleInfoPE)); + CloseHandle(hSnapshot); + return 0; + } + +}; + +inline ProcessManager ProcessMgr; \ No newline at end of file diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..f466619 Binary files /dev/null and b/favicon.ico differ diff --git a/main.cpp b/main.cpp new file mode 100644 index 0000000..a96e34f --- /dev/null +++ b/main.cpp @@ -0,0 +1,351 @@ +#include +#pragma comment (lib, "d3dx9.lib") +#pragma comment (lib, "d3d9.lib") +#include + +#include "ImGui/imgui_impl_win32.h" +#include "ImGui/imgui_impl_dx9.h" +#include "ImGui/imgui_internal.h" +#include "ImGui/imgui.h" +#include "ProcessManager.hpp" +#include "Game.h" +#include "Entity.h" + +#define RGBA_TO_FLOAT(r,g,b,a) (float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)a/255.0f + +// Data +static IDirect3D9* g_pD3D = NULL; +static IDirect3DDevice9* g_pd3dDevice = NULL; +static D3DPRESENT_PARAMETERS g_d3dpp = {}; + +// Forward declarations of helper functions +bool CreateDeviceD3D(HWND hWnd); +void CleanupDeviceD3D(); +void ResetDevice(); +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +HWND hwnd; +int WIDTH = 300; +int HEIGHT = 65; +POINTS position = { }; + +int prelogs_count = 0; +float on = 86400.f; +float off = 0.f; + +bool EnableGlow = false; + +void Glow() { + while (true) { + // Update EntityList Entry + gGame.UpdateEntityListEntry(); + + DWORD64 LocalControllerAddress = 0; + DWORD64 LocalPawnAddress = 0; + + while (LocalControllerAddress == 0) { + ProcessMgr.ReadMemory(gGame.GetLocalControllerAddress(), LocalControllerAddress); + if (LocalControllerAddress == 0) Sleep(100); + } + ProcessMgr.ReadMemory(gGame.GetLocalPawnAddress(), LocalPawnAddress); + + // LocalEntity + CEntity LocalEntity; + static int LocalPlayerControllerIndex = 1; + LocalEntity.UpdateController(LocalControllerAddress); + LocalEntity.UpdatePawn(LocalPawnAddress); + + for (int i = 0; i < 64; i++) + { + CEntity Entity; + DWORD64 EntityAddress = 0; + ProcessMgr.ReadMemory(gGame.GetEntityListEntry() + (i + 1) * 0x78, EntityAddress); + if (EntityAddress == LocalEntity.Controller.Address) + { + LocalPlayerControllerIndex = i; + } + Entity.UpdateController(EntityAddress); + Entity.UpdatePawn(Entity.Pawn.Address); + + if (!EnableGlow) + { + ProcessMgr.WriteMemory(Entity.Pawn.Address + Offset::Entity.EnemySensor, off); + } + else { + ProcessMgr.WriteMemory(Entity.Pawn.Address + Offset::Entity.EnemySensor, on); + } + } + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } +} + +int main(HINSTANCE hinst, DWORD fdwReason, LPVOID lpvReserved) +{ + FreeConsole(); + DisableThreadLibraryCalls(hinst); + + auto ProcessStatus = ProcessMgr.Attach("cs2.exe"); + if (ProcessStatus != StatusCode::SUCCEED) + { + MessageBox(NULL, L"Failed to attach \"cs2.exe\" process.", L"Error", MB_ICONERROR); + return 0; + } + + if (!Offset::UpdateOffsets()) + { + MessageBox(NULL, L"Failed to update offsets.", L"Error", MB_ICONERROR); + return 0; + } + + if (!gGame.InitAddress()) + { + MessageBox(NULL, L"Failed to call InitAddress().", L"Error", MB_ICONERROR); + return 0; + } + + std::thread run(Glow); + + RECT desktop; + GetWindowRect(GetDesktopWindow(), &desktop); + + // Create application window + WNDCLASSEX wc = { sizeof(WNDCLASSEX), CS_CLASSDC, WndProc, 0L, 0L, GetModuleHandle(NULL), NULL, NULL, NULL, NULL, L" ", NULL }; + ::RegisterClassEx(&wc); + hwnd = ::CreateWindow(wc.lpszClassName, L" ", WS_POPUP, desktop.right / 2 - WIDTH / 2, desktop.bottom / 2 - HEIGHT / 2, WIDTH, HEIGHT, NULL, NULL, wc.hInstance, NULL); + + // Show the window + ::ShowWindow(hwnd, SW_SHOWDEFAULT); + ::UpdateWindow(hwnd); + + // Initialize Direct3D + if (!CreateDeviceD3D(hwnd)) + { + CleanupDeviceD3D(); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + exit(0); + } + + // Setup Dear ImGui context + IMGUI_CHECKVERSION(); + ImGui::CreateContext(); + ImGuiIO& io = ImGui::GetIO(); (void)io; + ImGui::StyleColorsDark(); + + // Setup Platform/Renderer backends + ImGui_ImplWin32_Init(hwnd); + ImGui_ImplDX9_Init(g_pd3dDevice); + + ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f); + + ImGuiStyle& Style = ImGui::GetStyle(); + + ImGui::GetStyle().WindowPadding = ImVec2(10.000f, 8.000f); + Style.WindowTitleAlign = ImVec2(0.500f, 0.500f); + + Style.Colors[ImGuiCol_FrameBg] = ImVec4(0.141f, 0.141f, 0.141f, 0.667f); + Style.Colors[ImGuiCol_FrameBgHovered] = ImVec4(0.141f, 0.141f, 0.141f, 0.667f); + Style.Colors[ImGuiCol_FrameBgActive] = ImVec4(0.141f, 0.141f, 0.141f, 0.667f); + Style.Colors[ImGuiCol_TitleBgActive] = ImVec4(0.039f, 0.039f, 0.037f, 1.000f); + Style.Colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.141f, 0.141f, 0.141f, 0.667f); + Style.Colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.580f, 0.294f, 0.282f, 1.000f); + Style.Colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.643f, 0.329f, 0.318f, 1.000f); + Style.Colors[ImGuiCol_CheckMark] = ImVec4(0.769f, 0.349f, 0.333f, 1.000f); + Style.Colors[ImGuiCol_SliderGrab] = ImVec4(0.580f, 0.294f, 0.282f, 1.000f); + Style.Colors[ImGuiCol_SliderGrabActive] = ImVec4(0.769f, 0.349f, 0.333f, 1.000f); + Style.Colors[ImGuiCol_Button] = ImVec4(0.137f, 0.137f, 0.141f, 0.549f); + Style.Colors[ImGuiCol_ButtonHovered] = ImVec4(0.580f, 0.294f, 0.282f, 1.000f); + Style.Colors[ImGuiCol_ButtonActive] = ImVec4(0.769f, 0.349f, 0.333f, 1.000f); + Style.Colors[ImGuiCol_Header] = ImVec4(0.141f, 0.141f, 0.141f, 0.667f); + Style.Colors[ImGuiCol_HeaderHovered] = ImVec4(0.580f, 0.294f, 0.282f, 1.000f); + Style.Colors[ImGuiCol_HeaderActive] = ImVec4(0.769f, 0.349f, 0.333f, 1.000f); + Style.Colors[ImGuiCol_TextSelectedBg] = ImVec4(0.580f, 0.294f, 0.282f, 0.549f); + Style.Colors[ImGuiCol_Separator] = ImVec4(0.780f, 0.349f, 0.333f, 1.000f); + Style.Colors[ImGuiCol_Tab] = ImVec4(0.137f, 0.137f, 0.141f, 0.549f); + Style.Colors[ImGuiCol_TabHovered] = ImVec4(0.580f, 0.294f, 0.282f, 1.000f); + Style.Colors[ImGuiCol_TabActive] = ImVec4(0.769f, 0.349f, 0.333f, 1.000f); + Style.Colors[ImGuiCol_TabUnfocused] = ImVec4(0.137f, 0.137f, 0.141f, 0.549f); + Style.Colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.580f, 0.294f, 0.282f, 0.549f); + + // Main loop + bool done = false; + int cwr = 0; + while (!done) + { + // Poll and handle messages (inputs, window resize, etc.) + MSG msg; + while (::PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) + { + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + if (msg.message == WM_QUIT) + done = true; + } + if (done) + break; + + cwr++; + + // Start the Dear ImGui frame + ImGui_ImplDX9_NewFrame(); + ImGui_ImplWin32_NewFrame(); + ImGui::NewFrame(); + + ImGui::SetNextWindowPos(ImVec2(0, 0)); + ImGui::SetNextWindowSize(ImVec2(WIDTH, HEIGHT), ImGuiCond_Once); + + { + ImGui::Begin("xvisual - CS 2 by xvorost", NULL, 18470); + + ImGui::Spacing(); + ImGui::Text(" "); + ImGui::SameLine(); + ImGui::BulletText("Enable Glow:"); ImGui::SameLine(); + ImGui::Checkbox("##EnableGlow", &EnableGlow); + ImGui::SameLine(); + ImGui::Text(" "); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.769f, 0.349f, 0.333f, 1.000f)); + if (ImGui::Button("_")) ::ShowWindow(hwnd, SW_MINIMIZE); + ImGui::PopStyleColor(1); + ImGui::SameLine(); + ImGui::PushStyleColor(ImGuiCol_Button, ImVec4(0.769f, 0.349f, 0.333f, 1.000f)); + if (ImGui::Button("X")) { + ShellExecute(NULL, L"open", L"https://github.com/xvorost/", NULL, NULL, SW_SHOWNORMAL); + exit(0); + } + ImGui::PopStyleColor(1); + + ImGui::End(); + } + + // Rendering + if (cwr >= 1000) { ::UpdateWindow(hwnd); cwr = 0; } + ImGui::EndFrame(); + g_pd3dDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + g_pd3dDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + D3DCOLOR clear_col_dx = D3DCOLOR_RGBA((int)(clear_color.x * clear_color.w * 255.0f), (int)(clear_color.y * clear_color.w * 255.0f), (int)(clear_color.z * clear_color.w * 255.0f), (int)(clear_color.w * 255.0f)); + g_pd3dDevice->Clear(0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, clear_col_dx, 1.0f, 0); + if (g_pd3dDevice->BeginScene() >= 0) + { + ImGui::Render(); + ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); + g_pd3dDevice->EndScene(); + } + HRESULT result = g_pd3dDevice->Present(NULL, NULL, NULL, NULL); + + // Handle loss of D3D9 device + if (result == D3DERR_DEVICELOST && g_pd3dDevice->TestCooperativeLevel() == D3DERR_DEVICENOTRESET) + ResetDevice(); + + std::this_thread::sleep_for(std::chrono::milliseconds(1)); + } + + // Cleanup + ImGui_ImplDX9_Shutdown(); + ImGui_ImplWin32_Shutdown(); + ImGui::DestroyContext(); + + CleanupDeviceD3D(); + ::DestroyWindow(hwnd); + ::UnregisterClass(wc.lpszClassName, wc.hInstance); + //} + + return 0; +} + +bool CreateDeviceD3D(HWND hWnd) +{ + if ((g_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) == NULL) + return false; + + // Create the D3DDevice + g_d3dpp.Windowed = true; + g_d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; + g_d3dpp.hDeviceWindow = hWnd; + + HRESULT dummyDeviceCreated = g_pD3D->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, g_d3dpp.hDeviceWindow, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &g_d3dpp, &g_pd3dDevice); + if (dummyDeviceCreated != S_OK) + { + g_pD3D->Release(); + Sleep(5000); + return false; + } + + return true; +} + +void CleanupDeviceD3D() +{ + if (g_pd3dDevice) { g_pd3dDevice->Release(); g_pd3dDevice = NULL; } + if (g_pD3D) { g_pD3D->Release(); g_pD3D = NULL; } +} + +void ResetDevice() +{ + ImGui_ImplDX9_InvalidateDeviceObjects(); + HRESULT hr = g_pd3dDevice->Reset(&g_d3dpp); + if (hr == D3DERR_INVALIDCALL) + IM_ASSERT(0); + ImGui_ImplDX9_CreateDeviceObjects(); +} + +// Forward declare message handler from imgui_impl_win32.cpp +extern IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); + +// Win32 message handler +LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) + return true; + + switch (msg) + { + case WM_SIZE: + if (g_pd3dDevice != NULL && wParam != SIZE_MINIMIZED) + { + g_d3dpp.BackBufferWidth = LOWORD(lParam); + g_d3dpp.BackBufferHeight = HIWORD(lParam); + ResetDevice(); + } + return 0; + break; + case WM_SYSCOMMAND: + if ((wParam & 0xfff0) == SC_KEYMENU) // Disable ALT application menu + return 0; + break; + case WM_DESTROY: + ShellExecute(NULL, L"open", L"https://github.com/xvorost/", NULL, NULL, SW_SHOWNORMAL); + ::PostQuitMessage(0); + return 0; + case WM_LBUTTONDOWN: + position = MAKEPOINTS(lParam); // set click points + return 0; + case WM_MOUSEMOVE: + if (wParam == MK_LBUTTON) + { + const auto points = MAKEPOINTS(lParam); + auto rect = ::RECT{ }; + + GetWindowRect(hwnd, &rect); + + rect.left += points.x - position.x; + rect.top += points.y - position.y; + + if (position.x >= 0 && + position.x <= WIDTH && + position.y >= 0 && position.y <= 19) + SetWindowPos( + hwnd, + HWND_TOPMOST, + rect.left, + rect.top, + 0, 0, + SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOZORDER + ); + } + return 0; + } + + return ::DefWindowProc(hWnd, msg, wParam, lParam); +} \ No newline at end of file diff --git a/resource.h b/resource.h new file mode 100644 index 0000000..7eaf77c --- /dev/null +++ b/resource.h @@ -0,0 +1,16 @@ +//{{NO_DEPENDENCIES}} +// Включаемый файл, созданный в Microsoft Visual C++. +// Используется xvisual.rc +// +#define IDI_ICON1 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 102 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1001 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/xvisual.aps b/xvisual.aps new file mode 100644 index 0000000..4fdf8e5 Binary files /dev/null and b/xvisual.aps differ diff --git a/xvisual.rc b/xvisual.rc new file mode 100644 index 0000000..3660286 Binary files /dev/null and b/xvisual.rc differ diff --git a/xvisual.sln b/xvisual.sln new file mode 100644 index 0000000..11199cb --- /dev/null +++ b/xvisual.sln @@ -0,0 +1,31 @@ +п»ї +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.7.34003.232 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "xvisual", "xvisual.vcxproj", "{CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Debug|x64.ActiveCfg = Debug|x64 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Debug|x64.Build.0 = Debug|x64 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Debug|x86.ActiveCfg = Debug|Win32 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Debug|x86.Build.0 = Debug|Win32 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Release|x64.ActiveCfg = Release|x64 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Release|x64.Build.0 = Release|x64 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Release|x86.ActiveCfg = Release|Win32 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {88C95AF2-4A86-4E4D-BE48-77C82B8E7B70} + EndGlobalSection +EndGlobal diff --git a/xvisual.vcxproj b/xvisual.vcxproj new file mode 100644 index 0000000..082adf8 --- /dev/null +++ b/xvisual.vcxproj @@ -0,0 +1,167 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {CB8C0B94-7081-4696-B6A3-D3BE5B79ED5C} + Win32Proj + 10.0 + + + + Application + true + v143 + + + Application + false + v143 + + + Application + true + v143 + + + Application + false + v143 + Unicode + true + + + + + + + + + + + + + + + + + + + + + true + + + true + + + true + + + true + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Include;$(IncludePath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(LibraryPath) + C:\Program Files %28x86%29\Microsoft DirectX SDK %28June 2010%29\Lib\x64;$(ExternalIncludePath) + + + + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + + + + + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + + + + + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + + + true + Console + true + true + + + + + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + Level3 + stdcpp20 + stdc17 + + + true + Console + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/xvisual.vcxproj.filters b/xvisual.vcxproj.filters new file mode 100644 index 0000000..14ce91b --- /dev/null +++ b/xvisual.vcxproj.filters @@ -0,0 +1,106 @@ +п»ї + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/xvisual.vcxproj.user b/xvisual.vcxproj.user new file mode 100644 index 0000000..0f14913 --- /dev/null +++ b/xvisual.vcxproj.user @@ -0,0 +1,4 @@ +п»ї + + + \ No newline at end of file