diff --git a/src/ccsaveparser.py b/src/ccsaveparser.py index a52f373..964ddd7 100644 --- a/src/ccsaveparser.py +++ b/src/ccsaveparser.py @@ -1,6 +1,16 @@ import struct +class OFFSETS: + VERSION = 0x42e + KEYS = 0x12DB + ACCOUNT_LEVEL = 0x12AD + + +def _bytes_to_string(bytes): + return str(bytes.split(b"\x00")[0].decode()) + + def load_save(save_file_name): try: with open(save_file_name, "rb") as f: @@ -13,26 +23,22 @@ def load_save(save_file_name): def verify_save(save): try: struct.pack("bbbb", *save[:4]) == b"GVAS" - # This I think just means we have an unreal engine save but for now it should suffice - return True + token = _bytes_to_string(read_token_at_offset(save, OFFSETS.VERSION)) + if token == "CrabChampionsVersion": + return True except struct.error: return False -def read_token_at_offset(save, offset): - # Load the first 16 bytes from the offset +def read_token_at_offset(save, offset, size=1): try: - data = struct.pack("b" * 9, *save[offset : offset + 9]) - if data[-1] == 0x00: - return str(data.split(b"\x00")[0].decode()) - else: - data = struct.pack("b" * 16, *save[offset : offset + 16]) - if data[-1] == 0x00: - return str(data.split(b"\x00")[0].decode()) - else: - return None - except struct.error as e: - print(f"Failed to parse data: {e}") + data = struct.pack("b" * size, *save[offset: offset + size]) + if data[-1] != 0x00: + data = read_token_at_offset(save, offset, size + 1) + return data + except struct.error: + print("Failed to find NULL byte in token, probs not a token") + return None save = load_save("./test.sav") @@ -41,9 +47,11 @@ if verify_save(save): print("Save appears to be a save file of some kind") else: print("The fuck is this shit mate") + exit() # Should be fine to do shit here # print(read_token_at_offset(save, 0x12DB)) # Keys # print(read_token_at_offset(save, 0x12AD)) # AccountLevel -print(read_token_at_offset(save, 0x1329)) # AccountLevel +token = read_token_at_offset(save, OFFSETS.KEYS) +print(_bytes_to_string(token))