servuo/Server/Network/PacketReader.cs
VitaNex 7851c5e88c + Removed most file header regions.
+ Add MONO to Makefile compile definitions.
+ Update Ultima SDK to support MONO compile definition.
+ Rename Properties Gump parent directory to prevent VS issues.
+ Console error messages will now use red instead of dark red font.
+ Add crash state handler function to Core.
+ AI optimizations and housekeeping.
+ Context Menu optimizations and housekeeping.
+ Add ability to drop throttled packets.
+ Add string parsing support to Rectangle3D.
+ Optimize guild messages and chat.
+ IAddon implements IChopable.
+ Add more flexibility for altering Mobile names.
+ Add ability to enable or disable OPL for individual mobiles.
+ Optimize damaging regions and ensure timers are removed properly.
+ Update Welcome Timer with more intuitive message groups.
+ Normalize all virtue related objects to the Server.Services.Virtues namespace.
+ Add ability for ISpawner to append OPL and Context Menus to their spawn.
+ Add EventSink events for obtaining items, equipping items, context menus, and world broadcasts.
+ Add ability to lock a creature's direction and movement regardless of AI manipulation.
+ Add ability to dynamically change a creature's approach range and wait state.
+ Add extended enumeration features for AOS attributes.
+ Add ability to control whether creatures have blood, and its color.
+ Expose corpse flag manipulation methods.
+ Add ability to prevent criminal action when looting a corpse.
+ Corpse will now be permanently tagged as murderer at time of death if owner is a murderer.
+ Add TextDefinition support for Commodity Deed descriptions.
+ House add-on and component optimizations and housekeeping.
+ Item light is no longer backed by the direction property.
+ ITool implements IEntity.
+ Prevent trading of Siege Bless items.
+ Guards are naturally be immune to guards.
+ Siege Shard initialization housekeeping.
+ Character Creation housekeeping.
+ Generic commands housekeeping.
+ Add Mark command for staff.
2018-07-19 22:12:52 +01:00

511 lines
No EOL
8.6 KiB
C#

#region References
using System;
using System.IO;
using System.Text;
#endregion
namespace Server.Network
{
public class PacketReader
{
private readonly byte[] m_Data;
private readonly 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))
{
var 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;
var 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(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 >= m_Size)
{
return String.Empty;
}
int count = 0;
int index = m_Index;
while (index < m_Size && m_Data[index++] != 0)
{
++count;
}
index = 0;
var 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(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 >= m_Size)
{
return String.Empty;
}
int count = 0;
int index = m_Index;
while (index < m_Size && m_Data[index++] != 0)
{
++count;
}
index = 0;
var 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();
}
}
}