Skip to content

Commit

Permalink
Add ZiX-12A support.
Browse files Browse the repository at this point in the history
  • Loading branch information
Lattyware committed Apr 30, 2019
1 parent f54191b commit 27ca4a6
Show file tree
Hide file tree
Showing 6 changed files with 251 additions and 218 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ usage: unrpa [-h] [-v] [-s] [-l] [-p PATH] [-m] [-f VERSION]
| -l, --list | only list contents, do not extract. |
| -p PATH, --path PATH | will extract to the given path. |
| -m, --mkdir | will make any non-existent directories in extraction path. |
| -f VERSION, --force VERSION | forces an archive version. May result in failure.<br>Possible versions: RPA-3.0, ZiX-12B, ALT-1.0, RPA-2.0, RPA-1.0. |
| -f VERSION, --force VERSION | forces an archive version. May result in failure.<br>Possible versions: RPA-3.0, ZiX-12A, ZiX-12B, ALT-1.0, RPA-2.0, RPA-1.0. |
| --continue-on-error | try to continue extraction when something goes wrong. |
| -o OFFSET, --offset OFFSET | sets an offset to be used to decode unsupported archives. |
| -k KEY, --key KEY | sets a key to be used to decode unsupported archives. |
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

setuptools.setup(
name="unrpa",
version="2.0.0",
version="2.0.1",
author="Gareth Latty",
author_email="[email protected]",
description="Extract files from the RPA archive format (from the Ren'Py Visual Novel Engine).",
Expand All @@ -22,5 +22,5 @@
"Operating System :: OS Independent",
"Environment :: Console",
],
entry_points={"console_scripts": ["unrpa = unrpa:__main__"]},
entry_points={"console_scripts": ["unrpa = unrpa.__main__:main"]},
)
9 changes: 2 additions & 7 deletions unrpa/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import io
import os
import pickle
import sys
Expand Down Expand Up @@ -100,11 +99,7 @@ def extract_files(self) -> None:
os.path.join(self.path, os.path.split(path)[0])
)
file_view = self.extract_file(
path,
data,
file_number,
total_files,
cast(io.BufferedReader, archive),
path, data, file_number, total_files, archive
)
with open(os.path.join(self.path, path), "wb") as output_file:
version.postprocess(file_view, output_file)
Expand All @@ -131,7 +126,7 @@ def extract_file(
data: ComplexIndexEntry,
file_number: int,
total_files: int,
archive: io.BufferedIOBase,
archive: BinaryIO,
) -> ArchiveView:
self.log(
UnRPA.info, f"[{file_number / float(total_files):04.2%}] {name:>3}", name
Expand Down
272 changes: 142 additions & 130 deletions unrpa/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,140 +25,152 @@
from unrpa import UnRPA
from unrpa.errors import UnRPAError

parser = argparse.ArgumentParser(
prog="unrpa",
description="Extract files from the RPA archive format (from the Ren'Py Visual Novel Engine).",
)

parser.add_argument(
"-v",
"--verbose",
action="count",
dest="verbose",
default=1,
help="explain what is being done [default].",
)
parser.add_argument(
"-s", "--silent", action="store_const", const=0, dest="verbose", help="no output."
)
parser.add_argument(
"-l",
"--list",
action="store_true",
dest="list",
default=False,
help="only list contents, do not extract.",
)
parser.add_argument(
"-p",
"--path",
action="store",
type=str,
dest="path",
default=None,
help="will extract to the given path.",
)
parser.add_argument(
"-m",
"--mkdir",
action="store_true",
dest="mkdir",
default=False,
help="will make any non-existent directories in extraction path.",
)
parser.add_argument(
"-f",
"--force",
action="store",
type=str,
dest="version",
default=None,
help="forces an archive version. May result in failure. Possible versions: "
+ ", ".join(version.name for version in UnRPA.provided_versions)
+ ".",
)
parser.add_argument(
"--continue-on-error",
action="store_true",
dest="continue_on_error",
default=False,
help="try to continue extraction when something goes wrong.",
)
parser.add_argument(
"-o",
"--offset",
action="store",
type=int,
dest="offset",
default=None,
help="sets an offset to be used to decode unsupported archives.",
)
parser.add_argument(
"-k",
"--key",
action="store",
type=int,
dest="key",
default=None,
help="sets a key to be used to decode unsupported archives.",
)

parser.add_argument("--version", action="version", version="%(prog)s 2.0.0")

parser.add_argument(
"filename", metavar="FILENAME", type=str, help="the RPA file to extract."
)

args: Any = parser.parse_args()

provided_version = None
if args.version:
try:
provided_version = next(
version
for version in UnRPA.provided_versions
if args.version.lower() == version.name.lower()
)
except StopIteration:
parser.error(
"The archive version you gave isn’t one we recognise - it needs to be one of: "
+ ", ".join(version.name for version in UnRPA.provided_versions)
)

provided_offset_and_key: Optional[Tuple[int, int]] = None
if args.key and args.offset:
provided_offset_and_key = (args.offset, args.key)
elif bool(args.key) != bool(args.offset):
parser.error("If you set --key or --offset, you must set both.")
def main() -> None:
parser = argparse.ArgumentParser(
prog="unrpa",
description="Extract files from the RPA archive format (from the Ren'Py Visual Novel Engine).",
)

if args.list and args.path:
parser.error("Option -path: only valid when extracting.")
parser.add_argument(
"-v",
"--verbose",
action="count",
dest="verbose",
default=1,
help="explain what is being done [default].",
)
parser.add_argument(
"-s",
"--silent",
action="store_const",
const=0,
dest="verbose",
help="no output.",
)
parser.add_argument(
"-l",
"--list",
action="store_true",
dest="list",
default=False,
help="only list contents, do not extract.",
)
parser.add_argument(
"-p",
"--path",
action="store",
type=str,
dest="path",
default=None,
help="will extract to the given path.",
)
parser.add_argument(
"-m",
"--mkdir",
action="store_true",
dest="mkdir",
default=False,
help="will make any non-existent directories in extraction path.",
)
parser.add_argument(
"-f",
"--force",
action="store",
type=str,
dest="version",
default=None,
help="forces an archive version. May result in failure. Possible versions: "
+ ", ".join(version.name for version in UnRPA.provided_versions)
+ ".",
)
parser.add_argument(
"--continue-on-error",
action="store_true",
dest="continue_on_error",
default=False,
help="try to continue extraction when something goes wrong.",
)
parser.add_argument(
"-o",
"--offset",
action="store",
type=int,
dest="offset",
default=None,
help="sets an offset to be used to decode unsupported archives.",
)
parser.add_argument(
"-k",
"--key",
action="store",
type=int,
dest="key",
default=None,
help="sets a key to be used to decode unsupported archives.",
)

if args.mkdir and not args.path:
parser.error("Option --mkdir: only valid when --path is set.")
parser.add_argument("--version", action="version", version="%(prog)s 2.0.1")

if not args.mkdir and args.path and not os.path.isdir(args.path):
parser.error(f"No such directory: “{args.path}”. Use --mkdir to create it.")
parser.add_argument(
"filename", metavar="FILENAME", type=str, help="the RPA file to extract."
)

if args.list and args.verbose == 0:
parser.error("Option --list: can’t be silent while listing data.")
args: Any = parser.parse_args()

if not os.path.isfile(args.filename):
parser.error(f"No such file: “{args.filename}”.")
provided_version = None
if args.version:
try:
provided_version = next(
version
for version in UnRPA.provided_versions
if args.version.lower() == version.name.lower()
)
except StopIteration:
parser.error(
"The archive version you gave isn’t one we recognise - it needs to be one of: "
+ ", ".join(version.name for version in UnRPA.provided_versions)
)

try:
extractor = UnRPA(
args.filename,
args.verbose,
args.path,
args.mkdir,
provided_version,
args.continue_on_error,
provided_offset_and_key,
)
if args.list:
extractor.list_files()
else:
extractor.extract_files()
except UnRPAError as error:
sys.exit(f"\n\033[31m{error.message}\n{error.cmd_line_help}\033[30m")
provided_offset_and_key: Optional[Tuple[int, int]] = None
if args.key and args.offset:
provided_offset_and_key = (args.offset, args.key)
elif bool(args.key) != bool(args.offset):
parser.error("If you set --key or --offset, you must set both.")

if args.list and args.path:
parser.error("Option -path: only valid when extracting.")

if args.mkdir and not args.path:
parser.error("Option --mkdir: only valid when --path is set.")

if not args.mkdir and args.path and not os.path.isdir(args.path):
parser.error(f"No such directory: “{args.path}”. Use --mkdir to create it.")

if args.list and args.verbose == 0:
parser.error("Option --list: can’t be silent while listing data.")

if not os.path.isfile(args.filename):
parser.error(f"No such file: “{args.filename}”.")

try:
extractor = UnRPA(
args.filename,
args.verbose,
args.path,
args.mkdir,
provided_version,
args.continue_on_error,
provided_offset_and_key,
)
if args.list:
extractor.list_files()
else:
extractor.extract_files()
except UnRPAError as error:
help_message = f"\n{error.cmd_line_help}" if error.cmd_line_help else ""
sys.exit(f"\n\033[31m{error.message}{help_message}\033[30m")


if __name__ == "__main__":
main()
Loading

0 comments on commit 27ca4a6

Please sign in to comment.