* 🚧 WIP v2.

Signed-off-by: 秋雨落 <i@rain.cx>

* 🚧 WIP v2 * 2.

Signed-off-by: 秋雨落 <i@rain.cx>

* ✨ It works?

Signed-off-by: 秋雨落 <i@rain.cx>

* ✨ Publish to nexus.

Signed-off-by: 秋雨落 <i@rain.cx>

---------

Signed-off-by: 秋雨落 <i@rain.cx>
This commit is contained in:
秋 雨落
2024-01-10 09:52:50 +08:00
committed by GitHub
parent 3af3badcc5
commit 84f4e3543c
32 changed files with 2361 additions and 385 deletions
@@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
<Authors>qyl27,MeowCraftMC</Authors>
<RepositoryUrl>https://github.com/MeowCraftMC/CrystalConnector</RepositoryUrl>
<PackageLicenseExpression>Apache-2.0</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>True</PackageRequireLicenseAcceptance>
<IncludeSymbols>True</IncludeSymbols>
<PackageProjectUrl>https://github.com/MeowCraftMC/CrystalConnector</PackageProjectUrl>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Google.Protobuf" Version="3.25.1" />
<PackageReference Include="Google.Protobuf.Tools" Version="3.25.1" />
</ItemGroup>
<ItemGroup>
<Protobuf Include="proto\messages.proto" GrpcServices="Client" />
</ItemGroup>
<ItemGroup>
<Folder Include="Messages\" />
</ItemGroup>
</Project>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,53 @@
using CrystalConnector.Protocol.Messages;
using Google.Protobuf;
namespace CrystalConnector.Protocol.Packets.C2S;
public class AuthenticatePacket : IPacket
{
public NamespacedName ClientId { get; set; }
public string ClientName { get; set; }
public string Key { get; set; }
public List<Channel> Channels { get; } = [];
public AuthenticatePacket(NamespacedName clientId, string clientName, string key, List<Channel> channels)
{
ClientId = clientId;
ClientName = clientName;
Key = key;
Channels.AddRange(channels);
}
public AuthenticatePacket(byte[] bytes)
{
Read(bytes);
}
public AuthenticatePacket()
{
}
public void Read(byte[] bytes)
{
var message = Authenticate.Parser.ParseFrom(bytes);
ClientId = message.ClientId;
ClientName = message.ClientName;
Key = message.SecretKey;
Channels.AddRange(message.Channels);
}
public byte[] Write()
{
var message = new Authenticate
{
ClientId = ClientId,
ClientName = ClientName,
SecretKey = Key
};
message.Channels.AddRange(Channels);
return message.ToByteArray();
}
}
@@ -0,0 +1,43 @@
using CrystalConnector.Protocol.Messages;
using Google.Protobuf;
namespace CrystalConnector.Protocol.Packets.C2S;
public class PublishPacket : IPacket
{
public NamespacedName Channel { get; set; }
public string Payload { get; set; }
public PublishPacket(NamespacedName channel, string payload)
{
Channel = channel;
Payload = payload;
}
public PublishPacket(byte[] bytes)
{
Read(bytes);
}
public PublishPacket()
{
}
public void Read(byte[] bytes)
{
var message = Publish.Parser.ParseFrom(bytes);
Channel = message.Channel;
Payload = message.Payload;
}
public byte[] Write()
{
var message = new Publish
{
Channel = Channel,
Payload = Payload
};
return message.ToByteArray();
}
}
@@ -0,0 +1,50 @@
using CrystalConnector.Protocol.Packets.C2S;
using CrystalConnector.Protocol.Packets.S2C;
using Google.Protobuf;
namespace CrystalConnector.Protocol.Packets;
public interface IPacket
{
public void Read(byte[] bytes);
public byte[] Write();
public static IPacket? From(byte[] data)
{
var result = TryForm<AuthenticatePacket>(data);
if (result is not null)
{
return result;
}
result = TryForm<PublishPacket>(data);
if (result is not null)
{
return result;
}
result = TryForm<ForwardPacket>(data);
if (result is not null)
{
return result;
}
result = TryForm<ResultPacket>(data);
return result;
}
private static IPacket? TryForm<T>(byte[] data) where T : IPacket, new()
{
try
{
var message = new T();
message.Read(data);
return message;
}
catch (InvalidProtocolBufferException ex)
{
return null;
}
}
}
@@ -0,0 +1,51 @@
using CrystalConnector.Protocol.Messages;
using Google.Protobuf;
namespace CrystalConnector.Protocol.Packets.S2C;
public class ForwardPacket : IPacket
{
public string Publisher { get; set; }
public NamespacedName Channel { get; set; }
public string Payload { get; set; }
public ForwardPacket(string publisher, (string Namespace, string Name) channel, string payload)
{
Publisher = publisher;
Channel = new NamespacedName
{
Namespace = channel.Namespace,
Name = channel.Name
};
Payload = payload;
}
public ForwardPacket(byte[] bytes)
{
Read(bytes);
}
public ForwardPacket()
{
}
public void Read(byte[] bytes)
{
var message = Forward.Parser.ParseFrom(bytes);
Publisher = message.Publisher;
Channel = message.Channel;
Payload = message.Payload;
}
public byte[] Write()
{
var message = new Forward
{
Publisher = Publisher,
Channel = Channel,
Payload = Payload
};
return message.ToByteArray();
}
}
@@ -0,0 +1,59 @@
using CrystalConnector.Protocol.Messages;
using Google.Protobuf;
namespace CrystalConnector.Protocol.Packets.S2C;
public class ResultPacket : IPacket
{
public Result.ResultOneofCase ResultOneofCase { get; set; }
public Error? Error { get; set; }
public ResultPacket()
{
ResultOneofCase = Result.ResultOneofCase.Successful;
}
public ResultPacket(Error error)
{
ResultOneofCase = Result.ResultOneofCase.Error;
Error = error;
}
public ResultPacket(byte[] bytes)
{
Read(bytes);
}
public void Read(byte[] bytes)
{
var message = Result.Parser.ParseFrom(bytes);
ResultOneofCase = message.ResultCase;
if (message.HasError)
{
Error = message.Error;
}
}
public byte[] Write()
{
var message = ResultOneofCase switch
{
Result.ResultOneofCase.None => new Result
{
Error = Messages.Error.Unknown
},
Result.ResultOneofCase.Successful => new Result
{
Successful = new Successful()
},
Result.ResultOneofCase.Error => new Result
{
Error = Error!.Value
},
_ => throw new ArgumentOutOfRangeException()
};
return message.ToByteArray();
}
}
+7
View File
@@ -0,0 +1,7 @@
# CrystalConnector.Protocol
## Generate Proto file
```shell
protoc.exe --proto_path=proto --csharp_out=Messages proto\messages.proto
```
@@ -0,0 +1,25 @@
using CrystalConnector.Protocol.Messages;
namespace CrystalConnector.Protocol.Utilities;
public static class PacketHelperExtensions
{
public static (string Namespace, string Name) ToTuple(this NamespacedName name)
{
return (name.Namespace, name.Name);
}
public static NamespacedName ToName(this (string Namespace, string Name) name)
{
return new NamespacedName
{
Namespace = name.Namespace,
Name = name.Name
};
}
public static string ToIdString(this (string Namespace, string Name) name)
{
return $"{name.Namespace}:{name.Name}";
}
}
@@ -0,0 +1,59 @@
syntax = "proto3";
option csharp_namespace = "CrystalConnector.Protocol.Messages";
package CrystalConnector;
message NamespacedName {
string namespace = 1;
string name = 2;
}
enum MessageDirection {
NONE = 0;
INCOMING = 1;
OUTGOING = 2;
ALL = 3;
}
message Successful {
}
enum Error {
UNKNOWN = 0;
AUTHENTICATED = 1;
NAME_EXISTS = 2;
UNAUTHENTICATED = 3;
UNREGISTERED_CHANNEL = 4;
INTERNAL = 5;
}
message Result {
oneof result {
Successful successful = 1;
Error error = 2;
}
}
message Authenticate {
NamespacedName client_id = 1;
string client_name = 2;
string secret_key = 3;
repeated Channel channels = 4;
}
message Channel {
NamespacedName id = 1;
MessageDirection direction = 2;
}
message Publish {
NamespacedName channel = 1;
string payload = 2;
}
message Forward {
string publisher = 1;
NamespacedName channel = 2;
string payload = 3;
}