diff --git a/MAA.sln.DotSettings b/MAA.sln.DotSettings index 3cc5f38486..79bc4484f9 100644 --- a/MAA.sln.DotSettings +++ b/MAA.sln.DotSettings @@ -33,6 +33,7 @@ True True True + True True True True @@ -42,6 +43,7 @@ True True True + True True True True @@ -54,6 +56,7 @@ True True True + True True True True @@ -62,11 +65,13 @@ True True + True True True True True True + True True True True @@ -89,11 +94,17 @@ True True True + True + True True + True True + True True True + True True True + True True True diff --git a/src/MaaWpfGui/Main/AsstProxy.cs b/src/MaaWpfGui/Main/AsstProxy.cs index 271dd8894c..49cebe27e4 100644 --- a/src/MaaWpfGui/Main/AsstProxy.cs +++ b/src/MaaWpfGui/Main/AsstProxy.cs @@ -14,6 +14,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net.Sockets; @@ -69,7 +70,7 @@ namespace MaaWpfGui.Main var buf = new byte[len + 1]; fixed (byte* ptr = buf) { - enc.Convert(c, s.Length, ptr, len, true, out _, out _, out var completed); + enc.Convert(c, s.Length, ptr, len, true, out _, out _, out _); } return buf; @@ -90,9 +91,6 @@ namespace MaaWpfGui.Main } } - [DllImport("MaaCore.dll")] - private static extern AsstHandle AsstCreate(); - [DllImport("MaaCore.dll")] private static extern AsstHandle AsstCreateEx(CallbackDelegate callback, IntPtr customArg); @@ -159,6 +157,8 @@ namespace MaaWpfGui.Main [DllImport("MaaCore.dll")] private static extern bool AsstStop(AsstHandle handle); + // 现在拆分了 core 和 UI 的日志,所以这个函数暂时没用到 + /* [DllImport("MaaCore.dll")] private static extern unsafe void AsstLog(byte* level, byte* message); @@ -174,17 +174,18 @@ namespace MaaWpfGui.Main AsstLog(ptr1, ptr2); } } + */ [DllImport("MaaCore.dll")] private static extern unsafe ulong AsstGetImage(AsstHandle handle, byte* buff, ulong buffSize); [DllImport("MaaCore.dll")] - private static extern unsafe ulong AsstGetNullSize(); + private static extern ulong AsstGetNullSize(); public static unsafe BitmapImage AsstGetImage(AsstHandle handle) { byte[] buff = new byte[1280 * 720 * 3]; - ulong readSize = 0; + ulong readSize; fixed (byte* ptr = buff) { readSize = AsstGetImage(handle, ptr, (ulong)buff.Length); @@ -247,15 +248,15 @@ namespace MaaWpfGui.Main string clientType = Instances.SettingsViewModel.ClientType; string mainRes = Directory.GetCurrentDirectory(); - string globalResource = mainRes + "\\resource\\global\\" + clientType; - string mainCache = Directory.GetCurrentDirectory() + "\\cache"; - string globalCache = mainCache + "\\resource\\global\\" + clientType; + string globalResource = mainRes + @"\resource\global\" + clientType; + string mainCache = Directory.GetCurrentDirectory() + @"\cache"; + string globalCache = mainCache + @"\resource\global\" + clientType; - string officialClientType = "Official"; - string bilibiliClientType = "Bilibili"; + const string OfficialClientType = "Official"; + const string BilibiliClientType = "Bilibili"; bool loaded; - if (clientType == string.Empty || clientType == officialClientType || clientType == bilibiliClientType) + if (clientType == string.Empty || clientType == OfficialClientType || clientType == BilibiliClientType) { // Read resources first, then read cache loaded = LoadResIfExists(mainRes); @@ -308,6 +309,7 @@ namespace MaaWpfGui.Main this.AsstSetInstanceOption(InstanceOptionKey.DeploymentWithPause, Instances.SettingsViewModel.DeploymentWithPause ? "1" : "0"); this.AsstSetInstanceOption(InstanceOptionKey.AdbLiteEnabled, Instances.SettingsViewModel.AdbLiteEnabled ? "1" : "0"); // TODO: 之后把这个 OnUIThread 拆出来 + // ReSharper disable once AsyncVoidLambda Execute.OnUIThread(async () => { if (Instances.SettingsViewModel.RunDirectly) @@ -418,13 +420,7 @@ namespace MaaWpfGui.Main } } - private bool _connected = false; - - public bool Connected - { - get => _connected; - set => _connected = value; - } + public bool Connected { get; set; } private string _connectedAdb; private string _connectedAddress; @@ -435,19 +431,19 @@ namespace MaaWpfGui.Main switch (what) { case "Connected": - _connected = true; - _connectedAdb = details["details"]["adb"].ToString(); - _connectedAddress = details["details"]["address"].ToString(); + Connected = true; + _connectedAdb = details["details"]?["adb"]?.ToString(); + _connectedAddress = details["details"]?["address"]?.ToString(); Instances.SettingsViewModel.ConnectAddress = _connectedAddress; break; case "UnsupportedResolution": - _connected = false; + Connected = false; Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ResolutionNotSupported"), UiLogColor.Error); break; case "ResolutionError": - _connected = false; + Connected = false; Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ResolutionAcquisitionFailure"), UiLogColor.Error); break; @@ -460,7 +456,7 @@ namespace MaaWpfGui.Main break; case "Disconnect": - _connected = false; + Connected = false; Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ReconnectFailed"), UiLogColor.Error); if (_runningState.GetIdle()) { @@ -473,6 +469,7 @@ namespace MaaWpfGui.Main } // TODO: 之后把这个 OnUIThread 拆出来 + // ReSharper disable once AsyncVoidLambda Execute.OnUIThread(async () => { if (!Instances.SettingsViewModel.RetryOnDisconnected) @@ -519,13 +516,13 @@ namespace MaaWpfGui.Main } } - bool isCoplitTaskChain = taskChain == "Copilot" || taskChain == "VideoRecognition"; + bool isCopilotTaskChain = taskChain == "Copilot" || taskChain == "VideoRecognition"; switch (msg) { case AsstMsg.TaskChainStopped: Instances.TaskQueueViewModel.SetStopped(); - if (isCoplitTaskChain) + if (isCopilotTaskChain) { _runningState.SetIdle(true); } @@ -537,7 +534,7 @@ namespace MaaWpfGui.Main Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("TaskError") + taskChain, UiLogColor.Error); using var toast = new ToastNotification(LocalizationHelper.GetString("TaskError") + taskChain); toast.Show(); - if (isCoplitTaskChain) + if (isCopilotTaskChain) { // 如果启用战斗列表,需要中止掉剩余的任务 if (Instances.CopilotViewModel.UseCopilotList) @@ -597,7 +594,7 @@ namespace MaaWpfGui.Main Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("CompleteTask") + taskChain); } - if (isCoplitTaskChain) + if (isCopilotTaskChain) { if (!Instances.CopilotViewModel.UseCopilotList || Instances.CopilotViewModel.CopilotItemViewModels.All(model => !model.IsChecked)) { @@ -689,6 +686,24 @@ namespace MaaWpfGui.Main } break; + case AsstMsg.InternalError: + break; + case AsstMsg.InitFailed: + break; + case AsstMsg.ConnectionInfo: + break; + case AsstMsg.SubTaskError: + break; + case AsstMsg.SubTaskStart: + break; + case AsstMsg.SubTaskCompleted: + break; + case AsstMsg.SubTaskExtraInfo: + break; + case AsstMsg.SubTaskStopped: + break; + default: + throw new ArgumentOutOfRangeException(nameof(msg), msg, null); } } @@ -755,138 +770,145 @@ namespace MaaWpfGui.Main { string subTask = details["subtask"].ToString(); - if (subTask == "ProcessTask") + switch (subTask) { - string taskName = details["details"]["task"].ToString(); - int execTimes = (int)details["details"]["exec_times"]; - - switch (taskName) + case "ProcessTask": { - case "StartButton2": - case "AnnihilationConfirm": - var log = LocalizationHelper.GetString("MissionStart") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"); - if (SanityReport.HasSanityReport) - { - log += "\n" + LocalizationHelper.GetString("CurrentSanity") + $" {SanityReport.Sanity[0]}/{SanityReport.Sanity[1]}"; - } + string taskName = details["details"]?["task"]?.ToString(); + int execTimes = (int)details["details"]["exec_times"]; - Instances.TaskQueueViewModel.AddLog(log, UiLogColor.Info); - break; + switch (taskName) + { + case "StartButton2": + case "AnnihilationConfirm": + var log = LocalizationHelper.GetString("MissionStart") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"); + if (SanityReport.HasSanityReport) + { + log += "\n" + LocalizationHelper.GetString("CurrentSanity") + $" {SanityReport.Sanity[0]}/{SanityReport.Sanity[1]}"; + } - case "MedicineConfirm": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("MedicineUsed") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); - break; + Instances.TaskQueueViewModel.AddLog(log, UiLogColor.Info); + break; - case "StoneConfirm": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("StoneUsed") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); - break; + case "MedicineConfirm": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("MedicineUsed") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); + break; - case "AbandonAction": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ActingCommandError"), UiLogColor.Error); - break; + case "StoneConfirm": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("StoneUsed") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); + break; - case "RecruitRefreshConfirm": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("LabelsRefreshed"), UiLogColor.Info); - break; + case "AbandonAction": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ActingCommandError"), UiLogColor.Error); + break; - case "RecruitConfirm": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RecruitConfirm"), UiLogColor.Info); - break; + case "RecruitRefreshConfirm": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("LabelsRefreshed"), UiLogColor.Info); + break; - case "InfrastDormDoubleConfirmButton": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("InfrastDormDoubleConfirmed"), UiLogColor.Error); - break; + case "RecruitConfirm": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RecruitConfirm"), UiLogColor.Info); + break; - /* 肉鸽相关 */ - case "StartExplore": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("BegunToExplore") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); - break; + case "InfrastDormDoubleConfirmButton": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("InfrastDormDoubleConfirmed"), UiLogColor.Error); + break; - case "StageTraderInvestConfirm": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("HasInvested") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); - break; + /* 肉鸽相关 */ + case "StartExplore": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("BegunToExplore") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); + break; - case "ExitThenAbandon": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ExplorationAbandoned")); - break; + case "StageTraderInvestConfirm": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("HasInvested") + $" {execTimes} " + LocalizationHelper.GetString("UnitTime"), UiLogColor.Info); + break; - // case "StartAction": - // Instances.TaskQueueViewModel.AddLog("开始战斗"); - // break; - case "MissionCompletedFlag": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("FightCompleted")); - break; + case "ExitThenAbandon": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("ExplorationAbandoned")); + break; - case "MissionFailedFlag": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("FightFailed")); - break; + // case "StartAction": + // Instances.TaskQueueViewModel.AddLog("开始战斗"); + // break; + case "MissionCompletedFlag": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("FightCompleted")); + break; - case "StageTraderEnter": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("Trader")); - break; + case "MissionFailedFlag": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("FightFailed")); + break; - case "StageSafeHouseEnter": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("SafeHouse")); - break; + case "StageTraderEnter": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("Trader")); + break; - case "StageEncounterEnter": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("Encounter")); - break; + case "StageSafeHouseEnter": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("SafeHouse")); + break; - // case "StageBoonsEnter": - // Instances.TaskQueueViewModel.AddLog("古堡馈赠"); - // break; - case "StageCombatDpsEnter": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("CombatDps")); - break; + case "StageEncounterEnter": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("Encounter")); + break; - case "StageEmergencyDps": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("EmergencyDps")); - break; + // case "StageBoonsEnter": + // Instances.TaskQueueViewModel.AddLog("古堡馈赠"); + // break; + case "StageCombatDpsEnter": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("CombatDps")); + break; - case "StageDreadfulFoe": - case "StageDreadfulFoe-5Enter": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("DreadfulFoe")); - break; + case "StageEmergencyDps": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("EmergencyDps")); + break; - case "StageTraderInvestSystemFull": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("UpperLimit"), UiLogColor.Info); - break; + case "StageDreadfulFoe": + case "StageDreadfulFoe-5Enter": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("DreadfulFoe")); + break; - case "OfflineConfirm": - if (Instances.SettingsViewModel.AutoRestartOnDrop) - { - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("GameDrop"), UiLogColor.Warning); - } - else - { - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("GameDropNoRestart"), UiLogColor.Warning); - using var toast = new ToastNotification(LocalizationHelper.GetString("GameDropNoRestart")); - toast.Show(); - _ = Instances.TaskQueueViewModel.Stop(); - } + case "StageTraderInvestSystemFull": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("UpperLimit"), UiLogColor.Info); + break; - break; + case "OfflineConfirm": + if (Instances.SettingsViewModel.AutoRestartOnDrop) + { + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("GameDrop"), UiLogColor.Warning); + } + else + { + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("GameDropNoRestart"), UiLogColor.Warning); + using var toast = new ToastNotification(LocalizationHelper.GetString("GameDropNoRestart")); + toast.Show(); + _ = Instances.TaskQueueViewModel.Stop(); + } - case "GamePass": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoguelikeGamePass"), UiLogColor.RareOperator); - break; + break; - case "BattleStartAll": - Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("MissionStart"), UiLogColor.Info); - break; + case "GamePass": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoguelikeGamePass"), UiLogColor.RareOperator); + break; - case "StageTraderSpecialShoppingAfterRefresh": - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoguelikeSpecialItemBought"), UiLogColor.RareOperator); - break; + case "BattleStartAll": + Instances.CopilotViewModel.AddLog(LocalizationHelper.GetString("MissionStart"), UiLogColor.Info); + break; + + case "StageTraderSpecialShoppingAfterRefresh": + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoguelikeSpecialItemBought"), UiLogColor.RareOperator); + break; + } + + break; } - } - else if (subTask == "CombatRecordRecognitionTask") - { - string what = details["what"]?.ToString(); - if (!string.IsNullOrEmpty(what)) + case "CombatRecordRecognitionTask": { - Instances.CopilotViewModel.AddLog(what); + string what = details["what"]?.ToString(); + if (!string.IsNullOrEmpty(what)) + { + Instances.CopilotViewModel.AddLog(what); + } + + break; } } } @@ -901,24 +923,25 @@ namespace MaaWpfGui.Main { string taskChain = details["taskchain"].ToString(); - if (taskChain == "Recruit") + switch (taskChain) { - ProcRecruitCalcMsg(details); - } - else if (taskChain == "VideoRecognition") - { - ProcVideoRecMsg(details); + case "Recruit": + ProcRecruitCalcMsg(details); + break; + case "VideoRecognition": + ProcVideoRecMsg(details); + break; } var subTaskDetails = details["details"]; - if (taskChain == "Depot") + switch (taskChain) { - Instances.RecognizerViewModel.DepotParse((JObject)subTaskDetails); - } - - if (taskChain == "OperBox") - { - Instances.RecognizerViewModel.OperBoxParse((JObject)subTaskDetails); + case "Depot": + Instances.RecognizerViewModel.DepotParse((JObject)subTaskDetails); + break; + case "OperBox": + Instances.RecognizerViewModel.OperBoxParse((JObject)subTaskDetails); + break; } string what = details["what"].ToString(); @@ -928,10 +951,10 @@ namespace MaaWpfGui.Main case "StageDrops": { string allDrops = string.Empty; - JArray statistics = (JArray)subTaskDetails["stats"]; + JArray statistics = (JArray)subTaskDetails["stats"] ?? new JArray(); foreach (var item in statistics) { - string itemName = item["itemName"].ToString(); + string itemName = item["itemName"]?.ToString(); int totalQuantity = (int)item["quantity"]; int addQuantity = (int)item["addQuantity"]; allDrops += $"{itemName} : {totalQuantity}"; @@ -967,13 +990,9 @@ namespace MaaWpfGui.Main case "RecruitTagsDetected": { - JArray tags = (JArray)subTaskDetails["tags"]; - string logContent = string.Empty; - foreach (var tagName in tags) - { - string tagStr = tagName.ToString(); - logContent += tagStr + "\n"; - } + JArray tags = (JArray)subTaskDetails["tags"] ?? new JArray(); + string logContent = tags.Select(tagName => tagName.ToString()) + .Aggregate(string.Empty, (current, tagStr) => current + (tagStr + "\n")); logContent = logContent.EndsWith("\n") ? logContent.TrimEnd('\n') : LocalizationHelper.GetString("Error"); Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RecruitingResults") + "\n" + logContent); @@ -983,7 +1002,7 @@ namespace MaaWpfGui.Main case "RecruitSpecialTag": { - string special = subTaskDetails["tag"].ToString(); + string special = subTaskDetails["tag"]?.ToString(); if (special == "支援机械" && Instances.SettingsViewModel.NotChooseLevel1 == false) { break; @@ -997,7 +1016,7 @@ namespace MaaWpfGui.Main case "RecruitRobotTag": { - string special = subTaskDetails["tag"].ToString(); + string special = subTaskDetails["tag"]?.ToString(); using var toast = new ToastNotification(LocalizationHelper.GetString("RecruitingTips")); toast.AppendContentText(special).ShowRecruitRobot(); } @@ -1039,12 +1058,8 @@ namespace MaaWpfGui.Main case "RecruitTagsSelected": { - JArray selected = (JArray)subTaskDetails["tags"]; - string selectedLog = string.Empty; - foreach (var tag in selected) - { - selectedLog += tag + "\n"; - } + JArray selected = (JArray)subTaskDetails["tags"] ?? new JArray(); + string selectedLog = selected.Aggregate(string.Empty, (current, tag) => current + (tag + "\n")); selectedLog = selectedLog.EndsWith("\n") ? selectedLog.TrimEnd('\n') : LocalizationHelper.GetString("NoDrop"); @@ -1092,7 +1107,7 @@ namespace MaaWpfGui.Main case "PenguinId": { - string id = subTaskDetails["id"].ToString(); + string id = subTaskDetails["id"]?.ToString(); Instances.SettingsViewModel.PenguinId = id; } @@ -1108,17 +1123,17 @@ namespace MaaWpfGui.Main case "CopilotAction": { - string doc = subTaskDetails["doc"].ToString(); - if (doc.Length != 0) + string doc = subTaskDetails["doc"]?.ToString(); + if (doc?.Length != 0) { - string color = subTaskDetails["doc_color"].ToString(); - Instances.CopilotViewModel.AddLog(doc, color.Length == 0 ? UiLogColor.Message : color); + string color = subTaskDetails["doc_color"]?.ToString(); + Instances.CopilotViewModel.AddLog(doc, color?.Length == 0 ? UiLogColor.Message : color); } Instances.CopilotViewModel.AddLog( string.Format(LocalizationHelper.GetString("CurrentSteps"), - subTaskDetails["action"].ToString(), - subTaskDetails["target"].ToString())); + subTaskDetails["action"], + subTaskDetails["target"])); } break; @@ -1131,7 +1146,7 @@ namespace MaaWpfGui.Main case "SSSStage": { - Instances.CopilotViewModel.AddLog("CurrentStage: " + subTaskDetails["stage"].ToString(), UiLogColor.Info); + Instances.CopilotViewModel.AddLog("CurrentStage: " + subTaskDetails["stage"], UiLogColor.Info); } break; @@ -1170,18 +1185,15 @@ namespace MaaWpfGui.Main break; case "CustomInfrastRoomOperators": - string nameStr = string.Empty; - foreach (var name in subTaskDetails["names"]) - { - nameStr += name.ToString() + ", "; - } + string nameStr = (subTaskDetails["names"] ?? new JArray()) + .Aggregate(string.Empty, (current, name) => current + name + ", "); if (nameStr != string.Empty) { nameStr = nameStr.Remove(nameStr.Length - 2); } - Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoomOperators") + nameStr.ToString()); + Instances.TaskQueueViewModel.AddLog(LocalizationHelper.GetString("RoomOperators") + nameStr); break; /* 生息演算 */ @@ -1249,18 +1261,18 @@ namespace MaaWpfGui.Main Instances.RecognizerViewModel.ProcRecruitMsg(details); } - private void ProcVideoRecMsg(JObject details) + private static void ProcVideoRecMsg(JObject details) { string what = details["what"].ToString(); switch (what) { case "Finished": - var filename = details["details"]["filename"].ToString(); + var filename = details["details"]?["filename"]; Instances.CopilotViewModel.AddLog("Save to: " + filename, UiLogColor.Info); // string p = @"C:\tmp\this path contains spaces, and,commas\target.txt"; - string args = string.Format("/e, /select, \"{0}\"", filename); + string args = $"/e, /select, \"{filename}\""; ProcessStartInfo info = new ProcessStartInfo { @@ -1292,14 +1304,14 @@ namespace MaaWpfGui.Main } // normal -> [host]:[port] - string[] host_and_port = address.Split(':'); - if (host_and_port.Length != 2) + string[] hostAndPort = address.Split(':'); + if (hostAndPort.Length != 2) { return false; } - string host = host_and_port[0].Equals("emulator") ? "127.0.0.1" : host_and_port[0]; - if (!int.TryParse(host_and_port[1], out int port)) + string host = hostAndPort[0].Equals("emulator") ? "127.0.0.1" : hostAndPort[0]; + if (!int.TryParse(hostAndPort[1], out int port)) { return false; } @@ -1371,7 +1383,7 @@ namespace MaaWpfGui.Main } } - if (_connected && _connectedAdb == Instances.SettingsViewModel.AdbPath && + if (Connected && _connectedAdb == Instances.SettingsViewModel.AdbPath && _connectedAddress == Instances.SettingsViewModel.ConnectAddress) { _logger.Information($"Already connected to {_connectedAdb} {_connectedAddress}"); @@ -1449,6 +1461,7 @@ namespace MaaWpfGui.Main return AsstSetTaskParams(_handle, id, JsonConvert.SerializeObject(taskParams)); } + [SuppressMessage("ReSharper", "UnusedMember.Local")] private enum TaskType { StartUp, @@ -1686,12 +1699,12 @@ namespace MaaWpfGui.Main return id != 0; } - private JObject SerializeInfrastTaskParams(string[] order, string usesOfDrones, double dormThreshold, bool dormFilterNotStationedEnabled, bool dormDormTrustEnabled, bool originiumShardAutoReplenishment, + private static JObject SerializeInfrastTaskParams(IEnumerable order, string usesOfDrones, double dormThreshold, bool dormFilterNotStationedEnabled, bool dormDormTrustEnabled, bool originiumShardAutoReplenishment, bool isCustom, string filename, int planIndex) { var taskParams = new JObject { - ["facility"] = new JArray(order), + ["facility"] = new JArray(order.ToArray()), ["drones"] = usesOfDrones, ["threshold"] = dormThreshold, ["dorm_notstationed_enabled"] = dormFilterNotStationedEnabled, @@ -2028,6 +2041,7 @@ namespace MaaWpfGui.Main /// /// MaaCore 消息。 /// + [SuppressMessage("ReSharper", "UnusedMember.Global")] public enum AsstMsg { /* Global Info */ diff --git a/src/MaaWpfGui/Models/ResourceUpdater.cs b/src/MaaWpfGui/Models/ResourceUpdater.cs index 814c0712e1..fd7c371971 100644 --- a/src/MaaWpfGui/Models/ResourceUpdater.cs +++ b/src/MaaWpfGui/Models/ResourceUpdater.cs @@ -113,36 +113,41 @@ namespace MaaWpfGui.Models var ret = UpdateResult.NotModified; var context = File.ReadAllText(Path.Combine(Environment.CurrentDirectory, MaaDynamicFilesIndex)); - context.Split('\n').ToList().ForEach(Action); + // ReSharper disable once AsyncVoidLambda + context.Split('\n').ToList().ForEach(async (file) => + { + try + { + if (string.IsNullOrEmpty(file)) + { + return; + } + + // 这里有几千个文件,请求量太大了,且这些文件一般只新增,不修改。 + // 所以如果本地已经存在这些文件,就不再请求了。 + if (File.Exists(Path.Combine(Environment.CurrentDirectory, file))) + { + return; + } + + var sRet = await UpdateFileWithETag(MaaUrls.MaaResourceApi, file, file); + if (sRet == UpdateResult.Failed) + { + ret = UpdateResult.Failed; + } + + if (ret == UpdateResult.NotModified && sRet == UpdateResult.Success) + { + ret = UpdateResult.Success; + } + } + catch (Exception) + { + // ignore + } + }); return ret; - - // lambda 避免使用异步,任何未被 lambda 处理的异常都可能导致进程崩溃 - async void Action(string file) - { - if (string.IsNullOrEmpty(file)) - { - return; - } - - // 这里有几千个文件,请求量太大了,且这些文件一般只新增,不修改。 - // 所以如果本地已经存在这些文件,就不再请求了。 - if (File.Exists(Path.Combine(Environment.CurrentDirectory, file))) - { - return; - } - - var sRet = await UpdateFileWithETag(MaaUrls.MaaResourceApi, file, file); - if (sRet == UpdateResult.Failed) - { - ret = UpdateResult.Failed; - } - - if (ret == UpdateResult.NotModified && sRet == UpdateResult.Success) - { - ret = UpdateResult.Success; - } - } } private static bool _updating; diff --git a/src/MaaWpfGui/Services/HotKeys/MaaHotKeyManager.cs b/src/MaaWpfGui/Services/HotKeys/MaaHotKeyManager.cs index 4d5a1143fc..063ef2b477 100644 --- a/src/MaaWpfGui/Services/HotKeys/MaaHotKeyManager.cs +++ b/src/MaaWpfGui/Services/HotKeys/MaaHotKeyManager.cs @@ -84,7 +84,7 @@ namespace MaaWpfGui.Services.HotKeys } } - protected void InternalUnRegister(MaaHotKeyAction action) + private void InternalUnRegister(MaaHotKeyAction action) { if (!_actionHotKeyMapping.ContainsKey(action) || _actionHotKeyMapping[action] == null) { diff --git a/src/MaaWpfGui/Services/TrayIcon.cs b/src/MaaWpfGui/Services/TrayIcon.cs index c9fa99832c..bfb145f368 100644 --- a/src/MaaWpfGui/Services/TrayIcon.cs +++ b/src/MaaWpfGui/Services/TrayIcon.cs @@ -110,11 +110,6 @@ namespace MaaWpfGui.Services System.Windows.Application.Current.MainWindow?.Close(); } - private void AppShow(object sender, EventArgs e) - { - Instances.MainWindowManager.Show(); - } - private static void OnNotifyIconDoubleClick(object sender, EventArgs e) { Instances.MainWindowManager.Show(); diff --git a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs index be9cff9f88..75c8f6db63 100644 --- a/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/SettingsViewModel.cs @@ -78,13 +78,6 @@ namespace MaaWpfGui.ViewModels.UI /// public string VersionId => _versionId; - private static readonly string _versionInfo = LocalizationHelper.GetString("Version") + ": " + _versionId; - - /// - /// Gets the version info. - /// - public string VersionInfo => _versionInfo; - /// /// The Pallas language key. /// @@ -122,7 +115,6 @@ namespace MaaWpfGui.ViewModels.UI MessageBoxHelper.Show( LocalizationHelper.GetString("Hangover"), LocalizationHelper.GetString("Burping"), - MessageBoxButton.OK, iconKey: "HangoverGeometry", iconBrushKey: "PallasBrush"); Bootstrapper.ShutdownAndRestartWithOutArgs(); @@ -317,7 +309,7 @@ namespace MaaWpfGui.ViewModels.UI private void InfrastInit() { /* 基建设置 */ - var facilityList = new string[] + var facilityList = new[] { "Mfg", "Trade", @@ -764,7 +756,9 @@ namespace MaaWpfGui.ViewModels.UI if (Path.GetExtension(EmulatorPath).ToLower() == ".lnk") { + // ReSharper disable once SuspiciousTypeConversion.Global var link = (IShellLink)new ShellLink(); + // ReSharper disable once SuspiciousTypeConversion.Global var file = (IPersistFile)link; file.Load(EmulatorPath, 0); // STGM_READ link.Resolve(IntPtr.Zero, 1); // SLR_NO_UI @@ -892,8 +886,10 @@ namespace MaaWpfGui.ViewModels.UI if (i % 10 == 0) { + // 避免捕获的变量在闭包中被修改 + var i1 = i; Execute.OnUIThread(() => Instances.TaskQueueViewModel.AddLog( - LocalizationHelper.GetString("WaitForEmulator") + ": " + (delay - i) + "s")); + LocalizationHelper.GetString("WaitForEmulator") + ": " + (delay - i1) + "s")); _logger.Information("Waiting for the emulator to start: " + (delay - i) + "s"); } @@ -1001,6 +997,8 @@ namespace MaaWpfGui.ViewModels.UI /// /// Selects the emulator to execute. /// + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void SelectEmulatorExec() { var dialog = new OpenFileDialog @@ -1154,6 +1152,8 @@ namespace MaaWpfGui.ViewModels.UI set => SetAndNotify(ref _newConfigurationName, value); } + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void AddConfiguration() { if (string.IsNullOrEmpty(NewConfigurationName)) @@ -1165,28 +1165,30 @@ namespace MaaWpfGui.ViewModels.UI { ConfigurationList.Add(new CombinedData { Display = NewConfigurationName, Value = NewConfigurationName }); - var growinfo = new GrowlInfo + var growlInfo = new GrowlInfo { IsCustom = true, Message = string.Format(LocalizationHelper.GetString("AddConfigSuccess"), NewConfigurationName), IconKey = "HangoverGeometry", IconBrushKey = "PallasBrush", }; - Growl.Info(growinfo); + Growl.Info(growlInfo); } else { - var growinfo = new GrowlInfo + var growlInfo = new GrowlInfo { IsCustom = true, Message = string.Format(LocalizationHelper.GetString("ConfigExists"), NewConfigurationName), IconKey = "HangoverGeometry", IconBrushKey = "PallasBrush", }; - Growl.Info(growinfo); + Growl.Info(growlInfo); } } + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void DeleteConfiguration(CombinedData delete) { if (ConfigurationHelper.DeleteConfiguration(delete.Display)) @@ -1405,6 +1407,8 @@ namespace MaaWpfGui.ViewModels.UI /// /// Selects infrast config file. /// + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void SelectCustomInfrastFile() { var dialog = new OpenFileDialog @@ -1479,7 +1483,7 @@ namespace MaaWpfGui.ViewModels.UI /// public List DividerVerticalOffsetList { get; set; } - private int _selectedIndex = 0; + private int _selectedIndex; /// /// Gets or sets the index selected. @@ -1514,7 +1518,7 @@ namespace MaaWpfGui.ViewModels.UI } } - private double _scrollOffset = 0; + private double _scrollOffset; /// /// Gets or sets the scroll offset. @@ -1826,7 +1830,7 @@ namespace MaaWpfGui.ViewModels.UI set { SetAndNotify(ref _lastCreditFightTaskTime, value); - ConfigurationHelper.SetValue(ConfigurationKeys.LastCreditFightTaskTime, value.ToString()); + ConfigurationHelper.SetValue(ConfigurationKeys.LastCreditFightTaskTime, value); } } @@ -2060,7 +2064,7 @@ namespace MaaWpfGui.ViewModels.UI { _timerConfig = value ?? ConfigurationHelper.GetCurrentConfiguration(); OnPropertyChanged(); - ConfigurationHelper.SetTimerConfig(TimerId, _timerConfig.ToString()); + ConfigurationHelper.SetTimerConfig(TimerId, _timerConfig); } } @@ -2181,7 +2185,7 @@ namespace MaaWpfGui.ViewModels.UI } } - private bool _useExpedited = false; + private bool _useExpedited; /// /// Gets or sets a value indicating whether to use expedited. @@ -2389,7 +2393,7 @@ namespace MaaWpfGui.ViewModels.UI } } - private bool _isCheckingForUpdates = false; + private bool _isCheckingForUpdates; /// /// Gets or sets a value indicating whether the update is being checked. @@ -2486,6 +2490,8 @@ namespace MaaWpfGui.ViewModels.UI } } + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void ShowChangelog() { Instances.WindowManager.ShowWindow(Instances.VersionUpdateViewModel); @@ -2570,7 +2576,9 @@ namespace MaaWpfGui.ViewModels.UI ConnectAddressHistory = new ObservableCollection(history); } - public void RemoveAddress_Click(string address) + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global + public void RemoveAddressClick(string address) { ConnectAddressHistory.Remove(address); ConfigurationHelper.SetValue(ConfigurationKeys.AddressHistory, JsonConvert.SerializeObject(ConnectAddressHistory)); @@ -2805,6 +2813,8 @@ namespace MaaWpfGui.ViewModels.UI /// /// Selects ADB program file. /// + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void SelectFile() { var dialog = new OpenFileDialog @@ -2885,7 +2895,7 @@ namespace MaaWpfGui.ViewModels.UI private string _bluestacksKeyWord = ConfigurationHelper.GetValue(ConfigurationKeys.BluestacksConfigKeyword, string.Empty); /// - /// Tries to set Bluestack Hyper V address. + /// Tries to set BlueStack Hyper V address. /// /// success public string TryToSetBlueStacksHyperVAddress() @@ -3083,10 +3093,12 @@ namespace MaaWpfGui.ViewModels.UI /* 界面设置 */ + /* /// /// Gets a value indicating whether to use tray icon. /// public bool UseTray => true; + */ private bool _minimizeToTray = Convert.ToBoolean(ConfigurationHelper.GetValue(ConfigurationKeys.MinimizeToTray, bool.FalseString)); @@ -3395,13 +3407,15 @@ namespace MaaWpfGui.ViewModels.UI // var backup = _language; ConfigurationHelper.SetValue(ConfigurationKeys.Localization, value); - string FormatText(string text, string key) - => string.Format(text, LocalizationHelper.GetString(key, value), LocalizationHelper.GetString(key, _language)); - var mainWindow = Application.Current.MainWindow; - mainWindow.Show(); - mainWindow.WindowState = mainWindow.WindowState = WindowState.Normal; - mainWindow.Activate(); + + if (mainWindow != null) + { + mainWindow.Show(); + mainWindow.WindowState = mainWindow.WindowState = WindowState.Normal; + mainWindow.Activate(); + } + var result = MessageBoxHelper.Show( FormatText("{0}\n{1}", "LanguageChangedTip"), FormatText("{0}({1})", "Tip"), @@ -3415,6 +3429,10 @@ namespace MaaWpfGui.ViewModels.UI } SetAndNotify(ref _language, value); + return; + + string FormatText(string text, string key) + => string.Format(text, LocalizationHelper.GetString(key, value), LocalizationHelper.GetString(key, _language)); } } @@ -3469,13 +3487,12 @@ namespace MaaWpfGui.ViewModels.UI } } - private void SetPallasLanguage() + private static void SetPallasLanguage() { ConfigurationHelper.SetValue(ConfigurationKeys.Localization, PallasLangKey); var result = MessageBoxHelper.Show( LocalizationHelper.GetString("DrunkAndStaggering"), LocalizationHelper.GetString("Burping"), - MessageBoxButton.OK, iconKey: "DrunkAndStaggeringGeometry", iconBrushKey: "PallasBrush"); if (result == MessageBoxResult.OK) @@ -3487,7 +3504,7 @@ namespace MaaWpfGui.ViewModels.UI /// /// Gets or sets the hotkey: ShowGui. /// - public MaaHotKey HotKeyShowGui + public static MaaHotKey HotKeyShowGui { get => Instances.MaaHotKeyManager.GetOrNull(MaaHotKeyAction.ShowGui); set => SetHotKey(MaaHotKeyAction.ShowGui, value); @@ -3496,7 +3513,7 @@ namespace MaaWpfGui.ViewModels.UI /// /// Gets or sets the hotkey: LinkStart. /// - public MaaHotKey HotKeyLinkStart + public static MaaHotKey HotKeyLinkStart { get => Instances.MaaHotKeyManager.GetOrNull(MaaHotKeyAction.LinkStart); set => SetHotKey(MaaHotKeyAction.LinkStart, value); @@ -3674,18 +3691,24 @@ namespace MaaWpfGui.ViewModels.UI set => SetAndNotify(ref _guideTransitionMode, value); } - public void NextGuide(HandyControl.Controls.StepBar stepBar) + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global + public void NextGuide(StepBar stepBar) { GuideTransitionMode = "Bottom2Top"; stepBar.Next(); } - public void PrevGuide(HandyControl.Controls.StepBar stepBar) + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global + public void PrevGuide(StepBar stepBar) { GuideTransitionMode = "Top2Bottom"; stepBar.Prev(); } + // UI 绑定的方法 + // ReSharper disable once UnusedMember.Global public void DoneGuide() { TaskSettingVisibilities.Guide = false; diff --git a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs index b5d58f9f13..7109b2774f 100644 --- a/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs +++ b/src/MaaWpfGui/ViewModels/UI/TaskQueueViewModel.cs @@ -983,7 +983,7 @@ namespace MaaWpfGui.ViewModels.UI } } - private bool _roguelikeInCombatAndShowWait = false; + private bool _roguelikeInCombatAndShowWait; public bool RoguelikeInCombatAndShowWait { diff --git a/src/MaaWpfGui/Views/UserControl/ConnectSettingsOnWakeUpUserControl.xaml b/src/MaaWpfGui/Views/UserControl/ConnectSettingsOnWakeUpUserControl.xaml index 7a793f8c27..6227674092 100644 --- a/src/MaaWpfGui/Views/UserControl/ConnectSettingsOnWakeUpUserControl.xaml +++ b/src/MaaWpfGui/Views/UserControl/ConnectSettingsOnWakeUpUserControl.xaml @@ -14,9 +14,7 @@ d:DesignWidth="220" mc:Ignorable="d"> - + @@ -26,7 +24,7 @@ IsReadOnly="{c:Binding !Idle}" Style="{StaticResource TextBoxExtend}" Text="{Binding AccountName, UpdateSourceTrigger=PropertyChanged}" - ToolTip="{DynamicResource AccountSwitchTip}"/> + ToolTip="{DynamicResource AccountSwitchTip}" />