1
0
mirror of https://github.com/blawar/ooot.git synced 2024-07-02 09:03:36 +00:00
ooot/tools/oot.py
2022-04-13 17:00:41 -04:00

186 lines
3.5 KiB
Python

import sys
import os
import os.path
import json
import math
import hashlib
from pathlib import Path
_assetPath = None
_buildRom = None
_conf = None
def loadJson(path):
try:
with open(path, 'r') as f:
return json.load(f)
except:
raise
def saveJson(path, data):
try:
with open(path, 'w') as f:
json.dump(data, f, indent=4, sort_keys=True)
except:
raise
class ConfSection:
def __init__(self, j):
self.offset = 0
self.size = 0
try:
self.offset = int(j['offset'], 16)
self.size = int(j['size'], 16)
except:
pass
class ConfRom:
def __init__(self, j):
try:
self.UNCOMPRESSED_SIZE = int(j['UNCOMPRESSED_SIZE'], 16)
except:
pass
try:
self.FILE_TABLE_OFFSET = int(j['FILE_TABLE_OFFSET'], 16)
except:
pass
self.hash_md5 = j['hash_md5']
self.FILE_NAMES = j['FILE_NAMES']
class ConfSections:
def __init__(self):
pass
class Conf:
def __init__(self, path):
self.path = path
self.sections = ConfSections()
j = loadJson(path)
for k,v in j['sections'].items():
self.sections.__dict__[k] = ConfSection(v)
self.rom = ConfRom(j['rom'])
def config():
global _conf
if _conf is None:
_conf = Conf(romPath('config.json'))
return _conf
def fixSlashPath(path):
return str(Path(path))
def validBuildOptions():
r = []
base = 'roms'
for f in os.listdir(Path(base)):
if os.path.exists(Path(base).joinpath(f).joinpath('zapd/Config.xml')):
r.append(f)
return r
def setBuildRom(p):
global _buildRom
_buildRom = p
def findBuildRom():
if len(validBuildOptions()) == 1:
return validBuildOptions()[0]
return 'EUR_MQD'
def buildRom():
global _buildRom
if _buildRom is not None:
return _buildRom
if len(sys.argv) < 2:
print('incorrect usage, pass rom name')
exit(0)
_buildRom = sys.argv[1]
return _buildRom
def romPath(rom = '', root = None):
if not root:
root = buildRom()
return fixSlashPath('roms/%s/%s' % (root, rom))
def getAssetPath():
global _assetPath
_assetPath = fixSlashPath('assets/%s' % buildRom())
return _assetPath
def assetPath(s = ''):
return fixSlashPath('%s/%s' % (getAssetPath(), s))
def zapdBinary():
return str(Path('tools/ZAPD/ZAPD.out'))
def yaz0Binary():
return str(Path('tools/yaz0'))
def createDir(path):
Path.mkdir(Path(path), parents=True, exist_ok = True)
def mkdir(path):
createDir(path)
def relPath(path, sub = None):
if sub is None:
sub = basedir
left = os.path.abspath(sub)
path = os.path.abspath(path)
if left.startswith(path):
raise IOError('path is not under this project:\n%s\n%s' % (left, path))
r = path[len(left):]
if r[0] == '/' or r[0] == '\\':
return r[1:]
return r
def sha256_buffer(buffer):
m = hashlib.sha256()
m.update(buffer)
return m.hexdigest()
def getRomHashes(path):
chunkSize = 0x100000 # 1MB
headerSize = 0x1000
r = {}
with open(path, 'rb') as f:
buffer = f.read()
r['complete'] = sha256_buffer(buffer)
r['body'] = sha256_buffer(buffer[headerSize:])
r['chunks'] = []
for i in range(int(math.ceil((len(buffer) - headerSize) / chunkSize))):
offset = headerSize + (i * chunkSize)
r['chunks'].append(sha256_buffer(buffer[offset:offset + chunkSize]))
return r
def calcRomHashes():
for rom in validBuildOptions():
verified = romPath('verified', rom)
configPath = romPath('config.json', rom)
config = loadJson(configPath)
config['sha256'] = []
if not os.path.isdir(verified):
continue
for path in Path(verified).rglob('*.z64'):
config['sha256'].append(getRomHashes(path))
saveJson(configPath, config)
basedir = Path(__file__).absolute().parent.parent