test pipe connection

This commit is contained in:
DismissedLight
2024-10-21 15:52:55 +08:00
committed by qhy040404
parent 1aa23df648
commit d41b6f0573
6 changed files with 142 additions and 4 deletions

View File

@@ -0,0 +1,109 @@
using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.View.Pages;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using System;
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Threading;
using System.Threading.Tasks;
using Wpf.Ui;
namespace BetterGenshinImpact.Hutao;
internal sealed partial class BGINamedPipe : IDisposable
{
private const int Version = 1;
private readonly IServiceProvider serviceProvider;
private readonly ILogger<BGINamedPipe> logger;
private readonly CancellationTokenSource serverTokenSource = new();
private readonly TaskCompletionSource serverRunTaskCompletionSource = new();
private readonly NamedPipeServerStream serverStream;
public BGINamedPipe(IServiceProvider serviceProvider)
{
this.serviceProvider = serviceProvider;
logger = serviceProvider.GetRequiredService<ILogger<BGINamedPipe>>();
PipeSecurity? pipeSecurity = default;
if (RuntimeHelper.IsElevated)
{
SecurityIdentifier everyOne = new(WellKnownSidType.WorldSid, null);
pipeSecurity = new();
pipeSecurity.AddAccessRule(new PipeAccessRule(everyOne, PipeAccessRights.FullControl, AccessControlType.Allow));
}
serverStream = NamedPipeServerStreamAcl.Create(
"BetterGenshinImpact.NamedPipe",
PipeDirection.InOut,
NamedPipeServerStream.MaxAllowedServerInstances,
PipeTransmissionMode.Byte,
PipeOptions.Asynchronous | PipeOptions.WriteThrough,
0,
0,
pipeSecurity);
}
public void Dispose()
{
serverTokenSource.Cancel();
serverRunTaskCompletionSource.Task.GetAwaiter().GetResult();
serverTokenSource.Dispose();
serverStream.Dispose();
}
public async ValueTask RunAsync()
{
while (!serverTokenSource.IsCancellationRequested)
{
try
{
await serverStream.WaitForConnectionAsync(serverTokenSource.Token).ConfigureAwait(false);
logger.LogInformation("Pipe session created");
RunPacketSession(serverStream, serverTokenSource.Token);
}
catch (OperationCanceledException)
{
}
}
serverRunTaskCompletionSource.TrySetResult();
}
private void RunPacketSession(NamedPipeServerStream serverStream, CancellationToken token)
{
while (serverStream.IsConnected && !token.IsCancellationRequested)
{
serverStream.ReadPacket(out PipePacketHeader header);
logger.LogInformation("Pipe packet: [Type:{Type}] [Command:{Command}]", header.Type, header.Command);
switch ((header.Type, header.Command))
{
case (PipePacketType.Request, PipePacketCommand.SnapHutaoToBetterGenshinImpactRequest):
if (serverStream.ReadJsonContent<HutaoRequest>(in header) is { } request)
{
DispatchHutaoRequest(request);
}
break;
}
}
}
private void DispatchHutaoRequest(HutaoRequest request)
{
switch (request.Kind)
{
case HutaoRequestKind.StartCapture:
HomePageViewModel home = serviceProvider.GetRequiredService<HomePageViewModel>();
home.Start((nint)request.Data.GetInt64());
break;
}
}
}

View File

@@ -1,17 +1,21 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO.Pipes;
using System.Text;
using System.Text.Json.Serialization;
namespace BetterGenshinImpact.Hutao;
internal sealed class HutaoNamedPipe : IDisposable
internal sealed partial class HutaoNamedPipe : IDisposable
{
private const int Version = 1;
private readonly NamedPipeClientStream clientStream = new(".", "Snap.Hutao.PrivateNamedPipe", PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough);
private readonly IServiceProvider serviceProvider;
private Lazy<bool> isSupported;
private readonly Lazy<bool> isSupported;
public HutaoNamedPipe(IServiceProvider serviceProvider)
{

View File

@@ -0,0 +1,12 @@
using System.Text.Json;
namespace BetterGenshinImpact.Hutao;
internal sealed class HutaoRequest
{
// DO NOT RENAME: Json convert compatibility
public HutaoRequestKind Kind { get; set; }
// DO NOT RENAME: Json convert compatibility
public JsonElement Data { get; set; }
}

View File

@@ -0,0 +1,7 @@
namespace BetterGenshinImpact.Hutao;
internal enum HutaoRequestKind
{
None = 0,
StartCapture = 1,
}

View File

@@ -1,6 +1,12 @@
namespace BetterGenshinImpact.Hutao;
// Snap Hutao reserves all variables that don't appear below
// Any command may add in furure should not send to Snap Hutao Pipe
internal enum PipePacketCommand : byte
{
None = 0,
BetterGenshinImpactToSnapHutaoRequest = 20,
BetterGenshinImpactToSnapHutaoResponse = 21,
SnapHutaoToBetterGenshinImpactRequest = 22,
SnapHutaoToBetterGenshinImpactResponse = 23,
}

View File

@@ -223,7 +223,7 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware, IVi
Start(hWnd);
}
private void Start(IntPtr hWnd)
internal void Start(IntPtr hWnd)
{
Debug.WriteLine($"原神启动句柄{hWnd}");
lock (this)