impl part of hutao interop

This commit is contained in:
qhy040404
2025-02-17 20:17:19 +08:00
parent 2e0c215b87
commit b020c794b0
11 changed files with 136 additions and 43 deletions

View File

@@ -1,5 +1,4 @@
using BetterGenshinImpact.Helpers;
using BetterGenshinImpact.View.Pages;
using BetterGenshinImpact.ViewModel.Pages;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
@@ -7,9 +6,9 @@ using System;
using System.IO.Pipes;
using System.Security.AccessControl;
using System.Security.Principal;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using Wpf.Ui;
namespace BetterGenshinImpact.Hutao;
@@ -86,7 +85,7 @@ internal sealed partial class BGINamedPipe : IDisposable
switch ((header.Type, header.Command))
{
case (PipePacketType.Request, PipePacketCommand.SnapHutaoToBetterGenshinImpactRequest):
if (serverStream.ReadJsonContent<HutaoRequest>(in header) is { } request)
if (serverStream.ReadJsonContent<PipeRequest<JsonElement>>(in header) is { } request)
{
DispatchHutaoRequest(request);
}
@@ -100,14 +99,43 @@ internal sealed partial class BGINamedPipe : IDisposable
}
}
private void DispatchHutaoRequest(HutaoRequest request)
private void DispatchHutaoRequest(PipeRequest<JsonElement> request)
{
switch (request.Kind)
{
case HutaoRequestKind.StartCapture:
HomePageViewModel home = serviceProvider.GetRequiredService<HomePageViewModel>();
home.Start((nint)request.Data.GetInt64());
case PipeRequestKind.GetContractVersion:
{
PipeResponse<uint> response = new() { Kind = PipeResponseKind.Number, Data = Version };
serverStream.WritePacketWithJsonContent(Version, PipePacketType.Response, PipePacketCommand.BetterGenshinImpactToSnapHutaoResponse, response);
serverStream.Flush();
}
break;
case PipeRequestKind.StartCapture:
{
HomePageViewModel home = serviceProvider.GetRequiredService<HomePageViewModel>();
home.Start((nint)request.Data.GetInt64());
}
break;
case PipeRequestKind.StopCapture:
{
HomePageViewModel home = serviceProvider.GetRequiredService<HomePageViewModel>();
home.Stop();
}
break;
case PipeRequestKind.QueryTaskArray:
throw new NotImplementedException();
case PipeRequestKind.StartTask:
throw new NotImplementedException();
case PipeRequestKind.EndSwitchToNextGameAccount:
throw new NotImplementedException();
}
}
}

View File

@@ -1,6 +1,7 @@
using System;
using System.IO.Pipes;
using System.Text;
using System.Text.Json;
namespace BetterGenshinImpact.Hutao;
@@ -18,18 +19,7 @@ internal sealed partial class HutaoNamedPipe : IDisposable
{
this.serviceProvider = serviceProvider;
isSupported = new(() =>
{
try
{
clientStream.Connect(TimeSpan.Zero);
return true;
}
catch (TimeoutException)
{
return false;
}
});
isSupported = new(clientStream.TryConnectOnce);
}
public bool IsSupported
@@ -44,9 +34,23 @@ internal sealed partial class HutaoNamedPipe : IDisposable
return false;
}
byte[] buffer = Encoding.UTF8.GetBytes(log);
clientStream.Write(buffer, 0, buffer.Length);
return true;
if (!clientStream.TryConnectOnce())
{
return false;
}
try
{
PipeRequest<string> logRequest = new() { Kind = PipeRequestKind.Log, Data = log, };
clientStream.WritePacketWithJsonContent(Version, PipePacketType.Request, PipePacketCommand.BetterGenshinImpactToSnapHutaoRequest, logRequest);
clientStream.ReadPacket(out _, out PipeResponse<JsonElement>? _);
return true;
}
finally
{
clientStream.WritePacket(Version, PipePacketType.SessionTermination, PipePacketCommand.None);
clientStream.Flush();
}
}
public void Dispose()

View File

@@ -30,6 +30,7 @@ internal sealed class HutaoNamedPipeLogEventSink : ILogEventSink
public void Emit(LogEvent logEvent)
{
textFormatter.Format(logEvent, writer);
writer.Flush();
buffer.Position = 0;
NamedPipe.TryRedirectLog(reader.ReadToEnd());
buffer.SetLength(0);

View File

@@ -1,12 +0,0 @@
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

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

View File

@@ -0,0 +1,25 @@
using System;
using System.IO.Pipes;
namespace BetterGenshinImpact.Hutao;
internal static class NamedPipeClientStreamExtension
{
public static bool TryConnectOnce(this NamedPipeClientStream clientStream)
{
if (clientStream.IsConnected)
{
return true;
}
try
{
clientStream.Connect(TimeSpan.Zero);
return true;
}
catch (TimeoutException)
{
return false;
}
}
}

View File

@@ -0,0 +1,10 @@
using System.Text.Json;
namespace BetterGenshinImpact.Hutao;
internal sealed class PipeRequest<T>
{
public required PipeRequestKind Kind { get; set; }
public T Data { get; set; }
}

View File

@@ -0,0 +1,22 @@
namespace BetterGenshinImpact.Hutao;
internal enum PipeRequestKind
{
None = 0, // ContractVersion 1, Both
GetContractVersion = 1, // ContractVersion 1, Both
StartCapture = 2, // ContractVersion 1, S to B
StopCapture = 3, // ContractVersion 1, S to B
Log = 4, // ContractVersion 1, B to S
QueryTaskArray = 10, // ContractVersion 1, S to B
StartTask = 11, // ContractVersion 1, S to B
CreateOneShotTask = 20, // ContractVersion 1, B to S
CreateSteppedTask = 21, // ContractVersion 1, B to S
RemoveTask = 22, // ContractVersion 1, B to S
UpdateTaskDefinition = 23, // ContractVersion 1, B to S
UpdateTaskStepDefinition = 24, // ContractVersion 1, B to S
UpdateTaskStepIndex = 25, // ContractVersion 1, B to S
AddTaskStepDefinition = 26, // ContractVersion 1, B to S
BeginSwitchToNextGameAccount = 30, // ContractVersion 1, B to S
EndSwitchToNextGameAccount = 31, // ContractVersion 1, S to B
QueryCurrentCultivationProject = 40, // ContractVersion 1, B to S
}

View File

@@ -0,0 +1,11 @@
namespace BetterGenshinImpact.Hutao;
internal class PipeResponse
{
public required PipeResponseKind Kind { get; set; }
}
internal sealed class PipeResponse<T> : PipeResponse
{
public T? Data { get; set; }
}

View File

@@ -0,0 +1,11 @@
namespace BetterGenshinImpact.Hutao;
internal enum PipeResponseKind
{
None,
Object = 1,
Array = 2,
String = 3,
Number = 4,
Boolean = 5,
}

View File

@@ -225,7 +225,7 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware, IVi
internal void Start(IntPtr hWnd)
{
Debug.WriteLine($"原神启动句柄{hWnd}");
Debug.WriteLine($"原神启动句柄 {hWnd}");
lock (this)
{
if (Config.TriggerInterval <= 0)
@@ -258,7 +258,7 @@ public partial class HomePageViewModel : ObservableObject, INavigationAware, IVi
Stop();
}
private void Stop()
internal void Stop()
{
lock (this)
{