Beispiel #1
0
    def save(self, savegamename=None):
        """Saves a game
		@param savegamename: string with the full path of the savegame file or None to let user pick one
		@return: bool, whether no error happened (user aborting dialog means success)
		"""
        if savegamename is None:
            savegamename = self.gui.show_select_savegame(mode='save')
            if savegamename is None:
                return True  # user aborted dialog
            savegamename = SavegameManager.create_filename(savegamename)

        savegame = savegamename
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            shutil.copyfile(PATHS.SAVEGAME_TEMPLATE, savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError, e:  # usually invalid filename
            headline = _("Failed to create savegame file")
            descr = _(
                "There has been an error while creating your savegame file.")
            advice = _(
                "This usually means that the savegame name contains unsupported special characters."
            )
            self.gui.show_error_popup(headline, descr, advice, unicode(e))
            return self.save(
            )  # retry with new savegamename entered by the user
	def get_metadata(cls, savegamefile):
		"""Returns metainfo of a savegame as dict."""
		metadata = cls.savegame_metadata.copy()
		if isinstance(savegamefile, list):
			return metadata
		db = DbReader(savegamefile)

		try:
			for key in metadata.iterkeys():
				result = db("SELECT `value` FROM `metadata` WHERE `name` = ?", key)
				if result:
					assert len(result) == 1
					metadata[key] = cls.savegame_metadata_types[key](result[0][0])
		except sqlite3.OperationalError as e:
			cls.log.warning('Warning: Cannot read savegame {file}: {exception}'
			                ''.format(file=savegamefile, exception=e))
			return metadata

		screenshot_data = None
		try:
			screenshot_data = db("SELECT value FROM metadata_blob where name = ?", "screen")[0][0]
		except IndexError:
			pass
		except sqlite3.OperationalError:
			pass
		metadata['screenshot'] = screenshot_data

		return metadata
Beispiel #3
0
    def save_map(self, path, prefix):
        map_file = os.path.join(path, prefix + '.sqlite')
        if os.path.exists(map_file):
            os.unlink(map_file)  # the process relies on having an empty file

        db = DbReader(map_file)
        with open('content/map-template.sql') as map_template:
            db.execute_script(map_template.read())

        save_successful = True
        try:
            db('BEGIN')
            for island_id, coords_list in self._iter_islands():
                for x, y in coords_list:
                    tile = self.world.full_map[(x, y)]
                    db('INSERT INTO ground VALUES(?, ?, ?, ?, ?, ?)',
                       island_id, x, y, tile.id, tile.shape, tile.rotation)
            db('COMMIT')
        except sqlite3.Error as e:
            self.log.debug('Error: {error}'.format(error=e.args[0]))
            save_successful = False
        finally:
            db.close()

        return save_successful
Beispiel #4
0
def create_map():
    """
	Create a map with a square island (20x20) at position (20, 20) and return the path
	to the database file.
	"""

    tiles = []
    for x, y in Rect.init_from_topleft_and_size(0, 0, 20, 20).tuple_iter():
        if (0 < x < 20) and (0 < y < 20):
            ground = GROUND.DEFAULT_LAND
        else:
            # Add coastline at the borders.
            ground = GROUND.SHALLOW_WATER
        tiles.append([0, 20 + x, 20 + y] + list(ground))

    fd, map_file = tempfile.mkstemp()
    os.close(fd)

    db = DbReader(map_file)
    with open('content/map-template.sql') as map_template:
        db.execute_script(map_template.read())

    db('BEGIN')
    db.execute_many("INSERT INTO ground VALUES(?, ?, ?, ?, ?, ?)", tiles)
    db('COMMIT')
    db.close()
    return map_file
Beispiel #5
0
 def get_recommended_number_of_players(cls, savegamefile):
     dbdata = DbReader(savegamefile)\
             ("SELECT value FROM properties WHERE name = ?", "players_recommended")
     if dbdata:
         return dbdata[0][0]
     else:
         return "undefined"
	def get_recommended_number_of_players(cls, mapfile):
		"""Returns amount of players recommended for a map *mapfile*."""
		dbdata = DbReader(mapfile) \
			("SELECT value FROM properties WHERE name = ?", "players_recommended")
		if dbdata:
			return dbdata[0][0]
		else:
			return "undefined"
Beispiel #7
0
    def _do_save(self, savegame):
        """Actual save code.
		@param savegame: absolute path"""
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError as e:  # usually invalid filename
            headline = T("Failed to create savegame file")
            descr = T(
                "There has been an error while creating your savegame file.")
            advice = T(
                "This usually means that the savegame name contains unsupported special characters."
            )
            self.ingame_gui.open_error_popup(headline, descr, advice,
                                             unicode(e))
            # retry with new savegamename entered by the user
            # (this must not happen with quicksave/autosave)
            return self.save()
        except OSError as e:
            if e.errno != errno.EACCES:
                raise
            self.ingame_gui.open_error_popup(
                T("Access is denied"),
                T("The savegame file could be read-only or locked by another process."
                  ))
            return self.save()

        try:
            read_savegame_template(db)

            db("BEGIN")
            self.world.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)

            # Store RNG state
            rng_state = json.dumps(self.random.getstate())
            SavegameManager.write_metadata(db, self.savecounter, rng_state)

            # Make sure everything gets written now
            db("COMMIT")
            db.close()
            return True
        except Exception:
            self.log.error("Save Exception:")
            traceback.print_exc()
            # remove invalid savegamefile (but close db connection before deleting)
            db.close()
            os.unlink(savegame)
            return False
Beispiel #8
0
def save_map(world, path, prefix):
    map_file = os.path.join(path, prefix + '.sqlite')
    db = DbReader(map_file)
    read_savegame_template(db)
    db('BEGIN')
    for island in world.islands:
        island_name = '%s_island_%d_%d.sqlite' % (prefix, island.origin.x,
                                                  island.origin.y)
        island_db_path = os.path.join(path, island_name)
        if os.path.exists(island_db_path):
            os.unlink(
                island_db_path)  # the process relies on having an empty file
        db('INSERT INTO island (x, y, file) VALUES(?, ?, ?)', island.origin.x,
           island.origin.y, 'content/islands/' + island_name)
        island_db = DbReader(island_db_path)
        island.save_map(island_db)
        island_db.close()
    db('COMMIT')
    db.close()
Beispiel #9
0
    def save(self, savegamename=None):
        """Saves a game
		@param savegamename: string with the full path of the savegame file or None to let user pick one
		@return: bool, whether save was successfull
		"""
        if savegamename is None:
            savegamename = self.gui.show_select_savegame(mode='save')
            if savegamename is None:
                return False  # user aborted dialog
            savegamename = SavegameManager.create_filename(savegamename)

        savegame = savegamename
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            shutil.copyfile(PATHS.SAVEGAME_TEMPLATE, savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError:  # usually invalid filename
            self.gui.show_popup(_("Invalid filename"),
                                _("You entered an invalid filename."))
            return self.save(
            )  # retry with new savegamename entered by the user
            # this must not happen with quicksave/autosave

        try:
            db("BEGIN")
            self.world.save(db)
            #self.manager.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)

            for instance in self.selected_instances:
                db("INSERT INTO selected(`group`, id) VALUES(NULL, ?)",
                   instance.worldid)
            for group in xrange(len(self.selection_groups)):
                for instance in self.selection_groups[group]:
                    db("INSERT INTO selected(`group`, id) VALUES(?, ?)", group,
                       instance.worldid)

            SavegameManager.write_metadata(db, self.savecounter)
            # make sure everything get's written now
            db("COMMIT")
            db.close()
            return True
        except:
            print "Save Exception"
            traceback.print_exc()
            db.close()  # close db before delete
            os.unlink(savegame)  # remove invalid savegamefile
            return False
Beispiel #10
0
    def save_map(self, path, prefix):
        map_file = os.path.join(path, prefix + '.sqlite')
        if os.path.exists(map_file):
            os.unlink(map_file)  # the process relies on having an empty file

        db = DbReader(map_file)
        with open('content/map-template.sql') as map_template:
            db.execute_script(map_template.read())

        db('BEGIN')
        for island_id, coords_list in self._iter_islands():
            for x, y in coords_list:
                tile = self.world.full_map[(x, y)]
                db('INSERT INTO ground VALUES(?, ?, ?, ?, ?, ?)', island_id, x,
                   y, tile.id, tile.shape, tile.rotation + 45)
        db('COMMIT')
        db.close()
    def check_files(cls):
        """Check that the required atlas files exist."""
        paths = [
            'content' + os.sep + 'actionsets.json',
            'content' + os.sep + 'atlas.sql',
            'content' + os.sep + 'tilesets.json',
        ]
        for path in paths:
            if not os.path.exists(path):
                return False

        # verify that the combined images exist
        db = DbReader(':memory:')
        db.execute_script(open('content' + os.sep + 'atlas.sql').read())
        for db_row in db("SELECT atlas_path FROM atlas"):
            if not os.path.exists(db_row[0]):
                return False
        return True
	def check_files(cls):
		"""Check that the required atlas files exist."""
		paths = [
			PATHS.ACTION_SETS_JSON_FILE,
			PATHS.ATLAS_DB_PATH,
			PATHS.TILE_SETS_JSON_FILE,
		]
		for path in paths:
			if not os.path.exists(path):
				return False

		# verify that the combined images exist
		db = DbReader(':memory:')
		with open(PATHS.ATLAS_DB_PATH) as f:
			db.execute_script(f.read())
		for db_row in db("SELECT atlas_path FROM atlas"):
			if not os.path.exists(db_row[0]):
				return False
		return True
Beispiel #13
0
	def _upgrade(self):
		# fix import loop
		from horizons.savegamemanager import SavegameManager
		metadata = SavegameManager.get_metadata(self.original_path)
		rev = metadata['savegamerev']

		if rev < VERSION.SAVEGAMEREVISION:
			if not SavegameUpgrader.can_upgrade(rev):
				raise SavegameTooOld(revision=rev)

			self.log.warning('Discovered old savegame file, auto-upgrading: {} -> {}'
						     .format(rev, VERSION.SAVEGAMEREVISION))
			db = DbReader(self.final_path)
			db('BEGIN TRANSACTION')

			# placeholder for future upgrade calls
			if rev < 77:
				self._upgrade_to_rev77(db)

			db('COMMIT')
			db.close()
Beispiel #14
0
    def save_map(self, path, prefix, players_recommended):
        map_file = os.path.join(path, prefix + '.sqlite')
        if os.path.exists(map_file):
            os.unlink(map_file)  # the process relies on having an empty file

        db = DbReader(map_file)
        with open('content/map-template.sql') as map_template:
            db.execute_script(map_template.read())

        save_successful = True
        try:
            db('BEGIN')
            for island_id, coords_list in self._iter_islands():
                for x, y in coords_list:
                    tile = self.world.full_map[(x, y)]
                    db('INSERT INTO ground VALUES(?, ?, ?, ?, ?, ?)',
                       island_id, x, y, tile.id, tile.shape, tile.rotation)
            #test code to implement number of players recommended
            name = "players_recommended"
            if type(players_recommended) == int:
                value = players_recommended
            elif type(players_recommended) == str:
                value = int(players_recommended)
            elif type(players_recommended) == float:
                value = int(float(players_recommended))
            else:
                value = ""
            db('INSERT INTO properties VALUES(?,?)', name, value)
            db('COMMIT')
        except sqlite3.Error as e:
            self.log.debug('Error: {error}'.format(error=e.args[0]))
            save_successful = False
        finally:
            db.close()

        return save_successful
    def __init__(self, game_identifier, is_map, options=None):
        is_random_map = False
        if is_map:
            self.upgrader = None
            handle, self._temp_path = tempfile.mkstemp()
            os.close(handle)
            super().__init__(dbfile=self._temp_path)
            with open('content/savegame_template.sql') as savegame_template:
                self.execute_script(savegame_template.read())

            if isinstance(game_identifier, list):
                is_random_map = True
                random_island_sequence = game_identifier
            else:
                self._map_path = game_identifier
        else:
            self.upgrader = SavegameUpgrader(game_identifier)
            self._temp_path = None
            game_identifier = self.upgrader.get_path()
            super().__init__(dbfile=game_identifier)

            map_name_data = self('SELECT value FROM metadata WHERE name = ?',
                                 'map_name')
            if not map_name_data:
                is_random_map = True
                random_island_sequence = self(
                    'SELECT value FROM metadata WHERE name = ?',
                    'random_island_sequence')[0][0].split(' ')
            else:
                map_name = map_name_data[0][0]
                if map_name.startswith('USER_MAPS_DIR:'):
                    self._map_path = PATHS.USER_MAPS_DIR + map_name[
                        len('USER_MAPS_DIR:'):]
                elif os.path.isabs(map_name):
                    self._map_path = map_name
                else:
                    self._map_path = SavegameManager.get_filename_from_map_name(
                        map_name)

        if is_random_map:
            handle, self._temp_path2 = tempfile.mkstemp()
            os.close(handle)
            random_map_db = DbReader(self._temp_path2)
            with open('content/map-template.sql') as map_template:
                random_map_db.execute_script(map_template.read())
            for island_id, island_string in enumerate(random_island_sequence):
                create_random_island(random_map_db, island_id, island_string)
            random_map_db.close()
            self._map_path = self._temp_path2

            self('INSERT INTO metadata VALUES(?, ?)', 'random_island_sequence',
                 ' '.join(random_island_sequence))

        if options is not None:
            if options.map_padding is not None:
                self("INSERT INTO map_properties VALUES(?, ?)", 'padding',
                     options.map_padding)

        if not os.path.exists(self._map_path):
            raise MapFileNotFound("Map file " + str(self._map_path) +
                                  " not found!")

        self('ATTACH ? AS map_file', self._map_path)
        if is_random_map:
            self.map_name = random_island_sequence
        elif os.path.isabs(self._map_path):
            self.map_name = self._map_path
        else:
            self.map_name = SavegameManager.get_savegamename_from_filename(
                self._map_path)

        map_padding = self(
            "SELECT value FROM map_properties WHERE name = 'padding'")
        self.map_padding = int(
            map_padding[0][0]) if map_padding else MAP.PADDING

        self._load_building()
        self._load_settlement()
        self._load_concrete_object()
        self._load_production()
        self._load_storage()
        self._load_wildanimal()
        self._load_unit()
        self._load_building_collector()
        self._load_production_line()
        self._load_unit_path()
        self._load_storage_global_limit()
        self._load_health()
        self._load_fish_data()
        self._hash = None
 def get_players_num(cls, savegamefile):
     """Return number of regular human and ai players"""
     return DbReader(
         savegamefile
     )("SELECT count(rowid) FROM player WHERE is_trader = 0 AND is_pirate = 0"
       )[0][0]
Beispiel #17
0
    def _do_save(self, savegame):
        """Actual save code.
		@param savegame: absolute path"""
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError as e:  # usually invalid filename
            headline = _("Failed to create savegame file")
            descr = _(
                "There has been an error while creating your savegame file.")
            advice = _(
                "This usually means that the savegame name contains unsupported special characters."
            )
            self.gui.show_error_popup(headline, descr, advice, unicode(e))
            return self.save(
            )  # retry with new savegamename entered by the user
            # this must not happen with quicksave/autosave
        except OSError as e:
            if e.errno == errno.EACCES:
                self.gui.show_error_popup(
                    _("Access is denied"),
                    _("The savegame file could be read-only or locked by another process."
                      ))
                return self.save()
            raise

        try:
            read_savegame_template(db)

            db("BEGIN")
            self.world.save(db)
            #self.manager.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)
            LastActivePlayerSettlementManager().save(db)

            for instance in self.selected_instances:
                db("INSERT INTO selected(`group`, id) VALUES(NULL, ?)",
                   instance.worldid)
            for group in xrange(len(self.selection_groups)):
                for instance in self.selection_groups[group]:
                    db("INSERT INTO selected(`group`, id) VALUES(?, ?)", group,
                       instance.worldid)

            rng_state = json.dumps(self.random.getstate())
            SavegameManager.write_metadata(db, self.savecounter, rng_state)
            # make sure everything gets written now
            db("COMMIT")
            db.close()
            return True
        except:
            print "Save Exception"
            traceback.print_exc()
            db.close()  # close db before delete
            os.unlink(savegame)  # remove invalid savegamefile
            return False
    def _upgrade(self):
        # fix import loop
        from horizons.savegamemanager import SavegameManager
        metadata = SavegameManager.get_metadata(self.original_path)
        rev = metadata['savegamerev']
        if rev == 0:  # not a regular savegame, usually a map
            self.final_path = self.original_path
        elif rev == VERSION.SAVEGAMEREVISION:  # the current version
            self.final_path = self.original_path
        else:  # upgrade
            self.using_temp = True
            handle, self.final_path = tempfile.mkstemp(
                prefix='uh-savegame.' +
                os.path.basename(os.path.splitext(self.original_path)[0]) +
                '.',
                suffix='.sqlite')
            os.close(handle)
            shutil.copyfile(self.original_path, self.final_path)
            db = DbReader(self.final_path)
            db('BEGIN TRANSACTION')

            if rev < 49:
                self._upgrade_to_rev49(db)
            if rev < 50:
                self._upgrade_to_rev50(db)
            if rev < 51:
                self._upgrade_to_rev51(db)
            if rev < 52:
                self._upgrade_to_rev52(db)
            if rev < 53:
                self._upgrade_to_rev53(db)
            if rev < 54:
                self._upgrade_to_rev54(db)
            if rev < 55:
                self._upgrade_to_rev55(db)
            if rev < 56:
                self._upgrade_to_rev56(db)
            if rev < 57:
                self._upgrade_to_rev57(db)
            if rev < 58:
                self._upgrade_to_rev58(db)
            if rev < 59:
                self._upgrade_to_rev59(db)
            if rev < 60:
                self._upgrade_to_rev60(db)
            if rev < 61:
                self._upgrade_to_rev61(db)
            if rev < 62:
                self._upgrade_to_rev62(db)
            if rev < 63:
                self._upgrade_to_rev63(db)
            if rev < 64:
                self._upgrade_to_rev64(db)
            if rev < 65:
                self._upgrade_to_rev65(db)
            if rev < 66:
                self._upgrade_to_rev66(db)
            if rev < 67:
                self._upgrade_to_rev67(db)
            if rev < 68:
                self._upgrade_to_rev68(db)
            if rev < 69:
                self._upgrade_to_rev69(db)
            if rev < 70:
                self._upgrade_to_rev70(db)

            db('COMMIT')
            db.close()
    def __init__(self, game_identifier, is_map):
        is_random_map = False
        if is_map:
            self.upgrader = None
            handle, self._temp_path = tempfile.mkstemp()
            os.close(handle)
            super(SavegameAccessor, self).__init__(dbfile=self._temp_path)
            with open('content/savegame_template.sql') as savegame_template:
                self.execute_script(savegame_template.read())

            if isinstance(game_identifier, list):
                is_random_map = True
                random_island_sequence = game_identifier
            else:
                self._map_path = game_identifier
        else:
            self.upgrader = SavegameUpgrader(game_identifier)
            self._temp_path = None
            game_identifier = self.upgrader.get_path()
            super(SavegameAccessor, self).__init__(dbfile=game_identifier)

            map_name_data = self('SELECT value FROM metadata WHERE name = ?',
                                 'map_name')
            if not map_name_data:
                is_random_map = True
                random_island_sequence = self(
                    'SELECT value FROM metadata WHERE name = ?',
                    'random_island_sequence')[0][0].split(' ')
            else:
                map_name = map_name_data[0][0]
                if os.path.isabs(map_name):
                    self._map_path = map_name
                else:
                    self._map_path = SavegameManager.get_filename_from_map_name(
                        map_name)

        if is_random_map:
            handle, self._temp_path2 = tempfile.mkstemp()
            os.close(handle)
            random_map_db = DbReader(self._temp_path2)
            with open('content/map-template.sql') as map_template:
                random_map_db.execute_script(map_template.read())
            for island_id, island_string in enumerate(random_island_sequence):
                create_random_island(random_map_db, island_id, island_string)
            random_map_db.close()
            self._map_path = self._temp_path2

            self('INSERT INTO metadata VALUES(?, ?)', 'random_island_sequence',
                 ' '.join(random_island_sequence))

        self('ATTACH ? AS map_file', self._map_path)
        if is_random_map:
            self.map_name = random_island_sequence
        elif os.path.isabs(self._map_path):
            self.map_name = self._map_path
        else:
            self.map_name = SavegameManager.get_savegamename_from_filename(
                self._map_path)

        self._load_building()
        self._load_settlement()
        self._load_concrete_object()
        self._load_production()
        self._load_storage()
        self._load_wildanimal()
        self._load_unit()
        self._load_building_collector()
        self._load_production_line()
        self._load_unit_path()
        self._load_storage_global_limit()
        self._load_health()
        self._load_fish_data()
        self._hash = None
Beispiel #20
0
    def _upgrade(self):
        # fix import loop
        from horizons.savegamemanager import SavegameManager
        metadata = SavegameManager.get_metadata(self.original_path)
        rev = metadata['savegamerev']

        if rev < VERSION.SAVEGAMEREVISION:
            if not SavegameUpgrader.can_upgrade(rev):
                raise SavegameTooOld(revision=rev)

            self.log.warning('Discovered old savegame file, auto-upgrading: %s -> %s' % \
                    (rev, VERSION.SAVEGAMEREVISION))
            db = DbReader(self.final_path)
            db('BEGIN TRANSACTION')

            if rev < 49:
                self._upgrade_to_rev49(db)
            if rev < 50:
                self._upgrade_to_rev50(db)
            if rev < 51:
                self._upgrade_to_rev51(db)
            if rev < 52:
                self._upgrade_to_rev52(db)
            if rev < 53:
                self._upgrade_to_rev53(db)
            if rev < 54:
                self._upgrade_to_rev54(db)
            if rev < 55:
                self._upgrade_to_rev55(db)
            if rev < 56:
                self._upgrade_to_rev56(db)
            if rev < 57:
                self._upgrade_to_rev57(db)
            if rev < 58:
                self._upgrade_to_rev58(db)
            if rev < 59:
                self._upgrade_to_rev59(db)
            if rev < 60:
                self._upgrade_to_rev60(db)
            if rev < 61:
                self._upgrade_to_rev61(db)
            if rev < 62:
                self._upgrade_to_rev62(db)
            if rev < 63:
                self._upgrade_to_rev63(db)
            if rev < 64:
                self._upgrade_to_rev64(db)
            if rev < 65:
                self._upgrade_to_rev65(db)
            if rev < 66:
                self._upgrade_to_rev66(db)
            if rev < 67:
                self._upgrade_to_rev67(db)
            if rev < 68:
                self._upgrade_to_rev68(db)
            if rev < 69:
                self._upgrade_to_rev69(db)
            if rev < 70:
                self._upgrade_to_rev70(db)
            if rev < 71:
                self._upgrade_to_rev71(db)
            if rev < 72:
                self._upgrade_to_rev72(db)
            if 70 < rev < 73:
                self._upgrade_to_rev73(db)
            if rev < 74:
                self._upgrade_to_rev74(db)
            if rev < 75:
                self._upgrade_to_rev75(db)
            if rev < 76:
                self._upgrade_to_rev76(db)

            db('COMMIT')
            db.close()