fix(core): Cleans up serialization (#606)

This commit is contained in:
Kamron Batman 2021-05-16 13:45:32 -07:00 committed by GitHub
parent 8418d4a7db
commit cb66bef0e5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 177 additions and 218 deletions

View file

@ -19,7 +19,6 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime; using System.Runtime;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using System.Text.Json; using System.Text.Json;

View file

@ -15,7 +15,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Net;
namespace Server namespace Server
{ {
@ -35,14 +34,6 @@ namespace Server
return intern ? Utility.Intern(str) : str; 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 long ReadLong() => _reader.ReadInt64();
public ulong ReadULong() => _reader.ReadUInt64(); public ulong ReadULong() => _reader.ReadUInt64();
@ -65,43 +56,6 @@ namespace Server
public bool ReadBool() => _reader.ReadBoolean(); 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<byte> 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<byte> buffer) => _reader.Read(buffer); public int Read(Span<byte> buffer) => _reader.Read(buffer);
public long Seek(long offset, SeekOrigin origin) => _reader.BaseStream.Seek(offset, origin); public long Seek(long offset, SeekOrigin origin) => _reader.BaseStream.Seek(offset, origin);

View file

@ -17,7 +17,6 @@ using System;
using System.Buffers.Binary; using System.Buffers.Binary;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Net;
using System.Text; using System.Text;
using Server.Text; using Server.Text;
@ -52,7 +51,7 @@ namespace Server
return null; return null;
} }
var length = ReadEncodedInt(); var length = ((IGenericReader)this).ReadEncodedInt();
if (length <= 0) if (length <= 0)
{ {
return intern ? Utility.Intern("") : ""; return intern ? Utility.Intern("") : "";
@ -63,14 +62,6 @@ namespace Server
return intern ? Utility.Intern(str) : str; 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() public long ReadLong()
{ {
var v = BinaryPrimitives.ReadInt64LittleEndian(_buffer.AsSpan(_position, 8)); var v = BinaryPrimitives.ReadInt64LittleEndian(_buffer.AsSpan(_position, 8));
@ -133,42 +124,6 @@ namespace Server
public bool ReadBool() => _buffer[_position++] != 0; 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<byte> 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<byte> buffer) public int Read(Span<byte> buffer)
{ {
var length = buffer.Length; var length = buffer.Length;

View file

@ -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) public void Write(string value)
{ {
if (m_PrefixStrings) 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<byte> 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) public void Write(long value)
{ {
FlushIfNeeded(8); FlushIfNeeded(8);
@ -350,46 +287,11 @@ namespace Server
_buffer[Index++] = *(byte*)&value; // up to 30% faster to dereference the raw value on the stack _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) internal void InternalWriteString(string value)
{ {
var remaining = m_Encoding.GetByteCount(value); var remaining = m_Encoding.GetByteCount(value);
WriteEncodedInt(remaining); ((IGenericWriter)this).WriteEncodedInt(remaining);
if (remaining == 0) if (remaining == 0)
{ {

View file

@ -22,10 +22,6 @@ namespace Server
public interface IGenericReader public interface IGenericReader
{ {
string ReadString(bool intern = false); string ReadString(bool intern = false);
DateTime ReadDateTime();
TimeSpan ReadTimeSpan();
DateTime ReadDeltaTime();
decimal ReadDecimal();
long ReadLong(); long ReadLong();
ulong ReadULong(); ulong ReadULong();
int ReadInt(); int ReadInt();
@ -37,15 +33,69 @@ namespace Server
byte ReadByte(); byte ReadByte();
sbyte ReadSByte(); sbyte ReadSByte();
bool ReadBool(); bool ReadBool();
int ReadEncodedInt();
IPAddress ReadIPAddress(); DateTime ReadDateTime() => new(ReadLong(), DateTimeKind.Utc);
Point3D ReadPoint3D(); TimeSpan ReadTimeSpan() => new(ReadLong());
Point2D ReadPoint2D(); DateTime ReadDeltaTime() => new(ReadLong() + DateTime.UtcNow.Ticks, DateTimeKind.Utc);
Rectangle2D ReadRect2D(); decimal ReadDecimal() => new(stackalloc int[4] { ReadInt(), ReadInt(), ReadInt(), ReadInt() });
Rectangle3D ReadRect3D(); int ReadEncodedInt()
Map ReadMap(); {
Race ReadRace(); 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<byte> 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<byte> buffer); int Read(Span<byte> buffer);
unsafe T ReadEnum<T>() where T : unmanaged, Enum
{
switch (ReadByte())
{
case 1:
{
var num = ReadByte();
return *(T*)&num;
}
case 2:
{
var num = ReadShort();
return *(T*)&num;
}
case 3:
{
var num = ReadEncodedInt();
return *(T*)&num;
}
case 4:
{
var num = ReadLong();
return *(T*)&num;
}
}
return default;
}
long Seek(long offset, SeekOrigin origin); long Seek(long offset, SeekOrigin origin);
} }
} }

View file

@ -24,9 +24,6 @@ namespace Server
long Position { get; } long Position { get; }
void Close(); void Close();
void Write(string value); void Write(string value);
void Write(DateTime value);
void Write(TimeSpan value);
void Write(decimal value);
void Write(long value); void Write(long value);
void Write(ulong value); void Write(ulong value);
void Write(int value); void Write(int value);
@ -38,17 +35,120 @@ namespace Server
void Write(byte value); void Write(byte value);
void Write(sbyte value); void Write(sbyte value);
void Write(bool 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<byte> 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<byte> 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<byte> bytes);
unsafe void Write<T>(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); long Seek(long offset, SeekOrigin origin);
} }
} }

View file

@ -17,7 +17,6 @@ using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Text; using System.Text;
using Server.Text;
namespace Server namespace Server
{ {