Implement QR pairing window and mDNS announcements; update documentation and tests
This commit is contained in:
+26
-18
@@ -2,6 +2,7 @@ using System.Net;
|
||||
using System.Net.Sockets;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using MusicBridge.Agent;
|
||||
using MusicBridge.Agent.Media;
|
||||
using MusicBridge.Agent.Network;
|
||||
using Windows.Media.Control;
|
||||
@@ -39,16 +40,9 @@ try
|
||||
using var hostStopping = server.Stopping.Register(() => shutdown.Cancel());
|
||||
var fingerprint = certificate.GetCertHashString(HashAlgorithmName.SHA256);
|
||||
var addresses = new List<string> { $"https://127.0.0.1:{port}" };
|
||||
if (lan)
|
||||
{
|
||||
try
|
||||
{
|
||||
addresses.AddRange(Dns.GetHostAddresses(Dns.GetHostName())
|
||||
.Where(ip => ip.AddressFamily == AddressFamily.InterNetwork && !IPAddress.IsLoopback(ip))
|
||||
.Select(ip => $"https://{ip}:{port}"));
|
||||
}
|
||||
catch (SocketException) { }
|
||||
}
|
||||
Uri[] qrEndpoints = [];
|
||||
using var mdns = new MdnsPublisher(fingerprint, port);
|
||||
using var qrWindow = new PairingWindowHost(pairing, fingerprint, () => Volatile.Read(ref qrEndpoints));
|
||||
var message = "Готов к управлению.";
|
||||
IReadOnlyList<TrustedDevice> displayedDevices = [];
|
||||
var nextRefresh = DateTimeOffset.MinValue;
|
||||
@@ -73,13 +67,8 @@ try
|
||||
}
|
||||
else if (key == ConsoleKey.I)
|
||||
{
|
||||
var invitationTime = DateTimeOffset.UtcNow;
|
||||
var window = pairing.Current;
|
||||
var endpoints = addresses.Select(a => new Uri(a)).Where(ConnectionInvitation.IsLocalEndpoint).ToArray();
|
||||
message = window is null ? "Сначала нажми B, чтобы открыть сопряжение."
|
||||
: endpoints.Length == 0 ? "Для данных подключения запусти агент с --lan в домашней сети."
|
||||
: string.Join(Environment.NewLine, endpoints.Select(endpoint =>
|
||||
$"Данные для будущего QR ({endpoint.Host}): {ConnectionInvitation.Create(endpoint, fingerprint, window, invitationTime).ToQrPayload()}"));
|
||||
qrWindow.Open();
|
||||
message = "Окно QR открыто. Для нового кода нажми B.";
|
||||
}
|
||||
else if (key == ConsoleKey.B)
|
||||
{
|
||||
@@ -107,6 +96,23 @@ try
|
||||
}
|
||||
if (DateTimeOffset.UtcNow >= nextRefresh)
|
||||
{
|
||||
if (lan)
|
||||
{
|
||||
try
|
||||
{
|
||||
var ips = LocalAddresses.Read();
|
||||
Volatile.Write(ref qrEndpoints, ips.Select(ip => new Uri($"https://{ip}:{port}")).ToArray());
|
||||
addresses = new List<string> { $"https://127.0.0.1:{port}" };
|
||||
addresses.AddRange(qrEndpoints.Select(u => u.GetLeftPart(UriPartial.Authority)));
|
||||
mdns.Refresh(ips);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Volatile.Write(ref qrEndpoints, []);
|
||||
mdns.Refresh([]);
|
||||
message = $"Не удалось обновить адреса: {ex.Message}";
|
||||
}
|
||||
}
|
||||
if (!Console.IsOutputRedirected) Console.Clear();
|
||||
var state = server.Latest;
|
||||
Console.WriteLine("MUSICBRIDGE\n");
|
||||
@@ -126,6 +132,8 @@ try
|
||||
else Console.WriteLine($"Громкость недоступна: {state.VolumeError}");
|
||||
Console.WriteLine($"\nПодключение: {string.Join(" | ", addresses)}");
|
||||
Console.WriteLine(lan ? "Режим локальной сети (IPv4)." : "Режим только этого ПК; для Wi-Fi запусти с --lan.");
|
||||
if (lan) Console.WriteLine(mdns.Status);
|
||||
if (qrWindow.Error is { } qrError) Console.WriteLine($"Окно QR: {qrError}");
|
||||
Console.WriteLine($"SHA-256 сертификата: {fingerprint}");
|
||||
var window = pairing.Current;
|
||||
Console.WriteLine(window is null ? "Сопряжение закрыто. B — открыть заново."
|
||||
@@ -136,7 +144,7 @@ try
|
||||
Console.WriteLine($" {i + 1}. {displayedDevices[i].Name}");
|
||||
Console.WriteLine("\nПробел: play/pause | N/P: следующий/предыдущий трек");
|
||||
Console.WriteLine("←/→: ±10 с | ↑/↓: громкость ±5% | M: звук | B: сопряжение");
|
||||
Console.WriteLine("I: данные для будущего QR | Выход: Q или Ctrl+C");
|
||||
Console.WriteLine("I: открыть QR-код | Выход: Q или Ctrl+C");
|
||||
Console.WriteLine($"\n{message}");
|
||||
nextRefresh = DateTimeOffset.UtcNow.AddSeconds(1);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user