mirror of
https://github.com/ACEmulator/ACE
synced 2026-08-17 12:26:06 -04:00
53 lines
1.9 KiB
C#
53 lines
1.9 KiB
C#
using System.IO;
|
|
|
|
namespace ACE.Common.Extensions
|
|
{
|
|
public static class BinaryReaderExtensions
|
|
{
|
|
private static uint CalculatePadMultiple(uint length, uint multiple)
|
|
{
|
|
return multiple * ((length + multiple - 1u) / multiple) - length;
|
|
}
|
|
|
|
public static string ReadString32L(this BinaryReader reader)
|
|
{
|
|
uint length = reader.ReadUInt32();
|
|
|
|
// 32L strings are crazy. the only place this is known as of time of writing this is in the
|
|
// Login header packet. it's a DWORD of the data length, followed by a packed word of the
|
|
// string length. for most cases, this means the string comes out with a 1 or 2 character
|
|
// prefix that just needs to get tossed.
|
|
|
|
if (length == 0)
|
|
return "";
|
|
|
|
reader.Skip(1);
|
|
length--;
|
|
|
|
if (length > 255)
|
|
{
|
|
reader.Skip(1);
|
|
length--;
|
|
}
|
|
|
|
string rdrStr = (length != 0 ? new string(reader.ReadChars((int)length)) : string.Empty);
|
|
|
|
// in the login header, this is completely unnecessary as it's the end of the packet. if
|
|
// we find this is ever used somewhere else, we would need to validate it.
|
|
reader.Skip(CalculatePadMultiple(sizeof(uint) + length, 4u));
|
|
return rdrStr;
|
|
}
|
|
|
|
public static string ReadString16L(this BinaryReader reader)
|
|
{
|
|
ushort length = reader.ReadUInt16();
|
|
string rdrStr = (length != 0 ? new string(reader.ReadChars(length)) : string.Empty);
|
|
|
|
// client pads string length to be a multiple of 4 including the 2 bytes for length
|
|
reader.Skip(CalculatePadMultiple(sizeof(ushort) + (uint)length, 4u));
|
|
return rdrStr;
|
|
}
|
|
|
|
public static void Skip(this BinaryReader reader, uint length) { reader.BaseStream.Position += length; }
|
|
}
|
|
}
|