Fix crashing due to bug in BufferWriter.ToByteArray()
Renamed the serialisers and added CustomEvents to unit test to be more future-proof
This commit is contained in:
@ -5,7 +5,7 @@ using GTA.Math;
|
||||
|
||||
namespace RageCoop.Core
|
||||
{
|
||||
public unsafe abstract class BufferBase
|
||||
public unsafe abstract class Buffer
|
||||
{
|
||||
/// <summary>
|
||||
/// Size of this buffer in memory
|
||||
@ -41,9 +41,9 @@ namespace RageCoop.Core
|
||||
}
|
||||
}
|
||||
|
||||
public unsafe sealed class WriteBuffer : BufferBase
|
||||
public unsafe sealed class BufferWriter : Buffer
|
||||
{
|
||||
public WriteBuffer(int size)
|
||||
public BufferWriter(int size)
|
||||
{
|
||||
Resize(size);
|
||||
}
|
||||
@ -59,7 +59,7 @@ namespace RageCoop.Core
|
||||
var newAddr = (byte*)Marshal.AllocHGlobal(size);
|
||||
if (Address != null)
|
||||
{
|
||||
Buffer.MemoryCopy(Address, newAddr, size, Size);
|
||||
System.Buffer.MemoryCopy(Address, newAddr, size, Size);
|
||||
Marshal.FreeHGlobal((IntPtr)Address);
|
||||
}
|
||||
Size = size;
|
||||
@ -138,14 +138,14 @@ namespace RageCoop.Core
|
||||
var len = source.Length;
|
||||
fixed (T* pSource = source)
|
||||
{
|
||||
Buffer.MemoryCopy(pSource, Alloc(sizeof(T) * len), len, len);
|
||||
System.Buffer.MemoryCopy(pSource, Alloc(sizeof(T) * len), len, len);
|
||||
}
|
||||
}
|
||||
|
||||
public void Write<T>(Span<T> source) where T : unmanaged => Write((ReadOnlySpan<T>)source);
|
||||
|
||||
/// <summary>
|
||||
/// Write an array, prefix the data with its length so it can latter be read using <see cref="ReadBuffer.ReadArray{T}"/>
|
||||
/// Write an array, prefix the data with its length so it can latter be read using <see cref="BufferReader.ReadArray{T}"/>
|
||||
/// </summary>
|
||||
public void WriteArray<T>(T[] values) where T : unmanaged
|
||||
{
|
||||
@ -153,7 +153,7 @@ namespace RageCoop.Core
|
||||
WriteVal(len);
|
||||
fixed (T* pFrom = values)
|
||||
{
|
||||
Buffer.MemoryCopy(pFrom, Alloc(sizeof(T) * len), len, len);
|
||||
System.Buffer.MemoryCopy(pFrom, Alloc(sizeof(T) * len), len, len);
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +171,7 @@ namespace RageCoop.Core
|
||||
var result = new byte[cbSize];
|
||||
fixed (byte* pResult = result)
|
||||
{
|
||||
Buffer.MemoryCopy(Address, pResult, Size, Size);
|
||||
System.Buffer.MemoryCopy(Address, pResult, cbSize, cbSize);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -182,16 +182,16 @@ namespace RageCoop.Core
|
||||
public void Free() => Marshal.FreeHGlobal((IntPtr)Address);
|
||||
}
|
||||
|
||||
public unsafe sealed class ReadBuffer : BufferBase
|
||||
public unsafe sealed class BufferReader : Buffer
|
||||
{
|
||||
/// <summary>
|
||||
/// Initialize an empty instance, needs to call <see cref="Initialise(byte*, int)"/> before reading data
|
||||
/// </summary>
|
||||
public ReadBuffer()
|
||||
public BufferReader()
|
||||
{
|
||||
|
||||
}
|
||||
public ReadBuffer(byte* address, int size) => Initialise(address, size);
|
||||
public BufferReader(byte* address, int size) => Initialise(address, size);
|
||||
|
||||
public void Initialise(byte* address, int size)
|
||||
{
|
||||
@ -269,12 +269,12 @@ namespace RageCoop.Core
|
||||
var len = destination.Length;
|
||||
fixed (T* pTo = destination)
|
||||
{
|
||||
Buffer.MemoryCopy(Alloc(len * sizeof(T)), pTo, len, len);
|
||||
System.Buffer.MemoryCopy(Alloc(len * sizeof(T)), pTo, len, len);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads an array previously written using <see cref="WriteBuffer.WriteArray{T}(T[])"/>
|
||||
/// Reads an array previously written using <see cref="BufferWriter.WriteArray{T}(T[])"/>
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
@ -285,7 +285,7 @@ namespace RageCoop.Core
|
||||
var result = new T[len];
|
||||
fixed (T* pTo = result)
|
||||
{
|
||||
Buffer.MemoryCopy(from, pTo, len, len);
|
||||
System.Buffer.MemoryCopy(from, pTo, len, len);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -27,11 +27,11 @@ namespace RageCoop.Core
|
||||
m.Write(Hash);
|
||||
if (Args != null)
|
||||
{
|
||||
lock (WriteBufferShared)
|
||||
lock (SharedWriter)
|
||||
{
|
||||
WriteBufferShared.Reset();
|
||||
CustomEvents.WriteObjects(WriteBufferShared, Args);
|
||||
Payload = WriteBufferShared.ToByteArray(WriteBufferShared.Position);
|
||||
SharedWriter.Reset();
|
||||
CustomEvents.WriteObjects(SharedWriter, Args);
|
||||
Payload = SharedWriter.ToByteArray(SharedWriter.Position);
|
||||
}
|
||||
}
|
||||
m.Write(Payload);
|
||||
@ -44,10 +44,10 @@ namespace RageCoop.Core
|
||||
Payload = m.ReadBytes(m.LengthBytes - m.PositionInBytes);
|
||||
fixed (byte* p = Payload)
|
||||
{
|
||||
lock (ReadBufferShared)
|
||||
lock (SharedReader)
|
||||
{
|
||||
ReadBufferShared.Initialise(p,Payload.Length);
|
||||
Args = CustomEvents.ReadObjects(ReadBufferShared);
|
||||
SharedReader.Initialise(p, Payload.Length);
|
||||
Args = CustomEvents.ReadObjects(SharedReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,8 +152,8 @@ namespace RageCoop.Core
|
||||
|
||||
internal abstract class Packet : IPacket
|
||||
{
|
||||
public static WriteBuffer WriteBufferShared = new(1024);
|
||||
public static ReadBuffer ReadBufferShared = new();
|
||||
public static BufferWriter SharedWriter = new(1024);
|
||||
public static BufferReader SharedReader = new();
|
||||
|
||||
public abstract PacketType Type { get; }
|
||||
|
||||
|
@ -143,10 +143,10 @@ namespace RageCoop.Core.Scripting
|
||||
|
||||
#endregion
|
||||
|
||||
public static void WriteObjects(WriteBuffer b, params object[] objs)
|
||||
public static void WriteObjects(BufferWriter b, params object[] objs)
|
||||
{
|
||||
b.WriteVal(objs.Length);
|
||||
foreach(var obj in objs)
|
||||
foreach (var obj in objs)
|
||||
{
|
||||
switch (obj)
|
||||
{
|
||||
@ -219,7 +219,7 @@ namespace RageCoop.Core.Scripting
|
||||
}
|
||||
}
|
||||
}
|
||||
public static object[] ReadObjects(ReadBuffer r)
|
||||
public static object[] ReadObjects(BufferReader r)
|
||||
{
|
||||
var Args = new object[r.ReadVal<int>()];
|
||||
for (var i = 0; i < Args.Length; i++)
|
||||
@ -280,7 +280,7 @@ namespace RageCoop.Core.Scripting
|
||||
case T_ID_PED:
|
||||
case T_ID_PROP:
|
||||
case T_ID_VEH:
|
||||
Args[i] = IdToHandle(type,r.ReadVal<int>());
|
||||
Args[i] = IdToHandle(type, r.ReadVal<int>());
|
||||
break;
|
||||
default:
|
||||
throw new InvalidOperationException($"Unexpected type: {type}");
|
||||
@ -290,6 +290,6 @@ namespace RageCoop.Core.Scripting
|
||||
}
|
||||
|
||||
[LibraryImport("RageCoop.Client.dll")]
|
||||
public static partial int IdToHandle(byte type,int id);
|
||||
public static partial int IdToHandle(byte type, int id);
|
||||
}
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
using GTA.Math;
|
||||
using RageCoop.Core;
|
||||
using RageCoop.Core.Scripting;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace UnitTest
|
||||
@ -28,7 +29,7 @@ namespace UnitTest
|
||||
{
|
||||
TestElement[] test = new TestElement[1024];
|
||||
Console.WriteLine("Testing buffers");
|
||||
var buf = new WriteBuffer(1024);
|
||||
var buf = new BufferWriter(1024);
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
var e = test[i] = new TestElement(i);
|
||||
@ -42,7 +43,7 @@ namespace UnitTest
|
||||
Console.WriteLine($"Current position: {buf.Position}");
|
||||
|
||||
Console.WriteLine("Validating data");
|
||||
var reader = new ReadBuffer(buf.Address, buf.Size);
|
||||
var reader = new BufferReader(buf.Address, buf.Size);
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
var e = test[i];
|
||||
@ -69,6 +70,23 @@ namespace UnitTest
|
||||
}
|
||||
|
||||
Console.WriteLine("Buffers OK");
|
||||
|
||||
Console.WriteLine("Testing CustomEvents");
|
||||
var objs = new object[] { (byte)236, (short)82, (ushort)322,
|
||||
"test", 123, 123U, 456UL, 345L, 5F, new Vector2(15, 54), new Vector3(22, 45, 25), new Quaternion(2, 3, 222, 5) };
|
||||
|
||||
buf.Reset();
|
||||
CustomEvents.WriteObjects(buf, objs);
|
||||
var payload = buf.ToByteArray(buf.Position);
|
||||
fixed(byte* p = payload)
|
||||
{
|
||||
reader.Initialise(p, payload.Length);
|
||||
}
|
||||
|
||||
if (!CustomEvents.ReadObjects(reader).SequenceEqual(objs))
|
||||
throw new Exception("CustomEvents fail");
|
||||
|
||||
Console.WriteLine("CustomEvents OK");
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user