mirror of
https://github.com/moesnow/March7thAssistant.git
synced 2026-08-02 18:24:16 +08:00
parent
11a29f556a
commit
6d6a30e1d2
@ -895,6 +895,13 @@ class SettingInterface(ScrollArea):
|
||||
tr("最大排队等待时间(分钟)"),
|
||||
''
|
||||
)
|
||||
self.cloudGameLoginTimeoutCard = RangeSettingCard1(
|
||||
"cloud_game_login_timeout",
|
||||
[1, 120],
|
||||
FIF.DATE_TIME,
|
||||
tr("登录超时时间(分钟)"),
|
||||
tr("等待用户完成登录的最长时间,超时后将终止运行")
|
||||
)
|
||||
# self.cloudGameVideoQualityCard = ComboBoxSettingCard2(
|
||||
# "cloud_game_video_quality",
|
||||
# FIF.VIDEO,
|
||||
@ -2616,6 +2623,7 @@ class SettingInterface(ScrollArea):
|
||||
self.CloudGameGroup.addSettingCard(self.browserHeadlessCard)
|
||||
self.browserHeadlessCard.addSettingCards([self.browserHeadlessRestartCard])
|
||||
self.CloudGameGroup.addSettingCard(self.cloudGameMaxQueueTimeCard)
|
||||
self.CloudGameGroup.addSettingCard(self.cloudGameLoginTimeoutCard)
|
||||
# self.CloudGameGroup.addSettingCard(self.cloudGameVideoQualityCard)
|
||||
# self.CloudGameGroup.addSettingCard(self.cloudGameSmoothFirstCard)
|
||||
# self.CloudGameGroup.addSettingCard(self.cloudGameShowStatusCard)
|
||||
|
||||
@ -54,6 +54,7 @@ cloud_game_enable: False # 是否启动云游戏
|
||||
cloud_game_fullscreen_enable: True # 云崩铁是否全屏运行
|
||||
cloud_game_use_paid_time: False # 是否使用付费时长
|
||||
cloud_game_max_queue_time: 60 # 最大排队等待时间(分钟)
|
||||
cloud_game_login_timeout: 20 # 等待登录的超时时间(分钟),超时后终止运行
|
||||
# cloud_game_video_quality: '0' # 云崩铁画质 '0'(超高清),'1'(高清), '2'(标清), '3'(低清)
|
||||
# cloud_game_smooth_first_enable: False # 是否流畅优先
|
||||
# cloud_game_status_bar_enable: False # 是否显示网速
|
||||
|
||||
@ -175,6 +175,8 @@
|
||||
"打开后可在使用云游戏时使用付费时长免除排队": "Enable to use paid time for cloud gaming to skip queue",
|
||||
"当前账号付费时间不足,已切换为免费时间。": "Insufficient paid time on current account, switched to free time.",
|
||||
"最大排队等待时间(分钟)": "Max Queue Wait Time (Minutes)",
|
||||
"登录超时时间(分钟)": "Login Timeout (Minutes)",
|
||||
"等待用户完成登录的最长时间,超时后将终止运行": "Maximum time to wait for login. The run will stop after timeout.",
|
||||
"浏览器类型": "Browser Type",
|
||||
"建议保持默认的“集成(Chrome For Testing)”效果最好": "Recommended to keep default 'Integrated (Chrome For Testing)'",
|
||||
"集成(Chrome For Testing)": "Integrated (Chrome For Testing)",
|
||||
@ -1483,4 +1485,4 @@
|
||||
"界面可切换性测试": "Screen Switchability Test",
|
||||
"测试": "Test",
|
||||
"以最短路径遍历所有可达界面,验证界面切换是否正常": "Traverse all reachable screens via the shortest path to verify screen switching works correctly"
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,6 +175,8 @@
|
||||
"打开后可在使用云游戏时使用付费时长免除排队": "有効にすると、クラウドゲーム使用時に有料時間を使って待機時間を免除できます。",
|
||||
"当前账号付费时间不足,已切换为免费时间。": "現在のアカウントの有料時間が不足しているため、無料時間に切り替えました。",
|
||||
"最大排队等待时间(分钟)": "最大待機時間(分)",
|
||||
"登录超时时间(分钟)": "ログインタイムアウト(分)",
|
||||
"等待用户完成登录的最长时间,超时后将终止运行": "ユーザーのログイン完了を待つ最大時間です。タイムアウト後は実行を終了します。",
|
||||
"浏览器类型": "ブラウザー種類",
|
||||
"建议保持默认的“集成(Chrome For Testing)”效果最好": "通常はデフォルトの「統合(Chrome For Testing)」推奨です。",
|
||||
"集成(Chrome For Testing)": "統合(Chrome For Testing)",
|
||||
@ -1483,4 +1485,4 @@
|
||||
"界面可切换性测试": "画面切替テスト",
|
||||
"测试": "テスト",
|
||||
"以最短路径遍历所有可达界面,验证界面切换是否正常": "最短経路で到達可能なすべての画面を巡回し、画面切替が正常に動作するか検証します"
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,6 +175,8 @@
|
||||
"打开后可在使用云游戏时使用付费时长免除排队": "켜면 클라우드 게임 사용 시 유료 시간을 사용하여 대기열을 건너뛸 수 있습니다",
|
||||
"当前账号付费时间不足,已切换为免费时间。": "현재 계정의 유료 시간이 부족하여 무료 시간으로 전환되었습니다。",
|
||||
"最大排队等待时间(分钟)": "최대 대기열 대기 시간 (분)",
|
||||
"登录超时时间(分钟)": "로그인 타임아웃 (분)",
|
||||
"等待用户完成登录的最长时间,超时后将终止运行": "사용자가 로그인을 완료할 때까지 기다리는 최대 시간입니다. 타임아웃 후 실행을 종료합니다.",
|
||||
"浏览器类型": "브라우저 유형",
|
||||
"建议保持默认的“集成(Chrome For Testing)”效果最好": "기본값 '통합 (Chrome For Testing)' 사용 권장",
|
||||
"集成(Chrome For Testing)": "통합 (Chrome For Testing)",
|
||||
|
||||
@ -175,6 +175,8 @@
|
||||
"打开后可在使用云游戏时使用付费时长免除排队": "打开后可在使用云游戏时使用付费时长免除排队",
|
||||
"当前账号付费时间不足,已切换为免费时间。": "当前账号付费时间不足,已切换为免费时间。",
|
||||
"最大排队等待时间(分钟)": "最大排队等待时间(分钟)",
|
||||
"登录超时时间(分钟)": "登录超时时间(分钟)",
|
||||
"等待用户完成登录的最长时间,超时后将终止运行": "等待用户完成登录的最长时间,超时后将终止运行",
|
||||
"浏览器类型": "浏览器类型",
|
||||
"建议保持默认的“集成(Chrome For Testing)”效果最好": "建议保持默认的“集成(Chrome For Testing)”效果最好",
|
||||
"集成(Chrome For Testing)": "集成(Chrome For Testing)",
|
||||
@ -1483,4 +1485,4 @@
|
||||
"界面可切换性测试": "界面可切换性测试",
|
||||
"测试": "测试",
|
||||
"以最短路径遍历所有可达界面,验证界面切换是否正常": "以最短路径遍历所有可达界面,验证界面切换是否正常"
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,6 +175,8 @@
|
||||
"打开后可在使用云游戏时使用付费时长免除排队": "打開後可在使用雲遊戲時使用付費時長免除排隊",
|
||||
"当前账号付费时间不足,已切换为免费时间。": "當前帳號付費時間不足,已切換為免費時間。",
|
||||
"最大排队等待时间(分钟)": "最大排隊等待時間(分鐘)",
|
||||
"登录超时时间(分钟)": "登入逾時時間(分鐘)",
|
||||
"等待用户完成登录的最长时间,超时后将终止运行": "等待使用者完成登入的最長時間,逾時後將終止執行",
|
||||
"浏览器类型": "瀏覽器類型",
|
||||
"建议保持默认的“集成(Chrome For Testing)”效果最好": "建議保持預設的「整合(Chrome For Testing)」效果最好",
|
||||
"集成(Chrome For Testing)": "整合(Chrome For Testing)",
|
||||
@ -1483,4 +1485,4 @@
|
||||
"界面可切换性测试": "界面可切換性測試",
|
||||
"测试": "測試",
|
||||
"以最短路径遍历所有可达界面,验证界面切换是否正常": "以最短路徑遍歷所有可達界面,驗證界面切換是否正常"
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +32,10 @@ from module.logger import Logger
|
||||
from utils.console import is_docker_started
|
||||
|
||||
|
||||
class CloudGameLoginTimeoutError(RuntimeError):
|
||||
"""云游戏登录等待超时,不应按启动失败重试。"""
|
||||
|
||||
|
||||
class CloudGameController(GameControllerBase):
|
||||
COOKIE_PATH = "settings/cookies.enc" # Cookies 保存地址(仅用于调试)
|
||||
GAME_URL = "https://sr.mihoyo.com/cloud" # 游戏地址
|
||||
@ -489,6 +493,24 @@ class CloudGameController(GameControllerBase):
|
||||
self.log_warning("检测登录状态超时:未出现登录或未登录标志元素")
|
||||
return None
|
||||
|
||||
def _get_login_timeout_seconds(self) -> int:
|
||||
try:
|
||||
timeout_minutes = int(self.cfg.get_value("cloud_game_login_timeout", 10))
|
||||
except (TypeError, ValueError):
|
||||
timeout_minutes = 10
|
||||
return max(1, timeout_minutes) * 60
|
||||
|
||||
def _abort_login_timeout(self, timeout_seconds: int) -> None:
|
||||
timeout_minutes = timeout_seconds // 60
|
||||
message = f"等待云游戏登录超时({timeout_minutes} 分钟),停止运行"
|
||||
self.log_error(message)
|
||||
self.stop_game()
|
||||
raise CloudGameLoginTimeoutError(message)
|
||||
|
||||
def _check_login_timeout(self, deadline: float, timeout_seconds: int) -> None:
|
||||
if time.monotonic() >= deadline:
|
||||
self._abort_login_timeout(timeout_seconds)
|
||||
|
||||
def _click_enter_game(self, timeout=5) -> None:
|
||||
"""
|
||||
点击‘进入游戏’按钮。
|
||||
@ -979,10 +1001,13 @@ class CloudGameController(GameControllerBase):
|
||||
except Exception as e:
|
||||
self.log_warning(f"解析二维码内容失败: {e}")
|
||||
|
||||
def _wait_scan_success_with_refresh(self, qr_filename: str) -> None:
|
||||
def _wait_scan_success_with_refresh(self, qr_filename: str, login_deadline: float = None, timeout_seconds: int = None) -> None:
|
||||
import os
|
||||
check_interval = 2
|
||||
while True:
|
||||
if login_deadline is not None and timeout_seconds is not None:
|
||||
self._check_login_timeout(login_deadline, timeout_seconds)
|
||||
|
||||
# 成功
|
||||
if self.driver.find_elements(By.XPATH, "//*[contains(text(), '扫码成功')]"):
|
||||
try:
|
||||
@ -1025,7 +1050,7 @@ class CloudGameController(GameControllerBase):
|
||||
|
||||
time.sleep(check_interval)
|
||||
|
||||
def _run_qr_login_flow(self) -> None:
|
||||
def _run_qr_login_flow(self, login_deadline: float = None, timeout_seconds: int = None) -> None:
|
||||
self.log_info("正在切换到二维码登录...")
|
||||
|
||||
# 每次进入二维码登录流程时重置通知限流状态
|
||||
@ -1047,7 +1072,7 @@ class CloudGameController(GameControllerBase):
|
||||
self._decode_qr_from_element(qr_img, qr_filename)
|
||||
self.log_info("=" * 60)
|
||||
self.log_info("等待扫码(二维码过期将自动刷新)...")
|
||||
self._wait_scan_success_with_refresh(qr_filename)
|
||||
self._wait_scan_success_with_refresh(qr_filename, login_deadline, timeout_seconds)
|
||||
except TimeoutException:
|
||||
self.log_warning("等待二维码加载超时")
|
||||
except Exception as e:
|
||||
@ -1086,6 +1111,8 @@ class CloudGameController(GameControllerBase):
|
||||
try:
|
||||
# 检测登录状态
|
||||
while not self._check_login():
|
||||
login_timeout_seconds = self._get_login_timeout_seconds()
|
||||
login_deadline = time.monotonic() + login_timeout_seconds
|
||||
self.log_info("未登录")
|
||||
|
||||
# 如果是 headless 且配置了自动重启,则以非 headless 模式重启启动让用户登录
|
||||
@ -1095,12 +1122,15 @@ class CloudGameController(GameControllerBase):
|
||||
|
||||
# 如果是 headless 且配置了不重启,则尝试二维码登录
|
||||
if self.cfg.browser_headless_enable and (not self.cfg.browser_headless_restart_on_not_logged_in):
|
||||
self._run_qr_login_flow()
|
||||
self._run_qr_login_flow(login_deadline, login_timeout_seconds)
|
||||
|
||||
self.log_info("请在浏览器中完成登录操作")
|
||||
self.log_info(f"请在浏览器中完成登录操作,超时时间:{login_timeout_seconds // 60} 分钟")
|
||||
|
||||
# 循环检测用户是否登录
|
||||
while not self._check_login():
|
||||
while True:
|
||||
self._check_login_timeout(login_deadline, login_timeout_seconds)
|
||||
if self._check_login():
|
||||
break
|
||||
time.sleep(2)
|
||||
|
||||
self.log_info("检测到登录成功")
|
||||
@ -1146,6 +1176,8 @@ class CloudGameController(GameControllerBase):
|
||||
self._confirm_viewport_resolution() # 将浏览器内部分辨率设置为 1920x1080
|
||||
self.log_info("进入云游戏成功")
|
||||
return True
|
||||
except CloudGameLoginTimeoutError:
|
||||
raise
|
||||
except Exception as e:
|
||||
self.try_dump_page()
|
||||
self.log_error(f"进入云游戏失败: {e}")
|
||||
|
||||
@ -12,6 +12,7 @@ from utils.date import Date
|
||||
from utils.console import pause_on_success
|
||||
from tasks.power.power import Power
|
||||
from module.game import cloud_game, get_game_controller
|
||||
from module.game.cloud import CloudGameLoginTimeoutError
|
||||
from module.logger import log
|
||||
from module.screen import screen
|
||||
from module.automation import auto
|
||||
@ -207,6 +208,8 @@ def start_game():
|
||||
starrail.stop_game()
|
||||
continue
|
||||
break
|
||||
except CloudGameLoginTimeoutError:
|
||||
raise
|
||||
except Exception as e:
|
||||
log.error(f"尝试启动游戏时发生错误:{e}")
|
||||
# 确保在重试前停止游戏
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user