using System; using System.IO; using System.Text; namespace FilterAPI.Networking { public class Packet : IDisposable { private MemoryStream PacketStream; public BinaryWriter PacketWriter; public BinaryReader PacketReader; public Int32 Remaining { get { return Convert.ToInt32(PacketStream.Length - PacketStream.Position); } } public UInt16 OPCode; public Byte Header; public Byte Type; public Packet(Byte[] Buffer) { PacketStream = new MemoryStream(Buffer); PacketReader = new BinaryReader(PacketStream, Encoding.Default, false); } private bool disposed = false; protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { if (PacketReader != null) { PacketReader.Close(); PacketReader.Dispose(); } if (PacketWriter != null) { PacketWriter.Close(); PacketWriter.Dispose(); } if (PacketStream != null) { PacketStream.Close(); PacketStream.Dispose(); } } disposed = true; } } public void Dispose() { Dispose(true); } ~Packet() { Dispose(false); } public Boolean SetHeaderAndType() { if (disposed) { return false; } try { OPCode = PacketReader.ReadUInt16(); Header = Convert.ToByte(OPCode >> 10); Type = Convert.ToByte(OPCode & 1023); return true; } catch { return false; } } public Packet(Byte TransferHeader, Byte TransferType) { PacketStream = new MemoryStream(); PacketWriter = new BinaryWriter(PacketStream, Encoding.Default, false); Header = TransferHeader; Type = TransferType; OPCode = Convert.ToUInt16((Header << 10) + (Type & 1023)); PacketWriter.Write((UInt16)OPCode); } public String ReadString(Int32 ReadLength) { if (disposed) { return String.Empty; } else if (Remaining < ReadLength) { return String.Empty; } Byte[] Buffer = new Byte[ReadLength]; if (!ReadBytes(Buffer)) { return String.Empty; } Int32 Length = 0; if (Buffer[ReadLength - 1] != 0) { Length = ReadLength; } else { while (Buffer[Length] != 0x00 && Length < ReadLength) { Length++; } } if (Length > 0) { return Encoding.Default.GetString(Buffer, 0, Length); } return String.Empty; } public Boolean ReadBytes(Byte[] Buffer) { if (disposed) { return false; } else if (Remaining < Buffer.Length) { return false; } PacketStream.Read(Buffer, 0, Buffer.Length); return true; } public void WriteString(String Value) { if (disposed) { return; } PacketWriter.Write(Encoding.Default.GetBytes(Value)); } public void WriteString(String Value, Int32 FillLength) { if (disposed) { return; } Byte[] Buffer = Encoding.Default.GetBytes(Value); PacketWriter.Write(Buffer); for (Int32 Counter = 0; Counter < FillLength - Buffer.Length; Counter++) { PacketWriter.Write((Byte)0); } } public void WriteBytes(Byte[] Value) { if (disposed) { return; } PacketWriter.Write(Value); } public void ToArray(out Byte[] PacketBuffer) { if (disposed) { PacketBuffer = new Byte[0]; return; } try { Byte[] BuildBuffer; Byte[] StreamBuffer = PacketStream.ToArray(); if (StreamBuffer.Length <= 0xff) { BuildBuffer = new Byte[StreamBuffer.Length + 1]; Buffer.BlockCopy(StreamBuffer, 0, BuildBuffer, 1, StreamBuffer.Length); BuildBuffer[0] = Convert.ToByte(StreamBuffer.Length); } else { BuildBuffer = new Byte[StreamBuffer.Length + 3]; Buffer.BlockCopy(StreamBuffer, 0, BuildBuffer, 3, StreamBuffer.Length); Buffer.BlockCopy(BitConverter.GetBytes(Convert.ToUInt16(StreamBuffer.Length)), 0, BuildBuffer, 1, 2); } PacketBuffer = BuildBuffer; } catch { PacketBuffer = new Byte[0]; } } public void ToArray(FiestaCrypto Crypto, out Byte[] PacketBuffer) { if (disposed) { PacketBuffer = new Byte[1]; return; } try { Byte[] BuildBuffer; Byte[] StreamBuffer = PacketStream.ToArray(); Crypto.Crypt(StreamBuffer, 0, StreamBuffer.Length); if (StreamBuffer.Length <= 0xff) { BuildBuffer = new Byte[StreamBuffer.Length + 1]; Buffer.BlockCopy(StreamBuffer, 0, BuildBuffer, 1, StreamBuffer.Length); BuildBuffer[0] = Convert.ToByte(StreamBuffer.Length); } else { BuildBuffer = new Byte[StreamBuffer.Length + 3]; Buffer.BlockCopy(StreamBuffer, 0, BuildBuffer, 3, StreamBuffer.Length); Buffer.BlockCopy(BitConverter.GetBytes(Convert.ToUInt16(StreamBuffer.Length)), 0, BuildBuffer, 1, 2); } PacketBuffer = BuildBuffer; } catch { PacketBuffer = new Byte[1]; } } } }