Targets .NET Core 3.0 (#39)
This commit is contained in:
parent
0993c03b70
commit
08bf44af9a
125 changed files with 1473 additions and 14244 deletions
|
|
@ -18,25 +18,29 @@
|
|||
*
|
||||
***************************************************************************/
|
||||
|
||||
using System;
|
||||
using System.Buffers;
|
||||
using System.IO;
|
||||
using System.IO.Pipelines;
|
||||
using System.Text;
|
||||
|
||||
namespace Server.Network
|
||||
{
|
||||
public class PacketReader
|
||||
public ref struct PacketReader
|
||||
{
|
||||
private int m_Index;
|
||||
private SequenceReader<byte> m_Reader;
|
||||
|
||||
public PacketReader(byte[] data, int size, bool fixedSize)
|
||||
public SequencePosition Position => m_Reader.Position;
|
||||
public long Length => m_Reader.Length;
|
||||
public long Consumed => m_Reader.Consumed;
|
||||
public long Remaining => m_Reader.Remaining;
|
||||
|
||||
public PacketReader(ReadOnlySequence<byte> seq)
|
||||
{
|
||||
Buffer = data;
|
||||
Size = size;
|
||||
m_Index = fixedSize ? 1 : 3;
|
||||
m_Reader = new SequenceReader<byte>(seq);
|
||||
}
|
||||
|
||||
public byte[] Buffer{ get; }
|
||||
|
||||
public int Size{ get; }
|
||||
public byte Peek() => m_Reader.TryPeek(out byte value) ? value : (byte)0;
|
||||
|
||||
public void Trace(NetState state)
|
||||
{
|
||||
|
|
@ -44,7 +48,7 @@ namespace Server.Network
|
|||
{
|
||||
using (StreamWriter sw = new StreamWriter("Packets.log", true))
|
||||
{
|
||||
byte[] buffer = Buffer;
|
||||
byte[] buffer = m_Reader.Sequence.ToArray();
|
||||
|
||||
if (buffer.Length > 0)
|
||||
sw.WriteLine("Client: {0}: Unhandled packet 0x{1:X2}", state, buffer[0]);
|
||||
|
|
@ -64,113 +68,83 @@ namespace Server.Network
|
|||
}
|
||||
}
|
||||
|
||||
public int Seek(int offset, SeekOrigin origin)
|
||||
public SequencePosition Seek(long offset, SeekOrigin origin)
|
||||
{
|
||||
switch (origin)
|
||||
{
|
||||
case SeekOrigin.Begin:
|
||||
m_Index = offset;
|
||||
if (offset < m_Reader.Consumed)
|
||||
m_Reader.Rewind(m_Reader.Consumed - Math.Max(offset, 0L));
|
||||
else
|
||||
m_Reader.Advance(offset - m_Reader.Consumed);
|
||||
break;
|
||||
case SeekOrigin.Current:
|
||||
m_Index += offset;
|
||||
if (offset < 0)
|
||||
m_Reader.Rewind(Math.Min(m_Reader.Consumed, offset * -1));
|
||||
else
|
||||
m_Reader.Advance(Math.Min(m_Reader.Remaining, offset));
|
||||
break;
|
||||
case SeekOrigin.End:
|
||||
m_Index = Size - offset;
|
||||
long count = m_Reader.Remaining - offset;
|
||||
if (count < 0)
|
||||
m_Reader.Rewind(count * -1);
|
||||
else if (count > 0)
|
||||
m_Reader.Advance(count);
|
||||
break;
|
||||
}
|
||||
|
||||
return m_Index;
|
||||
return m_Reader.Position;
|
||||
}
|
||||
|
||||
public int ReadInt32()
|
||||
{
|
||||
if (m_Index + 4 > Size)
|
||||
return 0;
|
||||
public bool TryReadByte(out byte value) => m_Reader.TryRead(out value);
|
||||
|
||||
return (Buffer[m_Index++] << 24)
|
||||
| (Buffer[m_Index++] << 16)
|
||||
| (Buffer[m_Index++] << 8)
|
||||
| Buffer[m_Index++];
|
||||
}
|
||||
public int ReadInt32() => m_Reader.TryReadBigEndian(out int value) ? value : 0;
|
||||
|
||||
public short ReadInt16()
|
||||
{
|
||||
if (m_Index + 2 > Size)
|
||||
return 0;
|
||||
public short ReadInt16() => m_Reader.TryReadBigEndian(out short value) ? value : (short)0;
|
||||
|
||||
return (short)((Buffer[m_Index++] << 8) | Buffer[m_Index++]);
|
||||
}
|
||||
public byte ReadByte() => m_Reader.TryRead(out byte value) ? value : (byte)0;
|
||||
|
||||
public byte ReadByte()
|
||||
{
|
||||
if (m_Index + 1 > Size)
|
||||
return 0;
|
||||
public uint ReadUInt32() => (uint)ReadInt32();
|
||||
|
||||
return Buffer[m_Index++];
|
||||
}
|
||||
public ushort ReadUInt16() => (ushort)ReadInt16();
|
||||
|
||||
public uint ReadUInt32()
|
||||
{
|
||||
if (m_Index + 4 > Size)
|
||||
return 0;
|
||||
public sbyte ReadSByte() => (sbyte)ReadByte();
|
||||
|
||||
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 bool ReadBoolean() => ReadByte() > 0;
|
||||
|
||||
public string ReadUnicodeStringLE()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int c;
|
||||
|
||||
while (m_Index + 1 < Size && (c = Buffer[m_Index++] | (Buffer[m_Index++] << 8)) != 0)
|
||||
while (m_Reader.TryReadLittleEndian(out short c) && c != 0)
|
||||
sb.Append((char)c);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
public string ReadUnicodeStringLE(int fixedLength)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
while (fixedLength-- > 0 && m_Reader.TryReadLittleEndian(out short c) && c != 0)
|
||||
sb.Append((char)c);
|
||||
|
||||
if (fixedLength > 0)
|
||||
m_Reader.Advance(fixedLength);
|
||||
|
||||
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)
|
||||
while (fixedLength-- > 0 && m_Reader.TryReadLittleEndian(out short c) && c != 0)
|
||||
if (IsSafeChar(c))
|
||||
sb.Append((char)c);
|
||||
|
||||
m_Index = end;
|
||||
if (fixedLength > 0)
|
||||
m_Reader.Advance(fixedLength * 2);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
@ -179,9 +153,7 @@ namespace Server.Network
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int c;
|
||||
|
||||
while (m_Index + 1 < Size && (c = Buffer[m_Index++] | (Buffer[m_Index++] << 8)) != 0)
|
||||
while (m_Reader.TryReadLittleEndian(out short c) && c != 0)
|
||||
if (IsSafeChar(c))
|
||||
sb.Append((char)c);
|
||||
|
||||
|
|
@ -192,9 +164,7 @@ namespace Server.Network
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int c;
|
||||
|
||||
while (m_Index + 1 < Size && (c = (Buffer[m_Index++] << 8) | Buffer[m_Index++]) != 0)
|
||||
while (m_Reader.TryReadBigEndian(out short c) && c != 0)
|
||||
if (IsSafeChar(c))
|
||||
sb.Append((char)c);
|
||||
|
||||
|
|
@ -205,9 +175,7 @@ namespace Server.Network
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int c;
|
||||
|
||||
while (m_Index + 1 < Size && (c = (Buffer[m_Index++] << 8) | Buffer[m_Index++]) != 0)
|
||||
while (m_Reader.TryReadBigEndian(out short c) && c != 0)
|
||||
sb.Append((char)c);
|
||||
|
||||
return sb.ToString();
|
||||
|
|
@ -220,45 +188,17 @@ namespace Server.Network
|
|||
|
||||
public string ReadUTF8StringSafe(int fixedLength)
|
||||
{
|
||||
if (m_Index >= Size)
|
||||
string s;
|
||||
|
||||
if (m_Reader.TryReadTo(out ReadOnlySpan<byte> span, (byte)'\0', true))
|
||||
s = Utility.UTF8.GetString(span.Length > fixedLength ? span.Slice(0, fixedLength) : span);
|
||||
else
|
||||
{
|
||||
m_Index += fixedLength;
|
||||
return string.Empty;
|
||||
long size = Math.Min(m_Reader.Remaining, fixedLength);
|
||||
s = Utility.UTF8.GetString(m_Reader.Sequence.Slice(m_Reader.Position, size).ToArray());
|
||||
m_Reader.Advance(size);
|
||||
}
|
||||
|
||||
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)
|
||||
|
|
@ -270,32 +210,15 @@ namespace Server.Network
|
|||
|
||||
public string ReadUTF8StringSafe()
|
||||
{
|
||||
if (m_Index >= Size)
|
||||
return string.Empty;
|
||||
string s;
|
||||
|
||||
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;
|
||||
if (m_Reader.TryReadTo(out ReadOnlySpan<byte> span, (byte)'\0', true))
|
||||
s = Utility.UTF8.GetString(span);
|
||||
else
|
||||
{
|
||||
s = Utility.UTF8.GetString(m_Reader.Sequence.Slice(m_Reader.Position, m_Reader.Remaining).ToArray());
|
||||
m_Reader.Advance(m_Reader.Remaining);
|
||||
}
|
||||
|
||||
StringBuilder sb = new StringBuilder(s.Length);
|
||||
|
||||
|
|
@ -308,33 +231,17 @@ namespace Server.Network
|
|||
|
||||
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);
|
||||
return Utility.UTF8.GetString(
|
||||
m_Reader.TryReadTo(out ReadOnlySpan<byte> span, (byte)'\0', true) ? span :
|
||||
m_Reader.Sequence.Slice(m_Reader.Position, m_Reader.Remaining).ToArray()
|
||||
);
|
||||
}
|
||||
|
||||
public string ReadString()
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int c;
|
||||
|
||||
while (m_Index < Size && (c = Buffer[m_Index++]) != 0)
|
||||
while (m_Reader.TryRead(out byte c))
|
||||
sb.Append((char)c);
|
||||
|
||||
return sb.ToString();
|
||||
|
|
@ -344,9 +251,7 @@ namespace Server.Network
|
|||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
int c;
|
||||
|
||||
while (m_Index < Size && (c = Buffer[m_Index++]) != 0)
|
||||
while (m_Reader.TryRead(out byte c))
|
||||
if (IsSafeChar(c))
|
||||
sb.Append((char)c);
|
||||
|
||||
|
|
@ -355,84 +260,56 @@ namespace Server.Network
|
|||
|
||||
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)
|
||||
while (fixedLength-- > 0 && m_Reader.TryReadBigEndian(out short c) && c != 0)
|
||||
if (IsSafeChar(c))
|
||||
sb.Append((char)c);
|
||||
|
||||
m_Index = end;
|
||||
if (fixedLength > 0)
|
||||
m_Reader.Advance(fixedLength * 2);
|
||||
|
||||
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)
|
||||
while (fixedLength-- > 0 && m_Reader.TryReadBigEndian(out short c) && c != 0)
|
||||
sb.Append((char)c);
|
||||
|
||||
m_Index = end;
|
||||
if (fixedLength > 0)
|
||||
m_Reader.Advance(fixedLength * 2);
|
||||
|
||||
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)
|
||||
while (fixedLength-- > 0 && m_Reader.TryRead(out byte c) && c != 0)
|
||||
if (IsSafeChar(c))
|
||||
sb.Append((char)c);
|
||||
|
||||
m_Index = end;
|
||||
if (fixedLength > 0)
|
||||
m_Reader.Advance(fixedLength);
|
||||
|
||||
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)
|
||||
while (fixedLength-- > 0 && m_Reader.TryRead(out byte c) && c != 0)
|
||||
sb.Append((char)c);
|
||||
|
||||
m_Index = end;
|
||||
if (fixedLength > 0)
|
||||
m_Reader.Advance(fixedLength);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue