diff --git a/agent/go-service/autofight/autofight.go b/agent/go-service/autofight/autofight.go
index d803c0a70a..6c199781a7 100644
--- a/agent/go-service/autofight/autofight.go
+++ b/agent/go-service/autofight/autofight.go
@@ -50,6 +50,71 @@ func getCharactorLevelShow(ctx *maa.Context, img image.Image) bool {
return detail.Hit
}
+func screencapImage(ctx *maa.Context) (image.Image, bool) {
+ ctx.GetTasker().GetController().PostScreencap().Wait()
+ img, err := ctx.GetTasker().GetController().CacheImage()
+ if err != nil {
+ log.Error().Err(err).Str("component", "AutoFight").Msg("failed to cache image")
+ return nil, false
+ }
+ return img, true
+}
+
+// 竞技大会活动,触摸光球时游戏判断开始战斗,接着321倒计时,之后出现怪物。在321倒计时时按下锁定怪物按键会导致普攻松开,因此等待倒计时结束。
+func waitProtocolSpaceRestartIfNeeded(ctx *maa.Context) {
+ img, ok := screencapImage(ctx)
+ if !ok {
+ return
+ }
+
+ gate, err := ctx.RunRecognition("__AutoFightRecognitionProtocolSpaceMechanicsGate", img)
+ if err != nil || gate == nil {
+ log.Error().
+ Err(err).
+ Str("component", "AutoFight").
+ Str("step", "protocolSpaceMechanicsGate").
+ Str("recognition", "__AutoFightRecognitionProtocolSpaceMechanicsGate").
+ Msg("failed to run protocol space mechanics gate recognition")
+ return
+ }
+ if !gate.Hit {
+ return
+ }
+
+ log.Info().Str("component", "AutoFight").Msg("protocol space mechanics gate hit, waiting for SpaceResart")
+ maafocus.Print(ctx, i18n.T("autofight.wait_battle_start"))
+ deadline := time.Now().Add(5 * time.Second)
+ for {
+ restart, err := ctx.RunRecognition("__AutoFightRecognitionProtocolSpaceRestart", img)
+ if err != nil || restart == nil {
+ log.Error().
+ Err(err).
+ Str("component", "AutoFight").
+ Str("step", "protocolSpaceRestart").
+ Str("recognition", "__AutoFightRecognitionProtocolSpaceRestart").
+ Msg("failed to run protocol space restart recognition")
+ return
+ }
+ if restart.Hit {
+ log.Info().Str("component", "AutoFight").Msg("protocol space SpaceResart found, continue fight")
+ maafocus.Print(ctx, i18n.T("autofight.wait_battle_start_found"))
+ return
+ }
+
+ if time.Now().After(deadline) {
+ log.Warn().Str("component", "AutoFight").Msg("protocol space SpaceResart timeout, continue fight")
+ maafocus.Print(ctx, i18n.T("autofight.wait_battle_start_timeout"))
+ return
+ }
+
+ time.Sleep(1 * time.Second)
+ img, ok = screencapImage(ctx)
+ if !ok {
+ return
+ }
+ }
+}
+
// captureDurationTracker 统计截图识别的平均耗时:每 reportWindow 计算一次窗口内平均值并重置,
// 若平均耗时超过 alertThreshold,则通过 maafocus 提醒用户降低显卡资源占用。
type captureDurationTracker struct {
@@ -282,6 +347,8 @@ func (a *AutoFightMainAction) Run(ctx *maa.Context, arg *maa.CustomActionArg) bo
}
log.Debug().Str("component", "AutoFight").Interface("params", params).Msg("parsed action attach parameters")
+ waitProtocolSpaceRestartIfNeeded(ctx)
+
var pauseStart time.Time
var lastLevelShowCheck time.Time
var noLockStart time.Time
diff --git a/agent/go-service/taskersink/taskfail/sink.go b/agent/go-service/taskersink/taskfail/sink.go
index a3d1c222f1..afed42d982 100644
--- a/agent/go-service/taskersink/taskfail/sink.go
+++ b/agent/go-service/taskersink/taskfail/sink.go
@@ -3,6 +3,7 @@ package taskfail
import (
"github.com/MaaXYZ/MaaEnd/agent/go-service/pkg/i18n"
"github.com/MaaXYZ/MaaEnd/agent/go-service/pkg/maafocus"
+ "github.com/MaaXYZ/MaaEnd/agent/go-service/pkg/pienv"
maa "github.com/MaaXYZ/maa-framework-go/v4"
"github.com/rs/zerolog/log"
)
@@ -54,6 +55,15 @@ func (s *Sink) OnTaskerTask(_ *maa.Tasker, event maa.EventStatus, detail maa.Tas
return
}
+ if pienv.ControllerName() != "Win32-Front" {
+ log.Debug().
+ Uint64("task_id", detail.TaskID).
+ Str("entry", detail.Entry).
+ Str("controller", pienv.ControllerName()).
+ Msg("Task failed but controller is not Win32-Front, skip feedback hint")
+ return
+ }
+
log.Info().
Uint64("task_id", detail.TaskID).
Str("entry", detail.Entry).
diff --git a/assets/locales/go-service/en_us.json b/assets/locales/go-service/en_us.json
index 86e72a87b9..b9bc99719a 100644
--- a/assets/locales/go-service/en_us.json
+++ b/assets/locales/go-service/en_us.json
@@ -50,6 +50,9 @@
"autofight.health_dangerous_switch": "Operator #%d health critical, switching to operator #%d",
"autofight.enemy_accumulating_power": "Enemy is accumulating power",
"autofight.exit_fight": "Exiting combat",
+ "autofight.wait_battle_start": "Waiting for battle to start",
+ "autofight.wait_battle_start_found": "Battle started",
+ "autofight.wait_battle_start_timeout": "Timed out waiting for battle to start, continuing combat",
"autofight.capture_slow": "Combat recognition averages %d ms. Lower graphics quality and resolution in game settings to reduce device load.",
"autofight.adjust_view": "Adjusting view",
"autofight.move_back": "Enemy not found for a while, moving back",
diff --git a/assets/locales/go-service/ja_jp.json b/assets/locales/go-service/ja_jp.json
index c9c643fda4..99f129f5e9 100644
--- a/assets/locales/go-service/ja_jp.json
+++ b/assets/locales/go-service/ja_jp.json
@@ -50,6 +50,9 @@
"autofight.health_dangerous_switch": "オペレーター %d 号のHPが危険、%d 号に切り替えます",
"autofight.enemy_accumulating_power": "敵がチャージ中",
"autofight.exit_fight": "戦闘シーンを離脱",
+ "autofight.wait_battle_start": "戦闘開始を待機",
+ "autofight.wait_battle_start_found": "戦闘開始",
+ "autofight.wait_battle_start_timeout": "戦闘開始の待機がタイムアウト、戦闘を継続",
"autofight.capture_slow": "戦闘認識の平均処理時間は %d ms です。ゲーム設定で画質・解像度を下げ、デバイスの負荷を減らしてください",
"autofight.adjust_view": "視点を調整",
"autofight.move_back": "敵が長時間見つからないため、後退します",
diff --git a/assets/locales/go-service/ko_kr.json b/assets/locales/go-service/ko_kr.json
index aafea070e1..21675e388a 100644
--- a/assets/locales/go-service/ko_kr.json
+++ b/assets/locales/go-service/ko_kr.json
@@ -50,6 +50,9 @@
"autofight.health_dangerous_switch": "%d번 오퍼레이터 체력 위험, %d번 오퍼레이터로 전환합니다",
"autofight.enemy_accumulating_power": "적이 차징 중",
"autofight.exit_fight": "전투 장면 이탈",
+ "autofight.wait_battle_start": "전투 시작 대기",
+ "autofight.wait_battle_start_found": "전투 시작",
+ "autofight.wait_battle_start_timeout": "전투 시작 대기 시간 초과, 전투 계속",
"autofight.capture_slow": "전투 인식 평균 소요 시간 %d ms, 게임 설정에서 화질·해상도를 낮춰 기기 부하를 줄여 주세요",
"autofight.adjust_view": "시점 조정",
"autofight.move_back": "적을 오래 찾지 못해 후퇴합니다",
diff --git a/assets/locales/go-service/zh_cn.json b/assets/locales/go-service/zh_cn.json
index 1c89f1091c..f47bfc5f4d 100644
--- a/assets/locales/go-service/zh_cn.json
+++ b/assets/locales/go-service/zh_cn.json
@@ -50,6 +50,9 @@
"autofight.health_dangerous_switch": "当前 %d 号干员血量危险,切换到 %d 号干员",
"autofight.enemy_accumulating_power": "敌人正在蓄力",
"autofight.exit_fight": "退出战斗场景",
+ "autofight.wait_battle_start": "等待战斗开始",
+ "autofight.wait_battle_start_found": "战斗已开始",
+ "autofight.wait_battle_start_timeout": "等待战斗开始超时,继续战斗",
"autofight.capture_slow": "战斗识别平均耗时 %d ms,请在游戏设置中降低画质、分辨率,减少设备负载",
"autofight.adjust_view": "调整视角",
"autofight.move_back": "长时间找不到敌人,后退",
diff --git a/assets/locales/go-service/zh_tw.json b/assets/locales/go-service/zh_tw.json
index 107b206dcb..1ab67049f6 100644
--- a/assets/locales/go-service/zh_tw.json
+++ b/assets/locales/go-service/zh_tw.json
@@ -50,6 +50,9 @@
"autofight.health_dangerous_switch": "當前 %d 號幹員血量危險,切換到 %d 號幹員",
"autofight.enemy_accumulating_power": "敵人正在蓄力",
"autofight.exit_fight": "退出戰鬥場景",
+ "autofight.wait_battle_start": "等待戰鬥開始",
+ "autofight.wait_battle_start_found": "戰鬥已開始",
+ "autofight.wait_battle_start_timeout": "等待戰鬥開始超時,繼續戰鬥",
"autofight.capture_slow": "戰鬥識別平均耗時 %d ms,請在遊戲設定中降低畫質、解析度,減少裝置負載",
"autofight.adjust_view": "調整視角",
"autofight.move_back": "長時間找不到敵人,後退",
diff --git a/assets/locales/interface/en_us.json b/assets/locales/interface/en_us.json
index 40ca188c59..91caa91f5a 100644
--- a/assets/locales/interface/en_us.json
+++ b/assets/locales/interface/en_us.json
@@ -1014,6 +1014,7 @@
"controller.Wlroots.description": "For Wayland compositors based on wlroots (e.g. Sway).",
"task.SceneManager.focus.color_match_failed_prefix": "Color identification failed. Try disabling filters (e.g. RTX Dynamic Vibrance, GamePP filters, Mechrevo Color Calibration, etc.) or HDR
Note: a system restart is required for the change to take effect after disabling RTX Dynamic Vibrance.",
"task.SceneManager.focus.mod_check_failed_prefix": "UID display is incomplete. Enabling UID-hiding mods removes text in the upper-left corner of the screen, which affects recognition.",
+ "task.SceneManager.focus.osd_check_failed": "Screen overlay detected. Close FPS/hardware monitoring overlays (e.g. FPS, CPU, GPU, Afterburner) and try again",
"task.SceneManager.focus.language_not_zh_cn": "The game language is not Simplified Chinese. Compatibility is limited, and tasks may fail.",
"description.file": "locales/interface/DESCRIPTION/DESCRIPTION.en_us.md",
"contact.file": "https://end.maafw.com/CONTACT/CONTACT.en_us.md",
diff --git a/assets/locales/interface/ja_jp.json b/assets/locales/interface/ja_jp.json
index a164c2227d..5cc7802d63 100644
--- a/assets/locales/interface/ja_jp.json
+++ b/assets/locales/interface/ja_jp.json
@@ -1014,6 +1014,7 @@
"controller.Wlroots.description": "wlroots ベースの Wayland コンポジター(例: Sway)向けです。",
"task.SceneManager.focus.color_match_failed_prefix": "色の認識に失敗しました。フィルター(例:RTX Dynamic Vibrance、GamePP フィルター、Mechrevo 色彩補正など)または HDR をオフにしてください
注意:RTX Dynamic Vibrance をオフにした後は、PC の再起動が必要です。",
"task.SceneManager.focus.mod_check_failed_prefix": "UIDの表示が不完全です。UID非表示MODを有効にすると、画面左上の文字が欠落し、認識に影響します。",
+ "task.SceneManager.focus.osd_check_failed": "画面にオーバーレイが検出されました。フレームレート/ハードウェア監視オーバーレイ(FPS、CPU、GPU、Afterburner など)を閉じてから再試行してください",
"task.SceneManager.focus.language_not_zh_cn": "ゲーム言語が簡体字中国語ではありません。互換性が低く、タスクが失敗する可能性があります。",
"description.file": "locales/interface/DESCRIPTION/DESCRIPTION.ja_jp.md",
"contact.file": "https://end.maafw.com/CONTACT/CONTACT.ja_jp.md",
diff --git a/assets/locales/interface/ko_kr.json b/assets/locales/interface/ko_kr.json
index cd66b78a25..bf90c78e18 100644
--- a/assets/locales/interface/ko_kr.json
+++ b/assets/locales/interface/ko_kr.json
@@ -1014,6 +1014,7 @@
"controller.Wlroots.description": "wlroots 기반 Wayland 컴포지터(예: Sway)용입니다.",
"task.SceneManager.focus.color_match_failed_prefix": "색상 인식에 실패했습니다. 필터(예: RTX Dynamic Vibrance, GamePP 필터, Mechrevo 색상 보정 등) 또는 HDR을 꺼 보세요
참고: RTX Dynamic Vibrance를 비활성화한 후에는 PC를 재시작해야 적용됩니다.",
"task.SceneManager.focus.mod_check_failed_prefix": "UID 표시가 불완전합니다. UID 숨김 MOD를 켜면 화면 왼쪽 상단의 문자가 누락되어 인식에 영향을 줍니다.",
+ "task.SceneManager.focus.osd_check_failed": "화면에 오버레이가 감지되었습니다. 프레임레이트/하드웨어 모니터링 오버레이(FPS, CPU, GPU, Afterburner 등)를 끈 후 다시 시도하세요",
"task.SceneManager.focus.language_not_zh_cn": "게임 언어가 간체 중국어가 아닙니다. 호환성이 낮아 작업이 실패할 수 있습니다.",
"description.file": "locales/interface/DESCRIPTION/DESCRIPTION.ko_kr.md",
"contact.file": "https://end.maafw.com/CONTACT/CONTACT.ko_kr.md",
diff --git a/assets/locales/interface/zh_cn.json b/assets/locales/interface/zh_cn.json
index 2d33f5188c..282f896844 100644
--- a/assets/locales/interface/zh_cn.json
+++ b/assets/locales/interface/zh_cn.json
@@ -1014,6 +1014,7 @@
"controller.Wlroots.description": "适用于基于 wlroots 的 Wayland 合成器(如 Sway)",
"task.SceneManager.focus.color_match_failed_prefix": "识别颜色失败,请尝试关闭滤镜(例如 RTX 动态亮丽、游戏加加滤镜、机械革命色彩校正等)或 HDR
注意:关闭 RTX 动态亮丽后需重启电脑才能生效",
"task.SceneManager.focus.mod_check_failed_prefix": "UID显示不完整,开启UID隐藏MOD会导致画面左上方文字缺失,影响识别",
+ "task.SceneManager.focus.osd_check_failed": "屏幕存在遮挡,请关闭帧率/硬件监控悬浮窗(如 FPS、CPU、GPU、Afterburner 等)后重试",
"task.SceneManager.focus.language_not_zh_cn": "当前游戏语言不是简体中文,兼容性较差,任务可能会失败",
"description.file": "locales/interface/DESCRIPTION/DESCRIPTION.zh_cn.md",
"contact.file": "https://end.maafw.com/CONTACT/CONTACT.zh_cn.md",
diff --git a/assets/locales/interface/zh_tw.json b/assets/locales/interface/zh_tw.json
index 0d51cade4c..1842c0d3df 100644
--- a/assets/locales/interface/zh_tw.json
+++ b/assets/locales/interface/zh_tw.json
@@ -1014,6 +1014,7 @@
"option.DailyTaskCreation.desc": "自動進行一次簡易製作以獲取活躍度",
"task.SceneManager.focus.color_match_failed_prefix": "識別顏色失敗,請嘗試關閉濾鏡(例如 RTX 動態亮麗、遊戲加加濾鏡、機械革命色彩校正等)或 HDR
注意:關閉 RTX 動態亮麗後需重新啟動電腦才會生效",
"task.SceneManager.focus.mod_check_failed_prefix": "UID顯示不完整,開啟UID隱藏MOD會導致畫面左上方文字缺失,影響識別",
+ "task.SceneManager.focus.osd_check_failed": "螢幕存在遮擋,請關閉幀率/硬體監控懸浮窗(如 FPS、CPU、GPU、Afterburner 等)後重試",
"task.SceneManager.focus.language_not_zh_cn": "當前遊戲語言不是簡體中文,相容性較差,任務可能會失敗",
"description.file": "locales/interface/DESCRIPTION/DESCRIPTION.zh_tw.md",
"contact.file": "https://end.maafw.com/CONTACT/CONTACT.zh_tw.md",
diff --git a/assets/resource/image/ProtocolSpace/MechanicsIcon.png b/assets/resource/image/ProtocolSpace/MechanicsIcon.png
new file mode 100644
index 0000000000..600fffdcac
Binary files /dev/null and b/assets/resource/image/ProtocolSpace/MechanicsIcon.png differ
diff --git a/assets/resource/pipeline/AutoFight/Recognition.json b/assets/resource/pipeline/AutoFight/Recognition.json
index fd9bb0ccf0..5c8a68eab7 100644
--- a/assets/resource/pipeline/AutoFight/Recognition.json
+++ b/assets/resource/pipeline/AutoFight/Recognition.json
@@ -344,5 +344,43 @@
"focus": {
"Node.Recognition.Succeeded": "识别到敌人"
}
+ },
+ "__AutoFightRecognitionProtocolSpaceMechanicsGate": {
+ "desc": "协议空间机关场景,且不在影拓丰碑:左上角同时存在撤退与机关提示图标",
+ "recognition": "And",
+ "all_of": [
+ {
+ "recognition": "TemplateMatch",
+ "roi": [
+ 0,
+ 0,
+ 200,
+ 100
+ ],
+ "template": "ProtocolSpace/RetreatSpace.png"
+ },
+ {
+ "recognition": "TemplateMatch",
+ "roi": [
+ 0,
+ 0,
+ 200,
+ 100
+ ],
+ "template": "ProtocolSpace/MechanicsIcon.png"
+ }
+ ]
+ },
+ "__AutoFightRecognitionProtocolSpaceRestart": {
+ "desc": "协议空间战斗开始:SpaceResart 按钮",
+ "recognition": "TemplateMatch",
+ "roi": [
+ 0,
+ 200,
+ 160,
+ 120
+ ],
+ "template": "ProtocolSpace/SpaceResart.png",
+ "green_mask": true
}
}
diff --git a/assets/resource/pipeline/SceneManager/SceneLoading.json b/assets/resource/pipeline/SceneManager/SceneLoading.json
index f37376357d..4e0395f317 100644
--- a/assets/resource/pipeline/SceneManager/SceneLoading.json
+++ b/assets/resource/pipeline/SceneManager/SceneLoading.json
@@ -251,7 +251,7 @@
],
"focus": {
"Node.Recognition.Succeeded": {
- "content": "屏幕存在遮挡,请尝试关闭帧率显示",
+ "content": "$task.SceneManager.focus.osd_check_failed",
"display": "modal"
}
}
diff --git a/tools/optimize_templates/optimize_templates.json b/tools/optimize_templates/optimize_templates.json
index d1a4775ae9..e04b406df0 100644
--- a/tools/optimize_templates/optimize_templates.json
+++ b/tools/optimize_templates/optimize_templates.json
@@ -983,5 +983,6 @@
"resource/image/IMS/item/TACHYON_SCREENING_LATTICE_TEMPLATE": "36a7ec226ccadb3e7bf63a79d9ae8d583544a3b036bf76b702d2d91f4636d1fd",
"resource/image/IMS/item/PROTOHEDRON_TEMPLATE": "23e61c6003a5576e1309c77941b5691df11bcbc8b2b029c4269145b6362f48f9",
"resource/image/Common/Button/TrackedMissionMapButton": "476da5205d64343ce84275dbb8978269172bbb27ca93ad47461424850674705b",
- "resource/image/IMS/item/OROBERYL_TEMPLATE": "3602a08527a0542a7c7e2b6451e9ba17937d0b2fd6a1d4aad584b1b80f7b4e57"
+ "resource/image/IMS/item/OROBERYL_TEMPLATE": "3602a08527a0542a7c7e2b6451e9ba17937d0b2fd6a1d4aad584b1b80f7b4e57",
+ "resource/image/ProtocolSpace/MechanicsIcon": "10199ea056374f794a7109520918ce0b9a559eec05b012337649beff9898dba1"
}