#!/usr/bin/env python import sys, os from romutil import log from romutil import uromkan from romutil import fsutil from romutil import ndsheader from romutil import arclib from optparse import OptionParser, OptionGroup ROMTYPES = ['rar', 'zip', '7z', 'nds'] ARCHIVETYPES = ['rar', 'zip', '7z'] class _main: def __init__(self): import sys self.usage = "usage: %prog [options] file.nds ..." self.version = "%prog 0.1" parser = OptionParser(usage=self.usage, version=self.version) parser.add_option('-i', '--info', action='store_true', dest='info', help='Header information') parser.add_option('-f', '--fix-crc', action='store_true', dest='fixcrc', help='Fix the header CRC.') parser.add_option('-s', '--secure', type='choice', choices=['e', 'd'], action='store', dest='secure', help='[e|d] Encrypt/Decrypt secure area.') fsoptg = OptionGroup(parser, "FAT Filesystem options:", "Options dealing with the FAT filesystem" "within NDS roms.") fsoptg.add_option('-l', '--list', action='store_true', dest='list', help='List contained files') fsoptg.add_option('-c', '--create', action='store_true', dest='create', help='Create files') fsoptg.add_option('-x', '--extract', action='store_true', dest='extract', help='Extract files') generl = OptionGroup(parser, "General options:", "Options that are usable with multiple other" "options.") generl.add_option('-v', '--verbose', action='count', dest='verbose', help='Increase verbosity of output') generl.add_option('-d', '--debug', action='store_true', dest='debug', help='Enable debug output') generl.add_option('-t', '--translate', action='store_true', dest='translate', help='Translate Japanese Characters to Romaji where possible') parser.add_option_group(fsoptg) parser.add_option_group(generl) (options, args) = parser.parse_args() self.options, self.args = options, args if not len(args): parser.print_help() sys.exit(1) log.options['debug'] = options.debug files = fsutil.paths_to_list(args) self.resolve_conflicting_options() if options.info: self.doInfo(fsutil.filter_by_types(args, ROMTYPES)) def resolve_conflicting_options(self): options = self.options if options.create and options.extract: self.error("-c and -x conflict") if options.list and (options.create or options.extract): self.error("-l and -c/-x conflict") if options.info and (options.fixcrc or options.secure): self.error("-i and -f/-s conflict") def doInfo(self, files): for f in files: ext = fsutil.extension_of(f) if ext in ARCHIVETYPES: ndsrom = arclib.extract(f, '*.nds')[0] else: ndsrom = open(f, 'rb') header = ndsheader.NdsHeader(ndsrom) info = header.ndstool_info() self.safep(info) def doFixCrc(self, files): # fix the internal CRC's first, then fix the overall header crc # Internal CRC's: secure_area_crc, logo_crc pass def error(self, text='(appologies, no error text for this error)'): print >>sys.stderr, "Error: " + text + '.' sys.exit(0) def safep(self, text): if self.options.translate: text = uromkan.dekana(text) if sys.platform.startswith('win'): text = uromkan.unistr(text) text = text.encode('mbcs') print text if __name__ == "__main__": _main()