diff --git a/.editorconfig b/.editorconfig
index 84d50536e..5acefbd37 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -147,6 +147,7 @@ dotnet_diagnostic.IDE0008.severity = none # using var
# csharp_style_var_for_built_in_types = true:suggestion # suggest using var (implied) variables
# csharp_style_var_when_type_is_apparent = true:suggestion # suggest using var (implied) variables
# csharp_style_var_elsewhere = true:suggestion # suggest using var (implied) variables
+dotnet_diagnostic.RCS1123.severity = none
# ReSharper properties
resharper_apply_auto_detected_rules=false
diff --git a/Projects/Server/Serialization/BinaryFileReader.cs b/Projects/Server/Serialization/BinaryFileReader.cs
index 7a6ac2fde..f540f8e2e 100644
--- a/Projects/Server/Serialization/BinaryFileReader.cs
+++ b/Projects/Server/Serialization/BinaryFileReader.cs
@@ -21,6 +21,15 @@ using System.Text;
namespace Server;
+///
+/// Read bits of data from a serialized file in a managed environment.
+///
+/// Uses the following components collectively:
+///
+///
+///
+///
+///
public sealed unsafe class BinaryFileReader : IDisposable, IGenericReader
{
private readonly bool _usePrefixes;
@@ -28,6 +37,19 @@ public sealed unsafe class BinaryFileReader : IDisposable, IGenericReader
private readonly MemoryMappedViewStream _accessor;
private readonly UnmanagedDataReader _reader;
+ ///
+ /// Read bits of data from a serialized file in a managed environment.
+ ///
Encoding is UTF8 if left null.
+ ///
+ /// Uses the following components collectively:
+ ///
+ ///
+ ///
+ ///
+ ///
+ /// Full file path of the file to be deserialized.
+ /// Sets if strings should be read with itern.
+ /// Set an encoding. By default UTF8
public BinaryFileReader(string path, bool usePrefixes = true, Encoding encoding = null)
{
_usePrefixes = usePrefixes;
@@ -47,6 +69,9 @@ public sealed unsafe class BinaryFileReader : IDisposable, IGenericReader
}
}
+ ///
+ /// How many bits deep into the file is the reader at currently.
+ ///
public long Position => _reader.Position;
public void Dispose()
@@ -56,54 +81,118 @@ public sealed unsafe class BinaryFileReader : IDisposable, IGenericReader
_mmf?.Dispose();
}
+ ///
+ /// If usePrefixes is true, return a ReadString(intern) else ReadStringRaw(intern).
+ ///
+ /// A string value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ReadString(bool intern = false) => _usePrefixes ? _reader.ReadString(intern) : _reader.ReadStringRaw(intern);
-
+ ///
+ /// Returns the next set of bits that make up a string.
+ ///
+ /// Next string value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ReadStringRaw(bool intern = false) => _reader.ReadStringRaw(intern);
-
+ ///
+ /// Read the next 64 bits to make up a long (int64).
+ ///
+ /// Next long value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public long ReadLong() => _reader.ReadLong();
-
+ ///
+ /// Read the next 64 bits to make up an unsigned long (uint64).
+ ///
+ /// Next ulong value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong ReadULong() => _reader.ReadULong();
-
+ ///
+ /// Read the next 32 bits to make up an int (int32).
+ ///
+ /// Next int value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadInt() => _reader.ReadInt();
-
+ ///
+ /// Read the next 32 bits to make up an unsigned int (uint32).
+ ///
+ /// Next uint value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint ReadUInt() => _reader.ReadUInt();
-
+ ///
+ /// Read the next 16 bits to make up a short (int16).
+ ///
+ /// Next short value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short ReadShort() => _reader.ReadShort();
-
+ ///
+ /// Read the next 16 bits to make up an unsigned short (int16).
+ ///
+ /// Next ushort value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ushort ReadUShort() => _reader.ReadUShort();
-
+ ///
+ /// Read the next 8 bits to make up a float point double.
+ ///
+ /// Next double value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public double ReadDouble() => _reader.ReadDouble();
-
+ ///
+ /// Read the next 4 bits to make up a float point.
+ ///
+ /// Next float value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float ReadFloat() => _reader.ReadFloat();
-
+ ///
+ /// Read the next 8 bits to make up a byte.
+ ///
+ /// Next byte value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public byte ReadByte() => _reader.ReadByte();
-
+ ///
+ /// Read the next 8 bits to make up a signed byte.
+ ///
+ /// Next sbyte value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sbyte ReadSByte() => _reader.ReadSByte();
-
+ ///
+ /// Read the next 1 bit to make up a boolean.
+ ///
+ /// Next bool value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ReadBool() => _reader.ReadBool();
-
+ ///
+ /// Read the next 32 bytes to make up a .
+ ///
+ /// Next uint value cast as a struct.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Serial ReadSerial() => _reader.ReadSerial();
+ ///
+ /// Reads the next Byte which helps determin how to read the following Type.
+ ///
If the byte returns 1 => and translate into a Type via the
+ ///
If the byte returns 2 =>
+ ///
else return null
+ ///
+ /// Next Type value
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Type ReadType() => _reader.ReadType();
+ ///
+ /// Reads the next set of bytes to fill the buffer.
+ ///
+ /// A reference span that will be filled with the next set of bytes.
+ /// The length of the buffer.
+ /// Thrown if the buffer is larger than the remaining data to read in the file.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int Read(Span buffer) => _reader.Read(buffer);
+ ///
+ /// Sets the current position of the stream to a specified value.
+ ///
+ /// The new position, relative to the parameter.
+ /// The reference point for the parameter. It can be one of the values of .
+ /// The new position in the stream, in bytes.
+ /// Thrown when the or the resulting position is out of the valid range.
+ /// Thrown if the stream does not support seeking.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public long Seek(long offset, SeekOrigin origin) => _reader.Seek(offset, origin);
}
diff --git a/Projects/Server/Serialization/UnmanagedDataReader.cs b/Projects/Server/Serialization/UnmanagedDataReader.cs
index ed9675abb..9babb86fd 100644
--- a/Projects/Server/Serialization/UnmanagedDataReader.cs
+++ b/Projects/Server/Serialization/UnmanagedDataReader.cs
@@ -25,19 +25,31 @@ using Server.Text;
namespace Server;
+///
+/// Read bits of data raw from a serialized file using Little-endian.
+///
public unsafe class UnmanagedDataReader : IGenericReader
{
private static readonly ILogger logger = LogFactory.GetLogger(typeof(UnmanagedDataReader));
private readonly byte* _ptr;
- private long _position;
private readonly long _size;
private readonly Dictionary _typesDb;
private readonly Encoding _encoding;
- public long Position => _position;
+ ///
+ /// How many bits deep into the file is the reader at currently.
+ ///
+ public long Position { get; private set; }
+ ///
+ /// Read bits of data raw from a serialized file using Little-endian.
+ ///
+ /// The starting address for reading bits.
+ /// The total size of memory to be read.
+ /// The custom type dictionary. Will throw an error if left null ReadType is called.
+ /// by default.
public UnmanagedDataReader(byte* ptr, long size, Dictionary typesDb = null, Encoding encoding = null)
{
_encoding = encoding ?? TextEncoding.UTF8;
@@ -46,9 +58,19 @@ public unsafe class UnmanagedDataReader : IGenericReader
_size = size;
}
+ ///
+ /// Reads the next bit as a bool. If that bit is true, return an else null.
+ ///
+ ///
+ /// Next string value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public string ReadString(bool intern = false) => ReadBool() ? ReadStringRaw(intern) : null;
+ ///
+ /// Returns the next set of bits that make up a string.
+ ///
+ ///
+ /// Next string value.
public string ReadStringRaw(bool intern = false)
{
// ReadEncodedInt
@@ -57,7 +79,7 @@ public unsafe class UnmanagedDataReader : IGenericReader
do
{
- b = *(_ptr + _position++);
+ b = *(_ptr + Position++);
length |= (b & 0x7F) << shift;
shift += 7;
}
@@ -68,95 +90,153 @@ public unsafe class UnmanagedDataReader : IGenericReader
return "".Intern();
}
- var str = TextEncoding.GetString(new ReadOnlySpan(_ptr + _position, length), _encoding);
- _position += length;
+ var str = TextEncoding.GetString(new ReadOnlySpan(_ptr + Position, length), _encoding);
+ Position += length;
return intern ? str.Intern() : str;
}
+ ///
+ /// Read the next 64 bits to make up a long (int64).
+ ///
+ /// Next long value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public long ReadLong()
{
- var v = BinaryPrimitives.ReadInt64LittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(long)));
- _position += sizeof(long);
+ var v = BinaryPrimitives.ReadInt64LittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(long)));
+ Position += sizeof(long);
return v;
}
+ ///
+ /// Read the next 64 bits to make up an unsigned long (uint64).
+ ///
+ /// Next ulong value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ulong ReadULong()
{
- var v = BinaryPrimitives.ReadUInt64LittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(ulong)));
- _position += sizeof(ulong);
+ var v = BinaryPrimitives.ReadUInt64LittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(ulong)));
+ Position += sizeof(ulong);
return v;
}
+ ///
+ /// Read the next 32 bits to make up an int (int32).
+ ///
+ /// Next int value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public int ReadInt()
{
- var v = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(int)));
- _position += sizeof(int);
+ var v = BinaryPrimitives.ReadInt32LittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(int)));
+ Position += sizeof(int);
return v;
}
+ ///
+ /// Read the next 32 bits to make up an unsigned int (uint32).
+ ///
+ /// Next uint value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public uint ReadUInt()
{
- var v = BinaryPrimitives.ReadUInt32LittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(uint)));
- _position += sizeof(uint);
+ var v = BinaryPrimitives.ReadUInt32LittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(uint)));
+ Position += sizeof(uint);
return v;
}
+ ///
+ /// Read the next 16 bits to make up a short (int16).
+ ///
+ /// Next short value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public short ReadShort()
{
- var v = BinaryPrimitives.ReadInt16LittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(short)));
- _position += sizeof(short);
+ var v = BinaryPrimitives.ReadInt16LittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(short)));
+ Position += sizeof(short);
return v;
}
+ ///
+ /// Read the next 16 bits to make up an unsigned short (int16).
+ ///
+ /// Next ushort value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public ushort ReadUShort()
{
- var v = BinaryPrimitives.ReadUInt16LittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(ushort)));
- _position += sizeof(ushort);
+ var v = BinaryPrimitives.ReadUInt16LittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(ushort)));
+ Position += sizeof(ushort);
return v;
}
+ ///
+ /// Read the next 8 bits to make up a float point double.
+ ///
+ /// Next double value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public double ReadDouble()
{
- var v = BinaryPrimitives.ReadDoubleLittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(double)));
- _position += sizeof(double);
+ var v = BinaryPrimitives.ReadDoubleLittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(double)));
+ Position += sizeof(double);
return v;
}
+ ///
+ /// Read the next 4 bits to make up a float point.
+ ///
+ /// Next float value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public float ReadFloat()
{
- var v = BinaryPrimitives.ReadSingleLittleEndian(new ReadOnlySpan(_ptr + _position, sizeof(float)));
- _position += sizeof(float);
+ var v = BinaryPrimitives.ReadSingleLittleEndian(new ReadOnlySpan(_ptr + Position, sizeof(float)));
+ Position += sizeof(float);
return v;
}
+ ///
+ /// Read the next 8 bits to make up a byte.
+ ///
+ /// Next byte value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public byte ReadByte() => *(_ptr + _position++);
-
+ public byte ReadByte() => *(_ptr + Position++);
+ ///
+ /// Read the next 8 bits to make up a signed byte.
+ ///
+ /// Next sbyte value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public sbyte ReadSByte() => (sbyte)ReadByte();
-
+ ///
+ /// Read the next Byte and return true if it's value returns zero.
+ ///
+ /// Next bool value.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool ReadBool() => ReadByte() != 0;
+ ///
+ /// Read the next 32 bytes to make up a .
+ ///
+ /// Next uint value cast as a struct.
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public Serial ReadSerial() => (Serial)ReadUInt();
+ ///
+ /// Reads the next Byte which helps determin how to read the following Type.
+ ///
If the byte returns 1 => and translate into a Type via the
+ ///
If the byte returns 2 =>
+ ///
else return null
+ ///
+ /// Next Type value
public Type ReadType() =>
ReadByte() switch
{
- 0 => null,
1 => AssemblyHandler.FindTypeByFullName(ReadStringRaw()), // Backward compatibility
- 2 => ReadTypeByHash()
+ 2 => ReadTypeByHash(),
+ _ => null,
};
+ ///
+ /// Reads the next to create a hash and convert that into a Type using the .
+ /// Will log an if typesDb is null or typesDb doesn't contain the hash and return null
+ ///
+ /// Next Type value
public Type ReadTypeByHash()
{
var hash = ReadULong();
@@ -205,19 +285,33 @@ public unsafe class UnmanagedDataReader : IGenericReader
return t;
}
+ ///
+ /// Reads the next set of bytes to fill the buffer.
+ ///
+ /// A reference span that will be filled with the next set of bytes.
+ /// The length of the buffer.
+ /// Thrown if the buffer is larger than the remaining data to read in the file.
public int Read(Span buffer)
{
var length = buffer.Length;
- if (length > _size - _position)
+ if (length > _size - Position)
{
throw new OutOfMemoryException();
}
- new ReadOnlySpan(_ptr + _position, length).CopyTo(buffer);
- _position += length;
+ new ReadOnlySpan(_ptr + Position, length).CopyTo(buffer);
+ Position += length;
return length;
}
+ ///
+ /// Sets the current position of the stream to a specified value.
+ ///
+ /// The new position, relative to the parameter.
+ /// The reference point for the parameter. It can be one of the values of .
+ /// The new position in the stream, in bytes.
+ /// Thrown when the or the resulting position is out of the valid range.
+ /// Thrown if the stream does not support seeking.
public virtual long Seek(long offset, SeekOrigin origin)
{
Debug.Assert(
@@ -229,18 +323,16 @@ public unsafe class UnmanagedDataReader : IGenericReader
"Attempting to seek to an invalid position using SeekOrigin.Begin"
);
Debug.Assert(
- origin != SeekOrigin.Current || _position + offset >= 0 && _position + offset < _size,
+ origin != SeekOrigin.Current || Position + offset >= 0 && Position + offset < _size,
"Attempting to seek to an invalid position using SeekOrigin.Current"
);
- var position = Math.Max(0L, origin switch
+ Position = Math.Max(0L, origin switch
{
- SeekOrigin.Current => _position + offset,
+ SeekOrigin.Current => Position + offset,
SeekOrigin.End => _size + offset,
_ => offset // Begin
});
-
- _position = position;
- return _position;
+ return Position;
}
}
diff --git a/Rules.ruleset b/Rules.ruleset
index 32bd4e62c..84b14555f 100644
--- a/Rules.ruleset
+++ b/Rules.ruleset
@@ -1,496 +1,499 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file