Skip to content

Instantly share code, notes, and snippets.

@justinian
Created November 1, 2023 06:13
Show Gist options
  • Save justinian/13195d70e11e0a76e1e55f27b07d4d84 to your computer and use it in GitHub Desktop.
Save justinian/13195d70e11e0a76e1e55f27b07d4d84 to your computer and use it in GitHub Desktop.
Ark Survival Ascended save file parsing work
#!/usr/bin/env python3
def read_from(data, form):
import struct
n = struct.calcsize(form)
return data[n:], struct.unpack_from(form, data)[0]
def read_string(data):
data, n = read_from(data, "I")
if n == 0:
return data, None
return data[n:], data[:n-1].decode('utf-8')
def do_header(con):
cur = con.cursor()
res = cur.execute("SELECT value FROM custom WHERE key = 'SaveHeader'")
row = res.fetchone()[0]
data = row[18:]
parts = []
while True:
data, s = read_string(data)
if s is None:
break
parts.append(s)
data, _ = read_from(data, "I") # always -1
data = data[8:]
ids = {}
while data:
data, tid = read_from(data, "I")
data, name = read_string(data)
ids[tid] = name
return parts, ids
def do_game(con, tids):
from os import makedirs
from uuid import UUID
cur = con.cursor()
res = cur.execute("SELECT key, value FROM game")
rows = res.fetchall()
for row in rows:
uuid = UUID(bytes_le=row[0])
_, tid = read_from(row[1], "I")
tname = tids[tid]
makedirs(f"data/{tname}", exist_ok=True)
with open(f"data/{tname}/{uuid}", "wb") as out:
out.write(row[1])
if __name__ == "__main__":
import sqlite3
con = sqlite3.connect("TheIsland_WP.ark")
_, ids = do_header(con)
do_game(con, ids)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment