Last active
May 16, 2024 15:06
-
-
Save apocalyptech/8f8815c06bde9cd46d5170e1548c1e66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# vim: set expandtab tabstop=4 shiftwidth=4: | |
import struct | |
import argparse | |
def main(): | |
parser = argparse.ArgumentParser( | |
description='Fix Animal Well savefile verification after edits', | |
) | |
parser.add_argument('filename', | |
nargs=1, | |
type=str, | |
help='Save file to edit', | |
) | |
args = parser.parse_args() | |
args.filename = args.filename[0] | |
with open(args.filename, 'r+b') as df: | |
# Read the data and at least check the first uint32 to see if | |
# it's 9, which we believe is a version number for the savefile. | |
data = df.read() | |
df.seek(0) | |
version = struct.unpack('<I', df.read(4))[0] | |
if version != 9: | |
raise RuntimeError(f'{args.filename} does not look like an Animal Well savefile that we understand') | |
# Compute the XOR'd checksum (which lives at byte 0xD). Be sure | |
# to omit whatever checksum is currently living there. (We could | |
# substitute 0x00 but that wouldn't change the XOR, so we're just | |
# skipping the byte entirely.) | |
total = 0 | |
for byte in data[:13] + data[14:]: | |
total ^= byte | |
# Check to see if we even need to write it | |
if total == data[0xD]: | |
print(f'{args.filename}: No need to write checksum -- 0x{total:02X} is already correct') | |
else: | |
packed = struct.pack('<B', total) | |
df.seek(0xD) | |
df.write(packed) | |
print(f'{args.filename}: Wrote new checksum 0x{total:02X} (previous: 0x{data[0xD]:02X})') | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment