def common_generate_logic(args, permalink): from randovania.generator import generator def status_update(s): if args.status_update: print(s) if permalink.parameters.spoiler: debug.set_level(args.debug) extra_args = {} if args.no_retry: extra_args["attempts"] = 0 before = time.perf_counter() layout_description = asyncio.run( generator.generate_and_validate_description( generator_params=permalink.parameters, status_update=status_update, validate_after_generation=args.validate, timeout=None, **extra_args)) after = time.perf_counter() print("Took {} seconds. Hash: {}".format( after - before, layout_description.shareable_hash)) layout_description.save_to_file(args.output_file)
def distribute_command_logic(args): def status_update(s): if args.status_update: print(s) if args.permalink is not None: permalink = Permalink.from_str(args.permalink) else: permalink = asyncio.run(_create_permalink(args)) print(f"Permalink: {permalink.as_base64_str}") if permalink.spoiler: debug.set_level(args.debug) extra_args = {} if args.no_retry: extra_args["attempts"] = 0 before = time.perf_counter() layout_description = generator.generate_description( permalink=permalink, status_update=status_update, validate_after_generation=args.validate, timeout=None, **extra_args) after = time.perf_counter() print("Took {} seconds. Hash: {}".format( after - before, layout_description.shareable_hash)) layout_description.save_to_file(args.output_file)
def validate_command_logic(args): debug.set_level(args.debug) description = LayoutDescription.from_file(args.layout_file) if description.player_count != 1: raise ValueError( f"Validator does not support layouts with more than 1 player.") configuration = description.get_preset(0).configuration patches = description.all_patches[0] total_times = [] final_state_by_resolve = None for _ in range(args.repeat): before = time.perf_counter() final_state_by_resolve = asyncio.run( resolver.resolve(configuration=configuration, patches=patches)) after = time.perf_counter() total_times.append(after - before) print("Took {:.3f} seconds. Game is {}.".format( total_times[-1], "possible" if final_state_by_resolve is not None else "impossible")) if args.repeat > 1: cli_lib.print_report_multiple_times(total_times) if args.repeat < 1: raise ValueError("Expected at least 1 repeat") return 0 if final_state_by_resolve is not None else 1
def __init__(self, options: Options, preset_manager: PresetManager, preview: bool): super().__init__() self.setupUi(self) self.setWindowTitle("Randovania {}".format(VERSION)) self.is_preview_mode = preview self.setAcceptDrops(True) common_qt_lib.set_default_window_icon(self) self.intro_label.setText(self.intro_label.text().format(version=VERSION)) self._preset_manager = preset_manager if preview: debug.set_level(2) # Signals self.newer_version_signal.connect(self.display_new_version) self.background_tasks_button_lock_signal.connect(self.enable_buttons_with_background_tasks) self.progress_update_signal.connect(self.update_progress) self.stop_background_process_button.clicked.connect(self.stop_background_process) self.options_changed_signal.connect(self.on_options_changed) self.intro_play_now_button.clicked.connect(lambda: self.welcome_tab_widget.setCurrentWidget(self.tab_play)) self.open_faq_button.clicked.connect(self._open_faq) self.open_database_viewer_button.clicked.connect(self._open_data_visualizer) self.import_permalink_button.clicked.connect(self._import_permalink) self.create_new_seed_button.clicked.connect( lambda: self.welcome_tab_widget.setCurrentWidget(self.tab_create_seed)) # Menu Bar self.menu_action_data_visualizer.triggered.connect(self._open_data_visualizer) self.menu_action_item_tracker.triggered.connect(self._open_item_tracker) self.menu_action_edit_new_database.triggered.connect(self._open_data_editor_default) self.menu_action_edit_existing_database.triggered.connect(self._open_data_editor_prompt) self.menu_action_validate_seed_after.triggered.connect(self._on_validate_seed_change) self.menu_action_timeout_generation_after_a_time_limit.triggered.connect(self._on_generate_time_limit_change) self.generate_seed_tab = GenerateSeedTab(self, self, self, options) self.generate_seed_tab.setup_ui() self._details_window = SeedDetailsWindow(self, self, options) self._details_window.added_to_tab = False # Needs the GenerateSeedTab self._create_open_map_tracker_actions() # Setting this event only now, so all options changed trigger only once options.on_options_changed = self.options_changed_signal.emit self._options = options with options: self.on_options_changed() self.main_tab_widget.setCurrentIndex(0) # Update hints text self._update_hints_text()
def _generate_layout_worker(output_pipe: Connection, debug_level: int, extra_args: dict): def status_update(message: str): output_pipe.send(message) if output_pipe.poll(): raise RuntimeError(output_pipe.recv()) debug.set_level(debug_level) return asyncio.run(generator.generate_and_validate_description(status_update=status_update, **extra_args))
def validate_command_logic(args): debug.set_level(args.debug) data = prime_database.decode_data_file(args) game = data_reader.decode_data(data) description = LayoutDescription.from_file(args.layout_file) configuration = description.permalink.layout_configuration patches = description.patches final_state_by_resolve = resolver.resolve(configuration=configuration, game=game, patches=patches) print(final_state_by_resolve)
async def test_resolver_with_log_file(test_files_dir, seed_name: str): # Setup debug.set_level(2) description = LayoutDescription.from_file(test_files_dir.joinpath("log_files", seed_name)) configuration = description.permalink.presets[0].configuration patches = description.all_patches[0] # Run final_state_by_resolve = await resolver.resolve(configuration=configuration, patches=patches) # Assert assert final_state_by_resolve is not None
def test_resolver_with_log_file(test_files_dir): # Setup debug.set_level(0) description = LayoutDescription.from_file(test_files_dir.joinpath("log_files", "seed_a.json")) configuration = description.permalink.presets[0].layout_configuration patches = description.all_patches[0] # Run final_state_by_resolve = resolver.resolve(configuration=configuration, patches=patches) # Assert assert final_state_by_resolve is not None
def distribute_command_logic(args): from randovania.layout.permalink import Permalink from randovania.generator import generator async def _create_permalink(args_) -> Permalink: from randovania.interface_common import persistence from randovania.interface_common.preset_manager import PresetManager preset_manager = PresetManager(persistence.user_data_dir()) await preset_manager.load_user_presets() preset = preset_manager.preset_for_name(args_.preset_name).get_preset() return Permalink( args_.seed_number, spoiler=True, presets={i: preset for i in range(args_.player_count)}, ) def status_update(s): if args.status_update: print(s) if args.permalink is not None: permalink = Permalink.from_str(args.permalink) else: permalink = asyncio.run(_create_permalink(args)) print(f"Permalink: {permalink.as_base64_str}") if permalink.spoiler: debug.set_level(args.debug) extra_args = {} if args.no_retry: extra_args["attempts"] = 0 before = time.perf_counter() layout_description = generator.generate_description( permalink=permalink, status_update=status_update, validate_after_generation=args.validate, timeout=None, **extra_args) after = time.perf_counter() print("Took {} seconds. Hash: {}".format( after - before, layout_description.shareable_hash)) layout_description.save_to_file(args.output_file)
def validate_command_logic(args): debug.set_level(args.debug) description = LayoutDescription.from_file(args.layout_file) if description.permalink.player_count != 1: raise ValueError(f"Validator does not support layouts with more than 1 player.") configuration = description.permalink.presets[0].layout_configuration patches = description.all_patches[0] final_state_by_resolve = resolver.resolve( configuration=configuration, patches=patches ) print(final_state_by_resolve)
def test_resolver_with_log_file(test_files_dir): # Setup debug.set_level(0) description = LayoutDescription.from_file( test_files_dir.joinpath("log_files", "seed_a.json")) configuration = description.permalink.layout_configuration game = data_reader.decode_data(configuration.game_data) patches = description.patches # Run final_state_by_resolve = resolver.resolve(configuration=configuration, game=game, patches=patches) # Assert assert final_state_by_resolve is not None
def test_compare_generated_with_data(mock_permalink_as_str: PropertyMock, layout_description: LayoutDescription): debug.set_level(0) status_update = MagicMock() mock_permalink_as_str.return_value = "fixed-seed!" generated_description = generator.generate_description( layout_description.permalink, status_update=status_update, validate_after_generation=True, timeout=None) # indices: List[int] = [None] * echoes_pickup_database.total_pickup_count # for index, pickup in generated_description.patches.pickup_assignment.items(): # indices[index.index] = echoes_pickup_database.original_index(pickup).index # print(indices) assert generated_description.without_solver_path == layout_description
def distribute_command_logic(args): def status_update(s): pass permalink = Permalink.from_str(args.permalink) if permalink.spoiler: debug.set_level(args.debug) before = time.perf_counter() layout_description = generator.generate_description( permalink=permalink, status_update=status_update, validate_after_generation=args.validate, timeout=None) after = time.perf_counter() print("Took {} seconds. Hash: {}".format( after - before, layout_description.shareable_hash)) layout_description.save_to_file(args.output_file)
def validate_command_logic(args): debug.set_level(args.debug) description = LayoutDescription.from_file(args.layout_file) if description.player_count != 1: raise ValueError( f"Validator does not support layouts with more than 1 player.") configuration = description.get_preset(0).configuration patches = description.all_patches[0] before = time.perf_counter() final_state_by_resolve = asyncio.run( resolver.resolve(configuration=configuration, patches=patches)) after = time.perf_counter() print("Took {} seconds. Game is {}.".format( after - before, "possible" if final_state_by_resolve is not None else "impossible")) return 0 if final_state_by_resolve is not None else 1
def _generate_layout_worker(output_pipe: Connection, permalink: Permalink, validate_after_generation: bool, timeout_during_generation: bool, debug_level: int): def status_update(message: str): output_pipe.send(message) if output_pipe.poll(): raise RuntimeError(output_pipe.recv()) debug.set_level(debug_level) extra_args = {} if not timeout_during_generation: extra_args["timeout"] = None return generator.generate_description(permalink, status_update=status_update, validate_after_generation=validate_after_generation, **extra_args)
def _generate_layout_worker(output_pipe, permalink: Permalink, validate_after_generation: bool, timeout_during_generation: bool, debug_level: int): try: def status_update(message: str): output_pipe.send(message) debug.set_level(debug_level) extra_args = {} if not timeout_during_generation: extra_args["timeout"] = None layout_description = generator.generate_description( permalink, status_update=status_update, validate_after_generation=validate_after_generation, **extra_args) output_pipe.send(layout_description) except Exception as e: traceback.print_exc() output_pipe.send(e)
def common_generate_logic(args, permalink): from randovania.generator import generator def status_update(s): if args.status_update: print(s) if permalink.parameters.spoiler: debug.set_level(args.debug) extra_args = {} if args.no_retry: extra_args["attempts"] = 0 shareable_hashes = [] total_times = [] layout_description = None for _ in range(args.repeat): before = time.perf_counter() layout_description = asyncio.run( generator.generate_and_validate_description( generator_params=permalink.parameters, status_update=status_update, validate_after_generation=args.validate, timeout=None, **extra_args)) after = time.perf_counter() total_times.append(after - before) shareable_hashes.append(layout_description.shareable_hash) print("Took {:.3f} seconds. Hash: {}".format(total_times[-1], shareable_hashes[-1])) assert layout_description is not None layout_description.save_to_file(args.output_file) if args.repeat > 1: cli_lib.print_report_multiple_times(total_times)
def distribute_command_logic(args): debug.set_level(args.debug) def status_update(s): pass permalink = Permalink.from_str(args.permalink) before = time.perf_counter() layout_description = generator.generate_description( permalink=permalink, status_update=status_update, validate_after_generation=args.validate, timeout=None) after = time.perf_counter() print("Took {} seconds. Hash: {}".format( after - before, layout_description.shareable_hash)) layout_description.save_to_file(args.output_file) simplified_patcher.write_patcher_file_to_disk( args.output_file.with_suffix(".patcher-json"), layout_description, CosmeticPatches.default(), )
def __init__(self, options: Options, preset_manager: PresetManager, network_client, preview: bool): super().__init__() self.setupUi(self) self.setWindowTitle("Randovania {}".format(VERSION)) self._is_preview_mode = preview self.setAcceptDrops(True) common_qt_lib.set_default_window_icon(self) self.setup_about_text() self.setup_welcome_text() self.browse_racetime_label.setText( self.browse_racetime_label.text().replace("color:#0000ff;", "")) self._preset_manager = preset_manager self.network_client = network_client if preview: debug.set_level(2) if randovania.is_frozen(): self.menu_bar.removeAction(self.menu_edit.menuAction()) # Signals self.options_changed_signal.connect(self.on_options_changed) self.GameDetailsSignal.connect(self._open_game_details) self.InitPostShowSignal.connect(self.initialize_post_show) self.intro_play_now_button.clicked.connect( lambda: self.main_tab_widget.setCurrentWidget(self.tab_play)) self.open_faq_button.clicked.connect(self._open_faq) self.open_database_viewer_button.clicked.connect( partial(self._open_data_visualizer_for_game, RandovaniaGame.METROID_PRIME_ECHOES)) self.import_permalink_button.clicked.connect(self._import_permalink) self.import_game_file_button.clicked.connect(self._import_spoiler_log) self.browse_racetime_button.clicked.connect(self._browse_racetime) self.create_new_seed_button.clicked.connect( lambda: self.main_tab_widget.setCurrentWidget(self.tab_create_seed )) # Menu Bar self.game_menus = [] self.menu_action_edits = [] for game in RandovaniaGame.sorted_all_games(): # Sub-Menu in Open Menu game_menu = QtWidgets.QMenu(self.menu_open) game_menu.setTitle(_t(game.long_name)) game_menu.game = game if game.data.development_state.can_view(False): self.menu_open.addAction(game_menu.menuAction()) self.game_menus.append(game_menu) game_trick_details_menu = QtWidgets.QMenu(game_menu) game_trick_details_menu.setTitle(_t("Trick Details")) self._setup_trick_difficulties_menu_on_show( game_trick_details_menu, game) game_data_visualizer_action = QtGui.QAction(game_menu) game_data_visualizer_action.setText(_t("Data Visualizer")) game_data_visualizer_action.triggered.connect( partial(self._open_data_visualizer_for_game, game)) game_menu.addAction(game_trick_details_menu.menuAction()) game_menu.addAction(game_data_visualizer_action) # Data Editor action = QtGui.QAction(self) action.setText(_t(game.long_name)) self.menu_internal.addAction(action) action.triggered.connect( partial(self._open_data_editor_for_game, game)) self.menu_action_edits.append(action) self.menu_action_edit_existing_database.triggered.connect( self._open_data_editor_prompt) self.menu_action_validate_seed_after.triggered.connect( self._on_validate_seed_change) self.menu_action_timeout_generation_after_a_time_limit.triggered.connect( self._on_generate_time_limit_change) self.menu_action_dark_mode.triggered.connect( self._on_menu_action_dark_mode) self.menu_action_experimental_games.triggered.connect( self._on_menu_action_experimental_games) self.menu_action_open_auto_tracker.triggered.connect( self._open_auto_tracker) self.menu_action_previously_generated_games.triggered.connect( self._on_menu_action_previously_generated_games) self.menu_action_log_files_directory.triggered.connect( self._on_menu_action_log_files_directory) self.menu_action_layout_editor.triggered.connect( self._on_menu_action_layout_editor) # Setting this event only now, so all options changed trigger only once options.on_options_changed = self.options_changed_signal.emit self._options = options self.main_tab_widget.setCurrentIndex(0)
def __init__(self, options: Options, preset_manager: PresetManager, network_client: QtNetworkClient, preview: bool): super().__init__() self.setupUi(self) self.setWindowTitle("Randovania {}".format(VERSION)) self._is_preview_mode = preview self.setAcceptDrops(True) common_qt_lib.set_default_window_icon(self) # Remove all hardcoded link color about_document: QtGui.QTextDocument = self.about_text_browser.document( ) about_document.setHtml(about_document.toHtml().replace( "color:#0000ff;", "")) self.browse_racetime_label.setText( self.browse_racetime_label.text().replace("color:#0000ff;", "")) self.intro_label.setText( self.intro_label.text().format(version=VERSION)) self._preset_manager = preset_manager self.network_client = network_client if preview: debug.set_level(2) # Signals self.newer_version_signal.connect(self.display_new_version) self.options_changed_signal.connect(self.on_options_changed) self.GameDetailsSignal.connect(self._open_game_details) self.intro_play_now_button.clicked.connect( lambda: self.welcome_tab_widget.setCurrentWidget(self.tab_play)) self.open_faq_button.clicked.connect(self._open_faq) self.open_database_viewer_button.clicked.connect( partial(self._open_data_visualizer_for_game, RandovaniaGame.PRIME2)) self.import_permalink_button.clicked.connect(self._import_permalink) self.import_game_file_button.clicked.connect(self._import_spoiler_log) self.browse_racetime_button.clicked.connect(self._browse_racetime) self.browse_sessions_button.clicked.connect( self._browse_for_game_session) self.host_new_game_button.clicked.connect(self._host_game_session) self.create_new_seed_button.clicked.connect( lambda: self.welcome_tab_widget.setCurrentWidget(self. tab_create_seed)) # Menu Bar for action, game in ((self.menu_action_visualize_prime_1, RandovaniaGame.PRIME1), (self.menu_action_visualize_prime_2, RandovaniaGame.PRIME2), (self.menu_action_visualize_prime_3, RandovaniaGame.PRIME3)): action.triggered.connect( partial(self._open_data_visualizer_for_game, game)) for action, game in ((self.menu_action_edit_prime_1, RandovaniaGame.PRIME1), (self.menu_action_edit_prime_2, RandovaniaGame.PRIME2), (self.menu_action_edit_prime_3, RandovaniaGame.PRIME3)): action.triggered.connect( partial(self._open_data_editor_for_game, game)) self.menu_action_item_tracker.triggered.connect( self._open_item_tracker) self.menu_action_map_tracker.triggered.connect( self._on_menu_action_map_tracker) self.menu_action_edit_existing_database.triggered.connect( self._open_data_editor_prompt) self.menu_action_validate_seed_after.triggered.connect( self._on_validate_seed_change) self.menu_action_timeout_generation_after_a_time_limit.triggered.connect( self._on_generate_time_limit_change) self.menu_action_dark_mode.triggered.connect( self._on_menu_action_dark_mode) self.menu_action_open_auto_tracker.triggered.connect( self._open_auto_tracker) self.menu_action_previously_generated_games.triggered.connect( self._on_menu_action_previously_generated_games) self.menu_action_layout_editor.triggered.connect( self._on_menu_action_layout_editor) self.action_login_window.triggered.connect(self._action_login_window) self.generate_seed_tab = GenerateSeedTab(self, self, options) self.generate_seed_tab.setup_ui() # Needs the GenerateSeedTab self._setup_difficulties_menu() # Setting this event only now, so all options changed trigger only once options.on_options_changed = self.options_changed_signal.emit self._options = options with options: self.on_options_changed() self.main_tab_widget.setCurrentIndex(0) # Update hints text self._update_hints_text()
def __init__(self, options: Options, preview: bool): super().__init__() self.setupUi(self) self.setWindowTitle("Randovania {}".format(VERSION)) self.is_preview_mode = preview self.setAcceptDrops(True) set_default_window_icon(self) self.intro_label.setText( self.intro_label.text().format(version=VERSION)) if preview: debug.set_level(2) # Signals self.newer_version_signal.connect(self.display_new_version) self.background_tasks_button_lock_signal.connect( self.enable_buttons_with_background_tasks) self.progress_update_signal.connect(self.update_progress) self.stop_background_process_button.clicked.connect( self.stop_background_process) self.options_changed_signal.connect(self.on_options_changed) # Menu Bar self.menu_action_data_visualizer.triggered.connect( self._open_data_visualizer) self.menu_action_existing_seed_details.triggered.connect( self._open_existing_seed_details) self.menu_action_tracker.triggered.connect(self._open_tracker) self.menu_action_edit_new_database.triggered.connect( self._open_data_editor_default) self.menu_action_edit_existing_database.triggered.connect( self._open_data_editor_prompt) self.menu_action_export_iso.triggered.connect(self._export_iso) self.menu_action_validate_seed_after.triggered.connect( self._on_validate_seed_change) self.menu_action_timeout_generation_after_a_time_limit.triggered.connect( self._on_generate_time_limit_change) self.menu_action_export_iso.setEnabled(False) _translate = QtCore.QCoreApplication.translate self.tabs = [] from randovania.gui.game_patches_window import GamePatchesWindow from randovania.gui.iso_management_window import ISOManagementWindow from randovania.gui.logic_settings_window import LogicSettingsWindow from randovania.gui.cosmetic_window import CosmeticWindow from randovania.gui.main_rules import MainRulesWindow self.tab_windows = [ (ISOManagementWindow, "ROM Settings"), (GamePatchesWindow, "Game Patches"), (MainRulesWindow, "Main Rules"), (LogicSettingsWindow, "Logic Settings"), (CosmeticWindow, "Cosmetic"), ] for i, tab in enumerate(self.tab_windows): self.windows.append(tab[0](self, self, options)) self.tabs.append(self.windows[i].centralWidget) self.tabWidget.insertTab(i + 1, self.tabs[i], _translate("MainWindow", tab[1])) # Setting this event only now, so all options changed trigger only once options.on_options_changed = self.options_changed_signal.emit self._options = options with options: self.on_options_changed() self.tabWidget.setCurrentIndex(0) # Update hints text self._update_hints_text()