Skip to content

Instantly share code, notes, and snippets.

@sekaiwish
Last active February 11, 2024 09:13
Show Gist options
  • Save sekaiwish/1b4a616cf441c1127e1dc4442fc6610a to your computer and use it in GitHub Desktop.
Save sekaiwish/1b4a616cf441c1127e1dc4442fc6610a to your computer and use it in GitHub Desktop.
MHF Quest Backport Script
import os
import argparse
from multiprocessing import Pool
def convert_quest(fn):
if not os.path.exists(args.path + fn):
print(fn, 'does not exist')
return
if os.path.exists(args.path + fn + '.bak'):
print('Skipping', fn)
return
with open(args.path + fn, 'rb+') as f1:
data = bytearray(f1.read())
wp = int.from_bytes(data[0:4], byteorder='little')
if wp == 441600842: # JKR
print(fn, 'not decrypted')
return
print('Converting', fn)
if not args.no_backup:
with open(args.path + fn + '.bak', 'wb') as f2:
f2.write(data)
wp += 96
rp = wp + 4
for i in range(6):
for j in range(4):
data[wp + j] = data[rp + j]
if i == 5:
break
wp += 4
rp += 8
for i in range(180):
data[wp+i] = data[rp+i]
f1.seek(0)
f1.write(data)
parser = argparse.ArgumentParser()
parser.add_argument('-nb', '--no-backup', action='store_true', help='don\'t create backups')
parser.add_argument('-f', '--file', help='convert a single file')
parser.add_argument('-p', '--path', help='use a different path', default='.')
args = parser.parse_args()
args.path += '/' if not args.path.endswith('/') else ''
if not os.path.exists(args.path):
print('Path does not exist')
exit()
if __name__ == '__main__':
if args.file:
convert_quest(args.file)
else:
files = {filename for filename in os.listdir(args.path) if filename.endswith('.bin')}
if files:
with Pool() as p:
p.map(convert_quest, files)
else:
print('Nothing to convert')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment