diff --git a/MAA.sln.DotSettings b/MAA.sln.DotSettings index 55b742bd52..bed4fe8374 100644 --- a/MAA.sln.DotSettings +++ b/MAA.sln.DotSettings @@ -153,6 +153,7 @@ True True True + True True True True diff --git a/src/MaaWpfGui/Helper/WinAdapter.cs b/src/MaaWpfGui/Helper/WinAdapter.cs index 3ac0de0f8c..dbe139c6a5 100644 --- a/src/MaaWpfGui/Helper/WinAdapter.cs +++ b/src/MaaWpfGui/Helper/WinAdapter.cs @@ -27,38 +27,36 @@ namespace MaaWpfGui.Helper { private static readonly ILogger _logger = Log.ForContext(); - private static readonly Dictionary _emulatorIdDict = new Dictionary + private static readonly Dictionary _emulatorIdDict = new() { - { "HD-Player", "BlueStacks" }, + { "HD-Player", "BlueStacks" }, { "dnplayer", "LDPlayer" }, { "Nox", "Nox" }, { "MuMuPlayer", "MuMuEmulator12" }, // MuMu 12 { "MEmu", "XYAZ" }, }; - private static readonly Dictionary> _adbRelativePathDict = new Dictionary> + private static readonly Dictionary> _adbRelativePathDict = new() { { - "BlueStacks", new List - { + "BlueStacks", [ @".\HD-Adb.exe", - @".\Engine\ProgramFiles\HD-Adb.exe", - } + @".\Engine\ProgramFiles\HD-Adb.exe" + ] }, - { "LDPlayer", new List { @".\adb.exe" } }, - { "Nox", new List { @".\nox_adb.exe" } }, + { "LDPlayer", [@".\adb.exe"] }, + { "Nox", [@".\nox_adb.exe"] }, { - "MuMuEmulator12", new List - { + "MuMuEmulator12", [ @"..\vmonitor\bin\adb_server.exe", @"..\..\MuMu\emulator\nemu\vmonitor\bin\adb_server.exe", - @".\adb.exe", - } + @".\adb.exe" + ] }, - { "XYAZ", new List { @".\adb.exe" } }, + { "XYAZ", [@".\adb.exe"] }, }; - private readonly Dictionary _adbAbsolutePathDict = new Dictionary(); + private readonly Dictionary _adbAbsolutePathDict = new(); /// /// Refreshes emulator information. @@ -70,12 +68,11 @@ namespace MaaWpfGui.Helper var emulators = new List(); foreach (var process in allProcess) { - if (!_emulatorIdDict.ContainsKey(process.ProcessName)) + if (!_emulatorIdDict.TryGetValue(process.ProcessName, out var emulatorId)) { continue; } - var emulatorId = _emulatorIdDict[process.ProcessName]; emulators.Add(emulatorId); var processPath = process.MainModule?.FileName; foreach (string adbPath in _adbRelativePathDict[emulatorId] @@ -96,9 +93,7 @@ namespace MaaWpfGui.Helper /// The ADB path of the emulator. public string GetAdbPathByEmulatorName(string emulatorName) { - return _adbAbsolutePathDict.Keys.Contains(emulatorName) - ? _adbAbsolutePathDict[emulatorName] - : null; + return _adbAbsolutePathDict.GetValueOrDefault(emulatorName); } /// @@ -106,29 +101,49 @@ namespace MaaWpfGui.Helper /// /// The ADB path. /// The list of ADB addresses. - public List GetAdbAddresses(string adbPath) + public static List GetAdbAddresses(string adbPath) + { + string output = ExecuteAdbCommand(adbPath, "devices"); + var lines = output.Split('\r', '\n'); + return lines + .Where(line => !line.StartsWith("List of devices attached") && + !string.IsNullOrWhiteSpace(line) && + line.Contains("device")) + .Select(line => line.Split('\t')[0]) + .ToList(); + } + + /// + /// Executes an ADB command. + /// + /// adb path + /// adb command + /// output + public static string ExecuteAdbCommand(string adbPath, string command) { try { - using Process process = new Process(); - process.StartInfo.FileName = adbPath; - process.StartInfo.Arguments = "devices"; + var process = new Process + { + StartInfo = new() + { + FileName = adbPath, + Arguments = command, + RedirectStandardOutput = true, + UseShellExecute = false, + CreateNoWindow = true, + }, + }; - // 禁用操作系统外壳程序 - process.StartInfo.UseShellExecute = false; - process.StartInfo.CreateNoWindow = true; - process.StartInfo.RedirectStandardOutput = true; process.Start(); - var output = process.StandardOutput.ReadToEnd(); - _logger.Information(adbPath + " devices | output:\n" + output); - var outLines = output.Split('\r', '\n'); - - return (from line in outLines where !line.StartsWith("List of devices attached") && line.Length != 0 && line.Contains("device") select line.Split('\t')[0]).ToList(); + string output = process.StandardOutput.ReadToEnd(); + process.WaitForExit(); + return output; } catch (Exception e) { _logger.Error(e.Message); - return new List(); + return string.Empty; } } } diff --git a/src/MaaWpfGui/Main/AsstProxy.cs b/src/MaaWpfGui/Main/AsstProxy.cs index e01c546f1b..bb23f5e44a 100644 --- a/src/MaaWpfGui/Main/AsstProxy.cs +++ b/src/MaaWpfGui/Main/AsstProxy.cs @@ -1796,46 +1796,45 @@ namespace MaaWpfGui.Main private static readonly bool _forcedReloadResource = File.Exists("DEBUG") || File.Exists("DEBUG.txt"); /// - /// 检查端口是否有效。 + /// 使用 TCP 或 adb devices 命令检查连接。TCP 检测相比 adb devices 更快,但不支持实体机。 /// - /// 连接地址。 - /// 是否有效。 - private static bool IfPortEstablished(string? address) + /// adb path,用于实体机检测 + /// 连接地址 + /// 设备是否在线 + private static bool CheckConnection(string adbPath, string? address) { - if (string.IsNullOrEmpty(address) || (!address.Contains(':') && !address.Contains('-'))) + if (string.IsNullOrEmpty(address)) { return false; } + // 实体机可能设备名 -> [host] + if (!address.Contains(':') && !address.Contains('-')) + { + return WinAdapter.GetAdbAddresses(adbPath).Contains(address); + } + // normal -> [host]:[port] // LdPlayer -> emulator-[port] - string[] hostAndPort = address.Split([':', '-']); - if (hostAndPort.Length != 2) + string[] hostAndPort = address.Split([':', '-'], StringSplitOptions.RemoveEmptyEntries); + + if (hostAndPort.Length != 2 || !int.TryParse(hostAndPort[1], out var port)) { return false; } - string host; - if (!int.TryParse(hostAndPort[1], out var port)) - { - return false; - } - - if (hostAndPort[0].StartsWith("emulator")) + string host = hostAndPort[0]; + if (host.StartsWith("emulator")) { host = "127.0.0.1"; port += 1; } - else - { - host = hostAndPort[0]; - } using var client = new TcpClient(); try { IAsyncResult result = client.BeginConnect(host, port, null, null); - bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(.5)); + bool success = result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(0.5)); if (success) { @@ -1846,7 +1845,7 @@ namespace MaaWpfGui.Main client.Close(); return false; } - catch (Exception) + catch { return false; } @@ -1880,7 +1879,7 @@ namespace MaaWpfGui.Main if (Connected && _connectedAdb == SettingsViewModel.ConnectSettings.AdbPath && _connectedAddress == SettingsViewModel.ConnectSettings.ConnectAddress) { - var actualConnectionStatus = IfPortEstablished(SettingsViewModel.ConnectSettings.ConnectAddress); + var actualConnectionStatus = CheckConnection(_connectedAdb, _connectedAddress); if (!actualConnectionStatus) { Connected = false; @@ -1951,21 +1950,11 @@ namespace MaaWpfGui.Main private static bool AutoDetectConnection(ref string error) { - // 本地设备如果选了自动检测,还是重新检测一下,不然重新插拔地址变了之后就再也不会检测了 - /* - // tcp连接测试端口是否有效,超时时间500ms - // 如果是本地设备,没有冒号 - bool adbResult = !string.IsNullOrEmpty(Instances.SettingsViewModel.AdbPath) && - ((!Instances.SettingsViewModel.ConnectAddress.Contains(':') && - !string.IsNullOrEmpty(Instances.SettingsViewModel.ConnectAddress)) || - IfPortEstablished(Instances.SettingsViewModel.ConnectAddress)); - */ - var adbPath = SettingsViewModel.ConnectSettings.AdbPath; bool adbResult = !string.IsNullOrEmpty(adbPath) && File.Exists(adbPath) && Path.GetFileName(adbPath).Contains("adb", StringComparison.InvariantCultureIgnoreCase) && - IfPortEstablished(SettingsViewModel.ConnectSettings.ConnectAddress); + CheckConnection(adbPath, SettingsViewModel.ConnectSettings.ConnectAddress); if (adbResult) { @@ -1976,7 +1965,7 @@ namespace MaaWpfGui.Main // 蓝叠的特殊处理 { string bsHvAddress = SettingsViewModel.ConnectSettings.TryToSetBlueStacksHyperVAddress() ?? string.Empty; - bool bsResult = IfPortEstablished(bsHvAddress); + bool bsResult = CheckConnection(adbPath, bsHvAddress); if (bsResult) { error = string.Empty; diff --git a/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs b/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs index 396082b707..889a7d5b04 100644 --- a/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs +++ b/src/MaaWpfGui/ViewModels/UserControl/Settings/ConnectSettingsUserControlModel.cs @@ -708,7 +708,7 @@ public class ConnectSettingsUserControlModel : PropertyChangedBase return false; } - var addresses = adapter.GetAdbAddresses(AdbPath); + var addresses = WinAdapter.GetAdbAddresses(AdbPath); switch (addresses.Count) {