From 52d780ff34490540e1cadba1cc7a05a73a787918 Mon Sep 17 00:00:00 2001 From: CensoredUsername Date: Wed, 6 Mar 2024 03:13:52 +0100 Subject: [PATCH] Make un.rpyc actually pass the testing harness. --- un.rpyc/compile.py | 78 ++++++++++++++++----------------------- un.rpyc/unrpyc-compile.py | 4 +- 2 files changed, 33 insertions(+), 49 deletions(-) diff --git a/un.rpyc/compile.py b/un.rpyc/compile.py index b59ad04..7854a3b 100755 --- a/un.rpyc/compile.py +++ b/un.rpyc/compile.py @@ -93,6 +93,12 @@ def Exec(code): global files global __package__ +# backup the local environment +renpy_modules = modules.copy() +renpy_meta_path = meta_path.copy() +pickle_package = __package__ +__package__ = "" + # an easter egg exec(''' try: @@ -101,11 +107,12 @@ def Exec(code): raise _Stop(({"version": "broken", "key": "thrown away"}, [])) ''', globals()) +# figure out the files we need to process and load their contents in memory basepath = join(getcwd(), "game") files = listdirfiles() exec(''' -import os, sys, renpy, zlib +import os, sys, renpy, zlib, pathlib sys.files = [] for (dir, fn) in files: if fn.endswith((".rpyc", ".rpymc")): @@ -117,33 +124,20 @@ def Exec(code): abspath = os.path.join(dir, fn) if dir else os.path.join(basepath, fn) with renpy.loader.load(fn) as file: bindata = renpy.game.script.read_rpyc_data(file, 1) - sys.files.append((abspath, fn, dir, bindata)) + sys.files.append((pathlib.Path(abspath), bindata)) ''', globals()) -renpy_modules = modules.copy() - +# tear down the renpy environment exec(''' import sys for i in sys.modules.copy(): if "renpy" in i and not "renpy.execution" in i: sys.modules.pop(i) +sys.meta_path[:] = [i for i in sys.meta_path if "renpy" in i.__class__.__module__] ''', globals()) -renpy_loader = meta_path.pop() -package = __package__ -__package__ = "" - -_0 # decompiler shim -_1 # decompiler.translate shim -_2 # decompiler.astdump shim -_3 # decompiler.util -_4 # decompiler.magic -_5 # decompiler.renpycompat -_6 # decompiler.testcasedecompiler -_7 # decompiler.atldecompiler -_8 # decompiler.sl2decompiler -_9 # decompiler -_10 # unrpyc +# decompiler injection +_0 from unrpyc import decompile_game decompile_game() @@ -151,12 +145,13 @@ def Exec(code): from decompiler.magic import remove_fake_package remove_fake_package("renpy") +modules.clear() modules.update(renpy_modules) -meta_path.append(renpy_loader) -__package__ = package +meta_path[:] = renpy_meta_path +__package__ = pickle_package """ -decompiler_items = ( +decompiler_items = p.GetItem(p.Sequence( p.DeclareModule("decompiler"), p.DeclareModule("decompiler.translate"), p.DeclareModule("decompiler.astdump"), @@ -168,42 +163,32 @@ def Exec(code): Module("decompiler.sl2decompiler", BASE_FOLDER / "decompiler/sl2decompiler.py"), Module("decompiler", BASE_FOLDER / "decompiler/__init__.py", package="decompiler"), Module("unrpyc", PACK_FOLDER / "unrpyc-compile.py") -) +), "unrpyc") decompiler_rpyc = p.ExecTranspile(base + """ from renpy import script_version from renpy.game import script ({'version': script_version, 'key': script.key}, []) -""", decompiler_items) +""", (decompiler_items,)) -decompiler_rpyb = p.ExecTranspile(base + "(None, [])", decompiler_items) - -rpy_items = p.GetItem(p.Sequence( - p.DeclareModule("decompiler"), - p.DeclareModule("decompiler.translate"), - p.DeclareModule("decompiler.astdump"), - Module("decompiler.util", BASE_FOLDER / "decompiler/util.py"), - Module("decompiler.magic", BASE_FOLDER / "decompiler/magic.py", False), - Module("decompiler.renpycompat", BASE_FOLDER / "decompiler/renpycompat.py"), - Module("decompiler.testcasedecompiler", BASE_FOLDER / "decompiler/testcasedecompiler.py"), - Module("decompiler.atldecompiler", BASE_FOLDER / "decompiler/atldecompiler.py"), - Module("decompiler.sl2decompiler", BASE_FOLDER / "decompiler/sl2decompiler.py"), - Module("decompiler", BASE_FOLDER / "decompiler/__init__.py", package="decompiler"), - Module("unrpyc", PACK_FOLDER / "unrpyc-compile.py") -), "unrpyc") +decompiler_rpyb = p.ExecTranspile(base + "(None, [])", (decompiler_items,)) rpy_base = """ init python early hide: + import sys + renpy_modules = sys.modules.copy() + renpy_meta_path = sys.meta_path.copy() + # Set up the namespace import os import os.path - import sys import renpy import renpy.loader import base64 import pickle import zlib + import pathlib basepath = os.path.join(os.getcwd(), "game") files = renpy.loader.listdirfiles() @@ -219,14 +204,12 @@ def Exec(code): abspath = os.path.join(dir, fn) if dir else os.path.join(basepath, fn) with renpy.loader.load(fn) as file: bindata = renpy.game.script.read_rpyc_data(file, 1) - sys.files.append((abspath, fn, dir, bindata)) + sys.files.append((pathlib.Path(abspath), bindata)) - renpy_modules = sys.modules.copy() for i in renpy_modules: if "renpy" in i and not "renpy.execution" in i: sys.modules.pop(i) - - renpy_loader = sys.meta_path.pop() + sys.meta_path[:] = [i for i in sys.meta_path if "renpy" in i.__class__.__module__] # ????????? unrpyc = pickle.loads(base64.b64decode({})) @@ -235,8 +218,9 @@ def Exec(code): from decompiler.magic import remove_fake_package remove_fake_package("renpy") + sys.modules.clear() sys.modules.update(renpy_modules) - sys.meta_path.append(renpy_loader) + sys.meta_path[:] = renpy_meta_path """ unrpyc = zlib.compress( @@ -252,7 +236,7 @@ def Exec(code): 9) unrpy = rpy_base.format( - repr(base64.b64encode(p.optimize(p.dumps(rpy_items, protocol), protocol))) + repr(base64.b64encode(p.optimize(p.dumps(decompiler_items, protocol), protocol))) ) @@ -294,5 +278,5 @@ def Exec(code): p.pprint(decompiler_rpyc, f) with (PACK_FOLDER / "un.rpy.dis").open("w", encoding="utf-8") as f: - pickletools.dis(p.dumps(rpy_items, protocol), f) + pickletools.dis(p.dumps(decompiler_items, protocol), f) diff --git a/un.rpyc/unrpyc-compile.py b/un.rpyc/unrpyc-compile.py index d4bfd82..de6382c 100644 --- a/un.rpyc/unrpyc-compile.py +++ b/un.rpyc/unrpyc-compile.py @@ -51,10 +51,10 @@ def decompile_game(): logfile = Path.cwd().joinpath("game/unrpyc.log.txt") ensure_dir(logfile) - with logfile.open("w") as f: + with logfile.open("w", encoding="utf-8") as f: f.write("Beginning decompiling\n") - for fullpath, _, _, data in sys.files: + for fullpath, data in sys.files: try: decompile_rpyc(data, fullpath) except Exception as e: