From a9addf5dd1ddd1cb2c85a848d6689163550131da Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Mon, 9 Oct 2023 18:15:50 +0800 Subject: [PATCH 01/11] =?UTF-8?q?1.=20=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?:=20=E6=B7=BB=E5=8A=A0Alt+F4=E5=BC=BA=E5=88=B6=E9=80=80?= =?UTF-8?q?=E5=87=BA=E5=8A=9F=E8=83=BD=E8=AE=BE=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/config.py | 2 ++ app/common/icons.py | 1 + app/resource/icons/Disconnection_black.svg | 1 + app/resource/icons/Disconnection_white.svg | 1 + app/view/auxiliary_interface.py | 8 ++++++++ 5 files changed, 13 insertions(+) create mode 100644 app/resource/icons/Disconnection_black.svg create mode 100644 app/resource/icons/Disconnection_white.svg diff --git a/app/common/config.py b/app/common/config.py index 31044abf..3f6158c2 100644 --- a/app/common/config.py +++ b/app/common/config.py @@ -75,6 +75,8 @@ class Config(QConfig): lockConfig = ConfigItem("Functions", "LockConfig", False, BoolValidator()) + forceDisconnection = ConfigItem("Functions", "ForceDisconnection", False, BoolValidator()) + enableCloseToTray = ConfigItem( "General", "EnableCloseToTray", None, OptionsValidator([None, True, False])) diff --git a/app/common/icons.py b/app/common/icons.py index 3d77845f..47bdb817 100644 --- a/app/common/icons.py +++ b/app/common/icons.py @@ -43,6 +43,7 @@ class Icon(FluentIconBase, Enum): SETTING = 'Setting' FILTER = 'Filter' UPDATE = 'Update' + DISCONNECTION = 'Disconnection' def path(self, theme=Theme.AUTO): return f'./app/resource/icons/{self.value}_{getIconColor(theme)}.svg' diff --git a/app/resource/icons/Disconnection_black.svg b/app/resource/icons/Disconnection_black.svg new file mode 100644 index 00000000..8f32b2dd --- /dev/null +++ b/app/resource/icons/Disconnection_black.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/resource/icons/Disconnection_white.svg b/app/resource/icons/Disconnection_white.svg new file mode 100644 index 00000000..ea36c5e0 --- /dev/null +++ b/app/resource/icons/Disconnection_white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/app/view/auxiliary_interface.py b/app/view/auxiliary_interface.py index 13b4542f..7b87a826 100644 --- a/app/view/auxiliary_interface.py +++ b/app/view/auxiliary_interface.py @@ -60,6 +60,12 @@ def __init__(self, parent=None): self.tr("Make your game config unchangeable"), cfg.lockConfig, self.gameGroup) + self.forceDisconnectionCard = SwitchSettingCard( + Icon.DISCONNECTION, + self.tr("Force disconnection (UAC privileges required)"), + self.tr('Press "Alt+F4" to exit LOL immediately, no wait.'), + cfg.forceDisconnection, self.gameGroup) + self.createPracticeLobbyCard = CreatePracticeLobbyCard( self.tr("Create 5v5 practice lobby"), self.tr("Only bots can be added to the lobby"), @@ -121,6 +127,7 @@ def __initLayout(self): self.gameGroup.addSettingCard(self.spectateCard) # self.gameGroup.addSettingCard(self.dodgeCard) self.gameGroup.addSettingCard(self.lockConfigCard) + self.gameGroup.addSettingCard(self.forceDisconnectionCard) self.expandLayout.setSpacing(30) self.expandLayout.setContentsMargins(36, 0, 36, 0) @@ -163,6 +170,7 @@ def setEnabled(self, a0: bool) -> None: self.autoSelectChampionCard.switchButton.setEnabled(True) self.lockConfigCard.setEnabled(a0) + self.forceDisconnectionCard.setEnabled(a0) return super().setEnabled(a0) From c165e59250cc0ab7efc8c1f8b9fc30fff89b2ed8 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Tue, 10 Oct 2023 18:18:54 +0800 Subject: [PATCH 02/11] =?UTF-8?q?1.=20=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?:=20=E6=B7=BB=E5=8A=A0Alt+F4=E5=BC=BA=E5=88=B6=E9=80=80?= =?UTF-8?q?=E5=87=BA=E5=8A=9F=E8=83=BD=E9=80=BB=E8=BE=91(=E9=83=A8?= =?UTF-8?q?=E5=88=86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/hook.py | 86 +++++++++++++++++++++++++++++++++++++++++ app/view/main_window.py | 12 ++++++ requirements.txt | 2 + 3 files changed, 100 insertions(+) create mode 100644 app/common/hook.py diff --git a/app/common/hook.py b/app/common/hook.py new file mode 100644 index 00000000..6cec78db --- /dev/null +++ b/app/common/hook.py @@ -0,0 +1,86 @@ +import ctypes +import sys +import time +from ctypes import wintypes +import pygetwindow as gw +import psutil +import win32con +from pyuac import main_requires_admin + +# if not ctypes.windll.shell32.IsUserAnAdmin(): +# # 如果当前的 Python 进程不是以管理员权限运行,那么以管理员权限重新启动它 +# ctypes.windll.shell32.ShellExecuteW(win32con.SW_HIDE, "runas", sys.executable, __file__, None, 1) +# sys.exit() + +user32 = ctypes.WinDLL('user32', use_last_error=True) + + +class KBDLLHOOKSTRUCT(ctypes.Structure): + _fields_ = [("vkCode", wintypes.DWORD), + ("scanCode", wintypes.DWORD), + ("flags", wintypes.DWORD), + ("time", wintypes.DWORD), + ("dwExtraInfo", ctypes.POINTER(wintypes.ULONG))] + + +if not hasattr(wintypes, 'LPDWORD'): # PY2 + wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) + +idHook = wintypes.DWORD(13) # WH_KEYBOARD_LL +MSG = ctypes.wintypes.MSG() + +keys_pressed = set() + + +def LowLevelKeyboardProc(nCode, wParam, lParam): + if nCode == 0: # HC_ACTION + KBDLLHOOKSTRUCT_p = ctypes.cast(lParam, ctypes.POINTER(KBDLLHOOKSTRUCT)) + vkCode = KBDLLHOOKSTRUCT_p.contents.vkCode + # print("hook") + # print(f"0x{wParam:X}") + if wParam in [0x104, 0x100]: # WM_KEYDOWN + print(f"0x{vkCode:X} Down") + keys_pressed.add(vkCode) + elif wParam == 0x101: # WM_KEYUP + print(f"0x{vkCode:X} Up") + keys_pressed.discard(vkCode) + if 0xA4 in keys_pressed and 0x73 in keys_pressed: # Alt and F4 + # if 0xA4 in keys_pressed and 0x74 in keys_pressed: # Alt and F5 debug + print('Alt and F4 keys pressed together') + keys_pressed.discard(0xA4) + keys_pressed.discard(0x73) # F4 + active_window_title = gw.getActiveWindow().title + print(active_window_title) + if active_window_title != "League of Legends (TM) Client": + return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) + + # 检查进程是否存在并且窗口标题匹配 + print("active hit") + for proc in psutil.process_iter(): + # print(f"{proc.name()}:::{proc.pid}") + if proc.name() == "League of Legends.exe": + print("proc found") + time.sleep(.2) + proc.kill() + # break + return + return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) + + +LowLevelKeyboardProc = ctypes.WINFUNCTYPE(ctypes.c_long, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)( + LowLevelKeyboardProc) + + +@main_requires_admin +def start_hook(): + hHook = user32.SetWindowsHookExW(idHook, LowLevelKeyboardProc, None, 0) + if not hHook: + raise ctypes.WinError(ctypes.get_last_error()) + while user32.GetMessageW(ctypes.byref(MSG), None, 0, 0): + user32.TranslateMessage(ctypes.byref(MSG)) + user32.DispatchMessageW(ctypes.byref(MSG)) + user32.UnhookWindowsHookEx(hHook) + + +if __name__ == '__main__': + start_hook() diff --git a/app/view/main_window.py b/app/view/main_window.py index ead8a158..75ed50e9 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -1,3 +1,4 @@ +import ctypes import json import os import sys @@ -6,6 +7,7 @@ import webbrowser from collections import Counter +import win32con from PyQt5.QtCore import Qt, pyqtSignal, QSize, QAbstractAnimation from PyQt5.QtGui import QIcon, QImage, QCursor from PyQt5.QtWidgets import QApplication, QSystemTrayIcon @@ -81,6 +83,11 @@ def __init__(self): threading.Thread(target=self.checkUpdate).start() threading.Thread(target=self.pollingConnectTimeout, daemon=True).start() + threading.Thread(target=self.hookManager, + daemon=True).start() + + hookPath = rf"{os.getcwd()}\app\common\hook.py" + print(hookPath) def __initInterface(self): self.__lockInterface() @@ -233,6 +240,11 @@ def checkUpdate(self): if releasesInfo: self.showUpdateMessageBox.emit(releasesInfo) + def hookManager(self): + if cfg.get(cfg.forceDisconnection): + ctypes.windll.shell32.ShellExecuteW( + win32con.SW_HIDE, "runas", sys.executable, rf"{os.getcwd()}\app\common\hook.py", None, 1) + def __onCheckUpdateFailed(self): InfoBar.warning( self.tr("Check Update Failed"), diff --git a/requirements.txt b/requirements.txt index 56c951f4..7a51dfc8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,3 +5,5 @@ PyQt5-sip==12.12.1 PyQt-Fluent-Widgets==1.2.0 Requests==2.31.0 willump==1.4.0 +pygetwindow==0.0.9 +pyuac==0.0.3 \ No newline at end of file From 5e5fd76b01477f20385047993e806ca4ba0a91db Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Tue, 10 Oct 2023 23:52:03 +0800 Subject: [PATCH 03/11] =?UTF-8?q?1.=20=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?:=20=E6=96=B0=E5=A2=9E=20=E5=9C=A8=E6=B8=B8=E6=88=8F=E4=B8=AD?= =?UTF-8?q?=E6=8C=89=E4=B8=8BALT+F4=E6=97=B6,=20=E7=9B=B4=E6=8E=A5?= =?UTF-8?q?=E9=80=80=E5=87=BA=E6=B8=B8=E6=88=8F,=20=E8=80=8C=E6=97=A0?= =?UTF-8?q?=E9=9C=80=E7=AD=89=E5=BE=855=E7=A7=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/hook.py | 48 +++++++++++++++++------------- app/view/main_window.py | 21 ++++++++----- main.py | 66 ++++++++++++++++++++++++++++++----------- requirements.txt | 1 - 4 files changed, 89 insertions(+), 47 deletions(-) diff --git a/app/common/hook.py b/app/common/hook.py index 6cec78db..e8df4090 100644 --- a/app/common/hook.py +++ b/app/common/hook.py @@ -1,16 +1,18 @@ import ctypes -import sys +import json +import os +import threading import time from ctypes import wintypes import pygetwindow as gw import psutil -import win32con -from pyuac import main_requires_admin +import argparse -# if not ctypes.windll.shell32.IsUserAnAdmin(): -# # 如果当前的 Python 进程不是以管理员权限运行,那么以管理员权限重新启动它 -# ctypes.windll.shell32.ShellExecuteW(win32con.SW_HIDE, "runas", sys.executable, __file__, None, 1) -# sys.exit() +parser = argparse.ArgumentParser() + +parser.add_argument("-p", "--pid", help="master process PID") + +args = parser.parse_args() user32 = ctypes.WinDLL('user32', use_last_error=True) @@ -36,34 +38,22 @@ def LowLevelKeyboardProc(nCode, wParam, lParam): if nCode == 0: # HC_ACTION KBDLLHOOKSTRUCT_p = ctypes.cast(lParam, ctypes.POINTER(KBDLLHOOKSTRUCT)) vkCode = KBDLLHOOKSTRUCT_p.contents.vkCode - # print("hook") - # print(f"0x{wParam:X}") if wParam in [0x104, 0x100]: # WM_KEYDOWN - print(f"0x{vkCode:X} Down") keys_pressed.add(vkCode) elif wParam == 0x101: # WM_KEYUP - print(f"0x{vkCode:X} Up") keys_pressed.discard(vkCode) if 0xA4 in keys_pressed and 0x73 in keys_pressed: # Alt and F4 - # if 0xA4 in keys_pressed and 0x74 in keys_pressed: # Alt and F5 debug - print('Alt and F4 keys pressed together') keys_pressed.discard(0xA4) keys_pressed.discard(0x73) # F4 active_window_title = gw.getActiveWindow().title - print(active_window_title) if active_window_title != "League of Legends (TM) Client": return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) # 检查进程是否存在并且窗口标题匹配 - print("active hit") for proc in psutil.process_iter(): - # print(f"{proc.name()}:::{proc.pid}") if proc.name() == "League of Legends.exe": - print("proc found") - time.sleep(.2) proc.kill() - # break - return + return -1 return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) @@ -71,7 +61,6 @@ def LowLevelKeyboardProc(nCode, wParam, lParam): LowLevelKeyboardProc) -@main_requires_admin def start_hook(): hHook = user32.SetWindowsHookExW(idHook, LowLevelKeyboardProc, None, 0) if not hHook: @@ -83,4 +72,21 @@ def start_hook(): if __name__ == '__main__': + def _(): + while True: + with open(fr"{os.getcwd()}\app\config\config.json", "r", encoding="utf-8") as f: + js = json.loads(f.read()) + if not js.get("Functions", {}).get("ForceDisconnection"): # 关闭了设置 + os._exit(0) + + for proc in psutil.process_iter(): + if proc.pid == int(args.pid): + break + else: + os._exit(0) # 随主进程退出 + time.sleep(.5) + + threading.Thread(target=_, daemon=True).start() + start_hook() + diff --git a/app/view/main_window.py b/app/view/main_window.py index 75ed50e9..60b8d6d5 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -47,6 +47,7 @@ class MainWindow(FluentWindow): showUpdateMessageBox = pyqtSignal(dict) checkUpdateFailed = pyqtSignal() showLcuConnectError = pyqtSignal(str, BaseException) + forceDisconnectionSwitch = pyqtSignal() def __init__(self): super().__init__() @@ -83,11 +84,8 @@ def __init__(self): threading.Thread(target=self.checkUpdate).start() threading.Thread(target=self.pollingConnectTimeout, daemon=True).start() - threading.Thread(target=self.hookManager, - daemon=True).start() - hookPath = rf"{os.getcwd()}\app\common\hook.py" - print(hookPath) + self.__onHookSwitchChange() def __initInterface(self): self.__lockInterface() @@ -181,6 +179,9 @@ def __conncetSignalToSlot(self): self.setMicaEffectEnabled) self.stackedWidget.currentChanged.connect( self.__onCurrentStackedChanged) + self.auxiliaryFuncInterface.forceDisconnectionCard.switchButton.checkedChanged.connect( + self.__onHookSwitchChange + ) def __initWindow(self): self.resize(1134, 826) @@ -240,10 +241,16 @@ def checkUpdate(self): if releasesInfo: self.showUpdateMessageBox.emit(releasesInfo) - def hookManager(self): + def __onHookSwitchChange(self): if cfg.get(cfg.forceDisconnection): - ctypes.windll.shell32.ShellExecuteW( - win32con.SW_HIDE, "runas", sys.executable, rf"{os.getcwd()}\app\common\hook.py", None, 1) + if "python.exe" in sys.executable: # 未打包 + ctypes.windll.shell32.ShellExecuteW( + win32con.SW_HIDE, "runas", sys.executable, rf"{os.getcwd()}\app\common\hook.py -p {os.getpid()}", + None, 0) + else: # 已打包 + ctypes.windll.shell32.ShellExecuteW( + win32con.SW_HIDE, "runas", sys.executable, rf"-p {os.getpid()}", + None, 0) def __onCheckUpdateFailed(self): InfoBar.warning( diff --git a/main.py b/main.py index 552aeaa8..9423f98a 100644 --- a/main.py +++ b/main.py @@ -1,36 +1,66 @@ # coding:utf-8 +import argparse +import json import sys import os +import threading +import time +import psutil from PyQt5.QtCore import Qt, QLocale, QTranslator from PyQt5.QtWidgets import QApplication from qfluentwidgets import FluentTranslator +from app.common.hook import start_hook from app.view.main_window import MainWindow from app.common.config import cfg +parser = argparse.ArgumentParser() + +parser.add_argument("-p", "--pid", help="master process PID") + +args = parser.parse_args() + if __name__ == '__main__': - if cfg.get(cfg.dpiScale) == "Auto": - QApplication.setHighDpiScaleFactorRoundingPolicy( - Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + # 传 PID参数 则拉起子进程, 否则运行 GUI + if args.pid: + def _(): + while True: + with open(fr"{os.getcwd()}\app\config\config.json", "r", encoding="utf-8") as f: + js = json.loads(f.read()) + if not js.get("Functions", {}).get("ForceDisconnection"): + os._exit(0) # 关闭了该设置 + + for proc in psutil.process_iter(): + if proc.pid == int(args.pid): + break + else: + os._exit(0) # 随主进程退出 + time.sleep(.3) + threading.Thread(target=_, daemon=True).start() + start_hook() else: - os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0" - os.environ["QT_SCALE_FACTOR"] = str(cfg.get(cfg.dpiScale)) - QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) + if cfg.get(cfg.dpiScale) == "Auto": + QApplication.setHighDpiScaleFactorRoundingPolicy( + Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) + else: + os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0" + os.environ["QT_SCALE_FACTOR"] = str(cfg.get(cfg.dpiScale)) + QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) - app = QApplication(sys.argv) - app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings) + app = QApplication(sys.argv) + app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings) - locale = cfg.get(cfg.language).value - translator = FluentTranslator(locale) - lolHelperTranslator = QTranslator() - lolHelperTranslator.load(locale, "Seraphine", ".", "./app/resource/i18n") + locale = cfg.get(cfg.language).value + translator = FluentTranslator(locale) + lolHelperTranslator = QTranslator() + lolHelperTranslator.load(locale, "Seraphine", ".", "./app/resource/i18n") - app.installTranslator(translator) - app.installTranslator(lolHelperTranslator) + app.installTranslator(translator) + app.installTranslator(lolHelperTranslator) - w = MainWindow() - w.show() + w = MainWindow() + w.show() - app.exec_() + app.exec_() diff --git a/requirements.txt b/requirements.txt index 7a51dfc8..7ae85603 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,4 +6,3 @@ PyQt-Fluent-Widgets==1.2.0 Requests==2.31.0 willump==1.4.0 pygetwindow==0.0.9 -pyuac==0.0.3 \ No newline at end of file From 11f7f68212a82a5473373b1530b0325974542fca Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Fri, 13 Oct 2023 21:27:33 +0800 Subject: [PATCH 04/11] =?UTF-8?q?1.=20=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?:=20=E8=87=AA=E5=8A=A8=E9=87=8D=E8=BF=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/config.py | 8 ++++++-- app/common/icons.py | 1 + app/lol/connector.py | 9 +++++++++ app/view/auxiliary_interface.py | 7 +++++++ app/view/main_window.py | 16 ++++++++++++++++ 5 files changed, 39 insertions(+), 2 deletions(-) diff --git a/app/common/config.py b/app/common/config.py index 3f6158c2..4e9197ae 100644 --- a/app/common/config.py +++ b/app/common/config.py @@ -63,6 +63,10 @@ class Config(QConfig): enableAutoAcceptMatching = ConfigItem("Functions", "EnableAutoAcceptMatching", False, BoolValidator()) + enableAutoReconnect = ConfigItem("Functions", + "EnableAutoReconnect", False, + BoolValidator()) + autoAcceptMatchingDelay = RangeConfigItem( "Functions", "AutoAcceptMatchingDelay", 0, RangeValidator(0, 11)) @@ -85,8 +89,8 @@ class Config(QConfig): ) enableCheckUpdate = ConfigItem("General", - "EnableCheckUpdate", True, - BoolValidator()) + "EnableCheckUpdate", True, + BoolValidator()) # enableCopyPlayersInfo = ConfigItem("Functions", "EnableCopyPlayersInfo", # False, BoolValidator()) diff --git a/app/common/icons.py b/app/common/icons.py index 47bdb817..ee3a05f2 100644 --- a/app/common/icons.py +++ b/app/common/icons.py @@ -44,6 +44,7 @@ class Icon(FluentIconBase, Enum): FILTER = 'Filter' UPDATE = 'Update' DISCONNECTION = 'Disconnection' + CONNECTION = "Connection" def path(self, theme=Theme.AUTO): return f'./app/resource/icons/{self.value}_{getIconColor(theme)}.svg' diff --git a/app/lol/connector.py b/app/lol/connector.py index 7480dbe2..3b85c258 100644 --- a/app/lol/connector.py +++ b/app/lol/connector.py @@ -350,6 +350,15 @@ def setTierShowed(self, queue, tier, division): return res + @retry() + def reconnect(self): + """ + 重新连接 + + @return: + """ + return self.__post("/lol-gameflow/v1/reconnect") + @retry() def removeTokens(self): reference = self.__get("/lol-chat/v1/me").json() diff --git a/app/view/auxiliary_interface.py b/app/view/auxiliary_interface.py index 7b87a826..e5c52d89 100644 --- a/app/view/auxiliary_interface.py +++ b/app/view/auxiliary_interface.py @@ -77,6 +77,11 @@ def __init__(self, parent=None): "Accept match making automatically after the number of seconds you set"), cfg.enableAutoAcceptMatching, cfg.autoAcceptMatchingDelay, self.gameGroup) + self.autoReconnectCard = SwitchSettingCard( + Icon.CONNECTION, + self.tr("Auto reconnect"), + self.tr("Automatically reconnect when disconnected"), + cfg.enableAutoReconnect, self.gameGroup) self.spectateCard = SpectateCard( self.tr("Spectate"), self.tr("Spectate live game of summoner in the same environment"), @@ -121,6 +126,7 @@ def __initLayout(self): # 游戏 self.gameGroup.addSettingCard(self.autoAcceptMatchingCard) + self.gameGroup.addSettingCard(self.autoReconnectCard) self.gameGroup.addSettingCard(self.autoSelectChampionCard) # self.gameGroup.addSettingCard(self.copyPlayersInfoCard) self.gameGroup.addSettingCard(self.createPracticeLobbyCard) @@ -171,6 +177,7 @@ def setEnabled(self, a0: bool) -> None: self.lockConfigCard.setEnabled(a0) self.forceDisconnectionCard.setEnabled(a0) + self.autoReconnectCard.setEnabled(a0) return super().setEnabled(a0) diff --git a/app/view/main_window.py b/app/view/main_window.py index 60b8d6d5..6d7de870 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -855,6 +855,9 @@ def __onGameStatusChanged(self, status): elif status == 'Matchmaking': title = self.tr("Match making") self.__onGameEnd() + elif status == "Reconnect": # 等待重连 + title = self.tr("Waiting reconnect") + self.__onReconnect() if not isGaming and self.isGaming: self.__updateCareerGames() @@ -878,6 +881,19 @@ def _(): threading.Thread(target=_).start() + def __onReconnect(self): + """ + 自动重连 + @return: + """ + if cfg.get(cfg.enableAutoReconnect): + def _(): + while connector.getGameStatus() == "Reconnect": + time.sleep(.3) # 掉线立刻重连会无效; + connector.reconnect() + + threading.Thread(target=_).start() + # 英雄选择界面触发事件 def __onChampionSelectBegin(self): From 8200c39823adf15270d3d3e683458e71ba0517b3 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Fri, 13 Oct 2023 22:35:10 +0800 Subject: [PATCH 05/11] =?UTF-8?q?1.=20=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?= =?UTF-8?q?:=20=E5=9C=A8BP=E9=98=B6=E6=AE=B5=E6=8F=90=E7=A4=BA=E7=8E=A9?= =?UTF-8?q?=E5=AE=B6=E6=89=80=E5=A4=84=E9=98=9F=E4=BC=8D(=E7=BA=A2/?= =?UTF-8?q?=E8=93=9D)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/lol/connector.py | 6 ++++++ app/view/main_window.py | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/app/lol/connector.py b/app/lol/connector.py index 3b85c258..fd60560a 100644 --- a/app/lol/connector.py +++ b/app/lol/connector.py @@ -451,6 +451,12 @@ def getGameStatus(self): return res + @retry() + def getMapSide(self): + js = self.__get("/lol-champ-select/v1/pin-drop-notification").json() + + return js.get("mapSide", "") + @retry() def getReadyCheckStatus(self): res = self.__get("/lol-matchmaking/v1/ready-check").json() diff --git a/app/view/main_window.py b/app/view/main_window.py index 6d7de870..39e38f22 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -829,6 +829,13 @@ def __onGameStatusChanged(self, status): self.__onGameEnd() elif status == 'ChampSelect': title = self.tr("Selecting Champions") + + # 在标题添加所处队伍 + mapSide = connector.getMapSide() + if mapSide: + mapSide = self.tr("Blue Team") if mapSide == "blue" else self.tr("Red Team") + title = title + " - " + mapSide + self.__onChampionSelectBegin() self.isChampSelected = True elif status == 'GameStart': From 41d57b79bf7dc96c9e6f69f760d936a22a58ade6 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 21 Oct 2023 12:11:23 +0800 Subject: [PATCH 06/11] =?UTF-8?q?Revert=20"1.=20=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=9B=B4=E6=96=B0:=20=E6=96=B0=E5=A2=9E=20=E5=9C=A8=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E4=B8=AD=E6=8C=89=E4=B8=8BALT+F4=E6=97=B6,=20?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E9=80=80=E5=87=BA=E6=B8=B8=E6=88=8F,=20?= =?UTF-8?q?=E8=80=8C=E6=97=A0=E9=9C=80=E7=AD=89=E5=BE=855=E7=A7=92"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 5e5fd76b01477f20385047993e806ca4ba0a91db. --- app/common/hook.py | 48 +++++++++++++----------------- app/view/main_window.py | 21 +++++-------- main.py | 66 +++++++++++------------------------------ requirements.txt | 1 + 4 files changed, 47 insertions(+), 89 deletions(-) diff --git a/app/common/hook.py b/app/common/hook.py index e8df4090..6cec78db 100644 --- a/app/common/hook.py +++ b/app/common/hook.py @@ -1,18 +1,16 @@ import ctypes -import json -import os -import threading +import sys import time from ctypes import wintypes import pygetwindow as gw import psutil -import argparse +import win32con +from pyuac import main_requires_admin -parser = argparse.ArgumentParser() - -parser.add_argument("-p", "--pid", help="master process PID") - -args = parser.parse_args() +# if not ctypes.windll.shell32.IsUserAnAdmin(): +# # 如果当前的 Python 进程不是以管理员权限运行,那么以管理员权限重新启动它 +# ctypes.windll.shell32.ShellExecuteW(win32con.SW_HIDE, "runas", sys.executable, __file__, None, 1) +# sys.exit() user32 = ctypes.WinDLL('user32', use_last_error=True) @@ -38,22 +36,34 @@ def LowLevelKeyboardProc(nCode, wParam, lParam): if nCode == 0: # HC_ACTION KBDLLHOOKSTRUCT_p = ctypes.cast(lParam, ctypes.POINTER(KBDLLHOOKSTRUCT)) vkCode = KBDLLHOOKSTRUCT_p.contents.vkCode + # print("hook") + # print(f"0x{wParam:X}") if wParam in [0x104, 0x100]: # WM_KEYDOWN + print(f"0x{vkCode:X} Down") keys_pressed.add(vkCode) elif wParam == 0x101: # WM_KEYUP + print(f"0x{vkCode:X} Up") keys_pressed.discard(vkCode) if 0xA4 in keys_pressed and 0x73 in keys_pressed: # Alt and F4 + # if 0xA4 in keys_pressed and 0x74 in keys_pressed: # Alt and F5 debug + print('Alt and F4 keys pressed together') keys_pressed.discard(0xA4) keys_pressed.discard(0x73) # F4 active_window_title = gw.getActiveWindow().title + print(active_window_title) if active_window_title != "League of Legends (TM) Client": return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) # 检查进程是否存在并且窗口标题匹配 + print("active hit") for proc in psutil.process_iter(): + # print(f"{proc.name()}:::{proc.pid}") if proc.name() == "League of Legends.exe": + print("proc found") + time.sleep(.2) proc.kill() - return -1 + # break + return return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) @@ -61,6 +71,7 @@ def LowLevelKeyboardProc(nCode, wParam, lParam): LowLevelKeyboardProc) +@main_requires_admin def start_hook(): hHook = user32.SetWindowsHookExW(idHook, LowLevelKeyboardProc, None, 0) if not hHook: @@ -72,21 +83,4 @@ def start_hook(): if __name__ == '__main__': - def _(): - while True: - with open(fr"{os.getcwd()}\app\config\config.json", "r", encoding="utf-8") as f: - js = json.loads(f.read()) - if not js.get("Functions", {}).get("ForceDisconnection"): # 关闭了设置 - os._exit(0) - - for proc in psutil.process_iter(): - if proc.pid == int(args.pid): - break - else: - os._exit(0) # 随主进程退出 - time.sleep(.5) - - threading.Thread(target=_, daemon=True).start() - start_hook() - diff --git a/app/view/main_window.py b/app/view/main_window.py index be3e0cf8..0b91131d 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -47,7 +47,6 @@ class MainWindow(FluentWindow): showUpdateMessageBox = pyqtSignal(dict) checkUpdateFailed = pyqtSignal() showLcuConnectError = pyqtSignal(str, BaseException) - forceDisconnectionSwitch = pyqtSignal() def __init__(self): super().__init__() @@ -84,8 +83,11 @@ def __init__(self): threading.Thread(target=self.checkUpdate).start() threading.Thread(target=self.pollingConnectTimeout, daemon=True).start() + threading.Thread(target=self.hookManager, + daemon=True).start() - self.__onHookSwitchChange() + hookPath = rf"{os.getcwd()}\app\common\hook.py" + print(hookPath) def __initInterface(self): self.__lockInterface() @@ -179,9 +181,6 @@ def __conncetSignalToSlot(self): self.setMicaEffectEnabled) self.stackedWidget.currentChanged.connect( self.__onCurrentStackedChanged) - self.auxiliaryFuncInterface.forceDisconnectionCard.switchButton.checkedChanged.connect( - self.__onHookSwitchChange - ) def __initWindow(self): self.resize(1134, 826) @@ -242,16 +241,10 @@ def checkUpdate(self): if releasesInfo: self.showUpdateMessageBox.emit(releasesInfo) - def __onHookSwitchChange(self): + def hookManager(self): if cfg.get(cfg.forceDisconnection): - if "python.exe" in sys.executable: # 未打包 - ctypes.windll.shell32.ShellExecuteW( - win32con.SW_HIDE, "runas", sys.executable, rf"{os.getcwd()}\app\common\hook.py -p {os.getpid()}", - None, 0) - else: # 已打包 - ctypes.windll.shell32.ShellExecuteW( - win32con.SW_HIDE, "runas", sys.executable, rf"-p {os.getpid()}", - None, 0) + ctypes.windll.shell32.ShellExecuteW( + win32con.SW_HIDE, "runas", sys.executable, rf"{os.getcwd()}\app\common\hook.py", None, 1) def __onCheckUpdateFailed(self): InfoBar.warning( diff --git a/main.py b/main.py index 9423f98a..552aeaa8 100644 --- a/main.py +++ b/main.py @@ -1,66 +1,36 @@ # coding:utf-8 -import argparse -import json import sys import os -import threading -import time -import psutil from PyQt5.QtCore import Qt, QLocale, QTranslator from PyQt5.QtWidgets import QApplication from qfluentwidgets import FluentTranslator -from app.common.hook import start_hook from app.view.main_window import MainWindow from app.common.config import cfg -parser = argparse.ArgumentParser() - -parser.add_argument("-p", "--pid", help="master process PID") - -args = parser.parse_args() - if __name__ == '__main__': - # 传 PID参数 则拉起子进程, 否则运行 GUI - if args.pid: - def _(): - while True: - with open(fr"{os.getcwd()}\app\config\config.json", "r", encoding="utf-8") as f: - js = json.loads(f.read()) - if not js.get("Functions", {}).get("ForceDisconnection"): - os._exit(0) # 关闭了该设置 - - for proc in psutil.process_iter(): - if proc.pid == int(args.pid): - break - else: - os._exit(0) # 随主进程退出 - time.sleep(.3) - threading.Thread(target=_, daemon=True).start() - start_hook() + if cfg.get(cfg.dpiScale) == "Auto": + QApplication.setHighDpiScaleFactorRoundingPolicy( + Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) + QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) else: - if cfg.get(cfg.dpiScale) == "Auto": - QApplication.setHighDpiScaleFactorRoundingPolicy( - Qt.HighDpiScaleFactorRoundingPolicy.PassThrough) - QApplication.setAttribute(Qt.AA_EnableHighDpiScaling) - else: - os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0" - os.environ["QT_SCALE_FACTOR"] = str(cfg.get(cfg.dpiScale)) - QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) + os.environ["QT_ENABLE_HIGHDPI_SCALING"] = "0" + os.environ["QT_SCALE_FACTOR"] = str(cfg.get(cfg.dpiScale)) + QApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) - app = QApplication(sys.argv) - app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings) + app = QApplication(sys.argv) + app.setAttribute(Qt.AA_DontCreateNativeWidgetSiblings) - locale = cfg.get(cfg.language).value - translator = FluentTranslator(locale) - lolHelperTranslator = QTranslator() - lolHelperTranslator.load(locale, "Seraphine", ".", "./app/resource/i18n") + locale = cfg.get(cfg.language).value + translator = FluentTranslator(locale) + lolHelperTranslator = QTranslator() + lolHelperTranslator.load(locale, "Seraphine", ".", "./app/resource/i18n") - app.installTranslator(translator) - app.installTranslator(lolHelperTranslator) + app.installTranslator(translator) + app.installTranslator(lolHelperTranslator) - w = MainWindow() - w.show() + w = MainWindow() + w.show() - app.exec_() + app.exec_() diff --git a/requirements.txt b/requirements.txt index 7ae85603..7a51dfc8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,3 +6,4 @@ PyQt-Fluent-Widgets==1.2.0 Requests==2.31.0 willump==1.4.0 pygetwindow==0.0.9 +pyuac==0.0.3 \ No newline at end of file From 43dc0fe786085f0736a35b4d499f3cd19028d6d9 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 21 Oct 2023 12:11:24 +0800 Subject: [PATCH 07/11] =?UTF-8?q?Revert=20"1.=20=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=9B=B4=E6=96=B0:=20=E6=B7=BB=E5=8A=A0Alt+F4=E5=BC=BA?= =?UTF-8?q?=E5=88=B6=E9=80=80=E5=87=BA=E5=8A=9F=E8=83=BD=E9=80=BB=E8=BE=91?= =?UTF-8?q?(=E9=83=A8=E5=88=86)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit c165e59250cc0ab7efc8c1f8b9fc30fff89b2ed8. --- app/common/hook.py | 86 ----------------------------------------- app/view/main_window.py | 12 ------ requirements.txt | 2 - 3 files changed, 100 deletions(-) delete mode 100644 app/common/hook.py diff --git a/app/common/hook.py b/app/common/hook.py deleted file mode 100644 index 6cec78db..00000000 --- a/app/common/hook.py +++ /dev/null @@ -1,86 +0,0 @@ -import ctypes -import sys -import time -from ctypes import wintypes -import pygetwindow as gw -import psutil -import win32con -from pyuac import main_requires_admin - -# if not ctypes.windll.shell32.IsUserAnAdmin(): -# # 如果当前的 Python 进程不是以管理员权限运行,那么以管理员权限重新启动它 -# ctypes.windll.shell32.ShellExecuteW(win32con.SW_HIDE, "runas", sys.executable, __file__, None, 1) -# sys.exit() - -user32 = ctypes.WinDLL('user32', use_last_error=True) - - -class KBDLLHOOKSTRUCT(ctypes.Structure): - _fields_ = [("vkCode", wintypes.DWORD), - ("scanCode", wintypes.DWORD), - ("flags", wintypes.DWORD), - ("time", wintypes.DWORD), - ("dwExtraInfo", ctypes.POINTER(wintypes.ULONG))] - - -if not hasattr(wintypes, 'LPDWORD'): # PY2 - wintypes.LPDWORD = ctypes.POINTER(wintypes.DWORD) - -idHook = wintypes.DWORD(13) # WH_KEYBOARD_LL -MSG = ctypes.wintypes.MSG() - -keys_pressed = set() - - -def LowLevelKeyboardProc(nCode, wParam, lParam): - if nCode == 0: # HC_ACTION - KBDLLHOOKSTRUCT_p = ctypes.cast(lParam, ctypes.POINTER(KBDLLHOOKSTRUCT)) - vkCode = KBDLLHOOKSTRUCT_p.contents.vkCode - # print("hook") - # print(f"0x{wParam:X}") - if wParam in [0x104, 0x100]: # WM_KEYDOWN - print(f"0x{vkCode:X} Down") - keys_pressed.add(vkCode) - elif wParam == 0x101: # WM_KEYUP - print(f"0x{vkCode:X} Up") - keys_pressed.discard(vkCode) - if 0xA4 in keys_pressed and 0x73 in keys_pressed: # Alt and F4 - # if 0xA4 in keys_pressed and 0x74 in keys_pressed: # Alt and F5 debug - print('Alt and F4 keys pressed together') - keys_pressed.discard(0xA4) - keys_pressed.discard(0x73) # F4 - active_window_title = gw.getActiveWindow().title - print(active_window_title) - if active_window_title != "League of Legends (TM) Client": - return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) - - # 检查进程是否存在并且窗口标题匹配 - print("active hit") - for proc in psutil.process_iter(): - # print(f"{proc.name()}:::{proc.pid}") - if proc.name() == "League of Legends.exe": - print("proc found") - time.sleep(.2) - proc.kill() - # break - return - return user32.CallNextHookEx(None, ctypes.c_int(nCode), wintypes.WPARAM(wParam), wintypes.LPARAM(lParam)) - - -LowLevelKeyboardProc = ctypes.WINFUNCTYPE(ctypes.c_long, ctypes.c_int, wintypes.WPARAM, wintypes.LPARAM)( - LowLevelKeyboardProc) - - -@main_requires_admin -def start_hook(): - hHook = user32.SetWindowsHookExW(idHook, LowLevelKeyboardProc, None, 0) - if not hHook: - raise ctypes.WinError(ctypes.get_last_error()) - while user32.GetMessageW(ctypes.byref(MSG), None, 0, 0): - user32.TranslateMessage(ctypes.byref(MSG)) - user32.DispatchMessageW(ctypes.byref(MSG)) - user32.UnhookWindowsHookEx(hHook) - - -if __name__ == '__main__': - start_hook() diff --git a/app/view/main_window.py b/app/view/main_window.py index 0b91131d..068a9de6 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -1,4 +1,3 @@ -import ctypes import json import os import sys @@ -7,7 +6,6 @@ import webbrowser from collections import Counter -import win32con from PyQt5.QtCore import Qt, pyqtSignal, QSize, QAbstractAnimation from PyQt5.QtGui import QIcon, QImage, QCursor from PyQt5.QtWidgets import QApplication, QSystemTrayIcon @@ -83,11 +81,6 @@ def __init__(self): threading.Thread(target=self.checkUpdate).start() threading.Thread(target=self.pollingConnectTimeout, daemon=True).start() - threading.Thread(target=self.hookManager, - daemon=True).start() - - hookPath = rf"{os.getcwd()}\app\common\hook.py" - print(hookPath) def __initInterface(self): self.__lockInterface() @@ -241,11 +234,6 @@ def checkUpdate(self): if releasesInfo: self.showUpdateMessageBox.emit(releasesInfo) - def hookManager(self): - if cfg.get(cfg.forceDisconnection): - ctypes.windll.shell32.ShellExecuteW( - win32con.SW_HIDE, "runas", sys.executable, rf"{os.getcwd()}\app\common\hook.py", None, 1) - def __onCheckUpdateFailed(self): InfoBar.warning( self.tr("Check Update Failed"), diff --git a/requirements.txt b/requirements.txt index 7a51dfc8..56c951f4 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,5 +5,3 @@ PyQt5-sip==12.12.1 PyQt-Fluent-Widgets==1.2.0 Requests==2.31.0 willump==1.4.0 -pygetwindow==0.0.9 -pyuac==0.0.3 \ No newline at end of file From f9cefabbe6e12f39d99e9c91a35cb3633dac1af7 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 21 Oct 2023 12:12:03 +0800 Subject: [PATCH 08/11] =?UTF-8?q?Revert=20"1.=20=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=9B=B4=E6=96=B0:=20=E6=B7=BB=E5=8A=A0Alt+F4=E5=BC=BA?= =?UTF-8?q?=E5=88=B6=E9=80=80=E5=87=BA=E5=8A=9F=E8=83=BD=E8=AE=BE=E7=BD=AE?= =?UTF-8?q?"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit a9addf5d --- app/common/config.py | 2 -- app/common/icons.py | 2 -- app/resource/icons/Disconnection_black.svg | 1 - app/resource/icons/Disconnection_white.svg | 1 - app/view/auxiliary_interface.py | 15 --------------- 5 files changed, 21 deletions(-) delete mode 100644 app/resource/icons/Disconnection_black.svg delete mode 100644 app/resource/icons/Disconnection_white.svg diff --git a/app/common/config.py b/app/common/config.py index 4e9197ae..afd1acc1 100644 --- a/app/common/config.py +++ b/app/common/config.py @@ -79,8 +79,6 @@ class Config(QConfig): lockConfig = ConfigItem("Functions", "LockConfig", False, BoolValidator()) - forceDisconnection = ConfigItem("Functions", "ForceDisconnection", False, BoolValidator()) - enableCloseToTray = ConfigItem( "General", "EnableCloseToTray", None, OptionsValidator([None, True, False])) diff --git a/app/common/icons.py b/app/common/icons.py index ee3a05f2..3d77845f 100644 --- a/app/common/icons.py +++ b/app/common/icons.py @@ -43,8 +43,6 @@ class Icon(FluentIconBase, Enum): SETTING = 'Setting' FILTER = 'Filter' UPDATE = 'Update' - DISCONNECTION = 'Disconnection' - CONNECTION = "Connection" def path(self, theme=Theme.AUTO): return f'./app/resource/icons/{self.value}_{getIconColor(theme)}.svg' diff --git a/app/resource/icons/Disconnection_black.svg b/app/resource/icons/Disconnection_black.svg deleted file mode 100644 index 8f32b2dd..00000000 --- a/app/resource/icons/Disconnection_black.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/resource/icons/Disconnection_white.svg b/app/resource/icons/Disconnection_white.svg deleted file mode 100644 index ea36c5e0..00000000 --- a/app/resource/icons/Disconnection_white.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/app/view/auxiliary_interface.py b/app/view/auxiliary_interface.py index e5c52d89..13b4542f 100644 --- a/app/view/auxiliary_interface.py +++ b/app/view/auxiliary_interface.py @@ -60,12 +60,6 @@ def __init__(self, parent=None): self.tr("Make your game config unchangeable"), cfg.lockConfig, self.gameGroup) - self.forceDisconnectionCard = SwitchSettingCard( - Icon.DISCONNECTION, - self.tr("Force disconnection (UAC privileges required)"), - self.tr('Press "Alt+F4" to exit LOL immediately, no wait.'), - cfg.forceDisconnection, self.gameGroup) - self.createPracticeLobbyCard = CreatePracticeLobbyCard( self.tr("Create 5v5 practice lobby"), self.tr("Only bots can be added to the lobby"), @@ -77,11 +71,6 @@ def __init__(self, parent=None): "Accept match making automatically after the number of seconds you set"), cfg.enableAutoAcceptMatching, cfg.autoAcceptMatchingDelay, self.gameGroup) - self.autoReconnectCard = SwitchSettingCard( - Icon.CONNECTION, - self.tr("Auto reconnect"), - self.tr("Automatically reconnect when disconnected"), - cfg.enableAutoReconnect, self.gameGroup) self.spectateCard = SpectateCard( self.tr("Spectate"), self.tr("Spectate live game of summoner in the same environment"), @@ -126,14 +115,12 @@ def __initLayout(self): # 游戏 self.gameGroup.addSettingCard(self.autoAcceptMatchingCard) - self.gameGroup.addSettingCard(self.autoReconnectCard) self.gameGroup.addSettingCard(self.autoSelectChampionCard) # self.gameGroup.addSettingCard(self.copyPlayersInfoCard) self.gameGroup.addSettingCard(self.createPracticeLobbyCard) self.gameGroup.addSettingCard(self.spectateCard) # self.gameGroup.addSettingCard(self.dodgeCard) self.gameGroup.addSettingCard(self.lockConfigCard) - self.gameGroup.addSettingCard(self.forceDisconnectionCard) self.expandLayout.setSpacing(30) self.expandLayout.setContentsMargins(36, 0, 36, 0) @@ -176,8 +163,6 @@ def setEnabled(self, a0: bool) -> None: self.autoSelectChampionCard.switchButton.setEnabled(True) self.lockConfigCard.setEnabled(a0) - self.forceDisconnectionCard.setEnabled(a0) - self.autoReconnectCard.setEnabled(a0) return super().setEnabled(a0) From a0797b4a3baad502df0b95f8bf5c4acbb177d07e Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 21 Oct 2023 12:27:44 +0800 Subject: [PATCH 09/11] =?UTF-8?q?Revert=20"1.=20=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=9B=B4=E6=96=B0:=20=E8=87=AA=E5=8A=A8=E9=87=8D=E8=BF=9E"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 11f7f682 --- app/common/icons.py | 1 + app/view/auxiliary_interface.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/app/common/icons.py b/app/common/icons.py index 3d77845f..89c15c83 100644 --- a/app/common/icons.py +++ b/app/common/icons.py @@ -43,6 +43,7 @@ class Icon(FluentIconBase, Enum): SETTING = 'Setting' FILTER = 'Filter' UPDATE = 'Update' + CONNECTION = "Connection" def path(self, theme=Theme.AUTO): return f'./app/resource/icons/{self.value}_{getIconColor(theme)}.svg' diff --git a/app/view/auxiliary_interface.py b/app/view/auxiliary_interface.py index 13b4542f..a46a783b 100644 --- a/app/view/auxiliary_interface.py +++ b/app/view/auxiliary_interface.py @@ -71,6 +71,11 @@ def __init__(self, parent=None): "Accept match making automatically after the number of seconds you set"), cfg.enableAutoAcceptMatching, cfg.autoAcceptMatchingDelay, self.gameGroup) + self.autoReconnectCard = SwitchSettingCard( + Icon.CONNECTION, + self.tr("Auto reconnect"), + self.tr("Automatically reconnect when disconnected"), + cfg.enableAutoReconnect, self.gameGroup) self.spectateCard = SpectateCard( self.tr("Spectate"), self.tr("Spectate live game of summoner in the same environment"), @@ -115,6 +120,7 @@ def __initLayout(self): # 游戏 self.gameGroup.addSettingCard(self.autoAcceptMatchingCard) + self.gameGroup.addSettingCard(self.autoReconnectCard) self.gameGroup.addSettingCard(self.autoSelectChampionCard) # self.gameGroup.addSettingCard(self.copyPlayersInfoCard) self.gameGroup.addSettingCard(self.createPracticeLobbyCard) @@ -163,6 +169,7 @@ def setEnabled(self, a0: bool) -> None: self.autoSelectChampionCard.switchButton.setEnabled(True) self.lockConfigCard.setEnabled(a0) + self.autoReconnectCard.setEnabled(a0) return super().setEnabled(a0) From d7b3748fbc5d3e35fca139f2928f44af81ddebf9 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 21 Oct 2023 12:30:02 +0800 Subject: [PATCH 10/11] =?UTF-8?q?Revert=20"1.=20=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=9B=B4=E6=96=B0:=20=E5=9C=A8BP=E9=98=B6=E6=AE=B5=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E7=8E=A9=E5=AE=B6=E6=89=80=E5=A4=84=E9=98=9F=E4=BC=8D?= =?UTF-8?q?(=E7=BA=A2/=E8=93=9D)"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 8200c39823adf15270d3d3e683458e71ba0517b3. --- app/lol/connector.py | 6 ------ app/view/main_window.py | 7 ------- 2 files changed, 13 deletions(-) diff --git a/app/lol/connector.py b/app/lol/connector.py index 12eedb01..10397cbb 100644 --- a/app/lol/connector.py +++ b/app/lol/connector.py @@ -507,12 +507,6 @@ def getGameStatus(self): return res - @retry() - def getMapSide(self): - js = self.__get("/lol-champ-select/v1/pin-drop-notification").json() - - return js.get("mapSide", "") - @retry() def getReadyCheckStatus(self): res = self.__get("/lol-matchmaking/v1/ready-check").json() diff --git a/app/view/main_window.py b/app/view/main_window.py index 068a9de6..f04c75e6 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -812,13 +812,6 @@ def __onGameStatusChanged(self, status): self.__onGameEnd() elif status == 'ChampSelect': title = self.tr("Selecting Champions") - - # 在标题添加所处队伍 - mapSide = connector.getMapSide() - if mapSide: - mapSide = self.tr("Blue Team") if mapSide == "blue" else self.tr("Red Team") - title = title + " - " + mapSide - self.__onChampionSelectBegin() self.isChampSelected = True elif status == 'GameStart': From 9d404014a01ca08fe6000b0fc8ae393416772b42 Mon Sep 17 00:00:00 2001 From: Hpero4 Date: Sat, 21 Oct 2023 12:34:19 +0800 Subject: [PATCH 11/11] =?UTF-8?q?Revert=20"Revert=20"1.=20=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=9B=B4=E6=96=B0:=20=E5=9C=A8BP=E9=98=B6=E6=AE=B5?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E7=8E=A9=E5=AE=B6=E6=89=80=E5=A4=84=E9=98=9F?= =?UTF-8?q?=E4=BC=8D(=E7=BA=A2/=E8=93=9D)""?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit d7b3748fbc5d3e35fca139f2928f44af81ddebf9. --- app/lol/connector.py | 6 ++++++ app/view/main_window.py | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/app/lol/connector.py b/app/lol/connector.py index 10397cbb..12eedb01 100644 --- a/app/lol/connector.py +++ b/app/lol/connector.py @@ -507,6 +507,12 @@ def getGameStatus(self): return res + @retry() + def getMapSide(self): + js = self.__get("/lol-champ-select/v1/pin-drop-notification").json() + + return js.get("mapSide", "") + @retry() def getReadyCheckStatus(self): res = self.__get("/lol-matchmaking/v1/ready-check").json() diff --git a/app/view/main_window.py b/app/view/main_window.py index f04c75e6..068a9de6 100644 --- a/app/view/main_window.py +++ b/app/view/main_window.py @@ -812,6 +812,13 @@ def __onGameStatusChanged(self, status): self.__onGameEnd() elif status == 'ChampSelect': title = self.tr("Selecting Champions") + + # 在标题添加所处队伍 + mapSide = connector.getMapSide() + if mapSide: + mapSide = self.tr("Blue Team") if mapSide == "blue" else self.tr("Red Team") + title = title + " - " + mapSide + self.__onChampionSelectBegin() self.isChampSelected = True elif status == 'GameStart':