Closed w569111843 closed 9 months ago
The following is the complete error message
python convert.py .\Level.sav --to-json Converting .\Level.sav to JSON, saving to .\Level.sav.json Decompressing sav file Traceback (most recent call last): File "C:\Users\Desktop\palworld-save-tools-main\convert.py", line 115, in
main() File "C:\Users\Desktop\palworld-save-tools-main\convert.py", line 53, in main convert_sav_to_json(args.filename, output_path, args.minify_json) File "C:\Users\Desktop\palworld-save-tools-main\convert.py", line 72, in convert_sav_to_json rawgvas, = decompress_sav_to_gvas(data) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Desktop\palworld-save-tools-main\lib\palsav.py", line 25, in decompress_sav_to_gvas uncompressed_data = zlib.decompress(data[12:]) ^^^^^^^^^^^^^^^^^^^^^^^^^^ zlib.error: Error -5 while decompressing data: incomplete or truncated stream
I found the solution to this error. It involves replacing zlib.decompress
in palsav.py
with a streaming decompression. Here is the code:
def decompress_sav_to_gvas(data: bytes) -> tuple[bytes, int]:
uncompressed_len = int.from_bytes(data[0:4], byteorder="little")
compressed_len = int.from_bytes(data[4:8], byteorder="little")
magic_bytes = data[8:11]
save_type = data[11]
# Check for magic bytes
if magic_bytes != b"PlZ":
raise Exception(
f"not a compressed Palworld save, found {magic_bytes} instead of P1Z"
)
# Valid save types
if save_type not in [0x30, 0x31, 0x32]:
raise Exception(f"unknown save type: {save_type}")
# We only have 0x31 (single zlib) and 0x32 (double zlib) saves
if save_type not in [0x31, 0x32]:
raise Exception(f"unhandled compression type: {save_type}")
if save_type == 0x31:
# Check if the compressed length is correct
if compressed_len != len(data) - 12:
raise Exception(f"incorrect compressed length: {compressed_len}")
# Decompress file using streaming decompression
decompressor = zlib.decompressobj()
uncompressed_data = decompressor.decompress(data[12:] + decompressor.flush())
if save_type == 0x32:
# Check if the compressed length is correct
if compressed_len != len(uncompressed_data):
raise Exception(f"incorrect compressed length: {compressed_len}")
# Decompress file
uncompressed_data = zlib.decompress(uncompressed_data)
# Check if the uncompressed length is correct
if uncompressed_len != len(uncompressed_data):
raise Exception(f"incorrect uncompressed length: {uncompressed_len}")
return uncompressed_data, save_type
This modification replaces the direct use of zlib.decompress
with a streaming approach using decompressobj
. This change addresses the reported error.
But there is another issue: the lengths of uncompressed_data
and compressed_len
for the problematic save file are no longer the same (uncompressed_data < compressed_len
). Is it possible to fix this situation?
[Uploading Level.zip…]() This is an sav file that cannot be read correctly. I really need your help.
Level.zip I'm sorry, the upload was not successful just now
This is a sign of data corruption, in this case the save file being truncated before it was fully written to disk. Switching to a streaming decompressor just masks the issue, hence the check for uncompressed_len
fails.
This is a sign of data corruption. In this case, the save file was truncated before it was fully written to disk. Even when testing with an intact archive, an error -5 occurs during data decompression, indicating an incomplete or truncated stream. However, switching to a streaming decompressor allows successful decryption.
I encountered a situation where the disk space was filled up during server operation. The 'LevelMeta.sav' file in my save folder became 0 bytes, but the 'Level.sav' file and the data in the 'Players' folder are still present. How can I use this tool to fix my save?
Additionally, when I try to use this tool to convert 'Level.sav' to JSON, an error occurs in 'palworld-save-tools-main\lib\palsav.py', specifically in the 'decompress_sav_to_gvas' function at line 25:
The error message is:
How can I resolve this issue?"