From aaf6efb9cf23059d450a0ecc7cd726e3434341d5 Mon Sep 17 00:00:00 2001 From: Weiyou Wang <44151844+Alan-Charred@users.noreply.github.com> Date: Tue, 4 Aug 2026 14:53:54 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E6=9B=B4?= =?UTF-8?q?=E5=A4=9A=20CopilotTask=20=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CopilotConfiguration.swift | 29 ++++++++++++++++++ MeoAsstMac/Views/CopilotView.swift | 30 +++++++++++++++++-- 2 files changed, 56 insertions(+), 3 deletions(-) diff --git a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift index 6221ceb88..18f6c7288 100644 --- a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift +++ b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift @@ -11,7 +11,36 @@ struct RegularCopilotConfiguration: Codable { var enable = true var filename: String var formation = false + var formation_index = 0 var add_trust = false + var ignore_requirements = false + + enum SupportUnitUsage: Int, CaseIterable, Codable { + /// 不加助战干员 + case None = 0 + /// 如果仅缺一名干员则尝试补助战 + case WhenNeeded = 1 + /// 如果仅缺一名干员则尝试补助战,如无缺失则使用指定助战干员 + case Specific = 2 + /// 如果仅缺一名干员则尝试补助战,如无缺失则随机加一个助战干员 + case Random = 3 + + var description: String { + switch self { + case .None: + return NSLocalizedString("不借助战", comment: "") + case .WhenNeeded: + return NSLocalizedString("补漏", comment: "") + case .Specific: + return NSLocalizedString("指定", comment: "") + case .Random: + return NSLocalizedString("随机", comment: "") + } + } + } + + var support_unit_usage: SupportUnitUsage = .None + var support_unit_name = "" } struct SSSCopilotConfiguration: Codable { diff --git a/MeoAsstMac/Views/CopilotView.swift b/MeoAsstMac/Views/CopilotView.swift index b00662e38..fb6f5044e 100644 --- a/MeoAsstMac/Views/CopilotView.swift +++ b/MeoAsstMac/Views/CopilotView.swift @@ -51,9 +51,33 @@ struct CopilotView: View { } set: { newValue in viewModel.copilot = .regular(newValue) } - HStack { - Toggle("自动编队", isOn: binding.formation) - Toggle("信赖干员", isOn: binding.add_trust) + VStack { + HStack { + Toggle("自动编队", isOn: binding.formation) + if binding.formation.wrappedValue { + Picker("编队栏位", selection: binding.formation_index) { + ForEach(0..<5) { index in + Text("\(index)").tag(index) + } + } + .pickerStyle(.menu) + Toggle("信赖干员", isOn: binding.add_trust) + Toggle("忽视练度需求", isOn: binding.ignore_requirements) + } + } + if binding.formation.wrappedValue { + HStack { + Picker("助战模式", selection: binding.support_unit_usage) { + ForEach(RegularCopilotConfiguration.SupportUnitUsage.allCases, id: \.self) { + Text($0.description).tag($0) + } + } + if binding.support_unit_usage.wrappedValue == .Specific { + TextField("指定助战干员", text: binding.support_unit_name) + .frame(maxWidth: 150) + } + } + } } case .sss(let innerConfig): From a52138697e3e1964329eff341e44b0c36a7fe27b Mon Sep 17 00:00:00 2001 From: Weiyou Wang <44151844+Alan-Charred@users.noreply.github.com> Date: Thu, 6 Aug 2026 14:20:12 +0800 Subject: [PATCH 2/5] fix: avoid magic number --- MeoAsstMac/Task Configurations/CopilotConfiguration.swift | 4 ++++ MeoAsstMac/Views/CopilotView.swift | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift index 18f6c7288..2f33788d5 100644 --- a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift +++ b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift @@ -11,7 +11,11 @@ struct RegularCopilotConfiguration: Codable { var enable = true var filename: String var formation = false + + static let numFormationSlots = 4 + var formation_index = 0 + var add_trust = false var ignore_requirements = false diff --git a/MeoAsstMac/Views/CopilotView.swift b/MeoAsstMac/Views/CopilotView.swift index fb6f5044e..43b71f76f 100644 --- a/MeoAsstMac/Views/CopilotView.swift +++ b/MeoAsstMac/Views/CopilotView.swift @@ -56,8 +56,9 @@ struct CopilotView: View { Toggle("自动编队", isOn: binding.formation) if binding.formation.wrappedValue { Picker("编队栏位", selection: binding.formation_index) { - ForEach(0..<5) { index in - Text("\(index)").tag(index) + Text("当前").tag(0) + ForEach(0.. Date: Thu, 6 Aug 2026 14:21:06 +0800 Subject: [PATCH 3/5] fix: apply lowerCamelCase to enum case names --- .../CopilotConfiguration.swift | 18 +++++++++--------- MeoAsstMac/Views/CopilotView.swift | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift index 2f33788d5..6366a313c 100644 --- a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift +++ b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift @@ -21,29 +21,29 @@ struct RegularCopilotConfiguration: Codable { enum SupportUnitUsage: Int, CaseIterable, Codable { /// 不加助战干员 - case None = 0 + case none = 0 /// 如果仅缺一名干员则尝试补助战 - case WhenNeeded = 1 + case whenNeeded = 1 /// 如果仅缺一名干员则尝试补助战,如无缺失则使用指定助战干员 - case Specific = 2 + case specific = 2 /// 如果仅缺一名干员则尝试补助战,如无缺失则随机加一个助战干员 - case Random = 3 + case random = 3 var description: String { switch self { - case .None: + case .none: return NSLocalizedString("不借助战", comment: "") - case .WhenNeeded: + case .whenNeeded: return NSLocalizedString("补漏", comment: "") - case .Specific: + case .specific: return NSLocalizedString("指定", comment: "") - case .Random: + case .random: return NSLocalizedString("随机", comment: "") } } } - var support_unit_usage: SupportUnitUsage = .None + var support_unit_usage: SupportUnitUsage = .none var support_unit_name = "" } diff --git a/MeoAsstMac/Views/CopilotView.swift b/MeoAsstMac/Views/CopilotView.swift index 43b71f76f..17cb03be1 100644 --- a/MeoAsstMac/Views/CopilotView.swift +++ b/MeoAsstMac/Views/CopilotView.swift @@ -73,7 +73,7 @@ struct CopilotView: View { Text($0.description).tag($0) } } - if binding.support_unit_usage.wrappedValue == .Specific { + if binding.support_unit_usage.wrappedValue == .specific { TextField("指定助战干员", text: binding.support_unit_name) .frame(maxWidth: 150) } From df01574f2a2808df0c143ea5d529716aabff6037 Mon Sep 17 00:00:00 2001 From: Hao Guan <10684225+hguandl@users.noreply.github.com> Date: Fri, 7 Aug 2026 01:48:06 +0800 Subject: [PATCH 4/5] Refactor --- .../CopilotConfiguration.swift | 61 +++++--- MeoAsstMac/Views/CopilotView.swift | 136 +++++++++++------- Resources/Localizable.xcstrings | 37 +++++ 3 files changed, 166 insertions(+), 68 deletions(-) diff --git a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift index 6366a313c..dbb60dd8a 100644 --- a/MeoAsstMac/Task Configurations/CopilotConfiguration.swift +++ b/MeoAsstMac/Task Configurations/CopilotConfiguration.swift @@ -7,15 +7,34 @@ import Foundation -struct RegularCopilotConfiguration: Codable { +struct RegularCopilotConfiguration: Codable, Hashable { var enable = true + var filename: String + + struct CopilotItem: Codable, Hashable { + let filename: String + let stage_name: String + let is_raid: Bool + } + + var copilot_list: [CopilotItem] + + var loop_times = 1 + + var use_sanity_potion = false + var formation = false - - static let numFormationSlots = 4 - var formation_index = 0 - + static let formationCount = 4 + + struct UserUnit: Codable, Hashable { + let name: String + let skill: Int + } + + var user_additional = [UserUnit]() + var add_trust = false var ignore_requirements = false @@ -24,33 +43,39 @@ struct RegularCopilotConfiguration: Codable { case none = 0 /// 如果仅缺一名干员则尝试补助战 case whenNeeded = 1 - /// 如果仅缺一名干员则尝试补助战,如无缺失则使用指定助战干员 - case specific = 2 /// 如果仅缺一名干员则尝试补助战,如无缺失则随机加一个助战干员 case random = 3 - + /// 如果仅缺一名干员则尝试补助战,如无缺失则使用指定助战干员 + case specific = 2 + var description: String { switch self { case .none: - return NSLocalizedString("不借助战", comment: "") + return String(localized: "不借", comment: "") case .whenNeeded: - return NSLocalizedString("补漏", comment: "") + return String(localized: "补漏", comment: "") case .specific: - return NSLocalizedString("指定", comment: "") + return String(localized: "指定", comment: "") case .random: - return NSLocalizedString("随机", comment: "") + return String(localized: "随机", comment: "") } } } - + var support_unit_usage: SupportUnitUsage = .none var support_unit_name = "" } -struct SSSCopilotConfiguration: Codable { - var enable = true - var filename: String - var loop_times = 1 +typealias SSSCopilotConfiguration = RegularCopilotConfiguration + +extension RegularCopilotConfiguration { + init(filename: String) { + self.init(filename: filename, copilot_list: []) + } + + init(copilotList: [CopilotItem]) { + self.init(filename: "", copilot_list: copilotList) + } } struct VideoRecognitionConfiguration: Codable { @@ -62,7 +87,7 @@ struct VideoRecognitionConfiguration: Codable { } } -enum CopilotConfiguration { +enum CopilotConfiguration: Hashable { case regular(RegularCopilotConfiguration) case sss(SSSCopilotConfiguration) diff --git a/MeoAsstMac/Views/CopilotView.swift b/MeoAsstMac/Views/CopilotView.swift index 17cb03be1..fd94144f3 100644 --- a/MeoAsstMac/Views/CopilotView.swift +++ b/MeoAsstMac/Views/CopilotView.swift @@ -14,15 +14,16 @@ struct CopilotView: View { var body: some View { if let copilot = MAACopilot(url: url) { VStack(spacing: 20) { - pilotConfiguration() + CopilotConfigView(config: $viewModel.copilot).padding(.top) Divider() ScrollView { - pilotDescription(pilot: copilot) + CopilotDescriptionView(pilot: copilot) } } .task(id: url) { updateCopilot() } + .animation(.default, value: viewModel.copilot) } else { Text("文件格式错误") } @@ -40,67 +41,89 @@ struct CopilotView: View { private var copilot: MAACopilot? { MAACopilot(url: url) } +} + +// MARK: - Copilot Config - // MARK: - Copilot Config +private struct CopilotConfigView: View { + @Binding var config: CopilotConfiguration? - @ViewBuilder private func pilotConfiguration() -> some View { - switch viewModel.copilot { + var body: some View { + switch config { case .regular(let innerConfig): - let binding = Binding { + let binding = Binding { innerConfig } set: { newValue in - viewModel.copilot = .regular(newValue) + self.config = .regular(newValue) } - VStack { + RegularCopilotConfigView(config: binding) + case .sss(let innerConfig): + let binding = Binding { + innerConfig + } set: { newValue in + self.config = .sss(newValue) + } + SSSCopilotConfigView(config: binding) + case .none: + EmptyView() + } + + } +} + +private struct RegularCopilotConfigView: View { + @Binding var config: RegularCopilotConfiguration + + var body: some View { + VStack { + Toggle("自动编队", isOn: $config.formation) + if config.formation { HStack { - Toggle("自动编队", isOn: binding.formation) - if binding.formation.wrappedValue { - Picker("编队栏位", selection: binding.formation_index) { - Text("当前").tag(0) - ForEach(0.. { - innerConfig - } set: { newValue in - viewModel.copilot = .sss(newValue) - } - HStack { - Text("循环次数") - TextField("1", value: binding.loop_times, format: .number) - } - .frame(maxWidth: 130) +private struct SSSCopilotConfigView: View { + @Binding var config: SSSCopilotConfiguration - case .none: - EmptyView() + var body: some View { + HStack { + Text("循环次数") + TextField("1", value: $config.loop_times, format: .number) } + .frame(maxWidth: 130) + } +} - // MARK: - Copilot Document +// MARK: - Copilot Document - @ViewBuilder private func pilotDescription(pilot: MAACopilot) -> some View { +private struct CopilotDescriptionView: View { + let pilot: MAACopilot + + var body: some View { if let title = pilot.doc?.title { Text(title).font(.title2) } @@ -139,17 +162,30 @@ struct CopilotView: View { } } -struct CopilotView_Previews: PreviewProvider { - static let url = Bundle.main.resourceURL! +#Preview("Regular Copilot Config") { + let url = Bundle.main.resourceURL! .appendingPathComponent("resource") .appendingPathComponent("copilot") + .appendingPathComponent("OF-1_credit_fight") + .appendingPathExtension("json") + + VStack { + CopilotView(url: url) + } + .environmentObject(MAAViewModel()) +} + +#Preview("SSS Copilot Config") { + let url = Bundle.main.resourceURL! + .appendingPathComponent("resource") + .appendingPathComponent("copilot") + .appendingPathComponent("old") + .appendingPathComponent("约翰老妈新建地块_Mama_Johns_New_Plate") .appendingPathComponent("SSS_约翰老妈新建地块") .appendingPathExtension("json") - static var previews: some View { - VStack { - CopilotView(url: url) - } - .environmentObject(MAAViewModel()) + VStack { + CopilotView(url: url) } + .environmentObject(MAAViewModel()) } diff --git a/Resources/Localizable.xcstrings b/Resources/Localizable.xcstrings index 5913e5450..6df00467d 100644 --- a/Resources/Localizable.xcstrings +++ b/Resources/Localizable.xcstrings @@ -1783,6 +1783,9 @@ } } } + }, + "不借" : { + }, "不切换" : { "localizations" : { @@ -2048,6 +2051,7 @@ } }, "信赖干员" : { + "extractionState" : "stale", "localizations" : { "ko" : { "stringUnit" : { @@ -2586,6 +2590,9 @@ } } } + }, + "助战模式" : { + }, "单设施最优解" : { "localizations" : { @@ -2738,6 +2745,9 @@ } } } + }, + "地图太复杂了,先整个简单的刷钱脚本。\n在右下角有开始探索的界面开始。\n使用特勤分队 + 开局给的结构性原理(鹿精二后卖 10 个零件解锁的招募精通II 效果提升II,不是天赋的召唤物)跳节点。\n之前有手动刷过开局低保或者有襁褓生灵的自己开一把直接放弃。" : { + }, "基建工作心情阈值: %.0f%%" : { "localizations" : { @@ -2988,6 +2998,9 @@ } } } + }, + "干员名称" : { + }, "干员寻访" : { "localizations" : { @@ -3098,6 +3111,9 @@ } } } + }, + "当前" : { + }, "当前/上次" : { "localizations" : { @@ -3138,6 +3154,9 @@ } } } + }, + "忽视干员属性要求" : { + }, "我已知晓,继续" : { "localizations" : { @@ -3227,6 +3246,9 @@ } } } + }, + "指定" : { + }, "指定材料" : { "localizations" : { @@ -4119,6 +4141,9 @@ } } } + }, + "编队栏位" : { + }, "繁中服(txwy)" : { "localizations" : { @@ -4389,6 +4414,12 @@ } } } + }, + "补充低信赖干员" : { + + }, + "补漏" : { + }, "装备:" : { "localizations" : { @@ -4788,6 +4819,9 @@ } } } + }, + "随机" : { + }, "随机奖励" : { "localizations" : { @@ -4918,6 +4952,9 @@ } } } + }, + "黑流树海刷钱" : { + }, "默认兼容模式" : { From 2aa5e66bde1e1b6c4c3a36eccb9036d513f76cdb Mon Sep 17 00:00:00 2001 From: Hao Guan <10684225+hguandl@users.noreply.github.com> Date: Fri, 7 Aug 2026 02:08:47 +0800 Subject: [PATCH 5/5] Animation --- MeoAsstMac/Views/CopilotView.swift | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/MeoAsstMac/Views/CopilotView.swift b/MeoAsstMac/Views/CopilotView.swift index fd94144f3..82497fd61 100644 --- a/MeoAsstMac/Views/CopilotView.swift +++ b/MeoAsstMac/Views/CopilotView.swift @@ -23,7 +23,7 @@ struct CopilotView: View { } } .task(id: url) { updateCopilot() } - .animation(.default, value: viewModel.copilot) + .animation(.default, value: formation) } else { Text("文件格式错误") } @@ -41,6 +41,15 @@ struct CopilotView: View { private var copilot: MAACopilot? { MAACopilot(url: url) } + + private var formation: Bool { + switch viewModel.copilot { + case .regular(let innerConfig): + innerConfig.formation + default: + false + } + } } // MARK: - Copilot Config @@ -67,7 +76,6 @@ private struct CopilotConfigView: View { case .none: EmptyView() } - } } @@ -100,6 +108,7 @@ private struct RegularCopilotConfigView: View { .frame(maxWidth: 150) } } + .animation(.default, value: config.support_unit_usage) } } } @@ -114,7 +123,6 @@ private struct SSSCopilotConfigView: View { TextField("1", value: $config.loop_times, format: .number) } .frame(maxWidth: 130) - } }