Skip to content
This repository was archived by the owner on Sep 2, 2025. It is now read-only.

Commit f248852

Browse files
committed
New serialization method
1 parent 14b8b99 commit f248852

3 files changed

Lines changed: 210 additions & 4 deletions

File tree

src/FxEvents.Shared/EventSubsystem/Serialization/Implementations/MsgPackSerialization.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using FxEvents.Shared.EventSubsystem.Serialization;
2+
using FxEvents.Shared.EventSubsystem.Serialization.Implementations;
23
using FxEvents.Shared.EventSubsystem.Serialization.Implementations.MsgPack.MsgPackResolvers;
34
using FxEvents.Shared.EventSubsystem.Serialization.Implementations.MsgPackResolvers;
45
using FxEvents.Shared.Exceptions;
@@ -92,7 +93,10 @@ public void Serialize(Type type, object value, SerializationContext context)
9293
logger.Warning("Using Tuple is not advised due to differences between client and server environments and the unavailability of resolvers. Consider using ValueTuple instead.");
9394
SerializeTuple(type, value, context);
9495
}
95-
SerializeObject(type, value, context);
96+
else
97+
{
98+
SerializeObject(type, value, context);
99+
}
96100
}
97101

98102
private void SerializeTuple(Type type, object value, SerializationContext context)
@@ -108,13 +112,12 @@ private void SerializeTuple(Type type, object value, SerializationContext contex
108112

109113
private void SerializeObject(Type type, object value, SerializationContext context)
110114
{
111-
IMessagePackSingleObjectSerializer ser = MessagePackSerializer.Get(type, _context);
112-
ser.Pack(context.Writer.BaseStream, value);
115+
TypeSerializer.Serialize(value, context);
113116
}
114117

115118
public void Serialize<T>(T value, SerializationContext context)
116119
{
117-
Serialize(typeof(T), value, context);
120+
TypeSerializer.Serialize(value, context);
118121
}
119122
#endregion
120123

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
using CitizenFX.Core;
2+
using FxEvents.Shared.EventSubsystem.Serialization.Implementations.MsgPackResolvers;
3+
using FxEvents.Shared.Serialization.Implementations.MsgPackResolvers;
4+
using FxEvents.Shared.Snowflakes;
5+
using MsgPack;
6+
using MsgPack.Serialization;
7+
using System;
8+
using System.Collections;
9+
using System.Collections.Generic;
10+
using System.IO;
11+
using System.Linq;
12+
using System.Reflection;
13+
using System.Text;
14+
15+
namespace FxEvents.Shared.EventSubsystem.Serialization.Implementations
16+
{
17+
internal static class TypeSerializer
18+
{
19+
private static SerializationContext _context = new(PackerCompatibilityOptions.Classic) { SerializationMethod = SerializationMethod.Map, GeneratorOption = SerializationMethodGeneratorOption.Fast };
20+
private static readonly Type[] WriteTypes = new[] {
21+
typeof(string), typeof(DateTime), typeof(double),
22+
typeof(decimal), typeof(Guid),
23+
};
24+
public static bool IsSimpleType(this Type type)
25+
{
26+
return type.IsPrimitive || WriteTypes.Contains(type);
27+
}
28+
29+
30+
public static void Serialize(object obj, Shared.Serialization.SerializationContext context)
31+
{
32+
if (obj == null)
33+
{
34+
context.Writer.Write(new byte[] { 0xC0 });
35+
return;
36+
}
37+
38+
using var packer = Packer.Create(context.Writer.BaseStream, PackerCompatibilityOptions.None);
39+
Serialize(obj, packer);
40+
}
41+
42+
private static void Serialize(object obj, Packer packer)
43+
{
44+
if (obj == null)
45+
{
46+
packer.PackNull();
47+
48+
return;
49+
}
50+
51+
var type = obj.GetType();
52+
new Logger.Log().Warning("Item: " + obj + ", type: " + type.Name);
53+
54+
55+
if (type.IsSimpleType())
56+
{
57+
packer.Pack(obj);
58+
}
59+
else if (type.IsEnum)
60+
{
61+
var eTypeInfo = type.GetTypeInfo();
62+
var eValueType = eTypeInfo.DeclaredFields.First(x => x.Name == "value__").FieldType;
63+
var eAsNumber = Convert.ChangeType(obj, eValueType);
64+
packer.Pack(eAsNumber);
65+
}
66+
else if (obj is byte[] bytes)
67+
{
68+
packer.Pack(bytes);
69+
}
70+
else if (obj is IDictionary)
71+
{
72+
var dict = (IDictionary)obj;
73+
74+
packer.PackMapHeader(dict.Count);
75+
76+
foreach (var key in dict.Keys)
77+
{
78+
Serialize(key, packer);
79+
Serialize(dict[key], packer);
80+
}
81+
}
82+
else if (obj is IDictionary<string, object>) // special case for ExpandoObject
83+
{
84+
var dict = (IDictionary<string, object>)obj;
85+
86+
packer.PackMapHeader(dict.Count);
87+
88+
foreach (var kvp in dict)
89+
{
90+
Serialize(kvp.Key, packer);
91+
Serialize(kvp.Value, packer);
92+
}
93+
}
94+
else if (obj is IList)
95+
{
96+
var list = (IList)obj;
97+
98+
packer.PackArrayHeader(list.Count);
99+
100+
foreach (var item in list)
101+
{
102+
Serialize(item, packer);
103+
}
104+
}
105+
else if (obj is IEnumerable enu)
106+
{
107+
var list = new List<object>();
108+
109+
foreach (var item in enu)
110+
{
111+
list.Add(item);
112+
}
113+
114+
packer.PackArrayHeader(list.Count);
115+
116+
list.ForEach(a => Serialize(a, packer));
117+
}
118+
else if (obj is IPackable packable)
119+
{
120+
packable.PackToMessage(packer, null);
121+
}
122+
// we don't support it yet
123+
//else if (obj is Delegate deleg)
124+
//{
125+
// var serializer = new DelegateSerializer();
126+
// serializer.PackTo(packer, deleg);
127+
//}
128+
else if (obj is Vector2 vec2)
129+
{
130+
var serializer = new Vector2Resolver(_context);
131+
serializer.PackTo(packer, vec2);
132+
}
133+
else if (obj is Vector3 vec3)
134+
{
135+
var serializer = new Vector3Resolver(_context);
136+
serializer.PackTo(packer, vec3);
137+
}
138+
else if (obj is Vector4 vec4)
139+
{
140+
var serializer = new Vector4Resolver(_context);
141+
serializer.PackTo(packer, vec4);
142+
}
143+
else if (obj is Quaternion quat)
144+
{
145+
var serializer = new QuaternionResolver(_context);
146+
serializer.PackTo(packer, quat);
147+
}
148+
else if (obj is Entity ent)
149+
{
150+
var serializer = new EntityResolver(_context);
151+
serializer.PackTo(packer, ent);
152+
}
153+
else if (obj is Ped ped)
154+
{
155+
var serializer = new PedResolver(_context);
156+
serializer.PackTo(packer, ped);
157+
}
158+
else if (obj is Vehicle veh)
159+
{
160+
var serializer = new VehicleResolver(_context);
161+
serializer.PackTo(packer, veh);
162+
}
163+
else if (obj is Prop prop)
164+
{
165+
var serializer = new PropResolver(_context);
166+
serializer.PackTo(packer, prop);
167+
}
168+
else if (obj is Matrix mat)
169+
{
170+
var serializer = new MatrixResolver(_context);
171+
serializer.PackTo(packer, mat);
172+
}
173+
else if (obj is Matrix3x3 mat3x3)
174+
{
175+
var serializer = new Matrix3x3Resolver(_context);
176+
serializer.PackTo(packer, mat3x3);
177+
}
178+
else if (obj is Snowflake snow)
179+
{
180+
var serializer = new SnowflakeResolver(_context);
181+
serializer.PackTo(packer, snow);
182+
}
183+
else if (obj is Player player)
184+
{
185+
var serializer = new PlayerResolver(_context);
186+
serializer.PackTo(packer, player);
187+
}
188+
else
189+
{
190+
var properties = type.GetProperties();
191+
var dict = new Dictionary<string, object>();
192+
193+
foreach (var property in properties)
194+
{
195+
dict[property.Name] = property.GetValue(obj, null);
196+
}
197+
198+
Serialize(dict, packer);
199+
}
200+
}
201+
}
202+
}

src/FxEvents.Shared/FxEvents.Shared.projitems

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\BaseGateway.cs" />
2121
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\Message\EventRemote.cs" />
2222
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\Serialization\Implementations\MsgPack\MsgPackResolvers\DoubleFixer.cs" />
23+
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\Serialization\Implementations\TypeSerializer.cs" />
2324
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\Serialization\MsgPackCode.cs" />
2425
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\Serialization\TypeConvert.cs" />
2526
<Compile Include="$(MSBuildThisFileDirectory)EventSubsystem\TamperType.cs" />

0 commit comments

Comments
 (0)