rveitch
11/28/2015 - 9:27 PM

Fallout Shelter Python Script

Fallout Shelter Python Script

__author__ = 'RV'

#internal libraries
import os
import sys
import json
import base64

#external libraries
from Crypto.Cipher import AES  #pip install pycrypto

salt = "tu89geji340t89u2"
passphrase = "a7ca9f3366d892c2f0bef417341ca971b69ae9f7bacccffcf43c62d1d7d021f9".decode("hex")

def encrypt_save_str(json_str):
    cipher = AES.new(passphrase, AES.MODE_CBC, salt)
    if utils.parse_json(json_str):
        return base64.b64encode(cipher.encrypt(utils.pkcs7_pad_str(json_str)))
    return None

def decrypt_save_str(enc_str, pretty_json = True):
    cipher = AES.new(passphrase, AES.MODE_CBC, salt)
    if utils.parse_base64(enc_str):
        decrypted = cipher.decrypt(base64.b64decode(enc_str))
        if decrypted[-1] != "}":  #fix numerous different paddings
            decrypted = decrypted.rstrip(decrypted[-1])
        if utils.parse_json(decrypted):
            if pretty_json:
                decrypted = json.dumps(json.loads(decrypted), indent=4)
            return decrypted
    return None

def encrypt_save_file(in_json_file, out_save_file):
    cipher = AES.new(passphrase, AES.MODE_CBC, salt)
    if os.path.isfile(in_json_file):
        file_contents = open(in_json_file, "r").read()
        if utils.parse_json(file_contents):
            encrypted = base64.b64encode(cipher.encrypt(utils.pkcs7_pad_str(file_contents)))
            open(out_save_file, "w").write(encrypted)

def decrypt_save_file(in_save_file, out_json_file, pretty_json = True):
    cipher = AES.new(passphrase, AES.MODE_CBC, salt)
    if os.path.isfile(in_save_file):
        file_contents = open(in_save_file, "r").read()
        if utils.parse_base64(file_contents):
            decrypted = cipher.decrypt(base64.b64decode(file_contents))
            if decrypted[-1] != "}":  #fix numerous different paddings
                decrypted = decrypted.rstrip(decrypted[-1])
            if utils.parse_json(decrypted):
                if pretty_json:
                    decrypted = json.dumps(json.loads(decrypted), indent=4)
                open(out_json_file, "w").write(decrypted)

class utils(object):
    @staticmethod
    def pkcs7_pad_str(s):
        padding_count = (16 - len(s) % 16)
        return s + (padding_count * chr(padding_count))

    @staticmethod
    def parse_base64(s):
        try:
            base64.decodestring(s)
            return True
        except:
            return False

    @staticmethod
    def parse_json(s):
        try:
            json.loads(s)
            return True
        except:
            return False

args = [sys.argv[x] for x in range(1, len(sys.argv))]  #remove first arg
if len(args) == 3:
    mode = args[0].lower()
    input_file = args[1]
    output_file = args[2]
    if mode == "decrypt" or mode == "encrypt":
        if os.path.isfile(input_file):
            if mode == "decrypt":
                print "Decrypting \"{}\" to \"{}\"...".format(input_file, output_file)
                decrypt_save_file(input_file, output_file)
                print "Done!"
            elif mode == "encrypt":
                print "Encrypting \"{}\" to \"{}\"...".format(input_file, output_file)
                encrypt_save_file(input_file, output_file)
                print "Done!"
        else:
            print "Input file \"{}\" doesn't exist!".format(input_file)
    else:
        print "Invalid mode specified."
        print "Mode should be either encrypt or decrypt."
else:
    print "Not enough arguments (" + str(len(args)) + " given out of 3)"
    print "USAGE: FSM.exe (encrypt/decrypt) (input file) (output file)"
print "Press ENTER to exit..."
raw_input()  #wait on enter

'''
#example for modding lunchboxes
num_boxes = 4000
modded_json = json.loads(open("modded.json", "r").read())
for x in range(0, num_boxes):
    modded_json["vault"]["LunchBoxesByType"].append(0)
    modded_json["vault"]["LunchBoxesCount"] += 1
open("modded.json", "w").write(json.dumps(modded_json))
'''