mysimulation/server/FSO.Server.Protocol/Aries/AriesProtocolDecoder.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

111 lines
3.9 KiB
C#
Executable file

using Mina.Filter.Codec;
using System;
using Mina.Core.Buffer;
using Mina.Core.Session;
using FSO.Server.Protocol.Voltron;
using FSO.Server.Protocol.Electron;
using FSO.Common.Serialization;
using FSO.Server.Protocol.Utils;
using FSO.Server.Protocol.Gluon;
namespace FSO.Server.Protocol.Aries
{
public class AriesProtocolDecoder : CustomCumulativeProtocolDecoder
{
//private static Logger LOG = LogManager.GetCurrentClassLogger();
private ISerializationContext Context;
public AriesProtocolDecoder(ISerializationContext context)
{
this.Context = context;
}
protected override bool DoDecode(IoSession session, IoBuffer buffer, IProtocolDecoderOutput output)
{
if(buffer.Remaining < 12){
return false;
}
/**
* We expect aries, voltron or electron packets
*/
var startPosition = buffer.Position;
buffer.Order = ByteOrder.LittleEndian;
uint packetType = buffer.GetUInt32();
uint timestamp = buffer.GetUInt32();
uint payloadSize = buffer.GetUInt32();
if (buffer.Remaining < payloadSize)
{
/** Not all here yet **/
buffer.Position = startPosition;
return false;
}
//LOG.Info("[ARIES] " + packetType + " (" + payloadSize + ")");
if(packetType == AriesPacketType.Voltron.GetPacketCode())
{
DecodeVoltronStylePackets(buffer, ref payloadSize, output, VoltronPackets.GetByPacketCode);
}
else if (packetType == AriesPacketType.Electron.GetPacketCode())
{
DecodeVoltronStylePackets(buffer, ref payloadSize, output, ElectronPackets.GetByPacketCode);
}else if(packetType == AriesPacketType.Gluon.GetPacketCode())
{
DecodeVoltronStylePackets(buffer, ref payloadSize, output, GluonPackets.GetByPacketCode);
}
else
{
//Aries
var packetClass = AriesPackets.GetByPacketCode(packetType);
if (packetClass != null)
{
byte[] data = new byte[(int)payloadSize];
buffer.Get(data, 0, (int)payloadSize);
IAriesPacket packet = (IAriesPacket)Activator.CreateInstance(packetClass);
var io = IoBuffer.Wrap(data);
io.Order = ByteOrder.LittleEndian;
packet.Deserialize(io, Context);
output.Write(packet);
payloadSize = 0;
}
else
{
buffer.Skip((int)payloadSize);
payloadSize = 0;
}
}
return true;
}
private void DecodeVoltronStylePackets(IoBuffer buffer, ref uint payloadSize, IProtocolDecoderOutput output, Func<ushort, Type> typeResolver)
{
while (payloadSize > 0)
{
/** Voltron packet **/
buffer.Order = ByteOrder.BigEndian;
ushort type = buffer.GetUInt16();
uint innerPayloadSize = buffer.GetUInt32() - 6;
byte[] data = new byte[(int)innerPayloadSize];
buffer.Get(data, 0, (int)innerPayloadSize);
var packetClass = typeResolver(type);
if (packetClass != null)
{
IoBufferDeserializable packet = (IoBufferDeserializable)Activator.CreateInstance(packetClass);
packet.Deserialize(IoBuffer.Wrap(data), Context);
output.Write(packet);
}
payloadSize -= innerPayloadSize + 6;
}
}
}
}