From 9530fd24c00c14212275660b43adf2983cdeaebe Mon Sep 17 00:00:00 2001 From: maybegreat48 <96936658+maybegreat48@users.noreply.github.com> Date: Sun, 16 Mar 2025 14:19:26 -0400 Subject: [PATCH] fix(renderer): fix renderer --- cmake/imgui.cmake | 2 +- src/core/renderer/Renderer.cpp | 51 ++++++++++++++++----- src/core/renderer/Renderer.hpp | 47 +++++++++++++++++++ src/game/commands/PlayerCommand.cpp | 4 +- src/game/features/players/toxic/Explode.cpp | 3 +- src/game/features/players/toxic/Kill.cpp | 17 +++++++ src/game/frontend/submenus/Network.cpp | 7 +-- src/game/frontend/submenus/Player/Info.cpp | 10 ++-- src/game/frontend/submenus/Player/Toxic.cpp | 2 +- src/game/gta/Entity.cpp | 28 +++++------ src/game/gta/Entity.hpp | 4 +- src/game/pointers/Pointers.cpp | 11 +++-- src/game/pointers/Pointers.hpp | 3 ++ src/types/script/scriptHandler.hpp | 1 - 14 files changed, 146 insertions(+), 44 deletions(-) create mode 100644 src/game/features/players/toxic/Kill.cpp diff --git a/cmake/imgui.cmake b/cmake/imgui.cmake index 524f906..6677894 100644 --- a/cmake/imgui.cmake +++ b/cmake/imgui.cmake @@ -6,7 +6,7 @@ message(STATUS "Setting up ${LIB_NAME}") FetchContent_Declare( ${LIB_NAME} GIT_REPOSITORY https://github.com/ocornut/imgui - GIT_TAG 6e30c4210181aebb6137f6c10fdfc572ea1202f2 + GIT_TAG v1.91.9 GIT_PROGRESS TRUE ) diff --git a/src/core/renderer/Renderer.cpp b/src/core/renderer/Renderer.cpp index 0801b5f..47faa9b 100644 --- a/src/core/renderer/Renderer.cpp +++ b/src/core/renderer/Renderer.cpp @@ -30,6 +30,11 @@ namespace YimMenu ImGui_ImplDX12_Shutdown(); ImGui::DestroyContext(); + + // manually destroy the allocators we created for the rest of the frame contexts + for (size_t i = 1; i < m_SwapChainDesc.BufferCount; ++i) + if (m_FrameContext[i].CommandAllocator) + m_FrameContext[i].CommandAllocator->Release(); } bool Renderer::InitDX12() @@ -110,23 +115,25 @@ namespace YimMenu (void**)m_CommandAllocator.GetAddressOf()); result < 0) { - LOG(WARNING) << "Failed to create Command Allocator with result: [" << result << "]"; + LOG(WARNING) << "Failed to create primary Command Allocator with result: [" << result << "]"; return false; } - for (size_t i{}; i < m_SwapChainDesc.BufferCount; ++i) + m_FrameContext[0].CommandAllocator = m_CommandAllocator.Get(); // set initial command allocator + + // create the rest of the allocators + for (size_t i = 1; i < m_SwapChainDesc.BufferCount; ++i) { - m_FrameContext[i].CommandAllocator = m_CommandAllocator.Get(); + if (const auto result = m_Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(ID3D12CommandAllocator), (void**)&m_FrameContext[i].CommandAllocator); result < 0) + { + LOG(WARNING) << "Failed to create secondary Command Allocator with result: [" << result << "]"; + + return false; + } } - if (const auto result = m_Device->CreateCommandList(0, - D3D12_COMMAND_LIST_TYPE_DIRECT, - m_CommandAllocator.Get(), - NULL, - __uuidof(ID3D12GraphicsCommandList), - (void**)m_CommandList.GetAddressOf()); - result < 0) + if (const auto result = m_Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_CommandAllocator.Get(), NULL, __uuidof(ID3D12GraphicsCommandList), (void**)m_CommandList.GetAddressOf()); result < 0) { LOG(WARNING) << "Failed to create Command List with result: [" << result << "]"; @@ -163,15 +170,37 @@ namespace YimMenu RTVHandle.ptr += RTVDescriptorSize; } + m_HeapAllocator.Create(m_Device.Get(), m_DescriptorHeap.Get()); + // never returns false, useless to check return ImGui::CreateContext(&GetInstance().m_FontAtlas); ImGui_ImplWin32_Init(*Pointers.Hwnd); + + ImGui_ImplDX12_InitInfo init_info = {}; + init_info.Device = m_Device.Get(); + init_info.CommandQueue = m_CommandQueue.Get(); + init_info.NumFramesInFlight = m_SwapChainDesc.BufferCount; + init_info.RTVFormat = DXGI_FORMAT_R8G8B8A8_UNORM; + init_info.DSVFormat = DXGI_FORMAT_UNKNOWN; + // Allocating SRV descriptors (for textures) is up to the application, so we provide callbacks. + // (current version of the backend will only allocate one descriptor, future versions will need to allocate more) + init_info.SrvDescriptorHeap = m_DescriptorHeap.Get(); + init_info.SrvDescriptorAllocFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_handle) { + return GetInstance().m_HeapAllocator.Alloc(out_cpu_handle, out_gpu_handle); + }; + init_info.SrvDescriptorFreeFn = [](ImGui_ImplDX12_InitInfo*, D3D12_CPU_DESCRIPTOR_HANDLE cpu_handle, D3D12_GPU_DESCRIPTOR_HANDLE gpu_handle) { + return GetInstance().m_HeapAllocator.Free(cpu_handle, gpu_handle); + }; + ImGui_ImplDX12_Init(&init_info); + + #if 0 ImGui_ImplDX12_Init(m_Device.Get(), m_SwapChainDesc.BufferCount, DXGI_FORMAT_R8G8B8A8_UNORM, m_DescriptorHeap.Get(), m_DescriptorHeap->GetCPUDescriptorHandleForHeapStart(), m_DescriptorHeap->GetGPUDescriptorHandleForHeapStart()); + #endif ImGui::StyleColorsDark(); @@ -341,6 +370,6 @@ namespace YimMenu UINT64 FenceValue = GetInstance().m_FenceLastSignaledValue + 1; GetInstance().m_CommandQueue->Signal(GetInstance().m_Fence.Get(), FenceValue); GetInstance().m_FenceLastSignaledValue = FenceValue; - CurrentFrameContext.FenceValue = FenceValue; + CurrentFrameContext.FenceValue = FenceValue; } } \ No newline at end of file diff --git a/src/core/renderer/Renderer.hpp b/src/core/renderer/Renderer.hpp index be583f2..10bf482 100644 --- a/src/core/renderer/Renderer.hpp +++ b/src/core/renderer/Renderer.hpp @@ -32,6 +32,50 @@ namespace YimMenu UINT64 FenceValue; }; + struct ExampleDescriptorHeapAllocator + { + ID3D12DescriptorHeap* Heap = nullptr; + D3D12_DESCRIPTOR_HEAP_TYPE HeapType = D3D12_DESCRIPTOR_HEAP_TYPE_NUM_TYPES; + D3D12_CPU_DESCRIPTOR_HANDLE HeapStartCpu; + D3D12_GPU_DESCRIPTOR_HANDLE HeapStartGpu; + UINT HeapHandleIncrement; + ImVector FreeIndices; + + void Create(ID3D12Device* device, ID3D12DescriptorHeap* heap) + { + IM_ASSERT(Heap == nullptr && FreeIndices.empty()); + Heap = heap; + D3D12_DESCRIPTOR_HEAP_DESC desc = heap->GetDesc(); + HeapType = desc.Type; + HeapStartCpu = Heap->GetCPUDescriptorHandleForHeapStart(); + HeapStartGpu = Heap->GetGPUDescriptorHandleForHeapStart(); + HeapHandleIncrement = device->GetDescriptorHandleIncrementSize(HeapType); + FreeIndices.reserve((int)desc.NumDescriptors); + for (int n = desc.NumDescriptors; n > 0; n--) + FreeIndices.push_back(n - 1); + } + void Destroy() + { + Heap = nullptr; + FreeIndices.clear(); + } + void Alloc(D3D12_CPU_DESCRIPTOR_HANDLE* out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE* out_gpu_desc_handle) + { + IM_ASSERT(FreeIndices.Size > 0); + int idx = FreeIndices.back(); + FreeIndices.pop_back(); + out_cpu_desc_handle->ptr = HeapStartCpu.ptr + (idx * HeapHandleIncrement); + out_gpu_desc_handle->ptr = HeapStartGpu.ptr + (idx * HeapHandleIncrement); + } + void Free(D3D12_CPU_DESCRIPTOR_HANDLE out_cpu_desc_handle, D3D12_GPU_DESCRIPTOR_HANDLE out_gpu_desc_handle) + { + int cpu_idx = (int)((out_cpu_desc_handle.ptr - HeapStartCpu.ptr) / HeapHandleIncrement); + int gpu_idx = (int)((out_gpu_desc_handle.ptr - HeapStartGpu.ptr) / HeapHandleIncrement); + IM_ASSERT(cpu_idx == gpu_idx); + FreeIndices.push_back(cpu_idx); + } + }; + class Renderer final { private: @@ -133,6 +177,9 @@ namespace YimMenu return i; } + public: + ExampleDescriptorHeapAllocator m_HeapAllocator; + private: bool m_Resizing; diff --git a/src/game/commands/PlayerCommand.cpp b/src/game/commands/PlayerCommand.cpp index ab15eac..c7afaa3 100644 --- a/src/game/commands/PlayerCommand.cpp +++ b/src/game/commands/PlayerCommand.cpp @@ -1,6 +1,7 @@ #include "PlayerCommand.hpp" #include "game/backend/Players.hpp" +#include "game/backend/Self.hpp" namespace YimMenu { @@ -13,7 +14,8 @@ namespace YimMenu void PlayerAllCommand::OnCall() { for (auto& p : Players::GetPlayers()) - m_PlayerCommand->Call(p.second); + if (p.second.IsValid() && (!Self::GetPlayer().IsValid() || p.second.GetId() != Self::GetPlayer().GetId())) + m_PlayerCommand->Call(p.second); } PlayerCommand::PlayerCommand(std::string name, std::string label, std::string description, int num_args, bool all_version) : diff --git a/src/game/features/players/toxic/Explode.cpp b/src/game/features/players/toxic/Explode.cpp index d313c38..802f1cc 100644 --- a/src/game/features/players/toxic/Explode.cpp +++ b/src/game/features/players/toxic/Explode.cpp @@ -9,7 +9,8 @@ namespace YimMenu::Features virtual void OnCall(Player player) override { - player.GetPed().Explode(ExplosionType::ORBITAL_CANNON, 900.f); + if (auto ped = player.GetPed()) + ped.Explode(ExplosionType::ORBITAL_CANNON, 900.f); } }; diff --git a/src/game/features/players/toxic/Kill.cpp b/src/game/features/players/toxic/Kill.cpp new file mode 100644 index 0000000..188a733 --- /dev/null +++ b/src/game/features/players/toxic/Kill.cpp @@ -0,0 +1,17 @@ +#include "game/commands/PlayerCommand.hpp" + +namespace YimMenu::Features +{ + class Kill : public PlayerCommand + { + using PlayerCommand::PlayerCommand; + + virtual void OnCall(Player player) override + { + if (auto ped = player.GetPed()) + ped.Kill(); + } + }; + + static Kill _Kill{"kill", "Kill", "Kills the player"}; +} \ No newline at end of file diff --git a/src/game/frontend/submenus/Network.cpp b/src/game/frontend/submenus/Network.cpp index bd28128..b8b142f 100644 --- a/src/game/frontend/submenus/Network.cpp +++ b/src/game/frontend/submenus/Network.cpp @@ -7,10 +7,11 @@ namespace YimMenu::Submenus Submenu::Submenu("Network") { // TODO: this needs a rework - auto session = std::make_shared("Session"); - auto toxicGroup = std::make_shared("Toxic"); + auto session = std::make_shared("Session"); + auto toxicGroup = std::make_shared("Toxic"); - toxicGroup->AddItem(std::make_shared("explodeall"_J)); + toxicGroup->AddItem(std::make_shared("killall"_J, "Kill All")); + toxicGroup->AddItem(std::make_shared("explodeall"_J, "Explode All")); session->AddItem(toxicGroup); diff --git a/src/game/frontend/submenus/Player/Info.cpp b/src/game/frontend/submenus/Player/Info.cpp index d4d7bd1..fbed9b5 100644 --- a/src/game/frontend/submenus/Player/Info.cpp +++ b/src/game/frontend/submenus/Player/Info.cpp @@ -32,7 +32,7 @@ namespace YimMenu::Submenus playerOptionsGroup->AddItem(std::make_shared([] { if (Players::GetSelected().IsValid()) { - ImGui::Text("Rank: %d (%d RP)", Players::GetSelected().GetRank(), Players::GetSelected().GetRank()); + ImGui::Text("Rank: %d (%d RP)", Players::GetSelected().GetRank(), Players::GetSelected().GetRP()); ImGui::Text("Money: %d", Players::GetSelected().GetMoney()); if (Players::GetSelected().GetPed()) @@ -79,15 +79,15 @@ namespace YimMenu::Submenus if (ImGui::Button("View SC Profile")) FiberPool::Push([] { uint64_t handle[13]; - NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), (Any*)&handle, sizeof(handle)); - NETWORK::NETWORK_SHOW_PROFILE_UI((Any*)&handle); + NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), handle, sizeof(handle)); + NETWORK::NETWORK_SHOW_PROFILE_UI(handle); }); ImGui::SameLine(); if (ImGui::Button("Add Friend")) FiberPool::Push([] { uint64_t handle[13]; - NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), (Any*)&handle, sizeof(handle)); - NETWORK::NETWORK_ADD_FRIEND((Any*)&handle, ""); + NETWORK::NETWORK_HANDLE_FROM_PLAYER(Players::GetSelected().GetId(), handle, sizeof(handle)); + NETWORK::NETWORK_ADD_FRIEND(handle, ""); }); if (ImGui::Button("More Info")) diff --git a/src/game/frontend/submenus/Player/Toxic.cpp b/src/game/frontend/submenus/Player/Toxic.cpp index 27212da..6b7d570 100644 --- a/src/game/frontend/submenus/Player/Toxic.cpp +++ b/src/game/frontend/submenus/Player/Toxic.cpp @@ -7,7 +7,7 @@ namespace YimMenu::Submenus auto menu = std::make_shared("Toxic"); auto general = std::make_shared("General"); - // general->AddItem(std::make_shared("kill"_J)); + general->AddItem(std::make_shared("kill"_J)); general->AddItem(std::make_shared("explode"_J)); menu->AddItem(general); diff --git a/src/game/gta/Entity.cpp b/src/game/gta/Entity.cpp index 977540a..5ba523c 100644 --- a/src/game/gta/Entity.cpp +++ b/src/game/gta/Entity.cpp @@ -5,6 +5,7 @@ #include "game/pointers/Pointers.hpp" #include "types/rage/tlsContext.hpp" #include "game/gta/Scripts.hpp" +#include "types/ped/CPedFactory.hpp" namespace YimMenu { @@ -211,14 +212,6 @@ namespace YimMenu return GetPointer()->m_NetObject; } - bool Entity::HasControl() - { - if (!IsNetworked()) - return true; - - return !GetNetworkObject()->m_IsRemotelyControlled; - } - int Entity::GetOwner() { if (!IsNetworked()) @@ -290,6 +283,11 @@ namespace YimMenu } #endif + bool Entity::HasControl() + { + return NETWORK::NETWORK_HAS_CONTROL_OF_ENTITY(GetHandle()); + } + bool Entity::IsInvincible() { // TODO this is bad! @@ -314,23 +312,21 @@ namespace YimMenu { ENTITY_ASSERT_VALID(); - if (/* HasControl() */ true) + if (HasControl()) { ENTITY::SET_ENTITY_HEALTH(GetHandle(), 0, PLAYER::PLAYER_PED_ID(), 0); } else { -#if 0 - auto ptr = GetPointer(); - auto local = reinterpret_cast(Pointers.GetLocalPed()); - auto pos = GetPosition(); + auto ptr = GetPointer(); + auto local = reinterpret_cast((*Pointers.PedFactory)->m_LocalPed); + auto pos = GetPosition(); std::uint32_t weapon = "WEAPON_EXPLOSION"_J; - if (!ptr || !ptr->m_NetObject || !local || !local->m_NetObject) + if (!ptr || !local) return; - Pointers.TriggerWeaponDamageEvent(local->m_NetObject, ptr->m_NetObject, nullptr, &pos, nullptr, nullptr, true, &weapon, 9999.9f, 9999.0f, -1, -1, 16, nullptr, false, false, true, false, false, -1, 0, 0, 0, 0, 0); -#endif + Pointers.TriggerWeaponDamageEvent(local, ptr, &pos, 0, true, weapon, 9999.9f, 2, 0, (1<<4)|0x80000, 0, 0, 0, false, false, true, true, nullptr); } } diff --git a/src/game/gta/Entity.hpp b/src/game/gta/Entity.hpp index 48b8e28..36b562b 100644 --- a/src/game/gta/Entity.hpp +++ b/src/game/gta/Entity.hpp @@ -107,11 +107,13 @@ namespace YimMenu void SetFrozen(bool enabled); void Delete(); + bool HasControl(); + #if 0 // networking bool IsNetworked(); rage::netObject* GetNetworkObject(); - bool HasControl(); + int GetOwner(); // index because we want to avoid cyclic imports std::uint16_t GetNetworkObjectId(); /// diff --git a/src/game/pointers/Pointers.cpp b/src/game/pointers/Pointers.cpp index 72abf4e..8e325e6 100644 --- a/src/game/pointers/Pointers.cpp +++ b/src/game/pointers/Pointers.cpp @@ -57,10 +57,10 @@ namespace YimMenu RunScriptThreads = ptr.Sub(0xA).As(); }); - constexpr auto handlesAndPtrsPtrn = Pattern<"0F 1F 84 00 00 00 00 00 89 F8 0F 28 FE">("HandlesAndPtrs"); + constexpr auto handlesAndPtrsPtrn = Pattern<"0F 1F 84 00 00 00 00 00 89 F8 0F 28 FE 41">("HandlesAndPtrs"); scanner.Add(handlesAndPtrsPtrn, [this](PointerCalculator ptr) { - HandleToPtr = ptr.Add(0x21).Add(3).Rip().As(); - PtrToHandle = ptr.Sub(0xB).Add(3).Rip().As(); + HandleToPtr = ptr.Add(0x21).Add(1).Rip().As(); + PtrToHandle = ptr.Sub(0xB).Add(1).Rip().As(); }); constexpr auto pedFactoryPtrn = Pattern<"C7 40 30 03 00 00 00 48 8B 0D">("PedFactory"); @@ -88,6 +88,11 @@ namespace YimMenu ScriptGlobals = ptr.Add(7).Add(3).Rip().As(); }); + constexpr auto sendNetworkDamagePtrn = Pattern<"0F B6 41 28 04 FE 3C 03 0F 87 EA">("SendNetworkDamage"); + scanner.Add(sendNetworkDamagePtrn, [this](PointerCalculator ptr) { + TriggerWeaponDamageEvent = ptr.Sub(0x51).As(); + }); + if (!scanner.Scan()) { LOG(FATAL) << "Some patterns could not be found, unloading."; diff --git a/src/game/pointers/Pointers.hpp b/src/game/pointers/Pointers.hpp index 9d9dfa9..53e8471 100644 --- a/src/game/pointers/Pointers.hpp +++ b/src/game/pointers/Pointers.hpp @@ -13,6 +13,7 @@ namespace rage } class CPedFactory; class CNetGamePlayer; +class CEntity; namespace YimMenu { @@ -22,6 +23,7 @@ namespace YimMenu using HandleToPtr = void* (*)(int handle); using PtrToHandle = int (*)(void* pointer); using GetNetPlayerFromPid = CNetGamePlayer* (*)(int id); + using TriggerWeaponDamageEvent = void (*)(CEntity* source, CEntity* target, rage::fvector3* position, int hit_component, bool override_default_damage, int weapon_type, float override_damage, int tire_index, int suspension_index, int flags, uint32_t action_result_hash, int16_t action_result_id, int action_unk, bool hit_weapon, bool hit_weapon_ammo_attachment, bool silenced, bool unk, rage::fvector3* impact_direction); } struct PointerData @@ -42,6 +44,7 @@ namespace YimMenu Functions::GetNetPlayerFromPid GetNetPlayerFromPid; bool* IsSessionStarted; PVOID AssignPhysicalIndex; + Functions::TriggerWeaponDamageEvent TriggerWeaponDamageEvent; }; struct Pointers : PointerData diff --git a/src/types/script/scriptHandler.hpp b/src/types/script/scriptHandler.hpp index 6253543..473a991 100644 --- a/src/types/script/scriptHandler.hpp +++ b/src/types/script/scriptHandler.hpp @@ -4,7 +4,6 @@ #include -#pragma pack(push, 1) namespace rage { class scriptHandlerObject;