implement savechar/loadchar on DCv2 and Xbox
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoDC
|
||||
data:
|
||||
.data 0x8C4EC4E0 # char_file_part1
|
||||
.data 0x8C4EC4E4 # char_file_part2
|
||||
# Server adds a PSODCV2CharacterFile here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoDC
|
||||
data:
|
||||
.data 0x8C4EC4E0 # char_file_part1
|
||||
.data 0x8C4EC4E4 # char_file_part2
|
||||
# Server adds a PSODCV2CharacterFile here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoDC
|
||||
data:
|
||||
.data 0x8C4E5F80 # char_file_part1
|
||||
.data 0x8C4E5F84 # char_file_part2
|
||||
# Server adds a PSODCV2CharacterFile here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoDC
|
||||
data:
|
||||
.data 0x8C4DB9E0 # char_file_part1
|
||||
.data 0x8C4DB9E4 # char_file_part2
|
||||
# Server adds a PSODCV2CharacterFile here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x00632E04 # char_file_part1
|
||||
.data 0x00632EA8 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x0063269C # char_file_part1
|
||||
.data 0x00632740 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x0062D844 # char_file_part1
|
||||
.data 0x0062D8E8 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x0062DDE4 # char_file_part1
|
||||
.data 0x0062DE88 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x0063591C # char_file_part1
|
||||
.data 0x006359C0 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x00632E04 # char_file_part1
|
||||
.data 0x00632EA8 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,13 @@
|
||||
.meta hide_from_patches_menu
|
||||
.meta name="SetExtendedPlayerInfo"
|
||||
.meta description=""
|
||||
|
||||
entry_ptr:
|
||||
reloc0:
|
||||
.offsetof start
|
||||
start:
|
||||
.include SetExtendedPlayerInfoXB
|
||||
data:
|
||||
.data 0x0063319C # char_file_part1
|
||||
.data 0x00633240 # char_file_part2
|
||||
# Server adds a PSOXBCharacterFileCharacter here
|
||||
@@ -0,0 +1,83 @@
|
||||
start:
|
||||
sts.l -[r15], pr
|
||||
|
||||
mova r0, [data] # r8 = data pointer
|
||||
mov r7, r0
|
||||
|
||||
# memcpy(char_file_part1, inbound_part1, sizeof(char_file_part1))
|
||||
mov.l r4, [r7]
|
||||
mov.l r4, [r4]
|
||||
mov r5, r7
|
||||
add r5, 8
|
||||
calls memcpy
|
||||
mov.l r6, [part1_size]
|
||||
|
||||
# First, copy some important fields out of the saved character so that the
|
||||
# game won't consider the character corrupt. Note that r5 already points to
|
||||
# inbound_part2 here since it immediately follows inbound_part1.
|
||||
mov.l r4, [r7 + 4]
|
||||
mov.l r4, [r4]
|
||||
mov r1, r4 # r1 = character_file_part2
|
||||
mov r2, r5 # r2 = inbound_part2
|
||||
|
||||
mov r4, r2
|
||||
mov r5, r1
|
||||
mov.l r0, [r5 + 0x04] # creation_timestamp
|
||||
mov.l [r4 + 0x04], r0
|
||||
mov.l r0, [r5 + 0x08] # signature
|
||||
mov.l [r4 + 0x08], r0
|
||||
add r4, 0x14
|
||||
add r5, 0x14
|
||||
calls memcpy # save_count, ppp_username, ppp_password (0x30 bytes total)
|
||||
mov r6, 0x30
|
||||
|
||||
mov r4, r2
|
||||
mov r5, r1
|
||||
mov.l r0, [v1_creds_offset]
|
||||
add r4, r0
|
||||
add r5, r0
|
||||
calls memcpy # v1_serial_number, v1_access_key
|
||||
mov r6, 0x20
|
||||
|
||||
mov r4, r2
|
||||
mov r5, r1
|
||||
mov.l r0, [v2_creds_offset]
|
||||
add r4, r0
|
||||
add r5, r0
|
||||
calls memcpy # v2_serial_number, v2_access_key
|
||||
mov r6, 0x20
|
||||
|
||||
# memcpy(char_file_part2, inbound_part2, sizeof(char_file_part2))
|
||||
mov r4, r1
|
||||
mov r5, r2
|
||||
calls memcpy
|
||||
mov.l r6, [part2_size]
|
||||
|
||||
lds.l pr, [r15]+
|
||||
rets
|
||||
mov r0, 0
|
||||
|
||||
memcpy:
|
||||
test r6, r6
|
||||
bt memcpy_done
|
||||
mov.l r0, [r5]+
|
||||
mov.l [r4], r0
|
||||
add r4, 4
|
||||
bs memcpy
|
||||
add r6, -4
|
||||
memcpy_done:
|
||||
rets
|
||||
nop
|
||||
|
||||
.align 4
|
||||
part1_size:
|
||||
.data 0x0000041C
|
||||
part2_size:
|
||||
.data 0x000012D8
|
||||
v1_creds_offset:
|
||||
.data 0x0000118C
|
||||
v2_creds_offset:
|
||||
.data 0x000012B8
|
||||
|
||||
.align 4
|
||||
data:
|
||||
@@ -0,0 +1,39 @@
|
||||
push ebx
|
||||
|
||||
jmp get_data_ptr
|
||||
get_data_ptr_ret:
|
||||
pop ebx
|
||||
|
||||
# Copy part1 data into place
|
||||
mov eax, [ebx]
|
||||
mov eax, [eax]
|
||||
lea edx, [ebx + 8]
|
||||
mov ecx, 0x041C
|
||||
call memcpy
|
||||
|
||||
# Copy part2 data into place, but retain the values of a few metadata fields
|
||||
# so the game won't think the file is corrupt
|
||||
mov eax, [ebx + 4]
|
||||
mov eax, [eax]
|
||||
push dword [eax + 0x04] # creation_timestamp
|
||||
push dword [eax + 0x08] # signature
|
||||
push dword [eax + 0x14] # save_count
|
||||
lea edx, [ebx + 0x0424]
|
||||
mov ecx, 0x23B8 # Intentionally skip the last 0xF0 bytes since they aren't populated by the server
|
||||
call memcpy
|
||||
mov eax, [ebx + 4]
|
||||
mov eax, [eax]
|
||||
pop dword [eax + 0x14] # save_count
|
||||
pop dword [eax + 0x08] # signature
|
||||
pop dword [eax + 0x04] # creation_timestamp
|
||||
|
||||
mov eax, 1
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
memcpy:
|
||||
.include CopyData
|
||||
ret
|
||||
|
||||
get_data_ptr:
|
||||
call get_data_ptr_ret
|
||||
Reference in New Issue
Block a user