Example #1
0
        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);
        }
Example #2
0
        public void Read(ByteReader reader)
        {
            SessionId = reader.ReadInt32();
            reader.MpContext().map = map;

            data = SyncSerialization.ReadSync <RitualData>(reader);
            data.assignments.session = this;
        }
Example #3
0
        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;
            }
        }