fivem icon indicating copy to clipboard operation
fivem copied to clipboard

feat(clrcore-v2): Move to custom MsgPack serializer

Open thorium-cfx opened this issue 3 months ago • 1 comments

Goal of this PR

Enable (de)serialization to and from custom types on events, exports, nui callbacks, and other refFuncs within the mono rt2 runtime. A highly requested feature for the C# environments, as a lot of extra work and workarounds are currently applied to compensate for the lack there-of.

  1. Optional parameters are also supported with this update.
  2. Performance is roughly 30% faster for single listeners, making it slower for 3+ listeners for each event (why would you even do this?).

Notes:

  1. This is the last big update for the mono rt2 scripting runtime before we exit the pilot stage.
  2. Issues are expected; unit tests are put in place for some situations, but not all and/or unforeseen use-cases are tested yet.

How is this PR achieving the goal

Allows for in place conversion of serialized data.

  • Replaces deserializer on events, exports, nui callbacks, and other refFuncs with our custom and more extensive msgpack serialization.
  • Has support for:
    • Class/struct field/property (de)serialization.
    • Class/struct constructor deserialization.
    • Dictionary<K, V>, List<T>, and T[].
    • Primitives.
  • Add msgpack-cs submodule (production branch)
  • Temporary Player (de)serialization
  • Command remapper no longer allows reordering of parameters, only remote/player id

Example:

[EventHandler("myEvent")]
public static async Coroutine GimmeAll(int a)
	=> Debug.WriteLine($"GimmeAll1 {a}");

[EventHandler("myEvent")]
public static async Coroutine GimmeAll(string a, int b)
	=> Debug.WriteLine($"GimmeAll2 {a} {b}");

[EventHandler("myEvent")]
public static async Coroutine GimmeAll(string a, int b, string c = "Hey")
	=> Debug.WriteLine($"GimmeAll3 {a} {b} {c}");

[EventHandler("myEvent")]
public static async Coroutine GimmeAll(int a, string b, string c = "Oh", int d = 678)
	=> Debug.WriteLine($"GimmeAll4 {a} {b} {c} {d}");

[EventHandler("myEvent")]
public static async Coroutine GimmeAll(int a, Player b, string c = "Oh", int d = 678)
	=> Debug.WriteLine($"GimmeAll5 {a} {b} {c} {d}");

// Trigger it!
[Command("Gimme")]
public async Coroutine Gimme(uint source, object[] objects, string raw)
	=> Events.TriggerServerEvent("myEvent", 1234, "5678");

gives the following output:

[    script:csharp_v2] GimmeAll1 1234
[    script:csharp_v2] GimmeAll2 1234 5678
[    script:csharp_v2] GimmeAll3 1234 5678 Hey
[    script:csharp_v2] GimmeAll4 1234 5678 Oh 678
[    script:csharp_v2] GimmeAll5 1234 Player(5678) Oh 678

This PR applies to the following area(s)

ScRT: C#

Successfully tested on

FXServer and

Game builds: N/A

Platforms: Windows

Checklist

  • [x] Code compiles and has been tested successfully.
  • [x] Code explains itself well and/or is documented.
  • [x] My commit message explains what the changes do and what they are for.
  • [x] No extra compilation warnings are added by these changes.

Fixes issues

closes thorium-cfx/mono_v2_get_started#20

Thanks / Contributors

A big thanks goes out @manups4e, showing me how his FxEvents project used a completely different approach, this became the base and eventually the way forward on MsgPack (de)serialization for the mono v2 scripting environment.

thorium-cfx avatar May 15 '24 13:05 thorium-cfx