123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- using InABox.Core;
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Reflection.Emit;
- using System.Text;
- using System.Threading.Tasks;
- namespace InABox.WebSocket.Shared
- {
- public class ByteReader
- {
- public byte[] Data;
- public int Index;
- public ByteReader(byte[] data)
- {
- Data = data;
- Index = 0;
- }
- public Guid ReadGuid()
- {
- var guid = new Guid(new ReadOnlySpan<byte>(Data, Index, 16));
- Index += 16;
- return guid;
- }
- public string ReadUTF8String()
- {
- int i = Index;
- while (i < Data.Length && Data[i] != 0)
- {
- i++;
- }
- var str = Encoding.UTF8.GetString(Data, Index, i - Index);
- Index = i + 1;
- return str;
- }
- public byte ReadByte()
- {
- return Data[Index++];
- }
- public ByteReader Skip(int count)
- {
- Index += count;
- return this;
- }
- }
- public class ByteWriter
- {
- private Stream Stream;
- public ByteWriter(Stream stream)
- {
- Stream = stream;
- }
- public ByteWriter WriteByte(byte b)
- {
- Stream.WriteByte(b);
- return this;
- }
- public ByteWriter WriteGuid(Guid guid)
- {
- Stream.Write(guid.ToByteArray());
- return this;
- }
- /// <summary>
- /// Writes a null-terminated UTF-8 encoded string to the buffer
- /// </summary>
- /// <param name="str"></param>
- /// <returns></returns>
- public ByteWriter WriteUTF8String(string str)
- {
- Stream.Write(Encoding.UTF8.GetBytes(str));
- Stream.WriteByte(0);
- return this;
- }
- }
- public abstract class SocketMessage
- {
- public enum MessageType
- {
- Initial = 0x00,
- Notify = 0x01
- }
- public abstract MessageType Type { get; }
- protected abstract void Write(ByteWriter writer);
- public void Write(Stream stream)
- {
- var writer = new ByteWriter(stream)
- .WriteByte((byte)Type);
- Write(writer);
- }
- public byte[] WriteToBytes()
- {
- using(var stream = new MemoryStream())
- {
- Write(stream);
- return stream.GetBuffer().ToArray();
- }
- }
- public static SocketMessage? ReadMessage(byte[] data)
- {
- try
- {
- var type = (MessageType)data[0];
- var byteReader = new ByteReader(data).Skip(1);
- switch (type)
- {
- case MessageType.Initial:
- return InitialMessage.ReadMessage(byteReader);
- case MessageType.Notify:
- return NotifyMessage.ReadMessage(byteReader);
- }
- }
- catch (Exception)
- {
- return null;
- }
- return null;
- }
- }
- public class InitialMessage : SocketMessage
- {
- public override MessageType Type => MessageType.Initial;
- public Guid SessionID { get; set; }
- public Platform Platform { get; set; }
- public InitialMessage(Guid sessionID, Platform platform)
- {
- SessionID = sessionID;
- Platform = platform;
- }
- protected override void Write(ByteWriter writer)
- {
- writer.WriteGuid(SessionID)
- .WriteByte((byte)Platform);
- }
- public static InitialMessage ReadMessage(ByteReader data)
- {
- var session = data.ReadGuid();
- var platform = (Platform)data.ReadByte();
- return new InitialMessage(session, platform);
- }
- }
- public class NotifyMessage : SocketMessage
- {
- public override MessageType Type => MessageType.Notify;
- public string EntityType;
- public string EntityData;
- private NotifyMessage(string entityType, string entityData)
- {
- EntityType = entityType;
- EntityData = entityData;
- }
- protected override void Write(ByteWriter writer)
- {
- writer.WriteUTF8String(EntityType);
- writer.WriteUTF8String(EntityData);
- }
- public static NotifyMessage ReadMessage(ByteReader reader)
- {
- var type = reader.ReadUTF8String();
- var data = reader.ReadUTF8String();
- return new NotifyMessage(type, data);
- }
- public static NotifyMessage Notify<TNotification>(TNotification notification)
- {
- return new NotifyMessage(typeof(TNotification).EntityName(), Serialization.Serialize(notification));
- }
- public static NotifyMessage Notify(Type TNotification, object notification)
- {
- return new NotifyMessage(TNotification.EntityName(), Serialization.Serialize(notification));
- }
- }
- }
|