Extend profiles from 280 to 312 bytes with legacy compatibility. Keep tower relics run-local and share the profile bankroll.
295 lines
8.5 KiB
PHP
295 lines
8.5 KiB
PHP
; Existing signed saves are imported read-only. New writes stay in runtime/profiles.
|
|
BuildNativeProfileDir3D PROC
|
|
invoke CopyCString, OFFSET saveDirPath, nativeProfilesDirPtr3D
|
|
ret
|
|
BuildNativeProfileDir3D ENDP
|
|
|
|
ValidateGraphicProfile3D PROC uses ebx esi edi path:DWORD
|
|
local io:DWORD,fileBytes:DWORD,signature:DWORD
|
|
invoke CreateFileA, path, 80000000h, 1, 0, 3, 80h, 0
|
|
cmp eax, -1
|
|
je profile_invalid
|
|
mov ebx, eax
|
|
invoke GetFileSize, ebx, 0
|
|
mov fileBytes, eax
|
|
cmp eax, 32
|
|
jb profile_close_invalid
|
|
cmp eax, SAVE_FILE_SIZE
|
|
ja profile_close_invalid
|
|
invoke ReadFile, ebx, OFFSET entrySaveData3D, SAVE_FILE_SIZE, ADDR io, 0
|
|
test eax, eax
|
|
jz profile_close_invalid
|
|
invoke CloseHandle, ebx
|
|
mov eax, fileBytes
|
|
cmp eax, io
|
|
jne profile_invalid
|
|
cmp DWORD PTR entrySaveData3D, SAVE_MAGIC
|
|
jne profile_invalid
|
|
cmp DWORD PTR entrySaveData3D[4], 1000000000
|
|
ja profile_invalid
|
|
cmp fileBytes, SAVE_LEGACY_SIZE
|
|
jb profile_valid
|
|
mov esi, OFFSET entrySaveData3D
|
|
mov ecx, SAVE_SIGN_SIZE/4
|
|
mov eax, SAVE_SALT
|
|
profile_signature:
|
|
rol eax, 5
|
|
xor eax, [esi]
|
|
mov edx, eax
|
|
shr edx, 16
|
|
xor eax, edx
|
|
add eax, 9E3779B9h
|
|
add esi, 4
|
|
loop profile_signature
|
|
cmp eax, DWORD PTR entrySaveData3D[SAVE_SIGN_SIZE]
|
|
jne profile_invalid
|
|
cmp fileBytes,SAVE_LEGACY_SIZE
|
|
je profile_valid
|
|
cmp fileBytes,SAVE_FILE_SIZE
|
|
jne profile_invalid
|
|
invoke ValidateArtifactSave3D,OFFSET entrySaveData3D
|
|
test eax,eax
|
|
jz profile_invalid
|
|
profile_valid:
|
|
mov eax, 1
|
|
ret
|
|
profile_close_invalid:
|
|
invoke CloseHandle, ebx
|
|
profile_invalid:
|
|
xor eax, eax
|
|
ret
|
|
ValidateGraphicProfile3D ENDP
|
|
|
|
ScanGraphicProfiles3D PROC uses ebx esi edi
|
|
local index:DWORD
|
|
invoke CopyCString, OFFSET entryPattern3D, OFFSET entryScanDir3D
|
|
invoke AppendCString, OFFSET entryPattern3D, OFFSET entryWildcard3D
|
|
invoke FindFirstFileA, OFFSET entryPattern3D, OFFSET entryFindData3D
|
|
cmp eax, -1
|
|
je profile_scan_done
|
|
mov ebx, eax
|
|
profile_scan_next:
|
|
cmp entryAccountCount3D, 20
|
|
jae profile_scan_close
|
|
test DWORD PTR entryFindData3D, 10h
|
|
jnz profile_scan_advance
|
|
; Restrict account stems to the same safe alphabet as account creation.
|
|
mov esi, OFFSET entryFindData3D+44
|
|
xor ecx, ecx
|
|
profile_scan_name:
|
|
mov al, [esi+ecx]
|
|
cmp al, '.'
|
|
je profile_scan_extension
|
|
cmp ecx, 50
|
|
jae profile_scan_advance
|
|
cmp al, '0'
|
|
jb profile_scan_letter
|
|
cmp al, '9'
|
|
jbe profile_scan_char_ok
|
|
profile_scan_letter:
|
|
or al, 20h
|
|
cmp al, 'a'
|
|
jb profile_scan_symbol
|
|
cmp al, 'z'
|
|
jbe profile_scan_char_ok
|
|
profile_scan_symbol:
|
|
mov al, [esi+ecx]
|
|
cmp al, '_'
|
|
je profile_scan_char_ok
|
|
cmp al, '-'
|
|
jne profile_scan_advance
|
|
profile_scan_char_ok:
|
|
inc ecx
|
|
jmp profile_scan_name
|
|
profile_scan_extension:
|
|
test ecx, ecx
|
|
jz profile_scan_advance
|
|
lea eax, [esi+ecx]
|
|
invoke lstrcmpiA, eax, OFFSET entryDat3D
|
|
test eax, eax
|
|
jnz profile_scan_advance
|
|
mov index, 0
|
|
profile_scan_duplicate:
|
|
mov eax, index
|
|
cmp eax, entryAccountCount3D
|
|
jae profile_scan_validate
|
|
shl eax, 6
|
|
add eax, OFFSET entryAccountNames3D
|
|
invoke lstrcmpiA, eax, esi
|
|
test eax, eax
|
|
jz profile_scan_advance
|
|
inc index
|
|
jmp profile_scan_duplicate
|
|
profile_scan_validate:
|
|
invoke CopyCString, OFFSET entryScanPath3D, OFFSET entryScanDir3D
|
|
invoke AppendCString, OFFSET entryScanPath3D, OFFSET pathSlashText
|
|
invoke AppendCString, OFFSET entryScanPath3D, esi
|
|
invoke ValidateGraphicProfile3D, OFFSET entryScanPath3D
|
|
test eax, eax
|
|
jz profile_scan_advance
|
|
mov eax, entryAccountCount3D
|
|
mov edx, DWORD PTR entrySaveData3D[4]
|
|
mov entryAccountBanks3D[eax*4], edx
|
|
shl eax, 6
|
|
add eax, OFFSET entryAccountNames3D
|
|
invoke CopyCString, eax, esi
|
|
mov eax, entryAccountCount3D
|
|
imul eax, 260
|
|
add eax, OFFSET entryAccountPaths3D
|
|
invoke CopyCString, eax, OFFSET entryScanPath3D
|
|
inc entryAccountCount3D
|
|
profile_scan_advance:
|
|
invoke FindNextFileA, ebx, OFFSET entryFindData3D
|
|
test eax, eax
|
|
jnz profile_scan_next
|
|
profile_scan_close:
|
|
invoke FindClose, ebx
|
|
profile_scan_done:
|
|
ret
|
|
ScanGraphicProfiles3D ENDP
|
|
|
|
CollectGraphicProfiles3D PROC
|
|
mov entryAccountCount3D, 0
|
|
invoke CopyCString, OFFSET entryScanDir3D, nativeProfilesDirPtr3D
|
|
call ScanGraphicProfiles3D
|
|
; Do not call BuildAppDataDir here: discovery must not create outside folders.
|
|
invoke GetEnvironmentVariableA, OFFSET appDataEnvName, OFFSET entryScanDir3D, 220
|
|
test eax, eax
|
|
jz profiles_workspace
|
|
cmp eax, 220
|
|
jae profiles_workspace
|
|
invoke AppendCString, OFFSET entryScanDir3D, OFFSET appDataSubDir
|
|
call ScanGraphicProfiles3D
|
|
profiles_workspace:
|
|
invoke CopyCString, OFFSET entryScanDir3D, OFFSET entryLocalRoot3D
|
|
call ScanGraphicProfiles3D
|
|
ret
|
|
CollectGraphicProfiles3D ENDP
|
|
|
|
SyncGraphicBack3D PROC
|
|
mov eax, shopBackOwned
|
|
and eax, 1FFFh
|
|
or eax, 1
|
|
mov ownedBacks3D, eax
|
|
mov ecx, shopBackStyle
|
|
cmp ecx, 12
|
|
ja graphic_back_default
|
|
bt eax, ecx
|
|
jnc graphic_back_default
|
|
mov selectedBack3D, ecx
|
|
ret
|
|
graphic_back_default:
|
|
mov selectedBack3D, 0
|
|
ret
|
|
SyncGraphicBack3D ENDP
|
|
|
|
SelectGraphicProfile3D PROC uses ebx esi index:DWORD
|
|
mov eax, index
|
|
cmp eax, entryAccountCount3D
|
|
jae graphic_select_fail
|
|
mov ebx, eax
|
|
imul eax, 260
|
|
add eax, OFFSET entryAccountPaths3D
|
|
mov esi, eax
|
|
invoke ValidateGraphicProfile3D, esi
|
|
test eax, eax
|
|
jz graphic_select_fail
|
|
shl ebx, 6
|
|
add ebx, OFFSET entryAccountNames3D
|
|
invoke CopyCString, OFFSET entryFindPath3D, nativeProfilesDirPtr3D
|
|
invoke AppendCString, OFFSET entryFindPath3D, OFFSET pathSlashText
|
|
invoke AppendCString, OFFSET entryFindPath3D, ebx
|
|
invoke lstrcmpiA, esi, OFFSET entryFindPath3D
|
|
test eax, eax
|
|
jz graphic_select_load
|
|
invoke CreateDirectoryA, OFFSET runtime3D, 0
|
|
invoke CreateDirectoryA, nativeProfilesDirPtr3D, 0
|
|
invoke CopyFileA, esi, OFFSET entryFindPath3D, 1
|
|
test eax, eax
|
|
jz graphic_select_fail
|
|
graphic_select_load:
|
|
invoke ValidateGraphicProfile3D, OFFSET entryFindPath3D
|
|
test eax, eax
|
|
jz graphic_select_fail
|
|
call ResetProfileDefaults
|
|
invoke CopyCString, OFFSET saveFileName, ebx
|
|
mov nativeProfileActive3D, 1
|
|
call LoadSave
|
|
call SyncGraphicBack3D
|
|
call ApplySoundVolume
|
|
mov eax, 1
|
|
ret
|
|
graphic_select_fail:
|
|
xor eax, eax
|
|
ret
|
|
SelectGraphicProfile3D ENDP
|
|
|
|
CreateGraphicProfile3D PROC uses ebx
|
|
local previousBank:DWORD,previousOwned:DWORD,previousBack:DWORD
|
|
cmp arrivalNameLength3D, 0
|
|
je graphic_create_fail
|
|
invoke CopyCString, OFFSET entryFindPath3D, nativeProfilesDirPtr3D
|
|
invoke AppendCString, OFFSET entryFindPath3D, OFFSET pathSlashText
|
|
invoke AppendCString, OFFSET entryFindPath3D, OFFSET arrivalName3D
|
|
invoke AppendCString, OFFSET entryFindPath3D, OFFSET entryDat3D
|
|
invoke GetFileAttributesA, OFFSET entryFindPath3D
|
|
cmp eax, -1
|
|
jne graphic_create_fail
|
|
; Also reject a name present in the imported guest list.
|
|
invoke CopyCString, OFFSET entryDisplayName3D, OFFSET arrivalName3D
|
|
invoke AppendCString, OFFSET entryDisplayName3D, OFFSET entryDat3D
|
|
xor ebx, ebx
|
|
graphic_create_duplicate:
|
|
cmp ebx, entryAccountCount3D
|
|
jae graphic_create_store
|
|
mov eax, ebx
|
|
shl eax, 6
|
|
add eax, OFFSET entryAccountNames3D
|
|
invoke lstrcmpiA, eax, OFFSET entryDisplayName3D
|
|
test eax, eax
|
|
jz graphic_create_fail
|
|
inc ebx
|
|
jmp graphic_create_duplicate
|
|
graphic_create_store:
|
|
mov eax, bankroll
|
|
mov previousBank, eax
|
|
mov eax, ownedBacks3D
|
|
mov previousOwned, eax
|
|
mov eax, selectedBack3D
|
|
mov previousBack, eax
|
|
invoke CreateDirectoryA, OFFSET runtime3D, 0
|
|
invoke CreateDirectoryA, nativeProfilesDirPtr3D, 0
|
|
call ResetProfileDefaults
|
|
call ResetArtifacts3D
|
|
invoke CopyCString, OFFSET saveFileName, OFFSET entryDisplayName3D
|
|
mov nativeProfileActive3D, 1
|
|
call SyncGraphicBack3D
|
|
call SaveGame
|
|
call ApplySoundVolume
|
|
invoke ValidateGraphicProfile3D, OFFSET entryFindPath3D
|
|
test eax, eax
|
|
jnz @F
|
|
mov nativeProfileActive3D, 0
|
|
mov eax, previousBank
|
|
mov bankroll, eax
|
|
mov eax, previousOwned
|
|
mov ownedBacks3D, eax
|
|
mov eax, previousBack
|
|
mov selectedBack3D, eax
|
|
ret
|
|
@@:
|
|
mov eax, 1
|
|
ret
|
|
graphic_create_fail:
|
|
xor eax, eax
|
|
ret
|
|
CreateGraphicProfile3D ENDP
|
|
|
|
SaveGraphicProfile3D PROC
|
|
mov eax, ownedBacks3D
|
|
mov shopBackOwned, eax
|
|
mov eax, selectedBack3D
|
|
mov shopBackStyle, eax
|
|
call SaveGame
|
|
ret
|
|
SaveGraphicProfile3D ENDP
|