diff --git a/Projects/Server/Main.cs b/Projects/Server/Main.cs index 0612de954..d2a691ae5 100644 --- a/Projects/Server/Main.cs +++ b/Projects/Server/Main.cs @@ -19,7 +19,6 @@ using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text; using System.Text.Json; diff --git a/Projects/Server/Serialization/BinaryFileReader.cs b/Projects/Server/Serialization/BinaryFileReader.cs index 2170dda9f..51e86bd8b 100644 --- a/Projects/Server/Serialization/BinaryFileReader.cs +++ b/Projects/Server/Serialization/BinaryFileReader.cs @@ -15,7 +15,6 @@ using System; using System.IO; -using System.Net; namespace Server { @@ -35,14 +34,6 @@ namespace Server return intern ? Utility.Intern(str) : str; } - public DateTime ReadDateTime() => new(_reader.ReadInt64(), DateTimeKind.Utc); - - public TimeSpan ReadTimeSpan() => new(_reader.ReadInt64()); - - public DateTime ReadDeltaTime() => new(_reader.ReadInt64() + DateTime.UtcNow.Ticks, DateTimeKind.Utc); - - public decimal ReadDecimal() => _reader.ReadDecimal(); - public long ReadLong() => _reader.ReadInt64(); public ulong ReadULong() => _reader.ReadUInt64(); @@ -65,43 +56,6 @@ namespace Server public bool ReadBool() => _reader.ReadBoolean(); - public int ReadEncodedInt() - { - int v = 0, shift = 0; - byte b; - - do - { - b = _reader.ReadByte(); - v |= (b & 0x7F) << shift; - shift += 7; - } - while (b >= 0x80); - - return v; - } - - public IPAddress ReadIPAddress() - { - byte length = ReadByte(); - // Either 2 ushorts, or 8 ushorts - Span integer = stackalloc byte[length]; - Read(integer); - return Utility.Intern(new IPAddress(integer)); - } - - public Point3D ReadPoint3D() => new(ReadInt(), ReadInt(), ReadInt()); - - public Point2D ReadPoint2D() => new(ReadInt(), ReadInt()); - - public Rectangle2D ReadRect2D() => new(ReadPoint2D(), ReadPoint2D()); - - public Rectangle3D ReadRect3D() => new(ReadPoint3D(), ReadPoint3D()); - - public Map ReadMap() => Map.Maps[ReadByte()]; - - public Race ReadRace() => Race.Races[ReadByte()]; - public int Read(Span buffer) => _reader.Read(buffer); public long Seek(long offset, SeekOrigin origin) => _reader.BaseStream.Seek(offset, origin); diff --git a/Projects/Server/Serialization/BufferReader.cs b/Projects/Server/Serialization/BufferReader.cs index 1d309887a..de0d3208b 100644 --- a/Projects/Server/Serialization/BufferReader.cs +++ b/Projects/Server/Serialization/BufferReader.cs @@ -17,7 +17,6 @@ using System; using System.Buffers.Binary; using System.Diagnostics; using System.IO; -using System.Net; using System.Text; using Server.Text; @@ -52,7 +51,7 @@ namespace Server return null; } - var length = ReadEncodedInt(); + var length = ((IGenericReader)this).ReadEncodedInt(); if (length <= 0) { return intern ? Utility.Intern("") : ""; @@ -63,14 +62,6 @@ namespace Server return intern ? Utility.Intern(str) : str; } - public DateTime ReadDateTime() => new(ReadLong(), DateTimeKind.Utc); - - public TimeSpan ReadTimeSpan() => new(ReadLong()); - - public DateTime ReadDeltaTime() => new(ReadLong() + DateTime.UtcNow.Ticks, DateTimeKind.Utc); - - public decimal ReadDecimal() => new(stackalloc int[4] { ReadInt(), ReadInt(), ReadInt(), ReadInt() }); - public long ReadLong() { var v = BinaryPrimitives.ReadInt64LittleEndian(_buffer.AsSpan(_position, 8)); @@ -133,42 +124,6 @@ namespace Server public bool ReadBool() => _buffer[_position++] != 0; - public int ReadEncodedInt() - { - int v = 0, shift = 0; - byte b; - - do - { - b = ReadByte(); - v |= (b & 0x7F) << shift; - shift += 7; - } while (b >= 0x80); - - return v; - } - - public IPAddress ReadIPAddress() - { - byte length = ReadByte(); - // Either 2 ushorts, or 8 ushorts - Span integer = stackalloc byte[length]; - Read(integer); - return Utility.Intern(new IPAddress(integer)); - } - - public Point3D ReadPoint3D() => new(ReadInt(), ReadInt(), ReadInt()); - - public Point2D ReadPoint2D() => new(ReadInt(), ReadInt()); - - public Rectangle2D ReadRect2D() => new(ReadPoint2D(), ReadPoint2D()); - - public Rectangle3D ReadRect3D() => new(ReadPoint3D(), ReadPoint3D()); - - public Map ReadMap() => Map.Maps[ReadByte()]; - - public Race ReadRace() => Race.Races[ReadByte()]; - public int Read(Span buffer) { var length = buffer.Length; diff --git a/Projects/Server/Serialization/BufferWriter.cs b/Projects/Server/Serialization/BufferWriter.cs index 98c636c54..aa2973e4e 100644 --- a/Projects/Server/Serialization/BufferWriter.cs +++ b/Projects/Server/Serialization/BufferWriter.cs @@ -158,19 +158,6 @@ namespace Server }); } - public void WriteEncodedInt(int value) - { - var v = (uint)value; - - while (v >= 0x80) - { - Write((byte)(v | 0x80)); - v >>= 7; - } - - Write((byte)v); - } - public void Write(string value) { if (m_PrefixStrings) @@ -191,56 +178,6 @@ namespace Server } } - public void Write(DateTime value) - { - var ticks = (value.Kind switch - { - DateTimeKind.Local => value.ToUniversalTime(), - DateTimeKind.Unspecified => value.ToLocalTime().ToUniversalTime(), - _ => value - }).Ticks; - - Write(ticks); - } - - // TODO: Find a way to speed this up. - // Maybe used a special cached value? - public void WriteDeltaTime(DateTime value) - { - var ticks = (value.Kind switch - { - DateTimeKind.Local => value.ToUniversalTime(), - DateTimeKind.Unspecified => value.ToLocalTime().ToUniversalTime(), - _ => value - }).Ticks; - - // Technically supports negative deltas for times in the past - Write(ticks - DateTime.UtcNow.Ticks); - } - - public void Write(IPAddress value) - { - Span stack = stackalloc byte[16]; - value.TryWriteBytes(stack, out var bytesWritten); - Write((byte)bytesWritten); - Write(stack[..bytesWritten]); - } - - public void Write(TimeSpan value) - { - Write(value.Ticks); - } - - public void Write(decimal value) - { - var bits = decimal.GetBits(value); - - for (var i = 0; i < 4; ++i) - { - Write(bits[i]); - } - } - public void Write(long value) { FlushIfNeeded(8); @@ -350,46 +287,11 @@ namespace Server _buffer[Index++] = *(byte*)&value; // up to 30% faster to dereference the raw value on the stack } - public void Write(Point3D value) - { - Write(value.m_X); - Write(value.m_Y); - Write(value.m_Z); - } - - public void Write(Point2D value) - { - Write(value.m_X); - Write(value.m_Y); - } - - public void Write(Rectangle2D value) - { - Write(value.Start); - Write(value.End); - } - - public void Write(Rectangle3D value) - { - Write(value.Start); - Write(value.End); - } - - public void Write(Map value) - { - Write((byte)(value?.MapIndex ?? 0xFF)); - } - - public void Write(Race value) - { - Write((byte)(value?.RaceIndex ?? 0xFF)); - } - internal void InternalWriteString(string value) { var remaining = m_Encoding.GetByteCount(value); - WriteEncodedInt(remaining); + ((IGenericWriter)this).WriteEncodedInt(remaining); if (remaining == 0) { diff --git a/Projects/Server/Serialization/IGenericReader.cs b/Projects/Server/Serialization/IGenericReader.cs index 15f71d8ee..9717debb3 100644 --- a/Projects/Server/Serialization/IGenericReader.cs +++ b/Projects/Server/Serialization/IGenericReader.cs @@ -22,10 +22,6 @@ namespace Server public interface IGenericReader { string ReadString(bool intern = false); - DateTime ReadDateTime(); - TimeSpan ReadTimeSpan(); - DateTime ReadDeltaTime(); - decimal ReadDecimal(); long ReadLong(); ulong ReadULong(); int ReadInt(); @@ -37,15 +33,69 @@ namespace Server byte ReadByte(); sbyte ReadSByte(); bool ReadBool(); - int ReadEncodedInt(); - IPAddress ReadIPAddress(); - Point3D ReadPoint3D(); - Point2D ReadPoint2D(); - Rectangle2D ReadRect2D(); - Rectangle3D ReadRect3D(); - Map ReadMap(); - Race ReadRace(); + + DateTime ReadDateTime() => new(ReadLong(), DateTimeKind.Utc); + TimeSpan ReadTimeSpan() => new(ReadLong()); + DateTime ReadDeltaTime() => new(ReadLong() + DateTime.UtcNow.Ticks, DateTimeKind.Utc); + decimal ReadDecimal() => new(stackalloc int[4] { ReadInt(), ReadInt(), ReadInt(), ReadInt() }); + int ReadEncodedInt() + { + int v = 0, shift = 0; + byte b; + + do + { + b = ReadByte(); + v |= (b & 0x7F) << shift; + shift += 7; + } + while (b >= 0x80); + + return v; + } + IPAddress ReadIPAddress() + { + byte length = ReadByte(); + // Either 2 ushorts, or 8 ushorts + Span integer = stackalloc byte[length]; + Read(integer); + return Utility.Intern(new IPAddress(integer)); + } + Point3D ReadPoint3D() => new(ReadInt(), ReadInt(), ReadInt()); + Point2D ReadPoint2D() => new(ReadInt(), ReadInt()); + Rectangle2D ReadRect2D() => new(ReadPoint2D(), ReadPoint2D()); + Rectangle3D ReadRect3D() => new(ReadPoint3D(), ReadPoint3D()); + Map ReadMap() => Map.Maps[ReadByte()]; + Race ReadRace() => Race.Races[ReadByte()]; int Read(Span buffer); + unsafe T ReadEnum() where T : unmanaged, Enum + { + switch (ReadByte()) + { + case 1: + { + var num = ReadByte(); + return *(T*)# + } + case 2: + { + var num = ReadShort(); + return *(T*)# + } + case 3: + { + var num = ReadEncodedInt(); + return *(T*)# + } + case 4: + { + var num = ReadLong(); + return *(T*)# + } + } + + return default; + } long Seek(long offset, SeekOrigin origin); } } diff --git a/Projects/Server/Serialization/IGenericWriter.cs b/Projects/Server/Serialization/IGenericWriter.cs index a8a88b608..0716ff2d9 100644 --- a/Projects/Server/Serialization/IGenericWriter.cs +++ b/Projects/Server/Serialization/IGenericWriter.cs @@ -24,9 +24,6 @@ namespace Server long Position { get; } void Close(); void Write(string value); - void Write(DateTime value); - void Write(TimeSpan value); - void Write(decimal value); void Write(long value); void Write(ulong value); void Write(int value); @@ -38,17 +35,120 @@ namespace Server void Write(byte value); void Write(sbyte value); void Write(bool value); - void WriteEncodedInt(int value); - void Write(IPAddress value); - void WriteDeltaTime(DateTime value); - void Write(Point3D value); - void Write(Point2D value); - void Write(Rectangle2D value); - void Write(Rectangle3D value); - void Write(Map value); - void Write(Race value); - void Write(ReadOnlySpan bytes); + void Write(DateTime value) + { + var ticks = (value.Kind switch + { + DateTimeKind.Local => value.ToUniversalTime(), + DateTimeKind.Unspecified => value.ToLocalTime().ToUniversalTime(), + _ => value + }).Ticks; + + Write(ticks); + } + void WriteDeltaTime(DateTime value) + { + var ticks = (value.Kind switch + { + DateTimeKind.Local => value.ToUniversalTime(), + DateTimeKind.Unspecified => value.ToLocalTime().ToUniversalTime(), + _ => value + }).Ticks; + + // Technically supports negative deltas for times in the past + Write(ticks - DateTime.UtcNow.Ticks); + } + void Write(IPAddress value) + { + Span stack = stackalloc byte[16]; + value.TryWriteBytes(stack, out var bytesWritten); + Write((byte)bytesWritten); + Write(stack[..bytesWritten]); + } + void Write(TimeSpan value) + { + Write(value.Ticks); + } + + public void Write(decimal value) + { + var bits = decimal.GetBits(value); + + for (var i = 0; i < 4; ++i) + { + Write(bits[i]); + } + } + void WriteEncodedInt(int value) + { + var v = (uint)value; + + while (v >= 0x80) + { + Write((byte)(v | 0x80)); + v >>= 7; + } + + Write((byte)v); + } + void Write(Point3D value) + { + Write(value.m_X); + Write(value.m_Y); + Write(value.m_Z); + } + void Write(Point2D value) + { + Write(value.m_X); + Write(value.m_Y); + } + void Write(Rectangle2D value) + { + Write(value.Start); + Write(value.End); + } + void Write(Rectangle3D value) + { + Write(value.Start); + Write(value.End); + } + void Write(Map value) => Write((byte)(value?.MapIndex ?? 0xFF)); + void Write(Race value) => Write((byte)(value?.RaceIndex ?? 0xFF)); + void Write(ReadOnlySpan bytes); + unsafe void Write(T value) where T : unmanaged, Enum + { + var size = sizeof(T); + + switch (size) + { + default: throw new ArgumentException($"Argument of type {typeof(T)} is not a normal enum"); + case 1: + { + Write((byte)1); + Write(*(byte*)&value); + break; + } + case 2: + { + Write((byte)2); + Write(*(ushort*)&value); + break; + } + case 4: + { + Write((byte)3); + WriteEncodedInt(*(int*)&value); + break; + } + case 8: + { + Write((byte)4); + Write(*(ulong*)&value); + break; + } + } + } long Seek(long offset, SeekOrigin origin); } } diff --git a/Projects/Server/TileData.cs b/Projects/Server/TileData.cs index 6c6a6e1f2..a2289c2cd 100644 --- a/Projects/Server/TileData.cs +++ b/Projects/Server/TileData.cs @@ -17,7 +17,6 @@ using System; using System.IO; using System.Runtime.CompilerServices; using System.Text; -using Server.Text; namespace Server {