mirror of
https://github.com/babalae/better-genshin-impact.git
synced 2026-05-21 09:45:48 +08:00
impl part of hutao interop
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
namespace BetterGenshinImpact.Hutao;
|
||||
|
||||
internal enum HutaoRequestKind
|
||||
{
|
||||
None = 0,
|
||||
StartCapture = 1,
|
||||
}
|
||||
25
BetterGenshinImpact/Hutao/NamedPipeClientStreamExtension.cs
Normal file
25
BetterGenshinImpact/Hutao/NamedPipeClientStreamExtension.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
10
BetterGenshinImpact/Hutao/PipeRequest.cs
Normal file
10
BetterGenshinImpact/Hutao/PipeRequest.cs
Normal 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; }
|
||||
}
|
||||
22
BetterGenshinImpact/Hutao/PipeRequestKind.cs
Normal file
22
BetterGenshinImpact/Hutao/PipeRequestKind.cs
Normal 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
|
||||
}
|
||||
11
BetterGenshinImpact/Hutao/PipeResponse.cs
Normal file
11
BetterGenshinImpact/Hutao/PipeResponse.cs
Normal 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; }
|
||||
}
|
||||
11
BetterGenshinImpact/Hutao/PipeResponseKind.cs
Normal file
11
BetterGenshinImpact/Hutao/PipeResponseKind.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace BetterGenshinImpact.Hutao;
|
||||
|
||||
internal enum PipeResponseKind
|
||||
{
|
||||
None,
|
||||
Object = 1,
|
||||
Array = 2,
|
||||
String = 3,
|
||||
Number = 4,
|
||||
Boolean = 5,
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user