Skip to content

Commit a296a76

Browse files
Merge pull request #5 from manups4e/master
fix(vendor/msgpack-cs): patch to allow clientside serialization of types
2 parents 473f11b + 7d8e6ae commit a296a76

File tree

4 files changed

+571
-418
lines changed

4 files changed

+571
-418
lines changed

MsgPack/Formatters/DictionaryFormatter.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,11 @@ internal static class DictionaryFormatter
1212
{
1313
public static Tuple<Serializer, MethodInfo> Build(Type typeKey, Type typeValue)
1414
{
15+
#if IS_FXSERVER
1516
MethodInfo methodSerialize, methodDeserialize, methodObjectSerialize;
17+
#else
18+
MethodInfo methodDeserialize;
19+
#endif
1620

1721
Type typeKeyValuePair = typeof(KeyValuePair<,>).MakeGenericType(typeKey, typeValue);
1822
Type typeDictionary = typeof(Dictionary<,>).MakeGenericType(typeKey, typeValue);
@@ -26,22 +30,34 @@ public static Tuple<Serializer, MethodInfo> Build(Type typeKey, Type typeValue)
2630
{
2731
TypeBuilder typeBuilder = MsgPackRegistry.m_moduleBuilder.DefineType(name);
2832

33+
#if IS_FXSERVER
2934
methodSerialize = BuildSerializer(typeKey, typeValue, typeKeyValuePair, typeIDictionary, typeBuilder);
3035
BuildDeserializer(typeKey, typeValue, typeDictionary, typeBuilder);
3136
BuildObjectSerializer(typeIDictionary, methodSerialize, typeBuilder);
37+
#else
38+
BuildDeserializer(typeKey, typeValue, typeDictionary, typeBuilder);
39+
#endif
3240

3341
buildType = typeBuilder.CreateType();
3442
}
3543

44+
#if IS_FXSERVER
3645
methodSerialize = buildType.GetMethod("Serialize", new[] { typeof(MsgPackSerializer), typeIDictionary });
3746
methodDeserialize = buildType.GetMethod("Deserialize");
3847
methodObjectSerialize = buildType.GetMethod("Serialize", new[] { typeof(MsgPackSerializer), typeof(object) });
48+
#else
49+
methodDeserialize = buildType.GetMethod("Deserialize");
50+
#endif
3951

40-
Serializer serializeMethod = new Serializer(methodSerialize, methodObjectSerialize);
4152

53+
#if IS_FXSERVER
54+
Serializer serializeMethod = new Serializer(methodSerialize, methodObjectSerialize);
4255
MsgPackRegistry.RegisterSerializer(typeDictionary, serializeMethod);
4356
MsgPackRegistry.RegisterSerializer(typeIDictionary, serializeMethod);
4457
MsgPackRegistry.RegisterSerializer(typeIReadOnlyDictionary, serializeMethod);
58+
#else
59+
Serializer serializeMethod = new Serializer();
60+
#endif
4561

4662
MsgPackRegistry.RegisterDeserializer(typeDictionary, methodDeserialize);
4763
MsgPackRegistry.RegisterDeserializer(typeIDictionary, methodDeserialize);

MsgPack/Formatters/TypeFormatter.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,7 +1252,7 @@ private static DynamicArray<MemberInfo> GetReadableMembers(Type type)
12521252
return members;
12531253
}
12541254

1255-
private static DynamicArray<MemberInfo> GetWritableMembers(Type type)
1255+
internal static DynamicArray<MemberInfo> GetWritableMembers(Type type)
12561256
{
12571257
var members = new DynamicArray<MemberInfo>(type.GetMembers(BindingFlags.Instance | BindingFlags.Public));
12581258
members.RemoveAll(m => !((m is FieldInfo || (m is PropertyInfo p && p.CanWrite))
@@ -1261,7 +1261,7 @@ private static DynamicArray<MemberInfo> GetWritableMembers(Type type)
12611261
return members;
12621262
}
12631263

1264-
private static DynamicArray<MemberInfo> GetReadAndWritableKeyedMembers(Type type)
1264+
internal static DynamicArray<MemberInfo> GetReadAndWritableKeyedMembers(Type type)
12651265
{
12661266
var members = new DynamicArray<MemberInfo>(type.GetMembers(BindingFlags.Instance | BindingFlags.Public));
12671267
members.RemoveAll(m => !((m is FieldInfo || (m is PropertyInfo p && p.CanWrite && p.GetGetMethod()?.GetParameters().Length == 0))
@@ -1271,7 +1271,7 @@ private static DynamicArray<MemberInfo> GetReadAndWritableKeyedMembers(Type type
12711271
return members;
12721272
}
12731273

1274-
private static DynamicArray<MemberInfo> GetReadableIndexMembers(Type type)
1274+
internal static DynamicArray<MemberInfo> GetReadableIndexMembers(Type type)
12751275
{
12761276
var members = new DynamicArray<MemberInfo>(type.GetMembers(BindingFlags.Instance | BindingFlags.Public));
12771277
members.RemoveAll(m => !((m is FieldInfo || (m is PropertyInfo p && p.GetGetMethod()?.GetParameters().Length == 0))
@@ -1294,7 +1294,7 @@ private static void CallAndStore(ILGenerator g, MethodInfo methodReadInteger, Op
12941294
g.Emit(storeLoc);
12951295
}
12961296

1297-
private static void EmitDebugWriteLine(this ILGenerator g, string value)
1297+
internal static void EmitDebugWriteLine(this ILGenerator g, string value)
12981298
{
12991299
g.Emit(OpCodes.Ldstr, value);
13001300
#if MONO_V2

MsgPack/MsgPackRegistry.cs

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using CitizenFX.MsgPack.Formatters;
22
using System;
3+
using System.Collections;
34
using System.Collections.Generic;
45
using System.Reflection;
56
using System.Reflection.Emit;
@@ -113,12 +114,13 @@ internal static void Serialize(MsgPackSerializer serializer, object obj)
113114
// Adding too much checks here could run slower than a hash map lookup, profile accordingly
114115

115116
Type type = obj.GetType();
116-
if (type.IsPrimitive)
117+
if (type.IsPrimitive || obj is string)
117118
{
118119
switch (obj)
119120
{
120121
case bool v: serializer.Serialize(v); break;
121122
case char v: serializer.Serialize(v); break;
123+
case string v: serializer.Serialize(v); break;
122124

123125
case byte v: serializer.Serialize(v); break;
124126
case ushort v: serializer.Serialize(v); break;
@@ -132,28 +134,50 @@ internal static void Serialize(MsgPackSerializer serializer, object obj)
132134

133135
case float v: serializer.Serialize(v); break;
134136
case double v: serializer.Serialize(v); break;
135-
}
137+
}
136138
}
137-
else if (obj is Delegate del)
138-
{
139-
// add remote function delegate support ? - don't think if it's even planned or supported
140-
serializer.Serialize(del);
141-
}
142-
// byte[] is a special type handled like a Binary object.
143-
// It is not a primitive type, so i serialized as a binary object and deserialized as such.
144-
else if (obj is byte[] b)
139+
else if (obj is Delegate del)
140+
{
141+
// add remote function delegate support ? - don't think if it's even planned or supported
142+
serializer.Serialize(del);
143+
}
144+
#if !IS_FXSERVER
145+
else if (obj is IEnumerable e)
146+
{
147+
serializer.Serialize(e);
148+
}
149+
#endif
150+
else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>))
151+
{
152+
var keyProp = type.GetProperty("Key");
153+
var valueProp = type.GetProperty("Value");
154+
155+
var key = keyProp.GetValue(obj);
156+
var value = valueProp.GetValue(obj);
157+
158+
serializer.Serialize(new KeyValuePair<object, object>(key, value));
159+
}
160+
// byte[] is a special type handled like a Binary object.
161+
// It is not a primitive type, so i serialized as a binary object and deserialized as such.
162+
else if (obj is byte[] b)
145163
{
146164
serializer.Serialize(b);
147165
}
148-
// same applies to List<byte>
166+
// same applies to List<byte>
149167
// we serialize it as a byte array and deserialize it as such
150168
// it's not elegant but i needed to handle it like this as byte is a binary format even in List
151169
// Ps: Who the fuck in fivem would retrieve and send List<byte>??????
152-
else if (obj is List<byte> lb)
153-
{
154-
serializer.Serialize(lb.ToArray());
155-
}
156-
else if (TryGetSerializer(type, out var methodInfo))
170+
else if (obj is List<byte> lb)
171+
{
172+
serializer.Serialize(lb.ToArray());
173+
}
174+
#if !IS_FXSERVER
175+
else if (!type.IsPrimitive && !type.IsArray && !type.IsGenericType && type.FullName != "CitizenFX.Core.Player")
176+
{
177+
serializer.SerializeType(obj);
178+
}
179+
#endif
180+
else if (TryGetSerializer(type, out var methodInfo))
157181
{
158182
methodInfo.m_objectSerializer(serializer, obj);
159183
}
@@ -190,14 +214,14 @@ internal static MethodInfo GetOrCreateSerializer(Type type)
190214

191215
internal static MethodInfo GetOrCreateDeserializer(Type type)
192216
{
193-
return TryGetDeserializer(type, out var methodInfo)
217+
return TryGetDeserializer(type, out var methodInfo)
194218
? methodInfo
195219
: CreateSerializer(type)?.Item2;
196220
}
197221

198222
private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
199223
{
200-
if (type.IsPrimitive)
224+
if (type.IsPrimitive)
201225
{
202226
if (m_serializers.ContainsKey(type))
203227
return new Tuple<Serializer, MethodInfo>(m_serializers[type], m_serializers[type].m_method);
@@ -206,7 +230,7 @@ private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
206230
}
207231
else if (type.IsArray)
208232
{
209-
switch (type.GetArrayRank())
233+
switch (type.GetArrayRank())
210234
{
211235
case 1:
212236
return ArrayFormatter.Build(type.GetElementType(), type);
@@ -215,7 +239,7 @@ private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
215239
else if (type.IsGenericType)
216240
{
217241
var genericTypes = type.GetGenericArguments();
218-
switch (genericTypes.Length)
242+
switch (genericTypes.Length)
219243
{
220244
case 1:
221245
{
@@ -225,7 +249,7 @@ private static Tuple<Serializer, MethodInfo> CreateSerializer(Type type)
225249
break;
226250
case 2:
227251
{
228-
if (ImplementsGenericTypeDefinition(type, typeof(IDictionary<,>)))
252+
if (ImplementsGenericTypeDefinition(type, typeof(IDictionary<,>)))
229253
return DictionaryFormatter.Build(genericTypes[0], genericTypes[1]);
230254
break;
231255
}

0 commit comments

Comments
 (0)