using System; using System.IO; using System.Text; using Filter.Handlers.Login; using Filter.Handlers.Manager; using Filter.Handlers.Zone; namespace Filter.Networking.Instances { internal class Packet : IDisposable { private MemoryStream PacketStream; private BinaryWriter PacketWriter; private 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); } public Boolean SetHeaderAndType() { ReadUInt16(out OPCode); try { 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); Header = TransferHeader; Type = TransferType; OPCode = Convert.ToUInt16((Header << 10) + (Type & 1023)); WriteUInt16(OPCode); } public Packet(Login2TypeServer Type) : this(2, Convert.ToByte(Type)) { } public Packet(Login3TypeClient Type) : this(3, Convert.ToByte(Type)) { } public Packet(Login3TypeServer Type) : this(3, Convert.ToByte(Type)) { } public Packet(Manager2TypeServer Type) : this(2, Convert.ToByte(Type)) { } public Packet(Manager3TypeServer Type) : this(3, Convert.ToByte(Type)) { } public Packet(Manager4TypeClient Type) : this(4, Convert.ToByte(Type)) { } public Packet(Manager8TypeClient Type) : this(8, Convert.ToByte(Type)) { } public Packet(Manager8TypeServer Type) : this(8, Convert.ToByte(Type)) { } public Packet(Manager21TypeClient Type) : this(21, Convert.ToByte(Type)) { } public Packet(Manager25TypeServer Type) : this(25, Convert.ToByte(Type)) { } public Packet(Manager29TypeClient Type) : this(29, Convert.ToByte(Type)) { } public Packet(Manager38TypeClient Type) : this(38, Convert.ToByte(Type)) { } public Packet(Zone2TypeServer Type) : this(2, Convert.ToByte(Type)) { } public Packet(Zone6TypeClient Type) : this(6, Convert.ToByte(Type)) { } public Packet(Zone8TypeClient Type) : this(8, Convert.ToByte(Type)) { } public Packet(Zone26TypeClient Type) : this(26, Convert.ToByte(Type)) { } public Boolean ReadUInt16(out UInt16 Value) { if (Remaining < 2) { Value = 0; return false; } Value = PacketReader.ReadUInt16(); return true; } public Boolean ReadInt16(out Int16 Value) { if (Remaining < 2) { Value = 0; return false; } Value = PacketReader.ReadInt16(); return true; } public Boolean ReadString(out String Value) { Byte Length; if (!ReadByte(out Length)) { Value = String.Empty; return false; } if (Remaining < Length) { Value = String.Empty; return false; } return ReadString(out Value, Length); } public Boolean ReadString(out String Value, Int32 ReadLength) { if (Remaining < ReadLength) { Value = String.Empty; return false; } Byte[] Buffer = new Byte[ReadLength]; if(!ReadBytes(Buffer)) { Value = String.Empty; return false; } Int32 Length = 0; if (Buffer[ReadLength - 1] != 0) { Length = ReadLength; } else { while (Buffer[Length] != 0x00 && Length < ReadLength) { Length++; } } if (Length > 0) { Value = Encoding.Default.GetString(Buffer, 0, Length); return true; } Value = String.Empty; return false; } public Boolean ReadByte(out Byte Value) { if (Remaining < 1) { Value = 0; return false; } Value = PacketReader.ReadByte(); return true; } public Boolean ReadBytes(Byte[] Buffer) { if (Remaining < Buffer.Length) { return false; } PacketStream.Read(Buffer, 0, Buffer.Length); return true; } public Boolean ReadBytes(Byte[] Buffer, Int32 Length) { if (Remaining < Length) { return false; } Buffer = PacketReader.ReadBytes(Length); return true; } public void WriteUInt16(UInt16 Value) { PacketWriter.Write(Value); } public void WriteInt16(Int16 Value) { PacketWriter.Write(Value); } public void WriteString(String Value) { PacketWriter.Write(Encoding.Default.GetBytes(Value)); } public void WriteString(String Value, Boolean WriteLength) { WriteByte(Convert.ToByte(Value.Length)); WriteBytes(Encoding.Default.GetBytes(Value)); } public void WriteString(String Value, Int32 FillLength) { Byte[] Buffer = Encoding.Default.GetBytes(Value); WriteBytes(Buffer); for (Int32 Counter = 0; Counter < FillLength - Buffer.Length; Counter++) { WriteByte(0); } } public void WriteByte(Byte Value) { PacketWriter.Write(Value); } public void WriteBytes(Byte[] Value) { PacketWriter.Write(Value); } public void ToArray(FiestaCrypto Crypto, out Byte[] PacketBuffer) { 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; } public void ToArray(out Byte[] PacketBuffer) { 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; } ~Packet() { Dispose(); } public void Dispose() { try { PacketReader.Dispose(); } catch { } try { PacketWriter.Dispose(); } catch { } try { PacketStream.Dispose(); } catch { } } } }