public abstract class Packet { protected PacketWriter m_Stream; private int m_PacketID; private int m_Length; public int PacketID { get{ return m_PacketID; } } public Packet( int packetID ) { m_PacketID = packetID; PacketProfile prof = PacketProfile.GetOutgoingProfile( (byte)packetID ); if ( prof != null ) prof.RegConstruct(); } public void EnsureCapacity( int length ) { m_Stream = PacketWriter.CreateInstance( length );// new PacketWriter( length ); m_Stream.Write( (byte) m_PacketID ); m_Stream.Write( (short) 0 ); } public Packet( int packetID, int length ) { m_PacketID = packetID; m_Length = length; m_Stream = PacketWriter.CreateInstance( length );// new PacketWriter( length ); m_Stream.Write( (byte) packetID ); PacketProfile prof = PacketProfile.GetOutgoingProfile( (byte)packetID ); if ( prof != null ) prof.RegConstruct(); } public PacketWriter UnderlyingStream { get { return m_Stream; } } private byte[] m_CompiledBuffer; public byte[] Compile( bool compress ) { if ( m_CompiledBuffer == null ) InternalCompile( compress ); return m_CompiledBuffer; } private void InternalCompile( bool compress ) { if ( m_Length == 0 ) { long streamLen = m_Stream.Length; m_Stream.Seek( 1, SeekOrigin.Begin ); m_Stream.Write( (ushort) streamLen ); } else if ( m_Stream.Length != m_Length ) { int diff = (int)m_Stream.Length - m_Length; Console.WriteLine( "Packet: 0x{0:X2}: Bad packet length! ({1}{2} bytes)", m_PacketID, diff >= 0 ? "+" : "", diff ); } MemoryStream ms = m_Stream.UnderlyingStream; int length; m_CompiledBuffer = ms.GetBuffer(); length = (int)ms.Length; if ( compress ) { try { Compression.Compress( m_CompiledBuffer, length, out m_CompiledBuffer, out length ); } catch ( IndexOutOfRangeException ) { Console.WriteLine( "Warning: Compression buffer overflowed on packet 0x{0:X2} ('{1}') (length={2})", m_PacketID, GetType().Name, length ); m_CompiledBuffer = null; } } if ( m_CompiledBuffer != null ) { byte[] old = m_CompiledBuffer; m_CompiledBuffer = new byte[length]; Buffer.BlockCopy( old, 0, m_CompiledBuffer, 0, length ); } PacketWriter.ReleaseInstance( m_Stream ); m_Stream = null; } }