mysimulation/server/FSO.Server.Protocol/Aries/AriesProtocolEncoder.cs
Tony Bark 22191ce648 Removed NioTSO client and server
- NioTSO client isn't needed because we're using RayLib
- Added FreeSO's API server to handle most backend operations
2024-05-01 02:55:43 -04:00

166 lines
5.6 KiB
C#
Executable file

using FSO.Common.Serialization;
using FSO.Server.Protocol.Electron;
using FSO.Server.Protocol.Gluon;
using FSO.Server.Protocol.Voltron;
using Mina.Core.Buffer;
using Mina.Core.Session;
using Mina.Filter.Codec;
using System;
namespace FSO.Server.Protocol.Aries
{
public class AriesProtocolEncoder : IProtocolEncoder
{
//private static Logger LOG = LogManager.GetCurrentClassLogger();
private ISerializationContext Context;
public AriesProtocolEncoder(ISerializationContext context)
{
this.Context = context;
}
public void Dispose(IoSession session)
{
}
public void Encode(IoSession session, object message, IProtocolEncoderOutput output)
{
if (message is IVoltronPacket)
{
EncodeVoltron(session, message, output);
}
else if (message is IElectronPacket)
{
EncodeElectron(session, message, output);
}else if(message is IGluonPacket)
{
EncodeGluon(session, message, output);
}
else if (message is IAriesPacket)
{
EncodeAries(session, message, output);
}
else if (message.GetType().IsArray)
{
object[] arr = (object[])message;
bool allVoltron = true;
for (var i = 0; i < arr.Length; i++)
{
if (!(arr[i] is IVoltronPacket))
{
allVoltron = false;
break;
}
}
//TODO: Chunk these into fewer packets
for (var i = 0; i < arr.Length; i++)
{
Encode(session, arr[i], output);
}
}
}
private void EncodeAries(IoSession session, object message, IProtocolEncoderOutput output)
{
IAriesPacket ariesPacket = (IAriesPacket)message;
AriesPacketType ariesPacketType = ariesPacket.GetPacketType();
var payload = IoBuffer.Allocate(128);
payload.Order = ByteOrder.LittleEndian;
payload.AutoExpand = true;
ariesPacket.Serialize(payload, Context);
payload.Flip();
int payloadSize = payload.Remaining;
IoBuffer headers = IoBuffer.Allocate(12);
headers.Order = ByteOrder.LittleEndian;
/**
* Aries header
* uint32 type
* uint32 timestamp
* uint32 payloadSize
*/
uint timestamp = (uint)TimeSpan.FromTicks(DateTime.Now.Ticks - session.CreationTime.Ticks).TotalMilliseconds;
headers.PutUInt32(ariesPacketType.GetPacketCode());
headers.PutUInt32(timestamp);
headers.PutUInt32((uint)payloadSize);
if (payloadSize > 0)
{
headers.AutoExpand = true;
headers.Put(payload);
}
headers.Flip();
output.Write(headers);
//output.Flush();
}
private void EncodeVoltron(IoSession session, object message, IProtocolEncoderOutput output)
{
IVoltronPacket voltronPacket = (IVoltronPacket)message;
VoltronPacketType voltronPacketType = voltronPacket.GetPacketType();
EncodeVoltronStylePackets(session, output, AriesPacketType.Voltron, voltronPacketType.GetPacketCode(), voltronPacket);
}
private void EncodeElectron(IoSession session, object message, IProtocolEncoderOutput output)
{
IElectronPacket packet = (IElectronPacket)message;
ElectronPacketType packetType = packet.GetPacketType();
EncodeVoltronStylePackets(session, output, AriesPacketType.Electron, packetType.GetPacketCode(), packet);
}
private void EncodeGluon(IoSession session, object message, IProtocolEncoderOutput output)
{
IGluonPacket packet = (IGluonPacket)message;
GluonPacketType packetType = packet.GetPacketType();
EncodeVoltronStylePackets(session, output, AriesPacketType.Gluon, packetType.GetPacketCode(), packet);
}
private void EncodeVoltronStylePackets(IoSession session, IProtocolEncoderOutput output, AriesPacketType ariesType, ushort packetType, IoBufferSerializable message)
{
var payload = IoBuffer.Allocate(512);
payload.Order = ByteOrder.BigEndian;
payload.AutoExpand = true;
message.Serialize(payload, Context);
payload.Flip();
int payloadSize = payload.Remaining;
IoBuffer headers = IoBuffer.Allocate(18);
headers.Order = ByteOrder.LittleEndian;
/**
* Aries header
* uint32 type
* uint32 timestamp
* uint32 payloadSize
*/
uint timestamp = (uint)TimeSpan.FromTicks(DateTime.Now.Ticks - session.CreationTime.Ticks).TotalMilliseconds;
headers.PutUInt32(ariesType.GetPacketCode());
headers.PutUInt32(timestamp);
headers.PutUInt32((uint)payloadSize + 6);
/**
* Voltron header
* uint16 type
* uint32 payloadSize
*/
headers.Order = ByteOrder.BigEndian;
headers.PutUInt16(packetType);
headers.PutUInt32((uint)payloadSize + 6);
if (payloadSize > 0)
{
headers.AutoExpand = true;
headers.Put(payload);
}
headers.Flip();
output.Write(headers);
//output.Flush();
}
}
}