This commit is contained in:
@@ -0,0 +1,114 @@
|
||||
using System;
|
||||
using System.Buffers.Binary;
|
||||
|
||||
namespace ShrinkNetwork
|
||||
{
|
||||
internal enum ShrinkKcpEnvelopeKind : byte
|
||||
{
|
||||
ConnectRequest = 1,
|
||||
ConnectAccept = 2,
|
||||
Disconnect = 3,
|
||||
Data = 4
|
||||
}
|
||||
|
||||
internal static class ShrinkKcpTransportProtocol
|
||||
{
|
||||
private const int KindSize = 1;
|
||||
private const int ConversationSize = 4;
|
||||
private const int NonceSize = 8;
|
||||
|
||||
public static byte[] CreateConnectRequest(long nonce, uint requestedConversationId)
|
||||
{
|
||||
var buffer = new byte[KindSize + NonceSize + ConversationSize];
|
||||
buffer[0] = (byte)ShrinkKcpEnvelopeKind.ConnectRequest;
|
||||
BinaryPrimitives.WriteInt64LittleEndian(buffer.AsSpan(1, NonceSize), nonce);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(buffer.AsSpan(1 + NonceSize, ConversationSize), requestedConversationId);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static bool TryReadConnectRequest(byte[] datagram, out long nonce, out uint requestedConversationId)
|
||||
{
|
||||
nonce = default;
|
||||
requestedConversationId = default;
|
||||
if (datagram == null || datagram.Length != KindSize + NonceSize + ConversationSize)
|
||||
return false;
|
||||
if (datagram[0] != (byte)ShrinkKcpEnvelopeKind.ConnectRequest)
|
||||
return false;
|
||||
|
||||
nonce = BinaryPrimitives.ReadInt64LittleEndian(datagram.AsSpan(1, NonceSize));
|
||||
requestedConversationId = BinaryPrimitives.ReadUInt32LittleEndian(datagram.AsSpan(1 + NonceSize, ConversationSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static byte[] CreateConnectAccept(long nonce, uint conversationId)
|
||||
{
|
||||
var buffer = new byte[KindSize + NonceSize + ConversationSize];
|
||||
buffer[0] = (byte)ShrinkKcpEnvelopeKind.ConnectAccept;
|
||||
BinaryPrimitives.WriteInt64LittleEndian(buffer.AsSpan(1, NonceSize), nonce);
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(buffer.AsSpan(1 + NonceSize, ConversationSize), conversationId);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static bool TryReadConnectAccept(byte[] datagram, out long nonce, out uint conversationId)
|
||||
{
|
||||
nonce = default;
|
||||
conversationId = default;
|
||||
if (datagram == null || datagram.Length != KindSize + NonceSize + ConversationSize)
|
||||
return false;
|
||||
if (datagram[0] != (byte)ShrinkKcpEnvelopeKind.ConnectAccept)
|
||||
return false;
|
||||
|
||||
nonce = BinaryPrimitives.ReadInt64LittleEndian(datagram.AsSpan(1, NonceSize));
|
||||
conversationId = BinaryPrimitives.ReadUInt32LittleEndian(datagram.AsSpan(1 + NonceSize, ConversationSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static byte[] CreateDisconnect(uint conversationId)
|
||||
{
|
||||
var buffer = new byte[KindSize + ConversationSize];
|
||||
buffer[0] = (byte)ShrinkKcpEnvelopeKind.Disconnect;
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(buffer.AsSpan(1, ConversationSize), conversationId);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static bool TryReadDisconnect(byte[] datagram, out uint conversationId)
|
||||
{
|
||||
conversationId = default;
|
||||
if (datagram == null || datagram.Length != KindSize + ConversationSize)
|
||||
return false;
|
||||
if (datagram[0] != (byte)ShrinkKcpEnvelopeKind.Disconnect)
|
||||
return false;
|
||||
|
||||
conversationId = BinaryPrimitives.ReadUInt32LittleEndian(datagram.AsSpan(1, ConversationSize));
|
||||
return true;
|
||||
}
|
||||
|
||||
public static byte[] CreateDataPacket(uint conversationId, byte[] payload)
|
||||
{
|
||||
payload ??= Array.Empty<byte>();
|
||||
|
||||
var buffer = new byte[KindSize + ConversationSize + payload.Length];
|
||||
buffer[0] = (byte)ShrinkKcpEnvelopeKind.Data;
|
||||
BinaryPrimitives.WriteUInt32LittleEndian(buffer.AsSpan(1, ConversationSize), conversationId);
|
||||
if (payload.Length > 0)
|
||||
Buffer.BlockCopy(payload, 0, buffer, KindSize + ConversationSize, payload.Length);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public static bool TryReadDataPacket(byte[] datagram, out uint conversationId, out int payloadOffset, out int payloadLength)
|
||||
{
|
||||
conversationId = default;
|
||||
payloadOffset = default;
|
||||
payloadLength = default;
|
||||
if (datagram == null || datagram.Length < KindSize + ConversationSize)
|
||||
return false;
|
||||
if (datagram[0] != (byte)ShrinkKcpEnvelopeKind.Data)
|
||||
return false;
|
||||
|
||||
conversationId = BinaryPrimitives.ReadUInt32LittleEndian(datagram.AsSpan(1, ConversationSize));
|
||||
payloadOffset = KindSize + ConversationSize;
|
||||
payloadLength = datagram.Length - payloadOffset;
|
||||
return payloadLength >= 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user