Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions aao/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import argparse
import os
import sys
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

if TYPE_CHECKING:
from maa.controller import Win32Controller
Expand Down Expand Up @@ -493,7 +493,7 @@ def _reset_measure_timer(self, node_name: str) -> None:
logger.debug("计时器重置(pipeline 节点: %s)", node_name)
self.worker.request_reset_timer()

def _on_measure_state(self, state: dict) -> None:
def _on_measure_state(self, state: dict[str, Any]) -> None:
from aao.core.timing.time_source import format_timer

total = state.get("totalElapsedFrames", 0)
Expand Down
6 changes: 3 additions & 3 deletions aao/core/avatar.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import json
import time
from pathlib import Path
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

import numpy as np

Expand Down Expand Up @@ -71,7 +71,7 @@ def _normalize_name(name: str) -> str:
def detect_slots(
context: Context,
image: np.ndarray,
) -> list[dict]:
) -> list[dict[str, Any]]:
"""用 pipeline 节点 DetectSlots 检测待部署区所有干员槽位。"""
reco_detail = context.run_recognition("DetectSlots", image)

Expand Down Expand Up @@ -217,7 +217,7 @@ def _ocr_oper_name(context: Context, detail_img: np.ndarray) -> str | None:

def _save_avatar_from_image(
image: np.ndarray,
slot: dict,
slot: dict[str, Any],
oper_name: str,
) -> bool:
"""从截图截取槽位头像并存盘。"""
Expand Down
3 changes: 2 additions & 1 deletion aao/core/geometry/map_loader.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import json
from pathlib import Path
from typing import Any

from aao.utils.logger import logger
from aao.utils.runtime_paths import project_root
Expand Down Expand Up @@ -52,7 +53,7 @@ def find_map_file(code: str) -> Path | None:
return None


def load_map(code: str) -> dict | None:
def load_map(code: str) -> dict[str, Any] | None:
"""加载关卡数据。code 如 '1-7'。"""
path = find_map_file(code)
if path is None:
Expand Down
3 changes: 2 additions & 1 deletion aao/core/geometry/view.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from __future__ import annotations

import math
from typing import Any

import numpy as np

Expand Down Expand Up @@ -69,7 +70,7 @@ def _build_matrix(view_offset: list[float], side: bool) -> np.ndarray:


def transform_map_to_view(
level_data: dict,
level_data: dict[str, Any],
side: bool = False,
) -> list[list[tuple[float, float]]]:
"""把关卡数据投影为屏幕坐标(0-1 比例)。
Expand Down
5 changes: 4 additions & 1 deletion aao/core/timing/battle_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

from dataclasses import dataclass
from enum import Enum
from typing import Any

import numpy as np

Expand Down Expand Up @@ -445,7 +446,9 @@ def detect_battle_state(frame: np.ndarray) -> BattleState:
}


def _diagnose_battle_begin_bands(frame: np.ndarray, width: int, height: int, scale: float) -> dict:
def _diagnose_battle_begin_bands(
frame: np.ndarray, width: int, height: int, scale: float
) -> dict[str, Any]:
"""诊断 7 band sampling 各 band 的值。"""
step = max(4, round(scale * BATTLE_BEGIN_SAMPLE_STEP_SCALE))
top_y_step = max(step, round(height * 0.10))
Expand Down
4 changes: 2 additions & 2 deletions aao/measure/api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class ApiServer:

def __init__(
self,
get_state: Callable[[], dict],
get_state: Callable[[], dict[str, Any]],
host: str = "localhost",
port: int = DEFAULT_PORT,
rate_hz: float = 60.0,
Expand All @@ -34,7 +34,7 @@ def __init__(
self.host = host
self.port = port
self.rate_hz = rate_hz
self._clients: set = set()
self._clients: set[Any] = set()
self._thread: threading.Thread | None = None

def start(self) -> None:
Expand Down
4 changes: 3 additions & 1 deletion aao/measure/overlay.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

from __future__ import annotations

from typing import Any

from PySide6.QtCore import QRectF, Qt, QTimer
from PySide6.QtGui import (
QColor,
Expand Down Expand Up @@ -131,7 +133,7 @@ def reset_layout(self, x: int, y: int) -> None:
self.move(x, y)
self._save_window_state()

def on_state(self, state: dict) -> None:
def on_state(self, state: dict[str, Any]) -> None:
running = state.get("isRunning", False)
cf = state.get("currentFrame")
total = state.get("totalFramesInCycle", 0)
Expand Down
6 changes: 3 additions & 3 deletions aao/measure/worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

import threading
import time
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

from PySide6.QtCore import QObject, Signal

Expand Down Expand Up @@ -47,11 +47,11 @@ def __init__(
self._running = False
self._reset_requested = False
self._consecutive_errors = 0
self._latest: dict = {}
self._latest: dict[str, Any] = {}
self._lock = threading.Lock()

@property
def latest_state(self) -> dict:
def latest_state(self) -> dict[str, Any]:
with self._lock:
return dict(self._latest)

Expand Down
7 changes: 4 additions & 3 deletions aao/resources/updater.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
from collections.abc import Callable
from dataclasses import dataclass
from pathlib import Path
from typing import Any

from aao import __version__
from aao.resources import syncer
Expand Down Expand Up @@ -209,13 +210,13 @@ def update_resources(
progress_cb(r.message)
return results

def update_all(self, progress_cb: Callable[[str], None] | None = None) -> dict:
def update_all(self, progress_cb: Callable[[str], None] | None = None) -> dict[str, Any]:
"""检查软件更新 + 更新资源。

Returns:
{"software": ReleaseInfo | None, "resources": [SyncResult]}
"""
result: dict = {}
result: dict[str, Any] = {}

if progress_cb:
progress_cb("检查软件更新...")
Expand Down Expand Up @@ -417,7 +418,7 @@ def apply_update(self, zip_path: Path) -> None:
_DOWNLOAD_BACKOFF_SEC = 1.0


def _pick_win_asset(assets: list) -> AssetInfo | None:
def _pick_win_asset(assets: list[dict[str, Any]]) -> AssetInfo | None:
"""从 release assets 里选 win-x64 zip。"""
for a in assets:
name = str(a.get("name", "")).lower()
Expand Down
4 changes: 2 additions & 2 deletions aao/ui/farm_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import json
import threading
import time
from typing import TYPE_CHECKING
from typing import TYPE_CHECKING, Any

from PySide6.QtCore import QObject, Signal

Expand Down Expand Up @@ -114,7 +114,7 @@ def _on_node(node_name: str) -> None:
tl_param = json.dumps({"timeline_path": self._timeline_path}, ensure_ascii=False)
pipeline["Farm@ClickStage"]["custom_recognition_param"] = tl_param

exec_param: dict = {"timeline_path": self._timeline_path}
exec_param: dict[str, Any] = {"timeline_path": self._timeline_path}
if self._profile:
exec_param["calibration"] = self._profile
pipeline["Farm@Execute"]["custom_action_param"] = json.dumps(exec_param, ensure_ascii=False)
Expand Down
4 changes: 3 additions & 1 deletion aao/ui/map_picker.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

from __future__ import annotations

from typing import Any

from PySide6.QtCore import Signal
from PySide6.QtGui import QBrush, QColor, QFont, QMouseEvent, QPainter, QPen
from PySide6.QtWidgets import (
Expand Down Expand Up @@ -43,7 +45,7 @@ class _MapGrid(QGraphicsView):

picked = Signal(str) # 棋盘记号,如 "D2"

def __init__(self, map_data: dict):
def __init__(self, map_data: dict[str, Any]):
super().__init__()
self._map_data = map_data
self._height = map_data["height"]
Expand Down
6 changes: 3 additions & 3 deletions aao/ui/settings_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def _settings_path():
return project_root() / "config" / "settings.json"


def load_settings() -> dict:
def load_settings() -> dict[str, Any]:
p = _settings_path()
if not p.exists():
return {}
Expand All @@ -57,7 +57,7 @@ def load_settings() -> dict:
return {}


def save_settings(data: dict) -> None:
def save_settings(data: dict[str, Any]) -> None:
p = _settings_path()
p.parent.mkdir(parents=True, exist_ok=True)
p.write_text(json.dumps(data, indent=2, ensure_ascii=False), encoding="utf-8")
Expand Down Expand Up @@ -387,7 +387,7 @@ def _build_ui(self) -> None:
self.btn_token_eye.clicked.connect(self._toggle_token_visible)
self.btn_export_log.clicked.connect(self._on_export_log)

self._windows: list = [] # DesktopWindow 列表(与 list_windows 行对应)
self._windows: list[Any] = [] # DesktopWindow 列表(与 list_windows 行对应)
self._preview_thread: QThread | None = None
self._preview_worker: _PreviewWorker | None = None

Expand Down
9 changes: 6 additions & 3 deletions custom/action/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import time
from collections.abc import Callable
from dataclasses import dataclass
from typing import Any

import numpy as np
from maa.context import Context
Expand Down Expand Up @@ -87,7 +88,7 @@ def run(self, context: Context, argv: CustomAction.RunArg) -> CustomAction.RunRe
logger.exception("ExecuteTimeline 异常")
return CustomAction.RunResult(success=False)

def _execute(self, context: Context, params: dict) -> CustomAction.RunResult:
def _execute(self, context: Context, params: dict[str, Any]) -> CustomAction.RunResult:
ctrl = context.tasker.controller

# 优先 timeline_path(从文件加载,文件内含 map_code),兼容显式 timeline 数组
Expand Down Expand Up @@ -222,7 +223,7 @@ def _execute(self, context: Context, params: dict) -> CustomAction.RunResult:
# 漏怪 = 本局失败(farm pipeline 会走放弃重试)
return CustomAction.RunResult(success=not self._leaked and not self._abort_reason)

def _load_timeline_file(self, path: str) -> dict | None:
def _load_timeline_file(self, path: str) -> dict[str, Any] | None:
"""加载时间轴 JSON(纯文件名→config/timelines/,带路径→相对项目根)。"""
from custom.reco.click_stage import resolve_timeline_path

Expand All @@ -239,7 +240,9 @@ def _load_timeline_file(self, path: str) -> dict | None:
logger.info("加载时间轴 %s(map_code=%s, %d 动作)", p, data.get("map_code"), n)
return data

def _parse_actions(self, raw: list[dict], map_data: dict) -> list[Action]:
def _parse_actions(
self, raw: list[dict[str, Any]], map_data: dict[str, Any]
) -> list[Action]:
"""解析 JSON 动作列表 → Action 对象(含投影坐标 + 目标帧)。"""
h, w = map_data["height"], map_data["width"]
front = transform_map_to_view(map_data, side=False)
Expand Down
3 changes: 2 additions & 1 deletion custom/reco/click_stage.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import json
import time
from pathlib import Path
from typing import Any

from maa.context import Context
from maa.custom_recognition import CustomRecognition
Expand Down Expand Up @@ -65,7 +66,7 @@ def resolve_timeline_path(timeline_path: str) -> Path:
return _TIMELINE_DIR / timeline_path


def _load_timeline_data(timeline_path: str | None) -> dict | None:
def _load_timeline_data(timeline_path: str | None) -> dict[str, Any] | None:
"""加载 timeline JSON。"""
if not timeline_path:
logger.error("timeline_path 为空")
Expand Down
9 changes: 4 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,16 @@ extraPaths = ["custom", "aao", "tests", "tests/replay"]
pythonVersion = "3.13"
typeCheckingMode = "strict"

# strict 下关闭因 maafw 第三方库存根缺失导致的类型未知噪音
# (reportMissingTypeStubs / reportUnknown* / reportMissingTypeArgument),
# 保留 strict 的其余实质检查(privateUsage / unnecessaryComparison / unusedFunction 等)。
# MaaFramework 的 Python 包名是 MaaFw,导入名是 `maa`;当前不发布 PEP 561 类型信息。
reportMissingTypeStubs = "none"

# 项目大量动态边界来自 MaaFramework 回调、Qt Signal 和 JSON 配置。
# 保留 strict 的实质检查,但不为了消除 Unknown 传播而强行包一层项目内类型。
reportUnknownMemberType = "none"
reportUnknownArgumentType = "none"
reportUnknownVariableType = "none"
reportUnknownParameterType = "none"
reportUnknownLambdaType = "none"
reportMissingTypeArgument = "none"

# tests: 访问 protected 成员 + 解构未使用变量是测试常见模式
[[tool.pyright.executionEnvironments]]
Expand All @@ -67,4 +67,3 @@ reportUnusedVariable = "none"
[tool.pytest.ini_options]
testpaths = ["tests"]
pythonpath = ["."]