def _loop(self): logger.info(f"Connecting to {self.name}") try: f = None f = open(f"\\\\.\\pipe\\{self.name}", "r+b", 0) logger.info("Connected event handler!") while self.running: n = struct.unpack("I", f.read(4))[0] data = f.read(n) obj = msgpack.unpackb(data, raw=False) if obj["data"][0] == "call" and obj["data"][1][ "method"] == "emit": args = obj["data"][1]["args"][0] for evt_args in args: logger.debug(f"Event {evt_args['event_name']}") if evt_args["event_name"] in self.event_handlers: for handler in self.event_handlers[ evt_args["event_name"]]: handler.emit(evt_args["args"]) f.close() except: if f is not None: f.close() self.running = False self.event_loop = None self.on_connection_lost.emit()
def get_original(s, parts): global MINIFY if MINIFY is None: logger.debug("Fetching MINIFY") MINIFY = CONFIG.getboolean("Developer", "minify-untranslated-tags", fallback=True) return s if not MINIFY else parts[-1]
def on_maid_removed(self, args): guid = args["maid_id"] if guid not in self.maid_list_widgets: return logger.debug("Maid removed!") self.maid_list.takeItem( self.maid_list.row(self.maid_list_widgets[guid])) del self.maid_list_widgets[guid] self.maid_mgr.remove_maid(guid)
def _try_invoke_internal(self, method, try_count, *args): if isinstance(method, bytes): method = method.decode('utf-8') logger.debug(f"Calling {method}") self.call_id += 1 obj = { "msg_id": self.call_id, "data": ["call", { "method": method, "args": args }] } packed = msgpack.packb(obj) try: self.handler.write(struct.pack("I", len(packed))) self.handler.write(packed) # Advance the cursor by reading the packed bytes # Has to be done because it's not advanced automatically for some reason # self.handler.read(len(packed) + 4) response_len = struct.unpack("I", self.handler.read(4))[0] response_packed = self.handler.read(response_len) except: self.close() return (None, True) try: response = msgpack.unpackb(response_packed, raw=False) except msgpack.ExtraData as e: if try_count >= self.max_retries: logger.error(f"Forcing to fail after {try_count} tries.") return (None, True) logger.warning( f"Received extra data! Flushing and retrying. Extra: {e.extra}" ) self._flush() return self._try_invoke_internal(method, try_count + 1, *args) response_type = response["data"][0] if response_type == "response": return (response["data"][1]["result"], False) elif response_type == "error": error_info = response["data"][1] raise RemoteError(error_info["err_name"], error_info["err_message"], error_info["stack_trace"]) else: raise RemoteError("InvalidResponse", "The response from the method is invalid", "")
def reload_player_props(self): data = self.core.GetAllPlayerData() locked_vals = set(data["locked_props"]) for prop, value in data["props"].items(): logger.debug(f"data.items: {prop} , {value}") (el, cb) = self.properties[prop] el.set_value(value) cb.blockSignals(True) cb.setCheckState( Qt.Checked if prop in locked_vals else Qt.Unchecked) cb.blockSignals(False)
def on_maid_selected(self): if self.maid_mgr.selected_maid is None: return maid = self.maid_mgr.selected_maid for name, widgets in self.properties.items(): logger.debug(f"Setting {name}") widgets[0].set_value(maid["properties"][name]) widgets[1].setCheckState( Qt.Checked if maid["prop_locks"][name] else Qt.Unchecked) for name, widget in self.bonus_properties.items(): widget.setValue(maid["bonus_properties"][name])
def load_translation(name): global current_translation path = os.path.join(BASE_DIR, "translations", name) logger.debug(f"TL path: {path}") if not os.path.isfile(path): return with open(path, "r", encoding="utf-8-sig") as tl_file: current_translation = json.load(tl_file) if "translation" not in current_translation: logger.warning("translation invalid") current_translation = {} return
def _flush(self): logger.debug("Flushing stream") try: # Send a dummy ping call, but read all of the steam until EOF # This forces the stream to be reset # Yes, it slows initial load a bit, but this is fine in our case packed = msgpack.packb({ "msg_id": 0, "data": ["ping", { "pong": False }] }) self.handler.write(struct.pack("I", len(packed))) self.handler.write(packed) self.handler.read(2**32) self.handler.read(2**32) except: logger.debug("Flushed!")
def run(self): logger.debug("doing request") try: response = request.urlopen( f"https://api.github.com/repos/{GIT_REPO}/releases/latest", timeout=5) except URLError as e: self.error.emit(str(e.reason)) return data = json.load(response) version = data["tag_name"][1:] logger.info(f"Latest version: {version}, current version: {VERSION}") if version <= VERSION: self.no_update.emit() return self.update_available.emit(data)
def connect(self): logger.debug("showing connection dialog!") connect_dialog = ConnectDialog(self, self.core) result = connect_dialog.exec() if result != QDialog.Accepted: QApplication.instance().exit() sys.exit(0) return game_version = self.core.get_GameVersion() if game_version < MIN_SUPPORTED_GAME_VERSION: error_dialog = QMessageBox( QMessageBox.Critical, "Unsupported game version", f"Maid Fiddler {VERSION} only supports game version {MIN_SUPPORTED_GAME_VERSION} or newer.\nThis game's build version is {game_version}.\n\nPlease update the game before using this version of Maid Fiddler.", QMessageBox.Ok) error_dialog.exec() self.core.close() QApplication.instance().exit() sys.exit(0) return self.event_poller.start_polling() game_data = connect_dialog.game_data if game_data is None: self.on_connection_close() return connect_dialog.game_data = None self.core_version = self.core.get_Version() for tab in self.tabs: tab.game_data = game_data self.maids_list.reload_maids() self.player_tab.reload_player_props() # Reload translations to translate updated UI for tab in self.tabs: tab.translate_ui() # Finally, display a warning message if there is a need self.display_warning()
def on_maid_selected(self): if self.maid_mgr.selected_maid is None: return #Dictionary<string, object> maid = self.maid_mgr.selected_maid self.ui.personality_combo.setEnabled( not maid["properties"]["mainChara"]) # 디버깅용 for name, element in maid["properties"].items(): logger.debug(f"maid.items: {name} , {element}") for name, element in self.properties.items(): logger.debug(f"properties.items: {name} , {element}") for name, element in self.properties.items(): element.set_value(maid["properties"][name])
def run(self): logger.debug("Beginning download") tmp_downloads_path = os.path.join(util.BASE_DIR, TMP_FOLDER) if not os.path.exists(tmp_downloads_path): os.mkdir(tmp_downloads_path) try: response = request.urlopen(self.url) except URLError as e: self.error.emit(str(e.reason)) return with open(os.path.join(tmp_downloads_path, UPDATER_FILE), "wb") as f: while True: chunk = response.read(self.chunk_size) if not chunk: break f.write(chunk) self.chunk_downloaded.emit() logger.debug("Download complete") self.download_complete.emit()
def commit_bonus(self): element = self.sender() prop = element.property("prop_name") logger.debug(f"Setting bonus {prop} to {element.text()}")
def display_error_box(self, data): logger.debug("Trying to show error dialog") dialog = ErrorDialog(data["t"], data["val"], data["traceback"]) dialog.exec() self.close() QApplication.instance().exit()