-
-
Save mariomadproductions/9a649f43cbf3960cbdc4699c2ee97c66 to your computer and use it in GitHub Desktop.
tmd-printer by ihaveamac
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from argparse import ArgumentParser | |
from glob import iglob | |
from os.path import join | |
from sys import argv, exit, stderr | |
parser = ArgumentParser(description='Prints Content IDs and Title Versions.') | |
parser.add_argument('items', help='Path to TMDs or a folder containing TMDs.', nargs='*') | |
parser.add_argument('-verbose', help='Extra output.', action='store_true') | |
group = parser.add_mutually_exclusive_group(required=True) | |
group.add_argument('-id', help='Print Title ID', action='store_true') | |
group.add_argument('-version', help='Print Title Versions', action='store_true') | |
group.add_argument('-content', help='Print Content IDs', action='store_true') | |
a = parser.parse_args() | |
def debug(*args, **kwargs): | |
if a.verbose: | |
print('DEBUG:', *args, file=stderr, **kwargs) | |
items = set() | |
def parse_tmd(fn): | |
with open(fn, 'rb') as f: | |
debug('Reading', fn) | |
f.seek(0x18C) | |
title_id = f.read(8) | |
if a.id: | |
items.add(title_id.hex()) | |
return # all we need then | |
if a.version: | |
f.seek(0x1DC) | |
title_version = int.from_bytes(f.read(2), 'big') | |
debug(f'Adding title version', title_version) | |
items.add(title_version) | |
elif a.content: | |
f.seek(0x1DE) | |
content_count = int.from_bytes(f.read(2), 'big') | |
debug('Content count:', content_count) | |
if title_id[1] in {4, 5}: # not 3DS or Wii U | |
seek_to = 0xB04 | |
read_size = 0x30 | |
else: | |
seek_to = 0x1E4 | |
read_size = 0x24 | |
f.seek(seek_to) | |
for _ in range(content_count): | |
chunk = f.read(read_size) | |
c_id = chunk[0:4].hex() | |
debug('Adding', c_id) | |
items.add(c_id) | |
if title_id[1] == 5 and int.from_bytes(chunk[6:8], 'big') & 2: # check type if Wii U for h3 file | |
debug('Adding h3 for', c_id) | |
items.add(c_id + '.h3') | |
for arg in a.items: | |
try: | |
parse_tmd(arg) | |
except IsADirectoryError: | |
for p in iglob(join(arg, 'tmd.*')): | |
parse_tmd(p) | |
def sorter(x): | |
if a.id: | |
return int(x, 16) | |
elif a.version: | |
return x | |
elif a.content: | |
return int(x[0:8], 16) | |
debug('Sorting') | |
for t in sorted(items, key=sorter): | |
print(t) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment