Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BGI interprocess #2143

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using System.Collections.Immutable;

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class AutomationCultivaionEntry
{
public required uint ItemId { get; set; }

public required ImmutableArray<AutomationCultivaionItem> Items { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class AutomationCultivaionItem
{
public required uint ItemId { get; set; }

public required uint Count { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class AutomationGameAccount
{
public required AutomationGameAccountType Type { get; set; }

public required string NameOrUserId { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

[Flags]
internal enum AutomationGameAccountType
{
UseRegistry = 0B0000,
UseAuthTicket = 0B0001,

Chinese = 0B0000,
Oversea = 0B0010,

RegistryChinese = UseRegistry | Chinese,
RegistryOversea = UseRegistry | Oversea,
AuthTicketChinese = UseAuthTicket | Chinese,
AuthTicketOversea = UseAuthTicket | Oversea,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal class AutomationTaskDefinition
{
public required string Id { get; set; }

public required string Name { get; set; }

public required string Description { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class AutomationTaskStepDefinition
{
public required string Description { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using Snap.Hutao.Win32.Foundation;
using System.IO.Pipes;

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

[Injection(InjectAs.Singleton)]
internal sealed partial class BetterGenshinImpactNamedPipeClient : IDisposable
{
private readonly NamedPipeClientStream clientStream = new(".", "BetterGenshinImpact.NamedPipe", PipeDirection.InOut, PipeOptions.Asynchronous | PipeOptions.WriteThrough);

public void Dispose()
{
clientStream.Dispose();
}

public bool TryStartCapture(HWND hwnd)
{
if (!clientStream.TryConnectOnce())
{
return false;
}

PipeRequest<long> startCaptureRequest = new() { Kind = PipeRequestKind.StartCapture, Data = hwnd };
clientStream.WritePacketWithJsonContent(PrivateNamedPipe.Version, PipePacketType.Request, PipePacketCommand.SnapHutaoToBetterGenshinImpactRequest, startCaptureRequest);
clientStream.ReadPacket(out _, out PipeResponse? response);

if (response is not { Kind: PipeResponseKind.Boolean } || !response.Data.GetBoolean())
{
return false;
}

clientStream.WritePacket(PrivateNamedPipe.Version, PipePacketType.SessionTermination, PipePacketCommand.None);
clientStream.Flush();
return true;
}

public bool TryStopCapture()
{
if (!clientStream.TryConnectOnce())
{
return false;
}

PipeRequest<Void> stopCaptureRequest = new() { Kind = PipeRequestKind.StopCapture, Data = default };
clientStream.WritePacketWithJsonContent(PrivateNamedPipe.Version, PipePacketType.Request, PipePacketCommand.SnapHutaoToBetterGenshinImpactRequest, stopCaptureRequest);
clientStream.ReadPacket(out _, out PipeResponse? response);

if (response is not { Kind: PipeResponseKind.Boolean } || !response.Data.GetBoolean())
{
return false;
}

clientStream.WritePacket(PrivateNamedPipe.Version, PipePacketType.SessionTermination, PipePacketCommand.None);
clientStream.Flush();
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class CumulativeSteppedAutomationTaskDefinition : AutomationTaskDefinition
{
public required List<AutomationTaskStepDefinition> Steps { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using System.Collections.Immutable;

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class FixedSteppedAutomationTaskDefinition : AutomationTaskDefinition
{
public required ImmutableArray<AutomationTaskStepDefinition> Steps { get; set; }

public int CurrentStepIndex { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using System.Collections.Immutable;

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class PipeRequest<T>
{
public required PipeRequestKind Kind { get; set; }

public required T Data { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal enum PipeRequestKind
{
None,
StartCapture = 1,
StopCapture = 2,

CreateOneshotTask = 10,
CreateFixedSteppedTask = 11,
CreateCumulativeSteppedTask = 12,
RemoveTask = 13,
UpdateTaskDefinition = 14,
IncreaseTaskStepIndex = 15,
AddTaskStep = 16,

QueryGameAccountList = 30,
SwitchGameAccount = 31,

QueryCultivaionList = 40,
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal sealed class PipeResponse
{
public required PipeResponseKind Kind { get; set; }

public required JsonElement Data { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

namespace Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;

internal enum PipeResponseKind
{
None,
Boolean = 1,
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@ internal enum PipePacketCommand : byte
RedirectActivation = 10,
RequestElevationStatus = 11,
ResponseElevationStatus = 12,

BetterGenshinImpactToSnapHutaoRequest = 20,
BetterGenshinImpactToSnapHutaoResponse = 21,
SnapHutaoToBetterGenshinImpactRequest = 22,
SnapHutaoToBetterGenshinImpactResponse = 23,
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ internal static class PipeStreamExtension
{
Span<byte> content = memoryOwner.Memory.Span[..header.ContentLength];
stream.ReadExactly(content);

HutaoException.ThrowIf(XxHash64.HashToUInt64(content) != header.Checksum, "PipePacket Content Hash incorrect");

return JsonSerializer.Deserialize<TData>(content);
}
}
Expand Down Expand Up @@ -53,7 +53,7 @@ public static void WritePacketWithJsonContent<TData>(this PipeStream stream, byt
stream.WritePacket(ref header, JsonSerializer.SerializeToUtf8Bytes(data));
}

public static void WritePacket(this PipeStream stream, ref PipePacketHeader header, byte[] content)
public static void WritePacket(this PipeStream stream, ref PipePacketHeader header, ReadOnlySpan<byte> content)
{
header.ContentLength = content.Length;
header.Checksum = XxHash64.HashToUInt64(content);
Expand All @@ -79,4 +79,4 @@ public static unsafe void WritePacket(this PipeStream stream, ref readonly PipeP
stream.Write(new(pHeader, sizeof(PipePacketHeader)));
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.

using Snap.Hutao.Core.LifeCycle.InterProcess.BetterGenshinImpact;
using Snap.Hutao.Core.LifeCycle.InterProcess.Model;
using System.IO.Pipes;
using System.Security.AccessControl;
Expand Down Expand Up @@ -96,6 +97,10 @@ private void RunPacketSession(NamedPipeServerStream serverStream, CancellationTo
messageDispatcher.RedirectActivation(hutaoArgs);
break;

case (PipePacketType.Request, PipePacketCommand.BetterGenshinImpactToSnapHutaoRequest):
PipeRequest<JsonElement>? request = serverStream.ReadJsonContent<PipeRequest<JsonElement>>(in header);
break;

case (PipePacketType.SessionTermination, _):
serverStream.Disconnect();
if (header.Command is PipePacketCommand.Exit)
Expand Down
Loading