From 1879c290ad0f91712c201a9fa262ccffceac3d3b Mon Sep 17 00:00:00 2001 From: Status102 <102887808+status102@users.noreply.github.com> Date: Sun, 1 Feb 2026 22:59:30 +0800 Subject: [PATCH] =?UTF-8?q?rft:=20=E5=85=B3=E5=8D=A1=E5=80=99=E9=80=89?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E5=88=B7=E6=96=B0=20&=20=E5=85=B3=E5=8D=A1?= =?UTF-8?q?=E9=80=89=E6=8B=A9=E4=B8=8B=E6=8B=89=E5=88=97=E8=A1=A8=E5=88=B7?= =?UTF-8?q?=E6=96=B0=20(#15562)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * rft: 无效关卡重置 * fix: 显示翻转 * fix: 无效关卡开放状态错误 * fix: 无效关卡被错误重置 * feat: 自定义剿灭关卡将会同步修改关卡选择下拉框中的剿灭模式显示名 * perf: 修改任务参数快速退出 * i18n: invalid stage * fix: 刷理智任务在LinkStart后修改关卡无法生效 * i18n: KR * i18n: EN Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * i18n: JP * i18n: zh-tw --------- Co-authored-by: HX3N Co-authored-by: Constrat <56174894+Constrat@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Manicsteiner Co-authored-by: momomochi987 --- .../Configuration/Single/MaaTask/FightTask.cs | 3 + .../Constants/Enums/FightStageResetMode.cs | 27 +++++ src/MaaWpfGui/Res/Localizations/en-us.xaml | 6 +- src/MaaWpfGui/Res/Localizations/ja-jp.xaml | 4 +- src/MaaWpfGui/Res/Localizations/ko-kr.xaml | 4 +- src/MaaWpfGui/Res/Localizations/zh-cn.xaml | 10 +- src/MaaWpfGui/Res/Localizations/zh-tw.xaml | 6 +- .../FightSettingsUserControlModel.cs | 110 ++++++++++++------ .../TaskQueue/FightSettingsUserControl.xaml | 14 +++ 9 files changed, 138 insertions(+), 46 deletions(-) create mode 100644 src/MaaWpfGui/Constants/Enums/FightStageResetMode.cs diff --git a/src/MaaWpfGui/Configuration/Single/MaaTask/FightTask.cs b/src/MaaWpfGui/Configuration/Single/MaaTask/FightTask.cs index a1b4c9eecb..833c39b820 100644 --- a/src/MaaWpfGui/Configuration/Single/MaaTask/FightTask.cs +++ b/src/MaaWpfGui/Configuration/Single/MaaTask/FightTask.cs @@ -16,6 +16,7 @@ using System; using System.Collections.Generic; using System.Linq; using System.Text.Json.Serialization; +using MaaWpfGui.Constants.Enums; using static MaaWpfGui.Main.AsstProxy; namespace MaaWpfGui.Configuration.Single.MaaTask; @@ -127,6 +128,8 @@ public class FightTask : BaseTask, IJsonOnDeserialized /// public bool HideSeries { get; set; } + public FightStageResetMode StageResetMode { get; set; } = FightStageResetMode.Current; + /// /// Gets or sets a value indicating whether 是否启用周计划 /// diff --git a/src/MaaWpfGui/Constants/Enums/FightStageResetMode.cs b/src/MaaWpfGui/Constants/Enums/FightStageResetMode.cs new file mode 100644 index 0000000000..4484c4588f --- /dev/null +++ b/src/MaaWpfGui/Constants/Enums/FightStageResetMode.cs @@ -0,0 +1,27 @@ +// +// Part of the MaaWpfGui project, maintained by the MaaAssistantArknights team (Maa Team) +// Copyright (C) 2021-2025 MaaAssistantArknights Contributors +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License v3.0 only as published by +// the Free Software Foundation, either version 3 of the License, or +// any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY +// + +namespace MaaWpfGui.Constants.Enums; + +public enum FightStageResetMode +{ + /// + /// 当前 / 上次 + /// + Current, + + /// + /// 无效关卡 + /// + Invalid, +} diff --git a/src/MaaWpfGui/Res/Localizations/en-us.xaml b/src/MaaWpfGui/Res/Localizations/en-us.xaml index 07a04a0fd4..71d5b2e741 100644 --- a/src/MaaWpfGui/Res/Localizations/en-us.xaml +++ b/src/MaaWpfGui/Res/Localizations/en-us.xaml @@ -587,6 +587,7 @@ Then delete the entries corresponding to the paths. Use alternative stage Unlimited use of expiring (<48h) sanity potion Hide today's not open stages + Unopened stage is reset to Hide series Variable function button Manual entry of stage names @@ -738,14 +739,15 @@ If the number of battles is not enough to complete the set multiplier (such as o • {key=NotSwitch}: Do not adjust the proxy multiplier setting in the game Stage - Alternative - Add stage + Candidates + Add candidate Remaining Sanity No Use Cur/Last + Invalid The event is not open Unsupported stages Old Version, Update required diff --git a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml index f064d124b3..c40c05bf3b 100644 --- a/src/MaaWpfGui/Res/Localizations/ja-jp.xaml +++ b/src/MaaWpfGui/Res/Localizations/ja-jp.xaml @@ -586,7 +586,8 @@ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Notifications\Settin この機能は危険な機能と見なされます。「{key=Confirm}」ボタンを押すと、リスクを理解し、受け入れることに同意したと見なされます。 代替ステージを選択可能にする 48時間以内に期限が切れる回復剤を無制限に使用 - 当日開放されないステージを隠す + リストに当日開放されないステージを隠す + 未開放のレベルをこれにリセットする 連戦回数を隠します スタート画面に表示する便利ボタン ステージ名を入力する @@ -747,6 +748,7 @@ C:\\leidian\\LDPlayer9 現在/前回 + 無効なレベル ステージが未公開か既に終了している 未サポートステージ バージョンの更新が必要 diff --git a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml index 0d6e6a7295..c88bc14a7f 100644 --- a/src/MaaWpfGui/Res/Localizations/ko-kr.xaml +++ b/src/MaaWpfGui/Res/Localizations/ko-kr.xaml @@ -587,6 +587,7 @@ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Notifications\Settin 대체 스테이지 사용 48시간 미만 이성 회복제 사용 미개방 스테이지 숨기기 + 미개방 스테이지 재설정 {key=Series} 숨기기 메인 화면 버튼의 기능 스테이지 코드 수동 입력 @@ -748,7 +749,8 @@ C:\\leidian\\LDPlayer9 현재/최근 - 이벤트가 닫혀 있습니다 + 잘못된 스테이지 + 미개방 스테이지 미지원 스테이지 낮은 버전 최소 요구사항: diff --git a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml index a704d1fb06..8ac7a94e5a 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-cn.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-cn.xaml @@ -586,7 +586,8 @@ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Notifications\Settin 该功能属于危险功能。按下 「{key=Confirm}」 键即视为你了解并愿意承担可能出现的风险。 使用备选关卡 无限吃 48 小时内过期的理智药 - 隐藏当日不开放关卡 + 下拉框中隐藏当日不开放关卡 + 未开放关卡重置为 隐藏代理倍率 主界面可选择按钮功能 手动输入关卡名 @@ -738,15 +739,16 @@ C:\\leidian\\LDPlayer9。\n • {key=NotSwitch}: 不调整游戏内代理倍率设定 - 关卡选择 - 关卡备选 - 添加关卡 + 关卡指定 + 候选关卡 + 添加候选 剩余理智 不使用 当前/上次 + 无效关卡 活动未开放 不支持的关卡 版本过低 diff --git a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml index 5df1d2ead2..f67c34cb00 100644 --- a/src/MaaWpfGui/Res/Localizations/zh-tw.xaml +++ b/src/MaaWpfGui/Res/Localizations/zh-tw.xaml @@ -586,7 +586,8 @@ HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Notifications\Settin 該功能屬於危險功能。按下 「{key=Confirm}」 鍵即視為您了解並願意承擔可能出現的風險。 使用備選關卡 無限吃 48 小時內過期的理智藥 - 隱藏當日不開放關卡 + 下拉選單中隱藏當日不開放關卡 + 未開放關卡重設為 隱藏代理倍率 主介面可選擇按鈕功能 手動輸入關卡名稱 @@ -740,13 +741,14 @@ C:\\leidian\\LDPlayer9\n 不調整遊戲內代理倍率設定 關卡選擇 備選 - 新增關卡 + 新增備選 剩餘理智 不選擇 目前/上次 + 無效關卡 活動未開放 不支援的關卡 版本過低 diff --git a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs index eb23568205..a35cd632db 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/TaskQueue/FightSettingsUserControlModel.cs @@ -22,6 +22,7 @@ using JetBrains.Annotations; using MaaWpfGui.Configuration.Factory; using MaaWpfGui.Configuration.Single.MaaTask; using MaaWpfGui.Constants; +using MaaWpfGui.Constants.Enums; using MaaWpfGui.Helper; using MaaWpfGui.Models; using MaaWpfGui.Models.AsstTasks; @@ -91,6 +92,8 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel { "炭", "SK-5" }, }; + private readonly StageSourceItem InvalidStage = new() { Display = LocalizationHelper.GetString("InvalidStage"), Value = "__INVALID__", IsOpen = false, IsVisible = false }; + public ObservableCollection StagePlan { get => field; set => SetAndNotify(ref field, value); } = [new()]; // UI 绑定的方法 @@ -386,11 +389,11 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel foreach (var task in ConfigFactory.CurrentConfig.TaskQueue.OfType()) { if (AllDrops.FirstOrDefault(i => i.Value == task.DropId) is not { } item) - { + { task.DropId = string.Empty; + } } } - } /// /// Gets or private sets the list of drops. @@ -461,7 +464,10 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel public string AnnihilationStage { get => GetTaskConfig().AnnihilationStage; - set => SetTaskConfig(t => t.AnnihilationStage == value, t => t.AnnihilationStage = value); + set { + SetTaskConfig(t => t.AnnihilationStage == value, t => t.AnnihilationStage = value); + StageListSource.FirstOrDefault(i => i.Value == "Annihilation")?.Display = UseCustomAnnihilation ? (AnnihilationModeList.FirstOrDefault(i => i.Value == value).Key ?? LocalizationHelper.GetString("Annihilation.Current")) : LocalizationHelper.GetString("Annihilation.Current"); + } } /// @@ -484,6 +490,7 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel if (value) { HideUnavailableStage = false; + StageResetMode = FightStageResetMode.Invalid; } else { @@ -549,14 +556,27 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel if (value) { UseAlternateStage = false; + StageResetMode = FightStageResetMode.Current; } if (update) { - UpdateStageList(); + RefreshStageList(); } } } + public List> StageResetModeList { get; } = + [ + new() { Display = LocalizationHelper.GetString("DefaultStage"), Value = FightStageResetMode.Current }, + new() { Display = LocalizationHelper.GetString("InvalidStage"), Value = FightStageResetMode.Invalid }, + ]; + + public FightStageResetMode StageResetMode + { + get => GetTaskConfig().StageResetMode; + set => SetTaskConfig(t => t.StageResetMode == value, t => t.StageResetMode = value); + } + /// /// Gets or sets a value indicating whether to hide series. /// @@ -617,8 +637,9 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel public static string? GetFightStage(IEnumerable stageNames) { - var stage = stageNames.FirstOrDefault(Instances.TaskQueueViewModel.IsStageOpen); - stage ??= stageNames.FirstOrDefault(); + var list = stageNames.Where(i => i != Instance.InvalidStage.Value); + var stage = list.FirstOrDefault(Instances.TaskQueueViewModel.IsStageOpen); + stage ??= list.FirstOrDefault(); return stage; } @@ -633,7 +654,7 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel { fight.StagePlan.Add(string.Empty); } - UpdateStageList(); // 临时修复, 应为同步 + RefreshStageList(); RefreshCurrentStagePlan(); RefreshWeeklySchedule(); RefreshDropName(); @@ -680,12 +701,12 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel private bool? SetFightParams() { - if (TaskSettingVisibilityInfo.CurrentTask is not FightTask fight) + if (IsRefreshingUI || TaskSettingVisibilityInfo.CurrentTask is not FightTask fight) { return null; } - if (ConfigFactory.CurrentConfig.TaskQueue.IndexOf(fight) is int index && index > -1) + if (ConfigFactory.CurrentConfig.TaskQueue.IndexOf(fight) is int index && index > -1 && Instances.TaskQueueViewModel.TaskItemViewModels[index].TaskId > 0) { return SerializeTask(fight, Instances.TaskQueueViewModel.TaskItemViewModels[index].TaskId); } @@ -695,7 +716,7 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel public override bool? SerializeTask(BaseTask? baseTask, int? taskId = null) { - if (baseTask is not FightTask fight) + if (baseTask is not FightTask fight || taskId is int and <= 0) { return null; } @@ -766,39 +787,48 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel Execute.PostToUIThreadAsync(() => { _logger.Information("Updating stage list..."); using var scope = _lock.EnterScope(); - bool isFightTaskShow = TaskSettingVisibilityInfo.CurrentTask is FightTask; - var hideUnavailble = isFightTaskShow && HideUnavailableStage; - var stageList = Instances.StageManager.GetStageList().ToList(); - var listCurrent = StagePlan.Select(i => i.Value).ToList(); - - var listSource = stageList.Select(i => new StageSourceItem() { Display = i.Display, Value = i.Value, IsVisible = !hideUnavailble || i.IsStageOpen(Instances.TaskQueueViewModel.CurDayOfWeek), IsOpen = Instances.StageManager.GetStageList().FirstOrDefault(p => p.Value == i.Value)?.IsStageOpen(Instances.TaskQueueViewModel.CurDayOfWeek) ?? true }).ToList(); - if (isFightTaskShow) - { - foreach (var item in listCurrent.Where(i => !listSource.Any(p => p.Value == i))) // 补未开放进来 - { - listSource.Add(new StageSourceItem() { Display = item, Value = item, IsOpen = false, IsVisible = false }); - } - } - StageListSource = new ObservableCollection(listSource); - - if (TaskSettingVisibilityInfo.CurrentTask is FightTask current) - { - current.StagePlan = listCurrent; - } + var stageList = Instances.StageManager.GetStageList(); + RefreshStageList(); foreach (var task in ConfigFactory.CurrentConfig.TaskQueue.Where(i => i is FightTask fight && !fight.IsStageManually).OfType()) { - var removeList = task.StagePlan.Where(i => !stageList.Any(p => p.Value == i)).ToList(); - if (removeList.Count != 0) + for (int i = 0; i < task.StagePlan.Count; i++) { - _logger.Information("Removed non-existing stage from plan: {Stage}", removeList); - task.StagePlan = [.. task.StagePlan.Where(i => stageList.Any(p => p.Value == i))]; + var stage = task.StagePlan[i]; + if (stage != InvalidStage.Value && !stageList.Any(p => p.Value == stage)) + { + task.StagePlan[i] = task.StageResetMode switch { + FightStageResetMode.Current => string.Empty, + FightStageResetMode.Invalid => InvalidStage.Value, + _ => string.Empty, + }; + _logger.Information("Reset non-existing stage from plan: {Stage} to {}", stage, task.StagePlan[i]); + } } } - RefreshCurrentStagePlan(); }); } + private void RefreshStageList() + { + if (TaskSettingVisibilityInfo.CurrentTask is not FightTask current) + { + return; + } + var stageList = Instances.StageManager.GetStageList().ToList(); + var listCurrent = StagePlan.Select(i => i.Value).ToList(); + + var listSource = stageList.Select(i => new StageSourceItem() { Display = i.Display, Value = i.Value, IsVisible = !HideUnavailableStage || i.IsStageOpen(Instances.TaskQueueViewModel.CurDayOfWeek), IsOpen = Instances.StageManager.GetStageList().FirstOrDefault(p => p.Value == i.Value)?.IsStageOpen(Instances.TaskQueueViewModel.CurDayOfWeek) ?? true }).ToList(); + foreach (var item in listCurrent.Where(i => !listSource.Any(p => p.Value == i))) // 补未开放进来 + { + listSource.Add(new StageSourceItem() { Display = item, Value = item, IsOpen = false, IsVisible = false }); + } + listSource.Add(InvalidStage); // 无效关卡 + listSource.FirstOrDefault(i => i.Value == "Annihilation")?.Display = current.UseCustomAnnihilation ? (AnnihilationModeList.FirstOrDefault(i => i.Value == current.AnnihilationStage).Key ?? LocalizationHelper.GetString("Annihilation.Current")) : LocalizationHelper.GetString("Annihilation.Current"); + StageListSource = new ObservableCollection(listSource); + current.StagePlan = listCurrent; // StageListSource更新后, 恢复StagePlan + } + private void RefreshCurrentStagePlan() { if (TaskSettingVisibilityInfo.CurrentTask is not FightTask) @@ -895,7 +925,7 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel public class StageSourceItem : PropertyChangedBase { - public string Display { get; set; } = string.Empty; + public string Display { get => field; set => SetAndNotify(ref field, value); } = string.Empty; public string Value { get; set; } = string.Empty; @@ -925,7 +955,15 @@ public class FightSettingsUserControlModel : TaskSettingsViewModel return; } - IsOpen = Instances.StageManager.GetStageList().FirstOrDefault(p => p.Value == value)?.IsStageOpen(Instances.TaskQueueViewModel.CurDayOfWeek) ?? true; + if (value == Instance.InvalidStage.Value) + { + IsOpen = false; + } + else + { + IsOpen = Instances.StageManager.GetStageList().FirstOrDefault(p => p.Value == value)?.IsStageOpen(Instances.TaskQueueViewModel.CurDayOfWeek) ?? true; + } + Instance.SetFightParams(); } } = string.Empty; diff --git a/src/MaaWpfGui/Views/UserControl/TaskQueue/FightSettingsUserControl.xaml b/src/MaaWpfGui/Views/UserControl/TaskQueue/FightSettingsUserControl.xaml index 42785ac046..056b500137 100644 --- a/src/MaaWpfGui/Views/UserControl/TaskQueue/FightSettingsUserControl.xaml +++ b/src/MaaWpfGui/Views/UserControl/TaskQueue/FightSettingsUserControl.xaml @@ -398,6 +398,20 @@ + + + + +