Example #1
0
    def read_index(infile):
        l = infile.read(24)
        offset = int(l[8:], 16)
        infile.seek(offset)
        index = loads(zlib.decompress(infile.read()))

        return index
Example #2
0
    def read_index(infile):
        l = infile.read(40)
        offset = int(l[8:24], 16)
        key = int(l[25:33], 16)
        infile.seek(offset)
        index = loads(zlib.decompress(infile.read()))

        def start_to_bytes(s):
            if not s:
                return b''

            if not isinstance(s, bytes):
                s = s.encode("latin-1")

            return s

        # Deobfuscate the index.

        for k in index.keys():

            if len(index[k][0]) == 2:
                index[k] = [ (offset ^ key, dlen ^ key) for offset, dlen in index[k] ]
            else:
                index[k] = [ (offset ^ key, dlen ^ key, start_to_bytes(start)) for offset, dlen, start in index[k] ]

        return index
Example #3
0
def load(filename):
    """
    Loads persistence data from `filename`. Returns None if the data
    could not be loaded, or a Persistent object if it could be
    loaded.
    """

    if not os.path.exists(filename):
        return None

    # Unserialize the persistent data.
    try:
        with open(filename, "rb") as f:
            s = zlib.decompress(f.read())
        persistent = loads(s)
    except Exception:
        import renpy.display

        try:
            renpy.display.log.write("Loading persistent.")
            renpy.display.log.exception()
        except Exception:
            pass

        return None

    persistent._update()

    return persistent
Example #4
0
def load(filename):
    """
    :doc: loadsave

    Loads the game state from the save slot `filename`. If the file is loaded
    successfully, this function never returns.
    """

    roots, log = loads(location.load(filename))
    log.unfreeze(roots, label="_after_load")
Example #5
0
def load_cache():
    if renpy.game.args.compile:  # type: ignore
        return

    try:
        with renpy.loader.load(CACHE_FILENAME) as f:
            c = loads(zlib.decompress(f.read()))

        if c.version == ccache.version:
            ccache.ast_eval_cache.update(c.ast_eval_cache)
            ccache.ast_exec_cache.update(c.ast_exec_cache)
    except Exception:
        pass
Example #6
0
    def init_bytecode(self):
        """
        Init/Loads the bytecode cache.
        """

        # Load the oldcache.
        try:
            with renpy.loader.load(BYTECODE_FILE) as f:
                version, cache = loads(zlib.decompress(f.read()))
                if version == BYTECODE_VERSION:
                    self.bytecode_oldcache = cache

        except Exception:
            pass
Example #7
0
    def read_index(infile):
        l = infile.read(40)
        offset = int(l[8:24], 16)
        key = int(l[25:33], 16)
        infile.seek(offset)
        index = loads(zlib.decompress(infile.read()))

        # Deobfuscate the index.

        for k in index.keys():

            if len(index[k][0]) == 2:
                index[k] = [(offset ^ key, dlen ^ key)
                            for offset, dlen in index[k]]
            else:
                index[k] = [(offset ^ key, dlen ^ key, start)
                            for offset, dlen, start in index[k]]
        return index
Example #8
0
    def restore(self):
        """
        Restores the modules to a state similar to the state of the modules
        when the backup was created.
        """

        if not self.names:
            return

        # Remove new variables from the module.
        for mod, names in self.names.items():
            modvars = vars(mod)
            for name in set(modvars.keys()) - names:
                del modvars[name]

        objects = pickle.loads(self.objects_pickle)

        for k, v in self.variables.items():
            mod, field = k
            setattr(mod, field, objects[v])
Example #9
0
    def load_file(self, dir, fn): # @ReservedAssignment

        if fn.endswith(".rpy") or fn.endswith(".rpym"):

            if not dir:
                raise Exception("Cannot load rpy/rpym file %s from inside an archive." % fn)

            base, _, game = dir.rpartition("/")
            olddir = base + "/old-" + game

            fullfn = dir + "/" + fn
            rpycfn = fullfn + "c"

            oldrpycfn = olddir + "/" + fn + "c"

            stmts = renpy.parser.parse(fullfn)

            data = { }
            data['version'] = script_version
            data['key'] = self.key or 'unlocked'

            if stmts is None:
                return data, [ ]

            used_names = set()

            for mergefn in [ oldrpycfn, rpycfn ]:

                # See if we have a corresponding .rpyc file. If so, then
                # we want to try to upgrade our .rpy file with it.
                try:
                    self.record_pycode = False

                    with open(mergefn, "rb") as rpycf:
                        bindata = self.read_rpyc_data(rpycf, 1)

                    if bindata is not None:
                        old_data, old_stmts = loads(bindata)
                        self.merge_names(old_stmts, stmts, used_names)

                    del old_data
                    del old_stmts
                except Exception:
                    pass
                finally:
                    self.record_pycode = True

            self.assign_names(stmts, renpy.parser.elide_filename(fullfn))

            pickle_data_before_static_transforms = dumps((data, stmts))

            self.static_transforms(stmts)

            pickle_data_after_static_transforms = dumps((data, stmts))

            if not renpy.macapp:
                try:
                    with open(rpycfn, "wb") as f:
                        self.write_rpyc_header(f)
                        self.write_rpyc_data(f, 1, pickle_data_before_static_transforms)
                        self.write_rpyc_data(f, 2, pickle_data_after_static_transforms)

                        with open(fullfn, "rb") as fullf:
                            rpydigest = hashlib.md5(fullf.read()).digest()

                        self.write_rpyc_md5(f, rpydigest)
                except Exception:
                    import traceback
                    traceback.print_exc()

            self.loaded_rpy = True

        elif fn.endswith(".rpyc") or fn.endswith(".rpymc"):

            data = None
            stmts = None

            with renpy.loader.load(fn) as f:
                for slot in [ 2, 1 ]:
                    try:
                        bindata = self.read_rpyc_data(f, slot)

                        if bindata:
                            data, stmts = loads(bindata)
                            break

                    except Exception:
                        pass

                    f.seek(0)

                else:
                    return None, None

                if data is None:
                    print("Failed to load", fn)
                    return None, None

                if not isinstance(data, dict):
                    return None, None

                if self.key and data.get('key', 'unlocked') != self.key:
                    return None, None

                if data['version'] != script_version:
                    return None, None

                if slot < 2:
                    self.static_transforms(stmts)

        else:
            return None, None

        return data, stmts
Example #10
0
def loads(s):
    if renpy.config.use_cpickle:
        return cPickle.loads(s)
    else:
        return pickle.loads(s)
Example #11
0
def index_archives():
    """
    Loads in the indexes for the archive files. Also updates the lower_map.
    """

    # Index the archives.

    global old_config_archives

    if old_config_archives == renpy.config.archives:
        return

    old_config_archives = renpy.config.archives[:]

    # Update lower_map.
    lower_map.clear()

    cleardirfiles()

    global archives
    archives = []

    for prefix in renpy.config.archives:

        try:
            fn = transfn(prefix + ".rpa")
            f = open(fn, "rb")
            l = f.readline()

            # 3.0 Branch.
            if l.startswith(b"RPA-3.0 "):
                offset = int(l[8:24], 16)
                key = int(l[25:33], 16)
                f.seek(offset)
                index = loads(zlib.decompress(f.read()))

                # Deobfuscate the index.

                for k in index.keys():

                    if len(index[k][0]) == 2:
                        index[k] = [(offset ^ key, dlen ^ key)
                                    for offset, dlen in index[k]]
                    else:
                        index[k] = [(offset ^ key, dlen ^ key, start)
                                    for offset, dlen, start in index[k]]

                archives.append((prefix, index))

                f.close()
                continue

            # 2.0 Branch.
            if l.startswith(b"RPA-2.0 "):
                offset = int(l[8:], 16)
                f.seek(offset)
                index = loads(zlib.decompress(f.read()))
                archives.append((prefix, index))
                f.close()
                continue

            # 1.0 Branch.
            f.close()

            fn = transfn(prefix + ".rpi")
            index = loads(zlib.decompress(open(fn, "rb").read()))
            archives.append((prefix, index))
        except:
            raise

    for dir, fn in listdirfiles():  # @ReservedAssignment
        lower_map[fn.lower()] = fn

    for fn in remote_files:
        lower_map[fn.lower()] = fn
Example #12
0
 def read_index(infile):
     return loads(zlib.decompress(infile.read()))
Example #13
0
def MultiPersistent(name, save_on_quit=False):

    name = renpy.exports.fsdecode(name)

    if not renpy.game.context().init_phase:
        raise Exception("MultiPersistent objects must be created during the init phase.")

    if renpy.android or renpy.ios:
        # Due to the security policy of mobile devices, we store MultiPersistent
        # in the same place as common persistent.
        # This is better than not working at all.
        files = [ renpy.config.savedir ]

    elif renpy.windows:
        files = [ os.path.expanduser("~/RenPy/Persistent") ]

        if 'APPDATA' in os.environ:
            files.append(renpy.exports.fsdecode(os.environ['APPDATA']) + "/RenPy/persistent")

    elif renpy.macintosh:
        files = [ os.path.expanduser("~/.renpy/persistent"),
                  os.path.expanduser("~/Library/RenPy/persistent") ]
    else:
        files = [ os.path.expanduser("~/.renpy/persistent") ]

    if "RENPY_MULTIPERSISTENT" in os.environ:
        files = [ renpy.exports.fsdecode(os.environ["RENPY_MULTIPERSISTENT"]) ]

    # Make the new persistent directory, why not?
    try:
        os.makedirs(files[-1]) # type: ignore
    except Exception:
        pass

    fn = "" # prevent a warning from happening.
    data = None

    # Find the first file that actually exists. Otherwise, use the last
    # file.
    for fn in files:
        fn = os.path.join(fn, name) # type: ignore
        if os.path.isfile(fn):
            try:
                data = open(fn, "rb").read()
                break
            except Exception:
                pass

    rv = _MultiPersistent()

    if data is not None:
        try:
            rv = loads(data)
        except Exception:
            renpy.display.log.write("Loading MultiPersistent at %r:" % fn)
            renpy.display.log.exception()

    rv._filename = fn

    if save_on_quit:
        save_MP_instances.add(rv)

    return rv
Example #14
0
    def load_file(self, dir, fn):  # @ReservedAssignment

        if fn.endswith(".rpy") or fn.endswith(".rpym"):

            if not dir:
                raise Exception(
                    "Cannot load rpy/rpym file %s from inside an archive." %
                    fn)

            fullfn = dir + "/" + fn
            rpycfn = fullfn + "c"

            stmts = renpy.parser.parse(fullfn)

            data = {}
            data['version'] = script_version
            data['key'] = self.key or 'unlocked'

            if stmts is None:
                return data, []

            # See if we have a corresponding .rpyc file. If so, then
            # we want to try to upgrade our .rpy file with it.
            try:
                self.record_pycode = False

                with open(rpycfn, "rb") as rpycf:
                    bindata = self.read_rpyc_data(rpycf, 1)

                old_data, old_stmts = loads(bindata)

                self.merge_names(old_stmts, stmts)

                del old_data
                del old_stmts
            except:
                pass
            finally:
                self.record_pycode = True

            self.assign_names(stmts, renpy.parser.elide_filename(fullfn))

            if not renpy.macapp:

                try:
                    f = open(rpycfn, "wb")

                    self.write_rpyc_header(f)
                    self.write_rpyc_data(f, 1, dumps((data, stmts), 2))
                except:
                    pass

            self.static_transforms(stmts)

            if not renpy.macapp:

                try:
                    self.write_rpyc_data(f, 2, dumps((data, stmts), 2))

                    with open(fullfn, "rU") as fullf:
                        rpydigest = hashlib.md5(fullf.read()).digest()

                    self.write_rpyc_md5(f, rpydigest)

                    f.close()
                except:
                    pass

            self.loaded_rpy = True

        elif fn.endswith(".rpyc") or fn.endswith(".rpymc"):

            data = None
            stmts = None

            f = renpy.loader.load(fn)

            try:

                for slot in [2, 1]:
                    try:
                        bindata = self.read_rpyc_data(f, slot)

                        if bindata:
                            data, stmts = loads(bindata)
                            break

                    except:
                        pass

                    f.seek(0)

                else:
                    return None, None

                if data is None:
                    print("Failed to load", fn)
                    return None, None

                if not isinstance(data, dict):
                    return None, None

                if self.key and data.get('key', 'unlocked') != self.key:
                    return None, None

                if data['version'] != script_version:
                    return None, None

                if slot < 2:
                    self.static_transforms(stmts)

            finally:
                f.close()

        else:
            return None, None

        return data, stmts