From c1af6de33ddd7751d59e69b8d4c2f568bd7911e8 Mon Sep 17 00:00:00 2001 From: Disquse Date: Sun, 9 Jul 2023 03:51:36 +0300 Subject: [PATCH] tweak(extra-natives/five): clamp index in `SET_PED_COMBAT_ATTRIBUTES` --- .../extra-natives-five/src/NativeFixes.cpp | 57 +++++++++++++++++++ .../gta-core-five/include/RageParser.h | 1 + 2 files changed, 58 insertions(+) diff --git a/code/components/extra-natives-five/src/NativeFixes.cpp b/code/components/extra-natives-five/src/NativeFixes.cpp index cbe78f3bba..b0dd8ad358 100644 --- a/code/components/extra-natives-five/src/NativeFixes.cpp +++ b/code/components/extra-natives-five/src/NativeFixes.cpp @@ -12,6 +12,9 @@ #include #include #include +#include "RageParser.h" +#include "Resource.h" +#include "ScriptWarnings.h" static void FixVehicleWindowNatives() { @@ -311,6 +314,58 @@ static void FixStopEntityFire() }); } +static void FixPedCombatAttributes() +{ + const auto structDef = rage::GetStructureDefinition("CCombatInfo"); + + if (!structDef) + { + trace("Couldn't find struct definition for CCombatInfo!\n"); + return; + } + + static uint32_t attributesCount = 0; + + for (const auto member : structDef->m_members) + { + if (member->m_definition && member->m_definition->hash == HashRageString("BehaviourFlags")) + { + attributesCount = member->m_definition->enumElemCount; + break; + } + } + + if (!attributesCount) + { + trace("Couldn't get max enum size for BehaviourFlags!\n"); + return; + } + + constexpr const uint64_t nativeHash = 0x9F7794730795E019; // SET_PED_COMBAT_ATTRIBUTES + + auto originalHandler = fx::ScriptEngine::GetNativeHandler(nativeHash); + + if (!originalHandler) + { + return; + } + + auto handler = *originalHandler; + + fx::ScriptEngine::RegisterNativeHandler(nativeHash, [handler](fx::ScriptContext& ctx) + { + auto attributeIndex = ctx.GetArgument(1); + + if (attributeIndex >= attributesCount) + { + fx::scripting::Warningf("natives", "SET_PED_COMBAT_ATTRIBUTES: invalid attribute index was passed (%d), should be from 0 to %d\n", attributeIndex, attributesCount - 1); + return; + } + + handler(ctx); + }); +} + static HookFunction hookFunction([]() { g_fireInstances = (std::array*)(hook::get_address(hook::get_pattern("74 47 48 8D 0D ? ? ? ? 48 8B D3", 2), 3, 7) + 0x10); @@ -337,5 +392,7 @@ static HookFunction hookFunction([]() FixStartEntityFire(); FixStopEntityFire(); + + FixPedCombatAttributes(); }); }); diff --git a/code/components/gta-core-five/include/RageParser.h b/code/components/gta-core-five/include/RageParser.h index f67ed9dfdd..a7ab4b053e 100644 --- a/code/components/gta-core-five/include/RageParser.h +++ b/code/components/gta-core-five/include/RageParser.h @@ -126,6 +126,7 @@ namespace rage parEnumDefinition* enumData; uint32_t arrayElemCount; }; + uint16_t enumElemCount; // +48 for enum defs }; class parMember