public override void Handle(ByteReader data) { object target = null; if (targetType != null) { target = SyncSerialization.ReadSyncObject(data, targetType); if (target == null) { return; } } object value = SyncSerialization.ReadSyncObject(data, fieldType); if (cancelIfValueNull && value == null) { return; } object index = null; if (indexType != null) { index = SyncSerialization.ReadSyncObject(data, indexType); } preApply?.Invoke(target, value); MpLog.Debug($"Set {memberPath} in {target} to {value}, map {data.MpContext().map}, index {index}"); MpReflection.SetValue(target, memberPath, value, index); postApply?.Invoke(target, value); }
public void Read(ByteReader reader) { SessionId = reader.ReadInt32(); reader.MpContext().map = map; data = SyncSerialization.ReadSync <RitualData>(reader); data.assignments.session = this; }
public static object ReadSyncObject(ByteReader data, SyncType syncType) { MpContext context = data.MpContext(); Map map = context.map; Type type = syncType.type; try { if (typeof(object) == type) { return(null); } if (type.IsByRef) { return(null); } if (syncWorkersEarly.TryGetValue(type, out SyncWorkerEntry syncWorkerEntryEarly)) { object res = null; if (syncWorkerEntryEarly.shouldConstruct || type.IsValueType) { res = Activator.CreateInstance(type); } syncWorkerEntryEarly.Invoke(new ReadingSyncWorker(data), ref res); return(res); } if (syncType.expose) { if (!typeof(IExposable).IsAssignableFrom(type)) { throw new SerializationException($"Type {type} can't be exposed because it isn't IExposable"); } byte[] exposableData = data.ReadPrefixedBytes(); return(ReadExposable.MakeGenericMethod(type).Invoke(null, new[] { exposableData, null })); } if (typeof(ISynchronizable).IsAssignableFrom(type)) { var obj = Activator.CreateInstance(type); ((ISynchronizable)obj).Sync(new ReadingSyncWorker(data)); return(obj); } if (type.IsEnum) { Type enumType = Enum.GetUnderlyingType(type); return(ReadSyncObject(data, enumType)); } if (type.IsArray && type.GetArrayRank() == 1) { Type elementType = type.GetElementType(); ushort length = data.ReadUShort(); Array arr = Array.CreateInstance(elementType, length); for (int i = 0; i < length; i++) { arr.SetValue(ReadSyncObject(data, elementType), i); } return(arr); } if (type.IsGenericType) { if (type.GetGenericTypeDefinition() == typeof(List <>)) { ListType specialList = ReadSync <ListType>(data); if (specialList == ListType.MapAllThings) { return(map.listerThings.AllThings); } if (specialList == ListType.MapAllDesignations) { return(map.designationManager.allDesignations); } Type listType = type.GetGenericArguments()[0]; ushort size = data.ReadUShort(); IList list = (IList)Activator.CreateInstance(type, size); for (int j = 0; j < size; j++) { list.Add(ReadSyncObject(data, listType)); } return(list); } if (type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { Type element = type.GetGenericArguments()[0]; return(ReadSyncObject(data, typeof(List <>).MakeGenericType(element))); } if (type.GetGenericTypeDefinition() == typeof(Nullable <>)) { bool isNull = data.ReadBool(); if (isNull) { return(null); } bool hasValue = data.ReadBool(); if (!hasValue) { return(Activator.CreateInstance(type)); } Type nullableType = type.GetGenericArguments()[0]; return(Activator.CreateInstance(type, ReadSyncObject(data, nullableType))); } } // Def is a special case until the workers can read their own type if (typeof(Def).IsAssignableFrom(type)) { ushort shortHash = data.ReadUShort(); if (shortHash == 0) { return(null); } Def def = (Def)GetDefByIdMethod.MakeGenericMethod(type).Invoke(null, new object[] { shortHash }); if (def == null) { throw new Exception($"Couldn't find {type} with short hash {shortHash}"); } return(def); } // Where the magic happens if (syncWorkers.TryGetValue(type, out var syncWorkerEntry)) { object res = null; if (syncWorkerEntry.shouldConstruct || type.IsValueType) { res = Activator.CreateInstance(type); } syncWorkerEntry.Invoke(new ReadingSyncWorker(data), ref res); return(res); } throw new SerializationException("No reader for type " + type); } catch (Exception e) { MpLog.Error($"Error reading type: {type}, {e}"); throw; } }