73 lines
1.9 KiB
Python
73 lines
1.9 KiB
Python
import argparse
|
|
import os
|
|
|
|
from typing import Optional
|
|
|
|
from bemani.format import IFS
|
|
|
|
|
|
def main() -> None:
|
|
parser = argparse.ArgumentParser(description="A utility to extract IFS files.")
|
|
parser.add_argument(
|
|
"file",
|
|
help="IFS file to extract.",
|
|
type=str,
|
|
)
|
|
parser.add_argument(
|
|
"-d",
|
|
"--directory",
|
|
help="Directory to extract to. Defaults to current directroy.",
|
|
default=".",
|
|
)
|
|
parser.add_argument(
|
|
"--convert-xml-files",
|
|
help="Convert xml files that are in binary to readable text.",
|
|
action="store_true",
|
|
)
|
|
parser.add_argument(
|
|
"--convert-texture-files",
|
|
help="Convert texture files that are in game-format to PNG files.",
|
|
action="store_true",
|
|
)
|
|
args = parser.parse_args()
|
|
|
|
root = args.directory
|
|
if root[-1] != "/":
|
|
root = root + "/"
|
|
root = os.path.realpath(root)
|
|
|
|
fileroot = os.path.dirname(os.path.realpath(args.file))
|
|
|
|
def load_ifs(fname: str, root: bool = False) -> Optional[IFS]:
|
|
fname = os.path.join(fileroot, fname)
|
|
if os.path.isfile(fname):
|
|
fp = open(fname, "rb")
|
|
data = fp.read()
|
|
fp.close()
|
|
|
|
return IFS(
|
|
data,
|
|
decode_binxml=root and args.convert_xml_files,
|
|
decode_textures=root and args.convert_texture_files,
|
|
keep_hex_names=not root,
|
|
reference_loader=load_ifs,
|
|
)
|
|
else:
|
|
return None
|
|
|
|
ifs = load_ifs(args.file, root=True)
|
|
if ifs is None:
|
|
raise Exception(f"Couldn't locate file {args.file}!")
|
|
|
|
for fn in ifs.filenames:
|
|
print(f"Extracting {fn} to disk...")
|
|
realfn = os.path.join(root, fn)
|
|
dirof = os.path.dirname(realfn)
|
|
os.makedirs(dirof, exist_ok=True)
|
|
with open(realfn, "wb") as fp:
|
|
fp.write(ifs.read_file(fn))
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|