From 61b8ad1670f6ab24d9264266b4d13782231d714c Mon Sep 17 00:00:00 2001 From: szapp Date: Thu, 5 Sep 2024 18:22:07 +0200 Subject: [PATCH] Recover last invalid spell item This commit complements the previous one to attempt to fix an unrecoverable error of equipped invalid spell items. What the previous commit lacked was the recovery if the last equipped item (in order of inventory sorting) is an invalid spell item. Then the corrupted reading position was carried into the next unarchiving processes. Here this is attempted to fix by checking the following values from unarchiving. --- Makefile | 1 + src/core.asm | 4 ++-- src/exec/misc.asm | 45 +++++++++++++++++++++++++++++++++++++++++++++ verifySize.bat | 2 +- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 674f276..ac65503 100644 --- a/Makefile +++ b/Makefile @@ -142,6 +142,7 @@ BIN_BASE := core \ hook_oCSpawnManager__Archive \ hook_npcReference \ hook_recoverInvalidItem \ + hook_recoverInvalidItem2 \ hook_fastexit \ hook_CGameManager_destructor \ hook_libExit \ diff --git a/src/core.asm b/src/core.asm index 80c279e..931f363 100644 --- a/src/core.asm +++ b/src/core.asm @@ -4,13 +4,13 @@ %include "inc/engine.inc" %ifidn __OUTPUT_FORMAT__, bin - org g1g2(0x452640,0x459190,0x456D20,0x457470) + org g1g2(0x452604,0x459190,0x456D20,0x457470) %endif bits 32 ; This address space spans multiple methods of the deprecated class -; 'zCNetEventManager' starting with zCNetEventManager::HandleNetMessage. +; 'zCNetEventManager' starting with zCNetEventManager::_CreateNewInstance. ; After a long testing period any safety checks for ensuring that the ; overwritten methods are indeed never called are now omitted. diff --git a/src/exec/misc.asm b/src/exec/misc.asm index 3ef0f08..48ed34f 100644 --- a/src/exec/misc.asm +++ b/src/exec/misc.asm @@ -288,6 +288,51 @@ recoverInvalidItem: jmp g1g2(0x66DC47,0x69B420,0x6AFBB9,0x70D6D9) + 6 +global recoverInvalidItem2 +recoverInvalidItem2: + resetStackoffset g1g2(0x110,0x110,0x158,0x15C) + %assign var_loopIndex -g1g2(0xE8,0xD8,0x138,0x140) + %assign var_numInvSlots -g1g2(0xB8,0xA8,0xEC,0x100) + %assign var_used -g1g2(0x38,0x38,0x6C,0x70) + + mov eax, [esp+stackoffset+var_loopIndex] ; Check if first iteration (i.e. index == 0) + test eax, eax + jnz .backOriginal ; If not, jump back as original + + mov eax, [esi] ; Read as integer and store it + call [eax+0x60] ; zCArchive->ReadInt + addStack 4 + + movzx ecx, BYTE [esp+stackoffset+var_used] ; Take only the lowest byte + cmp ecx, 0x1 ; Check if boolean (i.e. low byte <= 1) + verifyStackoffset g1g2(0x110,0x110,0x158,0x15C) - 0x4 + jbe .backCorrect ; If so, continue as expected + + mov eax, [esp+stackoffset+var_used] ; Fix the misread values + mov [esp+stackoffset+var_numInvSlots], eax ; Update maximum loop iterations + + mov ecx, esi ; Read the next (correct) value from archive + lea eax, [esp+stackoffset+var_used] + push eax + mov eax, [esi] + call [eax+0x80] ; zCArchive->ReadBool + addStack 4 + verifyStackoffset g1g2(0x110,0x110,0x158,0x15C) - 0x4 + jmp .back + +.backCorrect: + mov [esp+stackoffset+var_used], ecx ; Nothing to fix, continue as expected + jmp .back + +.backOriginal: + mov eax, [esi] ; Re-write original instruction + call [eax+0x80] ; zCArchive->ReadBool + addStack 4 + +.back: + jmp g1g2(0x6A3DD9,0x6D67BB,0x6E96C1,0x748161) + 6 + + global ninja_injectInfo ninja_injectInfo: resetStackoffset ; 0xBC diff --git a/verifySize.bat b/verifySize.bat index 3803dd0..e34024b 100644 --- a/verifySize.bat +++ b/verifySize.bat @@ -24,7 +24,7 @@ SET filename=%~nx1 IF NOT EXIST %filefull% ECHO File '%filefull%' not found.&& EXIT /B 1 :: Set size limits in bytes corresponding to the available address range -IF %gothic% == 1 SET SIZELIMIT=11280 +IF %gothic% == 1 SET SIZELIMIT=11340 IF %gothic% == 112 SET SIZELIMIT=12096 IF %gothic% == 130 SET SIZELIMIT=11895 IF %gothic% == 2 SET SIZELIMIT=11904