/*************************************************************************** * PacketReader.cs * ------------------- * begin : May 1, 2002 * copyright : (C) The RunUO Software Team * email : info@runuo.com * * $Id$ * ***************************************************************************/ /*************************************************************************** * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * ***************************************************************************/ using System; using System.Text; using System.IO; namespace Server.Network { public class PacketReader { private byte[] m_Data; private int m_Size; private int m_Index; public PacketReader( byte[] data, int size, bool fixedSize ) { m_Data = data; m_Size = size; m_Index = fixedSize ? 1 : 3; } public byte[] Buffer { get { return m_Data; } } public int Size { get { return m_Size; } } public void Trace( NetState state ) { try { using ( StreamWriter sw = new StreamWriter( "Packets.log", true ) ) { byte[] buffer = m_Data; if ( buffer.Length > 0 ) sw.WriteLine( "Client: {0}: Unhandled packet 0x{1:X2}", state, buffer[0] ); using ( MemoryStream ms = new MemoryStream( buffer ) ) Utility.FormatBuffer( sw, ms, buffer.Length ); sw.WriteLine(); sw.WriteLine(); } } catch { } } public int Seek( int offset, SeekOrigin origin ) { switch ( origin ) { case SeekOrigin.Begin: m_Index = offset; break; case SeekOrigin.Current: m_Index += offset; break; case SeekOrigin.End: m_Index = m_Size - offset; break; } return m_Index; } public int ReadInt32() { if ( (m_Index + 4) > m_Size ) return 0; return (m_Data[m_Index++] << 24) | (m_Data[m_Index++] << 16) | (m_Data[m_Index++] << 8) | m_Data[m_Index++]; } public short ReadInt16() { if ( (m_Index + 2) > m_Size ) return 0; return (short)((m_Data[m_Index++] << 8) | m_Data[m_Index++]); } public byte ReadByte() { if ( (m_Index + 1) > m_Size ) return 0; return m_Data[m_Index++]; } public uint ReadUInt32() { if ( (m_Index + 4) > m_Size ) return 0; return (uint)((m_Data[m_Index++] << 24) | (m_Data[m_Index++] << 16) | (m_Data[m_Index++] << 8) | m_Data[m_Index++]); } public ushort ReadUInt16() { if ( (m_Index + 2) > m_Size ) return 0; return (ushort)((m_Data[m_Index++] << 8) | m_Data[m_Index++]); } public sbyte ReadSByte() { if ( (m_Index + 1) > m_Size ) return 0; return (sbyte)m_Data[m_Index++]; } public bool ReadBoolean() { if ( (m_Index + 1) > m_Size ) return false; return ( m_Data[m_Index++] != 0 ); } public string ReadUnicodeStringLE() { StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < m_Size && (c = (m_Data[m_Index++] | (m_Data[m_Index++] << 8))) != 0 ) sb.Append( (char)c ); return sb.ToString(); } public string ReadUnicodeStringLESafe( int fixedLength ) { int bound = m_Index + (fixedLength << 1); int end = bound; if ( bound > m_Size ) bound = m_Size; StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < bound && (c = (m_Data[m_Index++] | (m_Data[m_Index++] << 8))) != 0 ) { if ( IsSafeChar( c ) ) sb.Append( (char)c ); } m_Index = end; return sb.ToString(); } public string ReadUnicodeStringLESafe() { StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < m_Size && (c = (m_Data[m_Index++] | (m_Data[m_Index++] << 8))) != 0 ) { if ( IsSafeChar( c ) ) sb.Append( (char)c ); } return sb.ToString(); } public string ReadUnicodeStringSafe() { StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < m_Size && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 ) { if ( IsSafeChar( c ) ) sb.Append( (char)c ); } return sb.ToString(); } public string ReadUnicodeString() { StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < m_Size && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 ) sb.Append( (char)c ); return sb.ToString(); } public bool IsSafeChar( int c ) { return ( c >= 0x20 && c < 0xFFFE ); } public string ReadUTF8StringSafe( int fixedLength ) { if ( m_Index >= m_Size ) { m_Index += fixedLength; return String.Empty; } int bound = m_Index + fixedLength; //int end = bound; if ( bound > m_Size ) bound = m_Size; int count = 0; int index = m_Index; int start = m_Index; while ( index < bound && m_Data[index++] != 0 ) ++count; index = 0; byte[] buffer = new byte[count]; int value = 0; while ( m_Index < bound && (value = m_Data[m_Index++]) != 0 ) buffer[index++] = (byte)value; string s = Utility.UTF8.GetString( buffer ); bool isSafe = true; for ( int i = 0; isSafe && i < s.Length; ++i ) isSafe = IsSafeChar( (int) s[i] ); m_Index = start + fixedLength; if ( isSafe ) return s; StringBuilder sb = new StringBuilder( s.Length ); for ( int i = 0; i < s.Length; ++i ) if ( IsSafeChar( (int) s[i] ) ) sb.Append( s[i] ); return sb.ToString(); } public string ReadUTF8StringSafe() { if ( m_Index >= m_Size ) return String.Empty; int count = 0; int index = m_Index; while ( index < m_Size && m_Data[index++] != 0 ) ++count; index = 0; byte[] buffer = new byte[count]; int value = 0; while ( m_Index < m_Size && (value = m_Data[m_Index++]) != 0 ) buffer[index++] = (byte)value; string s = Utility.UTF8.GetString( buffer ); bool isSafe = true; for ( int i = 0; isSafe && i < s.Length; ++i ) isSafe = IsSafeChar( (int) s[i] ); if ( isSafe ) return s; StringBuilder sb = new StringBuilder( s.Length ); for ( int i = 0; i < s.Length; ++i ) { if ( IsSafeChar( (int) s[i] ) ) sb.Append( s[i] ); } return sb.ToString(); } public string ReadUTF8String() { if ( m_Index >= m_Size ) return String.Empty; int count = 0; int index = m_Index; while ( index < m_Size && m_Data[index++] != 0 ) ++count; index = 0; byte[] buffer = new byte[count]; int value = 0; while ( m_Index < m_Size && (value = m_Data[m_Index++]) != 0 ) buffer[index++] = (byte)value; return Utility.UTF8.GetString( buffer ); } public string ReadString() { StringBuilder sb = new StringBuilder(); int c; while ( m_Index < m_Size && (c = m_Data[m_Index++]) != 0 ) sb.Append( (char)c ); return sb.ToString(); } public string ReadStringSafe() { StringBuilder sb = new StringBuilder(); int c; while ( m_Index < m_Size && (c = m_Data[m_Index++]) != 0 ) { if ( IsSafeChar( c ) ) sb.Append( (char)c ); } return sb.ToString(); } public string ReadUnicodeStringSafe( int fixedLength ) { int bound = m_Index + (fixedLength << 1); int end = bound; if ( bound > m_Size ) bound = m_Size; StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < bound && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 ) { if ( IsSafeChar( c ) ) sb.Append( (char)c ); } m_Index = end; return sb.ToString(); } public string ReadUnicodeString( int fixedLength ) { int bound = m_Index + (fixedLength << 1); int end = bound; if ( bound > m_Size ) bound = m_Size; StringBuilder sb = new StringBuilder(); int c; while ( (m_Index + 1) < bound && (c = ((m_Data[m_Index++] << 8) | m_Data[m_Index++])) != 0 ) sb.Append( (char)c ); m_Index = end; return sb.ToString(); } public string ReadStringSafe( int fixedLength ) { int bound = m_Index + fixedLength; int end = bound; if ( bound > m_Size ) bound = m_Size; StringBuilder sb = new StringBuilder(); int c; while ( m_Index < bound && (c = m_Data[m_Index++]) != 0 ) { if ( IsSafeChar( c ) ) sb.Append( (char)c ); } m_Index = end; return sb.ToString(); } public string ReadString( int fixedLength ) { int bound = m_Index + fixedLength; int end = bound; if ( bound > m_Size ) bound = m_Size; StringBuilder sb = new StringBuilder(); int c; while ( m_Index < bound && (c = m_Data[m_Index++]) != 0 ) sb.Append( (char)c ); m_Index = end; return sb.ToString(); } } }