From b6d196e1befe91864081a6d889410342e9338aae Mon Sep 17 00:00:00 2001 From: CensoredUsername Date: Fri, 4 Jan 2019 20:09:39 +0100 Subject: [PATCH] Resolve #74: Some games have more script files than file handles that the OS support, so read them all straight into memory instead of keeping the file descriptors open --- un.rpyc/compile.py | 5 +++-- un.rpyc/unrpyc-compile.py | 13 +++++-------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/un.rpyc/compile.py b/un.rpyc/compile.py index 8cb3df9c..16838faf 100755 --- a/un.rpyc/compile.py +++ b/un.rpyc/compile.py @@ -84,6 +84,7 @@ def Exec(code): # an easter egg exec ''' +import StringIO try: import renpy except Exception: @@ -105,8 +106,8 @@ def Exec(code): continue elif (dir, fn[:-1]) not in files: abspath = os.path.join(dir, fn) if dir else os.path.join(basepath, fn) - fobj = renpy.loader.load(fn) - sys.files.append((abspath, fn, dir, fobj)) + with renpy.loader.load(fn) as file: + sys.files.append((abspath, fn, dir, file.read())) ''' in globals() _0 # util diff --git a/un.rpyc/unrpyc-compile.py b/un.rpyc/unrpyc-compile.py index 78611c50..e026b791 100644 --- a/un.rpyc/unrpyc-compile.py +++ b/un.rpyc/unrpyc-compile.py @@ -45,9 +45,8 @@ def __setstate__(self, state): factory = magic.FakeClassFactory((PyExpr, PyCode), magic.FakeStrict) -def read_ast_from_file(in_file): +def read_ast_from_file(raw_contents): # .rpyc files are just zlib compressed pickles of a tuple of some data and the actual AST of the file - raw_contents = in_file.read() if raw_contents.startswith("RENPY RPC2"): # parse the archive structure position = 10 @@ -70,12 +69,12 @@ def ensure_dir(filename): if dir and not path.exists(dir): os.makedirs(dir) -def decompile_rpyc(file_obj, abspath, init_offset): +def decompile_rpyc(data, abspath, init_offset): # Output filename is input filename but with .rpy extension filepath, ext = path.splitext(abspath) out_filename = filepath + ('.rpym' if ext == ".rpymc" else ".rpy") - ast = read_ast_from_file(file_obj) + ast = read_ast_from_file(data) ensure_dir(out_filename) with codecs.open(out_filename, 'w', encoding='utf-8') as out_file: @@ -90,17 +89,15 @@ def decompile_game(): with open(logfile, "w") as f: f.write("Beginning decompiling\n") - for abspath, fn, dir, file in sys.files: + for abspath, fn, dir, data in sys.files: try: - decompile_rpyc(file, abspath, sys.init_offset) + decompile_rpyc(data, abspath, sys.init_offset) except Exception, e: f.write("\nFailed at decompiling {0}\n".format(abspath)) traceback = sys.modules['traceback'] traceback.print_exc(None, f) else: f.write("\nDecompiled {0}\n".format(abspath)) - finally: - file.close() f.write("\nend decompiling\n")