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 ZeroDivisionError as err: # TODO: # this should say WindowsError, but that somehow now leads to a NameError if err.winerror == 5: self.gui.show_error_popup(_("Access is denied"), \ _("The savegame file is probably read-only.")) return self.save() elif err.winerror == 32: self.gui.show_error_popup(_("File used by another process"), \ _("The savegame file is currently used by another program.")) 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 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
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) db('COMMIT') db.close()
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.ingame_gui.show_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.show_error_popup( _("Access is denied"), _("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
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
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 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"
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
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 = [ '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
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:') with open('content' + os.sep + 'atlas.sql') 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
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()
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
def create_map(): """ Create a map with a square island (20x20) at position (20, 20) and return the path to the database file. """ # Create island. fd, islandfile = tempfile.mkstemp() os.close(fd) db = DbReader(islandfile) db("CREATE TABLE ground(x INTEGER NOT NULL, y INTEGER NOT NULL, ground_id INTEGER NOT NULL, action_id TEXT NOT NULL, rotation INTEGER NOT NULL)") db("CREATE TABLE island_properties(name TEXT PRIMARY KEY NOT NULL, value TEXT NOT NULL)") db("BEGIN TRANSACTION") 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([x, y] + list(ground)) db.execute_many("INSERT INTO ground VALUES(?, ?, ?, ?, ?)", tiles) db("COMMIT") # Create savegame with the island above. fd, savegame = tempfile.mkstemp() os.close(fd) db = DbReader(savegame) read_savegame_template(db) db("BEGIN TRANSACTION") db("INSERT INTO island (x, y, file) VALUES(?, ?, ?)", 20, 20, islandfile) db("COMMIT") return savegame
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
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 + 45) 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 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
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()
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()
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(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 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) 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 __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]
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.ingame_gui.show_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.show_error_popup( _("Access is denied"), _("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 instances that are selected right now. for instance in self.selected_instances: db("INSERT INTO selected (`group`, id) VALUES (NULL, ?)", instance.worldid) # If a single instance is selected, also store the currently displayed tab. # (Else, upon restoring, we display a multi-selection tab.) tabname = None if len(self.selected_instances) == 1: tabclass = self.ingame_gui.get_cur_menu().current_tab tabname = tabclass.__class__.__name__ db("INSERT INTO metadata (name, value) VALUES (?, ?)", "selected_tab", tabname) # Store user defined unit selection groups (Ctrl+number) for (number, group) in enumerate(self.selection_groups): for instance in group: db("INSERT INTO selected (`group`, id) VALUES (?, ?)", number, instance.worldid) # 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
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 < 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()
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
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
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.log.warning("Discovered old savegame file, auto-upgrading: %s -> %s" % (rev, VERSION.SAVEGAMEREVISION)) 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) 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) db("COMMIT") db.close()
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 _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) db('COMMIT') db.close()