CONSCRIPT: How to Extract Randomized Codes From Saves

A small python script to extract things like the picture/music/journal code, or the dog tag code, etc, from your save file.

 

How to Use This

This was made on Python 3.8, but later versions probably work. YMMV.

  • Save the code below to any file with a `py` extension.
  • Run the script with the path to the save file as the first argument.
    If you have Python installed and associated with `py` files, you can just drag/drop the file onto the py file itself.
  • Viola. Just read the output window.

Example output text:

Chapter 1 Front Line Trench (Abandon Post) Code:                           3081
Chapter 3 Prison Camp Code:                                                6771
Chapter 6 Fort Vaux Lion Door Code:                                        7682
Chapter 6 Weapon Storage Locker 1 (Left) Code:                             3765
Chapter 6 Weapon Storage Locker 3 (Right) Code Part 1 (Symbols):           1043
Chapter 6 Weapon Storage Locker 3 (Right) Code Part 2 (Last Journal Code): 2418

For the last code, the journal/picture code, 0 is the musical note. Move the dials numerically with that in mind.

Save File Location

%LOCALAPPDATA%\CONSCRIPT\Steam

The Script

import binascii
import json
import msvcrt
import pathlib
import sys
import zlib

# Save location:
# %LOCALAPPDATA%\CONSCRIPT\Steam

try:
    import pydevd
    DEBUGGING = True
except ImportError:
    DEBUGGING = False

if len(sys.argv) < 2:
    print("Error: Missing file argument.")
    exit()

saveFile = pathlib.Path(sys.argv[1])
txtFile  = pathlib.Path(sys.argv[1]).with_suffix(".txt")

with open(saveFile, "rb") as file:
    saveBytes = file.read()

contents = zlib.decompress(saveBytes)
contents = contents.decode("utf-8").strip()
contents = contents[:-1] # Strip null terminator.
contents = binascii.unhexlify(contents)
contents = contents[16:len(contents)] # Strip first 16 bytes.
#print(contents)

#with open(txtFile, "wb") as file:
#    file.write(contents)
#    print(f"\nContents written as: {txtFile}\n")

class SaveData(object):
    def __init__(self, j):
        # `[1]` because the first array entry is `roomData` and we can ignore that.
        # Even on new games, `roomData` will always be present even if empty.
        self.__dict__ = json.loads(j)[1]

data = SaveData(contents)

print(f"Chapter 1 Front Line Trench (Abandon Post) Code:                           {int(data.introBattleCode)}")
print(f"Chapter 3 Prison Camp Code:                                                {int(data.campLockCode)}")
print(f"Chapter 6 Fort Vaux Lion Door Code:                                        {int(data.isolementCode)}")
print(f"Chapter 6 Weapon Storage Locker 1 (Left) Code:                             {int(data.tagLockerCode)}")
print(f"Chapter 6 Weapon Storage Locker 3 (Right) Code Part 1 (Symbols):           {int(data.pierreCodeVal1)}{int(data.pierreCodeVal2)}{int(data.pierreCodeVal3)}{int(data.pierreCodeVal4)}")
print(f"Chapter 6 Weapon Storage Locker 3 (Right) Code Part 2 (Last Journal Code): {int(data.pierreBoxCode)}")

if not DEBUGGING:
    print("Press any key to continue.")
    msvcrt.getch()

Leave a Comment