diff --git a/Fika.Core/Networking/LiteNetLib/Utils/NetDataReader.cs b/Fika.Core/Networking/LiteNetLib/Utils/NetDataReader.cs index 86487f28..ca410e8e 100644 --- a/Fika.Core/Networking/LiteNetLib/Utils/NetDataReader.cs +++ b/Fika.Core/Networking/LiteNetLib/Utils/NetDataReader.cs @@ -195,6 +195,11 @@ public void Get(out string result, int maxLength) result = GetString(maxLength); } + public void Get(out Guid result) + { + result = GetGuid(); + } + public IPEndPoint GetNetEndPoint() { string host = GetString(1000); @@ -225,6 +230,30 @@ public T[] GetArray(ushort size) return result; } + public T[] GetArray() where T : INetSerializable, new() + { + ushort length = BitConverter.ToUInt16(_data, _position); + _position += 2; + T[] result = new T[length]; + for (int i = 0; i < length; i++) + { + var item = new T(); + item.Deserialize(this); + result[i] = item; + } + return result; + } + + public T[] GetArray(Func constructor) where T : class, INetSerializable + { + ushort length = BitConverter.ToUInt16(_data, _position); + _position += 2; + T[] result = new T[length]; + for (int i = 0; i < length; i++) + Get(out result[i], constructor); + return result; + } + public bool[] GetBoolArray() { return GetArray(1); @@ -370,40 +399,47 @@ public string GetString(int maxLength) { ushort size = GetUShort(); if (size == 0) - { return string.Empty; - } int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - - ArraySegment data = GetBytesSegment(actualSize); - - return (maxLength > 0 && NetDataWriter.uTF8Encoding.Value.GetCharCount(data.Array, data.Offset, data.Count) > maxLength) ? + string result = maxLength > 0 && NetDataWriter.uTF8Encoding.Value.GetCharCount(_data, _position, actualSize) > maxLength ? string.Empty : - NetDataWriter.uTF8Encoding.Value.GetString(data.Array, data.Offset, data.Count); + NetDataWriter.uTF8Encoding.Value.GetString(_data, _position, actualSize); + _position += actualSize; + return result; } public string GetString() { ushort size = GetUShort(); if (size == 0) - { return string.Empty; - } int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } + string result = NetDataWriter.uTF8Encoding.Value.GetString(_data, _position, actualSize); + _position += actualSize; + return result; + } - ArraySegment data = GetBytesSegment(actualSize); + public string GetLargeString() + { + int size = GetInt(); + if (size <= 0) + return string.Empty; + string result = NetDataWriter.uTF8Encoding.Value.GetString(_data, _position, size); + _position += size; + return result; + } - return NetDataWriter.uTF8Encoding.Value.GetString(data.Array, data.Offset, data.Count); + public Guid GetGuid() + { +#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1 + var result = new Guid(_data.AsSpan(_position, 16)); + _position += 16; + return result; +#else + return new Guid(GetBytesWithLength()); +#endif } public ArraySegment GetBytesSegment(int count) @@ -542,16 +578,9 @@ public string PeekString(int maxLength) { ushort size = PeekUShort(); if (size == 0) - { return string.Empty; - } int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - return (maxLength > 0 && NetDataWriter.uTF8Encoding.Value.GetCharCount(_data, _position + 2, actualSize) > maxLength) ? string.Empty : NetDataWriter.uTF8Encoding.Value.GetString(_data, _position + 2, actualSize); @@ -561,16 +590,9 @@ public string PeekString() { ushort size = PeekUShort(); if (size == 0) - { return string.Empty; - } int actualSize = size - 1; - if (actualSize >= NetDataWriter.StringBufferMaxLength) - { - return null; - } - return NetDataWriter.uTF8Encoding.Value.GetString(_data, _position + 2, actualSize); } #endregion @@ -767,4 +789,4 @@ public void Clear() _data = null; } } -} +} \ No newline at end of file diff --git a/Fika.Core/Networking/LiteNetLib/Utils/NetDataWriter.cs b/Fika.Core/Networking/LiteNetLib/Utils/NetDataWriter.cs index 11ecd521..9bcd62f1 100644 --- a/Fika.Core/Networking/LiteNetLib/Utils/NetDataWriter.cs +++ b/Fika.Core/Networking/LiteNetLib/Utils/NetDataWriter.cs @@ -30,8 +30,6 @@ public int Length } public static readonly ThreadLocal uTF8Encoding = new ThreadLocal(() => new UTF8Encoding(false, true)); - public const int StringBufferMaxLength = 65535; - private readonly byte[] _stringBuffer = new byte[StringBufferMaxLength]; public NetDataWriter() : this(true, InitialSize) { @@ -216,6 +214,18 @@ public void Put(byte value) _position++; } + public void Put(Guid value) + { +#if LITENETLIB_SPANS || NETCOREAPP2_1_OR_GREATER || NETSTANDARD2_1_OR_GREATER || NETCOREAPP2_1 || NETCOREAPP3_1 || NET5_0 || NETSTANDARD2_1 + if (_autoResize) + ResizeIfNeed(_position + 16); + value.TryWriteBytes(_data.AsSpan(_position)); + _position += 16; +#else + PutBytesWithLength(value.ToByteArray()); +#endif + } + public void Put(byte[] data, int offset, int length) { if (_autoResize) @@ -338,12 +348,40 @@ public void PutArray(string[] value, int strMaxLength) Put(value[i], strMaxLength); } + public void PutArray(T[] value) where T : INetSerializable, new() + { + ushort strArrayLength = (ushort)(value?.Length ?? 0); + Put(strArrayLength); + for (int i = 0; i < strArrayLength; i++) + value[i].Serialize(this); + } + public void Put(IPEndPoint endPoint) { Put(endPoint.Address.ToString()); Put(endPoint.Port); } + public void PutLargeString(string value) + { + if (string.IsNullOrEmpty(value)) + { + Put(0); + return; + } + int size = uTF8Encoding.Value.GetByteCount(value); + if (size == 0) + { + Put(0); + return; + } + Put(size); + if (_autoResize) + ResizeIfNeed(_position + size); + uTF8Encoding.Value.GetBytes(value, 0, size, _data, _position); + _position += size; + } + public void Put(string value) { Put(value, 0); @@ -361,16 +399,17 @@ public void Put(string value, int maxLength) } int length = maxLength > 0 && value.Length > maxLength ? maxLength : value.Length; - int size = uTF8Encoding.Value.GetBytes(value, 0, length, _stringBuffer, 0); - - if (size == 0 || size >= StringBufferMaxLength) + int maxSize = uTF8Encoding.Value.GetMaxByteCount(length); + if (_autoResize) + ResizeIfNeed(_position + maxSize + sizeof(ushort)); + int size = uTF8Encoding.Value.GetBytes(value, 0, length, _data, _position + sizeof(ushort)); + if (size == 0) { Put((ushort)0); return; } - Put(checked((ushort)(size + 1))); - Put(_stringBuffer, 0, size); + _position += size; } public void Put(T obj) where T : INetSerializable @@ -378,4 +417,4 @@ public void Put(T obj) where T : INetSerializable obj.Serialize(this); } } -} +} \ No newline at end of file diff --git a/Fika.Core/Networking/LiteNetLib/Utils/NetSerializer.cs b/Fika.Core/Networking/LiteNetLib/Utils/NetSerializer.cs index 975b2b5f..e6494c67 100644 --- a/Fika.Core/Networking/LiteNetLib/Utils/NetSerializer.cs +++ b/Fika.Core/Networking/LiteNetLib/Utils/NetSerializer.cs @@ -422,6 +422,12 @@ private class IPEndPointSerializer : FastCallSpecificAuto protected override void ElementRead(NetDataReader r, out IPEndPoint prop) { prop = r.GetNetEndPoint(); } } + private class GuidSerializer : FastCallSpecificAuto + { + protected override void ElementWrite(NetDataWriter w, ref Guid guid) { w.Put(guid); } + protected override void ElementRead(NetDataReader r, out Guid guid) { guid = r.GetGuid(); } + } + private class StringSerializer : FastCallSpecific { private readonly int _maxLength; @@ -644,6 +650,8 @@ private ClassInfo RegisterInternal< serialzer = new CharSerializer(); else if (elementType == typeof(IPEndPoint)) serialzer = new IPEndPointSerializer(); + else if (elementType == typeof(Guid)) + serialzer = new GuidSerializer(); else { _registeredTypes.TryGetValue(elementType, out var customType); @@ -758,4 +766,4 @@ public byte[] Serialize< return _writer.CopyData(); } } -} +} \ No newline at end of file