Exemple #1
0
    def __init__(self):

        # A map from (module, field) to the id of the object in that field.
        self.variables = {}

        # A map from id(object) to objects. This is discarded after being
        # pickled.
        self.objects = {}

        # A map from module to the set of names in that module.
        self.names = {}

        if mobile:
            return

        for m in sys.modules.values():
            if m is None:
                continue

            self.backup_module(m)

        # A pickled version of self.objects.
        self.objects_pickle = pickle.dumps(self.objects,
                                           pickle.HIGHEST_PROTOCOL)

        self.objects = None
Exemple #2
0
def save():
    """
    Saves the persistent data to disk.
    """

    if not should_save_persistent:
        return

    try:
        data = zlib.compress(dumps(renpy.game.persistent), 3)
        renpy.loadsave.location.save_persistent(data)
    except Exception:
        if renpy.config.developer:
            raise

    global persistent_mtime

    # Prevent updates just after save
    mtime = persistent_mtime

    for mtime, _data in renpy.loadsave.location.load_persistent():
        if mtime <= persistent_mtime:
            continue

    persistent_mtime = mtime
Exemple #3
0
    def backup_module(self, mod):
        """
        Makes a backup of `mod`, which must be a Python module.
        """

        try:
            name = mod.__name__
        except:
            return

        if not name.startswith("renpy"):
            return

        if name in backup_blacklist:
            return

        if name.startswith("renpy.styledata"):
            return

        self.names[mod] = set(vars(mod).keys())

        for k, v in vars(mod).items():

            if k.startswith("__") and k.endswith("__"):
                continue

            if isinstance(v, type_blacklist):
                continue

            if name + "." + k in name_blacklist:
                continue

            idv = id(v)

            self.variables[mod, k] = idv
            self.objects[idv] = v

            # If we have a problem pickling things, uncomment the next block.

            try:
                pickle.dumps(v, pickle.HIGHEST_PROTOCOL)
            except:
                print("Cannot pickle", name + "." + k, "=", repr(v))
                print("Reduce Ex is:",
                      repr(v.__reduce_ex__(pickle.HIGHEST_PROTOCOL)))
Exemple #4
0
    def save_bytecode(self):
        if renpy.macapp:
            return

        if self.bytecode_dirty:
            try:
                fn = renpy.loader.get_path(BYTECODE_FILE)

                with open(fn, "wb") as f:
                    data = (BYTECODE_VERSION, self.bytecode_newcache)
                    f.write(zlib.compress(dumps(data), 3))
            except Exception:
                pass
Exemple #5
0
def save_cache():
    if not ccache.updated:
        return

    if renpy.macapp:
        return

    try:
        data = zlib.compress(dumps(new_ccache, True), 3)

        with open(renpy.loader.get_path(CACHE_FILENAME), "wb") as f:
            f.write(data)
    except Exception:
        pass
Exemple #6
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
Exemple #7
0
def dumps(o):
    if renpy.config.use_cpickle:
        return cPickle.dumps(o, cPickle.HIGHEST_PROTOCOL)
    else:
        return pickle.dumps(o, pickle.HIGHEST_PROTOCOL)
Exemple #8
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