You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
101 lines
2.4 KiB
101 lines
2.4 KiB
3 years ago
|
using System;
|
||
|
using System.IO;
|
||
|
|
||
|
namespace ET
|
||
|
{
|
||
|
public enum ParserState
|
||
|
{
|
||
|
PacketSize,
|
||
|
PacketBody
|
||
|
}
|
||
|
|
||
|
public class PacketParser
|
||
|
{
|
||
|
private readonly CircularBuffer buffer;
|
||
|
private int packetSize;
|
||
|
private ParserState state;
|
||
|
public AService service;
|
||
|
private readonly byte[] cache = new byte[8];
|
||
|
public const int InnerPacketSizeLength = 4;
|
||
|
public const int OuterPacketSizeLength = 2;
|
||
|
public MemoryStream MemoryStream;
|
||
|
|
||
|
public PacketParser(CircularBuffer buffer, AService service)
|
||
|
{
|
||
|
this.buffer = buffer;
|
||
|
this.service = service;
|
||
|
}
|
||
|
|
||
|
public bool Parse()
|
||
|
{
|
||
|
while (true)
|
||
|
{
|
||
|
switch (this.state)
|
||
|
{
|
||
|
case ParserState.PacketSize:
|
||
|
{
|
||
|
if (this.service.ServiceType == ServiceType.Inner)
|
||
|
{
|
||
|
if (this.buffer.Length < InnerPacketSizeLength)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
this.buffer.Read(this.cache, 0, InnerPacketSizeLength);
|
||
|
|
||
|
this.packetSize = BitConverter.ToInt32(this.cache, 0);
|
||
|
if (this.packetSize > ushort.MaxValue * 16 || this.packetSize < Packet.MinPacketSize)
|
||
|
{
|
||
|
throw new Exception($"recv packet size error, 可能是外网探测端口: {this.packetSize}");
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (this.buffer.Length < OuterPacketSizeLength)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
this.buffer.Read(this.cache, 0, OuterPacketSizeLength);
|
||
|
|
||
|
this.packetSize = BitConverter.ToUInt16(this.cache, 0);
|
||
|
if (this.packetSize < Packet.MinPacketSize)
|
||
|
{
|
||
|
throw new Exception($"recv packet size error, 可能是外网探测端口: {this.packetSize}");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
this.state = ParserState.PacketBody;
|
||
|
break;
|
||
|
}
|
||
|
case ParserState.PacketBody:
|
||
|
{
|
||
|
if (this.buffer.Length < this.packetSize)
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
MemoryStream memoryStream = new MemoryStream(this.packetSize);
|
||
|
this.buffer.Read(memoryStream, this.packetSize);
|
||
|
//memoryStream.SetLength(this.packetSize - Packet.MessageIndex);
|
||
|
this.MemoryStream = memoryStream;
|
||
|
|
||
|
if (this.service.ServiceType == ServiceType.Inner)
|
||
|
{
|
||
|
memoryStream.Seek(Packet.MessageIndex, SeekOrigin.Begin);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
memoryStream.Seek(Packet.OpcodeLength, SeekOrigin.Begin);
|
||
|
}
|
||
|
|
||
|
this.state = ParserState.PacketSize;
|
||
|
return true;
|
||
|
}
|
||
|
default:
|
||
|
throw new ArgumentOutOfRangeException();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|