예제 #1
0
    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()
예제 #2
0
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)
예제 #4
0
    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", "")
예제 #5
0
    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)
예제 #6
0
    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])
예제 #7
0
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
예제 #8
0
 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)
예제 #10
0
    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()
예제 #11
0
    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()
예제 #13
0
 def commit_bonus(self):
     element = self.sender()
     prop = element.property("prop_name")
     logger.debug(f"Setting bonus {prop} to {element.text()}")
예제 #14
0
 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()