From 620ca71f6e8eb4af8a773c9d0ae2607ecb87a80e Mon Sep 17 00:00:00 2001 From: Septirage <75088531+Septirage@users.noreply.github.com> Date: Sat, 23 Aug 2025 03:04:40 +0200 Subject: [PATCH] Fix ExecuteScriptEnhanced - properly set the maxSize value on the NWN2ParamsList - create a NWN2Heap managed memory buffer for parameters - Add the "number of parameters" bytes at the start of the paramBuffer and set it to 0 to avoid deep delete. - Properly call the CleanParameters at the end of execution. --- src/hook/scriptManagement.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/src/hook/scriptManagement.cpp b/src/hook/scriptManagement.cpp index 10d7f46..45ea3a6 100644 --- a/src/hook/scriptManagement.cpp +++ b/src/hook/scriptManagement.cpp @@ -35,8 +35,9 @@ constexpr uint32_t NWN2_OFFSET_CleanParam = 0x006b5cd0; struct NWN2ParamsList { struct NWN2Param* list; size_t size; + size_t maxSize; }; -static_assert(sizeof(NWN2ParamsList) == 8); +static_assert(sizeof(NWN2ParamsList) == 0xC); static struct NWN2ParamsList* nwn2_scriptparams = (struct NWN2ParamsList*)(0x0086F15C); // static size_t scriptparams_count = 0; @@ -90,6 +91,15 @@ int* GetPtrToCNWSMessage() return (int*)(ptr + 0x10020); } +__declspec(naked) void __fastcall CleanHeapParams(__in void* heapParamPtr, __in void* Unused) +{ + __asm + { + mov edx, NWN2_OFFSET_CleanParam; + jmp edx; + } +} + void ApplyScriptCNWSMessage() { int* ptrToCNWSMessage = GetPtrToCNWSMessage(); @@ -189,8 +199,18 @@ int32_t ExecuteScriptEnhanced(const char* sScriptName, NWN2ParamsList save = *nwn2_scriptparams; - nwn2_scriptparams->list = scriptparams.data(); - nwn2_scriptparams->size = scriptparams.size(); + // Prepare a heapMemory container. So Script Function can work inside this ExecuteEnhancedScript + NWN2_HeapMgr* pHeapMgr = NWN2_HeapMgr::Instance(); + NWN2_Heap* pHeap = pHeapMgr->GetDefaultHeap(); + size_t total_size = scriptparams.size() * sizeof(NWN2Param) + sizeof(int32_t); + uint32_t* parametersHeap = (uint32_t*)pHeap->Allocate(total_size); + parametersHeap[0] = 0; // Avoid to delete inner parameters. + + std::memcpy(parametersHeap + 1, scriptparams.data(), scriptparams.size() * sizeof(NWN2Param)); + + nwn2_scriptparams->list = reinterpret_cast(parametersHeap + 1); + nwn2_scriptparams->size = scriptparams.size(); + nwn2_scriptparams->maxSize = scriptparams.size(); // call the script int retValue @@ -205,6 +225,9 @@ int32_t ExecuteScriptEnhanced(const char* sScriptName, else retValue = -1; + // As we want to restore saved scriptParameters, we always "clean" what happened here. + CleanHeapParams((void*)nwn2_scriptparams, NULL); + *nwn2_scriptparams = save; if (bReplaceCNWSMsg)