def run(self): try: for randomizer in self.randomizers: local_status_steps_left = randomizer.step_count() local_status = Status() def local_status_fn(_, descr): nonlocal local_status_steps_left if descr != Status.DONE_SPECIAL_STR: if local_status_steps_left > 0: local_status_steps_left -= 1 self.status.step(descr) else: for i in range(local_status_steps_left): self.status.step('Randomizing...') local_status.subscribe(local_status_fn) randomizer.run(local_status) self.status.step('Saving scripts...') save_scripts(self.rom, self.static_data) except BaseException as error: logger.error("Exception during randomization.", exc_info=error) self.error = sys.exc_info() with self.lock: self.done = True self.status.done()
async def on_message(self, message): decoded_message = json.loads(message) logger.debug(f'{self.request.remote_ip}: Sent msg.') try: if not self.randomization_is_running: if decoded_message['action'] == 'start': logger.info(f'{self.request.remote_ip}: Sent start request.') self.randomization_is_running = True config = ConfigFileLoader.load_from_dict(decoded_message['config']) rom = RomStorage.roms[self.request.remote_ip] seed = get_effective_seed(config['seed']) random.seed(seed) status = Status() def update_fn(progress, desc): logger.debug(f'{self.request.remote_ip}: {round((progress - 1 / randomizer.total_steps * 100))}: {desc}') if desc == Status.DONE_SPECIAL_STR: self.write_message(json.dumps( {'status': 'progress', 'step': progress - 1, 'totalSteps': randomizer.total_steps, 'message': "Randomizing complete!", 'seed': seed})) else: self.write_message(json.dumps( {'status': 'progress', 'step': progress - 1, 'totalSteps': randomizer.total_steps, 'message': desc, 'seed': seed})) def check_done(): if not randomizer.is_done(): return True logger.debug(f'{self.request.remote_ip}: Check done!') if randomizer.error: traceback_str = ''.join(traceback.format_exception(*randomizer.error)) logger.error(f'{self.request.remote_ip}: ERROR: {traceback_str}') self.write_message(json.dumps( {'status': 'error', 'message': f"Error: {traceback_str}", 'seed': seed})) else: logger.info(f'{self.request.remote_ip}: DONE!') self.write_message(json.dumps( {'status': 'done', 'step': randomizer.total_steps, 'totalSteps': randomizer.total_steps, 'message': "Randomization complete!", 'seed': seed})) return False status.subscribe(lambda a, b: WebserverFrontend.run_on_main_thread(partial(update_fn, a, b))) randomizer = RandomizerThread(status, rom, config, seed, WebserverFrontend()) WebserverFrontend.run_timeout(0.1, check_done) randomizer.start() except BaseException as ex: self.randomization_is_running = False tb = traceback.format_exc() print(tb) await self.write_message(json.dumps({'status': 'error', 'message': f"Fatal error: {ex}\n{tb}"}))
def on_randomize_clicked(self, *args): if self.chosen_file is None: self.display_error("Please choose an input file.") return dialog = Gtk.FileChooserNative.new( "Output ROM filename...", self.window, Gtk.FileChooserAction.SAVE, None, None ) filter_nds = Gtk.FileFilter() filter_nds.set_name("Nintendo DS ROMs (*.nds)") filter_nds.add_mime_type("application/x-nintendo-ds-rom") filter_nds.add_pattern("*.nds") dialog.add_filter(filter_nds) response = dialog.run() out_fn = dialog.get_filename() dialog.destroy() if response == Gtk.ResponseType.ACCEPT: clear_script_cache() if '.' not in out_fn: out_fn += '.nds' try: self.builder.get_object('progress_close').set_sensitive(False) progress_bar: Gtk.ProgressBar = self.builder.get_object('progress_bar') progress_label: Gtk.Label = self.builder.get_object('progress_label') progress_diag: Gtk.Dialog = self.builder.get_object('progress') progress_diag.set_title('Randomizing...') def update_fn(progress, desc): progress_bar.set_fraction((progress - 1) / randomizer.total_steps) if desc == Status.DONE_SPECIAL_STR: progress_label.set_text("Randomizing complete!") else: progress_label.set_text(f"{floor((progress - 1) / randomizer.total_steps * 100)}%: {desc}") def check_done(): if not randomizer.is_done(): return True self.builder.get_object('progress_close').set_sensitive(True) if randomizer.error: img: Gtk.Image = self.builder.get_object('img_portrait_duskako') img.set_from_file(os.path.join(data_dir(), 'duskako_sad.png')) traceback_str = ''.join(traceback.format_exception(*randomizer.error)) progress_label.set_text(f"Error: {traceback_str}") progress_diag.set_title('Randomizing failed!') else: rom.saveToFile(out_fn) img: Gtk.Image = self.builder.get_object('img_portrait_duskako') img.set_from_file(os.path.join(data_dir(), 'duskako_happy.png')) progress_label.set_text("Randomizing complete!") progress_diag.set_title('Randomizing complete!') return False rom = NintendoDSRom.fromFile(self.chosen_file) status = Status() status.subscribe(lambda a, b: GLib.idle_add(partial(update_fn, a, b))) config = self.ui_reader.read() # Set the seed seed = get_effective_seed(config['seed']) random.seed(seed) self.builder.get_object('seed_label').set_text('Your Seed: ' + str(seed)) randomizer = RandomizerThread(status, rom, config, seed) randomizer.start() # SHOW DIALOG img: Gtk.Image = self.builder.get_object('img_portrait_duskako') img.set_from_file(os.path.join(data_dir(), 'duskako_neutral.png')) GLib.timeout_add(100, check_done) progress_diag.run() except BaseException as ex: tb = traceback.format_exc() print(tb) self.display_error(f"Error: {ex}\n{tb}") return