diff --git a/app/lol/connector.py b/app/lol/connector.py index 5eb7f39..c0cd23c 100644 --- a/app/lol/connector.py +++ b/app/lol/connector.py @@ -1,17 +1,16 @@ +import asyncio import inspect -import os import json -import threading +import os import re +import threading +import time from asyncio import CancelledError from collections import deque -import requests -import time - -import asyncio import aiohttp -from PyQt5.QtCore import pyqtSignal, QObject +import requests +from PyQt5.QtCore import QObject from app.common.config import cfg, Language from app.common.logger import logger @@ -69,7 +68,7 @@ async def wrapper(*args, **kwargs): # 构建参数字典,将参数名与对应的实参值一一对应 params_dict = {param: arg for param, - arg in zip(param_names, tmp_args)} + arg in zip(param_names, tmp_args)} logger.debug(f"args = {params_dict}|kwargs = {kwargs}", TAG) # logger.debug(f"args = {args[1:]}|kwargs = {kwargs}", TAG) @@ -965,6 +964,31 @@ async def spectate(self, summonerName): return res + async def spectateDirectly(self, summonerName): + """ + 用命令行唤起客户端,无需等待 + """ + info = await self.getSummonerByName(summonerName) + puuid = info.get('puuid') + + if not puuid: + raise SummonerNotFound() + + info = await self.getSummonerGamingInfoByPuuidViaSgp(puuid) + + credentials = info.get('playerCredentials') + if credentials is None: + raise SummonerNotInGame() + + credentials = info['playerCredentials'] + params = (f"spectator {credentials['observerServerIp']}" + f":{credentials['observerServerPort']}" + f" {credentials['observerEncryptionKey']}" + f" {credentials['gameId']}" + f" {self.server}") + + return params + async def dodge(self): data = { "destination": 'lcdsServiceProxy', @@ -1074,6 +1098,14 @@ async def getSummonerGamesByPuuidViaSGP(self, puuid, begIdx, endIdx): res = await self.__sgp__get(url, params) return await res.json() + async def getSummonerGamingInfoByPuuidViaSgp(self, puuid): + logger.debug( + f"getSummonerGamingInfoByPuuidViaSgp called, {puuid = }", TAG) + + url = f"/gsm/v1/ledge/spectator/region/{self.server.lower()}/puuid/{puuid}" + res = await self.__sgp__get(url) + return await res.json() + async def getRankedStatsByPuuidViaSGP(self, puuid): logger.debug( f"getRankedStatsByPuuidViaSGP called, {puuid = }", TAG) diff --git a/app/view/auxiliary_interface.py b/app/view/auxiliary_interface.py index 7389dfe..520df2c 100644 --- a/app/view/auxiliary_interface.py +++ b/app/view/auxiliary_interface.py @@ -1,31 +1,30 @@ -import threading import os import stat - - -from app.common.qfluentwidgets import (SettingCardGroup, SwitchSettingCard, ExpandLayout, - SmoothScrollArea, SettingCard, LineEdit, PushButton, - setCustomStyleSheet, ComboBox, SwitchButton, ConfigItem, - qconfig, IndicatorPosition, InfoBar, InfoBarPosition, - SpinBox, ExpandGroupSettingCard, TransparentToolButton, - FluentIcon, Flyout, FlyoutAnimationType, TeachingTip, - MessageBox, CheckBox, ToolTipFilter, ToolTipPosition) +import subprocess +import threading from PyQt5.QtCore import Qt, pyqtSignal, QEvent, QSize from PyQt5.QtWidgets import (QWidget, QLabel, QVBoxLayout, QHBoxLayout, QGridLayout, QFrame, QSpacerItem, QSizePolicy) from qasync import asyncSlot -from app.components.seraphine_interface import SeraphineInterface -from app.components.message_box import MultiChampionSelectMsgBox, SplashesMessageBox -from app.components.champion_icon_widget import RoundIcon -from app.components.multi_champion_select import ChampionSelectFlyout -from app.lol.tools import fixLCUWindowViaExe -from app.common.icons import Icon from app.common.config import cfg +from app.common.icons import Icon +from app.common.qfluentwidgets import (SettingCardGroup, SwitchSettingCard, ExpandLayout, + SettingCard, LineEdit, PushButton, + setCustomStyleSheet, ComboBox, SwitchButton, ConfigItem, + qconfig, IndicatorPosition, InfoBar, InfoBarPosition, + SpinBox, ExpandGroupSettingCard, TransparentToolButton, + FluentIcon, Flyout, FlyoutAnimationType, MessageBox, ToolTipFilter, + ToolTipPosition) from app.common.style_sheet import StyleSheet +from app.components.champion_icon_widget import RoundIcon +from app.components.message_box import MultiChampionSelectMsgBox, SplashesMessageBox +from app.components.multi_champion_select import ChampionSelectFlyout +from app.components.seraphine_interface import SeraphineInterface from app.lol.connector import connector from app.lol.exceptions import * +from app.lol.tools import fixLCUWindowViaExe class AuxiliaryInterface(SeraphineInterface): @@ -312,7 +311,6 @@ def __initWidget(self): self.pushButton.setEnabled(False) self.pushButton.clicked.connect(self.__onApplyButtonClicked) - def __onSelectButtonClicked(self): view = ChampionSelectFlyout(self.champions) self.w = Flyout.make(view, self.championButton, @@ -320,7 +318,6 @@ def __onSelectButtonClicked(self): view.championSelected.connect(self.__onChampionSelected) - def __onSkinButtonClicked(self): w = SplashesMessageBox(self.skins, self.window()) if w.exec(): @@ -382,8 +379,8 @@ async def __onApplyButtonClicked(self): msg.exec_() InfoBar.success(title=self.tr("Apply"), content=self.tr("Successfully"), orient=Qt.Vertical, isClosable=True, - position=InfoBarPosition.TOP_RIGHT, duration=5000, - parent=self.window().auxiliaryFuncInterface) + position=InfoBarPosition.TOP_RIGHT, duration=5000, + parent=self.window().auxiliaryFuncInterface) @asyncSlot() async def __onMsgBoxYesButtonClicked(self): @@ -541,10 +538,10 @@ def __onTierTextChanged(self): currentDivision = self.divisionBox.currentText() self.divisionBox.clear() if currentTier in [ - self.tr("Na"), - self.tr('Master'), - self.tr('Grandmaster'), - self.tr('Challenger') + self.tr("Na"), + self.tr('Master'), + self.tr('Grandmaster'), + self.tr('Challenger') ]: self.divisionBox.addItems(['--']) self.divisionBox.setCurrentText('--') @@ -887,7 +884,11 @@ def info(type, title, content): text = self.lineEdit.text() text = text.replace('\u2066', '').replace('\u2069', '') - await connector.spectate(text) + res = await connector.spectateDirectly(text) + pwd = os.getcwd() + os.chdir(f"{cfg.get(cfg.lolFolder)[0]}/../Game") + subprocess.Popen(['League of Legends.exe', f'{res}']) + os.chdir(pwd) except SummonerNotFound: info('error', self.tr("Summoner not found"), @@ -896,7 +897,7 @@ def info(type, title, content): info('error', self.tr("Summoner isn't in game"), "") else: info('success', self.tr("Spectate successfully"), - self.tr("Please wait"),) + self.tr("Please wait"), ) class AutoAcceptMatchingCard(ExpandGroupSettingCard): @@ -1068,7 +1069,7 @@ def __init__(self, title, content, parent): class LockConfigCard(SettingCard): - def __init__(self, title, content, parent): + def __init__(self, title, content, parent): super().__init__(Icon.LOCK, title, content, parent) self.switchButton = SwitchButton(indicatorPos=IndicatorPosition.RIGHT) @@ -1343,9 +1344,9 @@ def __initLayout(self): champions = getattr(self, f"{ty}Champions") button = getattr(self, f"{ty}SelectButton") - self.rankCfgLayout.addWidget(label, i+1, 0, Qt.AlignLeft) - self.rankCfgLayout.addWidget(champions, i+1, 1, Qt.AlignHCenter) - self.rankCfgLayout.addWidget(button, i+1, 2, Qt.AlignRight) + self.rankCfgLayout.addWidget(label, i + 1, 0, Qt.AlignLeft) + self.rankCfgLayout.addWidget(champions, i + 1, 1, Qt.AlignHCenter) + self.rankCfgLayout.addWidget(button, i + 1, 2, Qt.AlignRight) self.buttonsLayout.setVerticalSpacing(19) self.buttonsLayout.setContentsMargins(48, 18, 44, 18) @@ -1617,9 +1618,9 @@ def __initLayout(self): champions = getattr(self, f"{ty}Champions") button = getattr(self, f"{ty}SelectButton") - self.rankCfgLayout.addWidget(label, i+1, 0, Qt.AlignLeft) - self.rankCfgLayout.addWidget(champions, i+1, 1, Qt.AlignHCenter) - self.rankCfgLayout.addWidget(button, i+1, 2, Qt.AlignRight) + self.rankCfgLayout.addWidget(label, i + 1, 0, Qt.AlignLeft) + self.rankCfgLayout.addWidget(champions, i + 1, 1, Qt.AlignHCenter) + self.rankCfgLayout.addWidget(button, i + 1, 2, Qt.AlignRight) self.buttonsCfgLayout.setVerticalSpacing(19) self.buttonsCfgLayout.setContentsMargins(48, 18, 44, 18) @@ -1676,7 +1677,7 @@ async def initChampionList(self, champions: dict = None): continue champions.updateChampions( - [self.champions[id][1]for id in selected]) + [self.champions[id][1] for id in selected]) return self.champions