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)
{