Skip to content
This repository has been archived by the owner on Apr 21, 2023. It is now read-only.

Commit

Permalink
Added export script and minor fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
NiceneNerd committed Apr 8, 2019
1 parent 4e54477 commit cd77cdc
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 2 deletions.
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,40 @@ optional arguments:
-v, --verbose Verbose output covering every file processed
```

### Export Mod Configuration

```
python export.py LotsOfCoolMods.zip
```

This script exports all of your installed mods, including the BCML merges, into a single modpack. By default, it exports in graphicPack format, but it also supports SDCafiine and the MLC folder in Cemu (or on the Wii U). Usage info:

```
usage: export.py [-h] [-d DIRECTORY] [-o] [-s | -m] [-t TITLE] output
Exports BCML-managed files as a standalone mod
positional arguments:
output Path to the mod ZIP that BCML should create
optional arguments:
-h, --help show this help message and exit
-d DIRECTORY, --directory DIRECTORY
Specify path to Cemu graphicPacks folder, default assumes relative path from BCML install directory
-o, --onlymerges Only include the merged RSTB and packs, not all installed content
-s, --sdcafiine Export in SDCafiine format instead of graphicPack
-m, --mlc Export in the MLC content format instead of graphicPack
-t TITLE, --title TITLE
The TitleID to use for SDCafiine or mlc export, default 00050000101C9400 (US version)
```

More details on each argument (except `--directory`, because it's been covered):

* `--onlymerges`: By default, BCML will create a zip with the whole contents of all your active mod files. This option exports *only* the RSTB and any packs which BCML has merged. I'm not entirely sure why you might need this, but it's here in case you do.
* `--sdcafiine`: By default, BCML exports to Cemu's graphicPack format. This option exports to a format which can be easily used with SDCafiine on your Wii U instead.
* `--mlc`: By default, BCML exports to Cemu's graphicPack format. This option exports to a format that can be extracted directly into the MLC directory for Cemu or on your Wii U using FTPiiU.
* `--title`: By default, BCML assumes you are using the US version of BOTW. Use this option with SDCafiine or MLC exports to specify the TitleID for another region.

## Known Bugs

* At present, this probably only works completely with the US version of the game. I don't yet have hashes or complete RSTB info for non-US versions. If you would like to help with that, open an issue.
Expand Down
78 changes: 78 additions & 0 deletions export.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import argparse
import glob
import os
import zipfile

args = None

def main():
sdir = os.getcwd()

files = {}
for mod in glob.iglob(os.path.join(args.directory, 'BotwMod*')):
if args.onlymerges and '999' not in mod: continue
os.chdir(mod)
for file in glob.iglob('**\\*', recursive=True):
if file.endswith('.log') or file.endswith('.md') or file == 'rules.txt': continue
files[file] = os.path.abspath(file)
os.chdir(sdir)

exzip = zipfile.ZipFile(args.output, mode='w', compression=zipfile.ZIP_DEFLATED)
for file in files:
if args.sdcafiine:
arcfile = os.path.join(f'{args.title}', 'bcml-mod', file)
elif args.mlc:
if file.startswith('aoc'):
arcfile = os.path.join('usr', 'title', args.title.replace('00050000', '00050000\\'), file.replace('aoc\\0010','aoc\\content\\0010'))
else:
arcfile = os.path.join('usr', 'title', args.title.replace('00050000', '00050000\\'), file)
else:
arcfile = file
exzip.write(files[file], arcfile)

if args.sdcafiine:
with open('README.md', 'w') as readme:
readme.writelines([
'# BCML Export SDCafiine Readme\n\n',
'To install, just extract the contents of this ZIP file to your SD card at the path:\n',
'/sdcafiine/\n\n',
'That\'s really all there is to it!'
])
exzip.write(os.path.abspath('README.md'), 'README.md')
os.remove('README.md')
elif args.mlc:
with open('README.md', 'w') as readme:
readme.writelines([
'# BCML Export MLC Readme\n\n',
'To install, just extract the contents of this ZIP file to the mlc01 folder where you installed Cemu, for example:\n',
'C:\\Cemu\\mlc01\n\n',
'That\'s really all there is to it!'
])
exzip.write(os.path.abspath('README.md'), 'README.md')
os.remove('README.md')
else:
with open('tmprules.txt','w') as rules:
rules.writelines([
'[Definition]\n',
'titleIds = 00050000101C9300,00050000101C9400,00050000101C9500\n',
'name = Exported BCML Mod\n',
'path = The Legend of Zelda: Breath of the Wild/BCML Mods/Exported BCML\n',
'description = Exported contents of all BCML-managed mods\n',
'version = 4\n'
])
exzip.write(os.path.abspath('tmprules.txt'), 'rules.txt')
os.remove('tmprules.txt')

exzip.close()

if __name__ == "__main__":
parser = argparse.ArgumentParser(description = 'Exports BCML-managed files as a standalone mod')
parser.add_argument('output', help = 'Path to the mod ZIP that BCML should create')
parser.add_argument('-d', '--directory', help = 'Specify path to Cemu graphicPacks folder, default assumes relative path from BCML install directory', default = '..\\graphicPacks', type = str)
parser.add_argument('-o', '--onlymerges', help = 'Only include the merged RSTB and packs, not all installed content', action = 'store_true')
formats = parser.add_mutually_exclusive_group()
formats.add_argument('-s', '--sdcafiine', help = 'Export in SDCafiine format instead of graphicPack', action = 'store_true')
formats.add_argument('-m', '--mlc', help = 'Export in the MLC content format instead of graphicPack', action = 'store_true')
parser.add_argument('-t', '--title', help = 'The TitleID to use for SDCafiine or mlc export, default 00050000101C9400 (US version)', default = '00050000101C9400', type = str)
args = parser.parse_args()
main()
2 changes: 1 addition & 1 deletion helpers/mergepacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def main(path, verbose):
newpath = os.path.join(path, 'BotwMod_mod999_BCML', packpath)
os.makedirs(os.path.dirname(newpath), exist_ok=True)
shutil.copy(basepack, newpath)
os.system(f'sarc update {tmpdir} {newpath}')
os.system('sarc update {} {}{}'.format(tmpdir, newpath, ' >nul 2>&1' if not verbose else ''))
shutil.rmtree(tmpdir)

if __name__ == "__main__":
Expand Down
2 changes: 1 addition & 1 deletion install.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ def main():
with open(os.path.join(moddir,'packs.log'),'w') as plog:
plog.write('name,path\n')
for pack in modfiles.keys():
if pack.endswith('pack'):
if (pack.endswith('pack') or pack.endswith('sarc')) and packs[pack]['path'] != '':
plog.write('{},{}\n'.format(pack, modfiles[pack]['path'].replace('/','\\')))

p = args.priority if args.priority > 100 else modid
Expand Down

0 comments on commit cd77cdc

Please sign in to comment.