Open Lightczx opened 3 weeks ago
使用两个命名管道进行全双工通信
SH 使用名称为 Snap.Hutao.PrivateNamedPipe
的管道
BGI 使用名称为 BetterGenshinImpact.NamedPipe
的管道
管道的连通由抽象的 Session
控制
每个 Session
都由抽象的 PipePacket
组成
每个 PipePacket
都由 PipePacketHeader
与可能紧随其后的抽象的 Content
组成
// Any content will be placed after the header.
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct PipePacketHeader
{
public byte Version;
public PipePacketType Type;
public PipePacketCommand Command;
public PipePacketContentType ContentType;
public int ContentLength;
public ulong Checksum;
}
Version
目前为 0x1
internal enum PipePacketType : byte
{
None = 0,
Request = 1,
Response = 2,
SessionTermination = 3,
}
internal enum PipePacketCommand : byte
{
None = 0,
// 应且仅应使用这些 Command,未在此处写出的 Command 均由 SH/BGI 保留
BetterGenshinImpactToSnapHutaoRequest = 20,
BetterGenshinImpactToSnapHutaoResponse = 21,
SnapHutaoToBetterGenshinImpactRequest = 22,
SnapHutaoToBetterGenshinImpactResponse = 23,
}
internal enum PipePacketContentType : byte
{
None = 0,
Json = 1,
}
在向管道写入 PipePacket
时,先以二进制字节流的形式写入组织好的 PipePacketHeader
,随后可选的在在其后写入由 PipePacketContentType
决定的 Content
。
对于 Json
类型,需要写入格式为UTF8编码下的Json字符串
为了最大限度避免因连接占用导致的死锁,使用 Session
来抽象所有单次请求/响应
每个 Session
的结尾必须为 PipePacketType
为 SessionTermination
的 PipePacket
,用于提示会话终止,可以释放连接
SessionTermination
包不能附加任何 Content
对于SH与BGI间的任何请求,使用 PipePacketType
为 Request
,PipePacketContentType
为 Json
的 PipePacket