Skip to content

Commit 61b8ad1

Browse files
committed
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.
1 parent 1d9fe00 commit 61b8ad1

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ BIN_BASE := core \
142142
hook_oCSpawnManager__Archive \
143143
hook_npcReference \
144144
hook_recoverInvalidItem \
145+
hook_recoverInvalidItem2 \
145146
hook_fastexit \
146147
hook_CGameManager_destructor \
147148
hook_libExit \

src/core.asm

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44
%include "inc/engine.inc"
55

66
%ifidn __OUTPUT_FORMAT__, bin
7-
org g1g2(0x452640,0x459190,0x456D20,0x457470)
7+
org g1g2(0x452604,0x459190,0x456D20,0x457470)
88
%endif
99

1010
bits 32
1111

1212
; This address space spans multiple methods of the deprecated class
13-
; 'zCNetEventManager' starting with zCNetEventManager::HandleNetMessage.
13+
; 'zCNetEventManager' starting with zCNetEventManager::_CreateNewInstance.
1414
; After a long testing period any safety checks for ensuring that the
1515
; overwritten methods are indeed never called are now omitted.
1616

src/exec/misc.asm

+45
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,51 @@ recoverInvalidItem:
288288
jmp g1g2(0x66DC47,0x69B420,0x6AFBB9,0x70D6D9) + 6
289289

290290

291+
global recoverInvalidItem2
292+
recoverInvalidItem2:
293+
resetStackoffset g1g2(0x110,0x110,0x158,0x15C)
294+
%assign var_loopIndex -g1g2(0xE8,0xD8,0x138,0x140)
295+
%assign var_numInvSlots -g1g2(0xB8,0xA8,0xEC,0x100)
296+
%assign var_used -g1g2(0x38,0x38,0x6C,0x70)
297+
298+
mov eax, [esp+stackoffset+var_loopIndex] ; Check if first iteration (i.e. index == 0)
299+
test eax, eax
300+
jnz .backOriginal ; If not, jump back as original
301+
302+
mov eax, [esi] ; Read as integer and store it
303+
call [eax+0x60] ; zCArchive->ReadInt
304+
addStack 4
305+
306+
movzx ecx, BYTE [esp+stackoffset+var_used] ; Take only the lowest byte
307+
cmp ecx, 0x1 ; Check if boolean (i.e. low byte <= 1)
308+
verifyStackoffset g1g2(0x110,0x110,0x158,0x15C) - 0x4
309+
jbe .backCorrect ; If so, continue as expected
310+
311+
mov eax, [esp+stackoffset+var_used] ; Fix the misread values
312+
mov [esp+stackoffset+var_numInvSlots], eax ; Update maximum loop iterations
313+
314+
mov ecx, esi ; Read the next (correct) value from archive
315+
lea eax, [esp+stackoffset+var_used]
316+
push eax
317+
mov eax, [esi]
318+
call [eax+0x80] ; zCArchive->ReadBool
319+
addStack 4
320+
verifyStackoffset g1g2(0x110,0x110,0x158,0x15C) - 0x4
321+
jmp .back
322+
323+
.backCorrect:
324+
mov [esp+stackoffset+var_used], ecx ; Nothing to fix, continue as expected
325+
jmp .back
326+
327+
.backOriginal:
328+
mov eax, [esi] ; Re-write original instruction
329+
call [eax+0x80] ; zCArchive->ReadBool
330+
addStack 4
331+
332+
.back:
333+
jmp g1g2(0x6A3DD9,0x6D67BB,0x6E96C1,0x748161) + 6
334+
335+
291336
global ninja_injectInfo
292337
ninja_injectInfo:
293338
resetStackoffset ; 0xBC

verifySize.bat

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ SET filename=%~nx1
2424
IF NOT EXIST %filefull% ECHO File '%filefull%' not found.&& EXIT /B 1
2525

2626
:: Set size limits in bytes corresponding to the available address range
27-
IF %gothic% == 1 SET SIZELIMIT=11280
27+
IF %gothic% == 1 SET SIZELIMIT=11340
2828
IF %gothic% == 112 SET SIZELIMIT=12096
2929
IF %gothic% == 130 SET SIZELIMIT=11895
3030
IF %gothic% == 2 SET SIZELIMIT=11904

0 commit comments

Comments
 (0)