ModernUO/Server/Network/PacketReader.cs

438 lines
No EOL
9.6 KiB
C#

/***************************************************************************
* 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.IO;
using System.Text;
namespace Server.Network
{
public class PacketReader
{
private int m_Index;
public PacketReader(byte[] data, int size, bool fixedSize)
{
Buffer = data;
Size = size;
m_Index = fixedSize ? 1 : 3;
}
public byte[] Buffer{ get; }
public int Size{ get; }
public void Trace(NetState state)
{
try
{
using (StreamWriter sw = new StreamWriter("Packets.log", true))
{
byte[] buffer = Buffer;
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
{
// ignored
}
}
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 = Size - offset;
break;
}
return m_Index;
}
public int ReadInt32()
{
if (m_Index + 4 > Size)
return 0;
return (Buffer[m_Index++] << 24)
| (Buffer[m_Index++] << 16)
| (Buffer[m_Index++] << 8)
| Buffer[m_Index++];
}
public short ReadInt16()
{
if (m_Index + 2 > Size)
return 0;
return (short)((Buffer[m_Index++] << 8) | Buffer[m_Index++]);
}
public byte ReadByte()
{
if (m_Index + 1 > Size)
return 0;
return Buffer[m_Index++];
}
public uint ReadUInt32()
{
if (m_Index + 4 > Size)
return 0;
return (uint)((Buffer[m_Index++] << 24) | (Buffer[m_Index++] << 16) | (Buffer[m_Index++] << 8) |
Buffer[m_Index++]);
}
public ushort ReadUInt16()
{
if (m_Index + 2 > Size)
return 0;
return (ushort)((Buffer[m_Index++] << 8) | Buffer[m_Index++]);
}
public sbyte ReadSByte()
{
if (m_Index + 1 > Size)
return 0;
return (sbyte)Buffer[m_Index++];
}
public bool ReadBoolean()
{
if (m_Index + 1 > Size)
return false;
return Buffer[m_Index++] != 0;
}
public string ReadUnicodeStringLE()
{
StringBuilder sb = new StringBuilder();
int c;
while (m_Index + 1 < Size && (c = Buffer[m_Index++] | (Buffer[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 > Size)
bound = Size;
StringBuilder sb = new StringBuilder();
int c;
while (m_Index + 1 < bound && (c = Buffer[m_Index++] | (Buffer[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 < Size && (c = Buffer[m_Index++] | (Buffer[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 < Size && (c = (Buffer[m_Index++] << 8) | Buffer[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 < Size && (c = (Buffer[m_Index++] << 8) | Buffer[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 >= Size)
{
m_Index += fixedLength;
return string.Empty;
}
int bound = m_Index + fixedLength;
//int end = bound;
if (bound > Size)
bound = Size;
int count = 0;
int index = m_Index;
int start = m_Index;
while (index < bound && Buffer[index++] != 0)
++count;
index = 0;
byte[] buffer = new byte[count];
int value = 0;
while (m_Index < bound && (value = Buffer[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(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(s[i]))
sb.Append(s[i]);
return sb.ToString();
}
public string ReadUTF8StringSafe()
{
if (m_Index >= Size)
return string.Empty;
int count = 0;
int index = m_Index;
while (index < Size && Buffer[index++] != 0)
++count;
index = 0;
byte[] buffer = new byte[count];
int value = 0;
while (m_Index < Size && (value = Buffer[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(s[i]);
if (isSafe)
return s;
StringBuilder sb = new StringBuilder(s.Length);
for (int i = 0; i < s.Length; ++i)
if (IsSafeChar(s[i]))
sb.Append(s[i]);
return sb.ToString();
}
public string ReadUTF8String()
{
if (m_Index >= Size)
return string.Empty;
int count = 0;
int index = m_Index;
while (index < Size && Buffer[index++] != 0)
++count;
index = 0;
byte[] buffer = new byte[count];
int value = 0;
while (m_Index < Size && (value = Buffer[m_Index++]) != 0)
buffer[index++] = (byte)value;
return Utility.UTF8.GetString(buffer);
}
public string ReadString()
{
StringBuilder sb = new StringBuilder();
int c;
while (m_Index < Size && (c = Buffer[m_Index++]) != 0)
sb.Append((char)c);
return sb.ToString();
}
public string ReadStringSafe()
{
StringBuilder sb = new StringBuilder();
int c;
while (m_Index < Size && (c = Buffer[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 > Size)
bound = Size;
StringBuilder sb = new StringBuilder();
int c;
while (m_Index + 1 < bound && (c = (Buffer[m_Index++] << 8) | Buffer[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 > Size)
bound = Size;
StringBuilder sb = new StringBuilder();
int c;
while (m_Index + 1 < bound && (c = (Buffer[m_Index++] << 8) | Buffer[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 > Size)
bound = Size;
StringBuilder sb = new StringBuilder();
int c;
while (m_Index < bound && (c = Buffer[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 > Size)
bound = Size;
StringBuilder sb = new StringBuilder();
int c;
while (m_Index < bound && (c = Buffer[m_Index++]) != 0)
sb.Append((char)c);
m_Index = end;
return sb.ToString();
}
}
}