Beispiel #1
0
        private object ReadDataType(RepLayoutCmdType replayout, NetBitReader netBitReader, Type objectType = null)
        {
            object data = null;

            switch (replayout)
            {
            case RepLayoutCmdType.Property:
                data = _linqCache.CreateObject(objectType);
                (data as IProperty).Serialize(netBitReader);
                (data as IResolvable)?.Resolve(GuidCache);
                break;

            case RepLayoutCmdType.PropertyBool:
                data = netBitReader.SerializePropertyBool();
                break;

            case RepLayoutCmdType.PropertyName:
                data = netBitReader.SerializePropertyName();
                break;

            case RepLayoutCmdType.PropertyFloat:
                data = netBitReader.SerializePropertyFloat();
                break;

            case RepLayoutCmdType.PropertyNativeBool:
                data = netBitReader.SerializePropertyNativeBool();
                break;

            case RepLayoutCmdType.PropertyNetId:
                data = netBitReader.SerializePropertyNetId();
                break;

            case RepLayoutCmdType.PropertyObject:
                data = netBitReader.SerializePropertyObject();
                break;

            case RepLayoutCmdType.PropertyPlane:
                throw new NotImplementedException("Plane RepLayoutCmdType not implemented");

            case RepLayoutCmdType.PropertyRotator:
                data = netBitReader.SerializePropertyRotator();
                break;

            case RepLayoutCmdType.PropertyString:
                data = netBitReader.SerializePropertyString();
                break;

            case RepLayoutCmdType.PropertyVector10:
                data = netBitReader.SerializePropertyVector10();
                break;

            case RepLayoutCmdType.PropertyVector100:
                data = netBitReader.SerializePropertyVector100();
                break;

            case RepLayoutCmdType.PropertyVectorNormal:
                data = netBitReader.SerializePropertyVectorNormal();
                break;

            case RepLayoutCmdType.PropertyVectorQ:
                data = netBitReader.SerializePropertyQuantizedVector(VectorQuantization.RoundWholeNumber);
                break;

            case RepLayoutCmdType.RepMovement:
                data = netBitReader.SerializeRepMovement();
                break;

            case RepLayoutCmdType.Enum:
                data = netBitReader.SerializePropertyEnum();
                break;

            // TODO Auto generation fix to handle 1-8 bits
            case RepLayoutCmdType.PropertyByte:
                data = netBitReader.ReadByte();
                break;

            case RepLayoutCmdType.PropertyInt:
                data = netBitReader.ReadInt32();
                break;

            case RepLayoutCmdType.PropertyInt16:
                data = netBitReader.ReadInt16();
                break;

            case RepLayoutCmdType.PropertyUInt64:
                data = netBitReader.ReadUInt64();
                break;

            case RepLayoutCmdType.PropertyUInt16:
                data = netBitReader.ReadUInt16();
                break;

            case RepLayoutCmdType.PropertyUInt32:
                data = netBitReader.ReadUInt32();
                break;

            case RepLayoutCmdType.PropertyVector:
                data = netBitReader.SerializePropertyVector();
                break;

            case RepLayoutCmdType.PropertyVector2D:
                data = netBitReader.SerializePropertyVector2D();
                break;

            default:
                netBitReader.Seek(netBitReader.GetBitsLeft(), System.IO.SeekOrigin.Current);
                break;
            }

            return(data);
        }
Beispiel #2
0
        /// <summary>
        /// see https://github.com/EpicGames/UnrealEngine/blob/5677c544747daa1efc3b5ede31642176644518a6/Engine/Source/Runtime/Engine/Private/RepLayout.cpp#L3141
        /// </summary>
        private Array ReadArrayField(NetFieldExportGroup netfieldExportGroup, NetFieldInfo fieldInfo, NetBitReader netBitReader)
        {
            var arrayIndexes = netBitReader.ReadIntPacked();

            var elementType    = fieldInfo.PropertyInfo.PropertyType.GetElementType();
            var isPrimitveType = _primitiveTypeLayout.TryGetValue(elementType, out var replayout);

            if (replayout == RepLayoutCmdType.Ignore)
            {
                return(null);
            }

            var arr = Array.CreateInstance(elementType, arrayIndexes);

            while (true)
            {
                var index = netBitReader.ReadIntPacked();

                if (index == 0)
                {
                    // At this point, the 0 either signifies:
                    // An array terminator, at which point we're done.
                    // An array element terminator, which could happen if the array had tailing elements removed.
                    if (netBitReader.GetBitsLeft() == 8)
                    {
                        // We have bits left over, so see if its the Array Terminator.
                        // This should be 0
                        var terminator = netBitReader.ReadIntPacked();

                        if (terminator != 0x00)
                        {
                            //Log error

                            return(arr);
                        }
                    }

                    return(arr);
                }

                // Shift all indexes down since 0 represents null handle
                index--;

                if (index >= arrayIndexes)
                {
                    //Log error
                    return(arr);
                }

                object data = null;

                if (!isPrimitveType)
                {
                    data = _linqCache.CreateObject(elementType);
                }

                while (true)
                {
                    var handle = netBitReader.ReadIntPacked();

                    if (handle == 0)
                    {
                        break;
                    }

                    handle--;

                    if (netfieldExportGroup.NetFieldExports.Length < handle)
                    {
                        return(arr);
                    }

                    var export  = netfieldExportGroup.NetFieldExports[handle];
                    var numBits = netBitReader.ReadIntPacked();

                    if (numBits == 0)
                    {
                        continue;
                    }

                    if (export == null)
                    {
                        netBitReader.SkipBits((int)numBits);
                        continue;
                    }

                    var cmdReader = new NetBitReader(netBitReader.ReadBits(numBits))
                    {
                        EngineNetworkVersion = netBitReader.EngineNetworkVersion,
                        NetworkVersion       = netBitReader.NetworkVersion
                    };

                    if (!isPrimitveType)
                    {
                        ReadField(data, export, handle, netfieldExportGroup, cmdReader);
                    }
                    else
                    {
                        data = ReadDataType(replayout, cmdReader, elementType);
                    }
                }

                arr.SetValue(data, index);
            }
        }
Beispiel #3
0
        /// <summary>
        /// Tries to read the property and update the value accordingly.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="export"></param>
        /// <param name="handle"></param>
        /// <param name="exportGroup"></param>
        /// <param name="netBitReader"></param>
        public void ReadField(object obj, NetFieldExport export, uint handle, NetFieldExportGroup exportGroup, NetBitReader netBitReader)
        {
            if (!_netFieldGroups.TryGetValue(exportGroup.PathName, out var netGroupInfo))
            {
                return;
            }

            NetFieldInfo netFieldInfo;

            if (netGroupInfo.UsesHandles)
            {
                if (!netGroupInfo.Handles.TryGetValue(handle, out netFieldInfo))
                {
                    return;
                }
            }
            else
            {
                if (!netGroupInfo.Properties.TryGetValue(export.Name, out netFieldInfo))
                {
                    return;
                }
            }

            SetType(obj, exportGroup, netFieldInfo, netBitReader);
        }
Beispiel #4
0
        private void SetType(object obj, NetFieldExportGroup exportGroup, NetFieldInfo netFieldInfo, NetBitReader netBitReader)
        {
            var data = netFieldInfo.Attribute.Type switch
            {
                RepLayoutCmdType.DynamicArray => ReadArrayField(exportGroup, netFieldInfo, netBitReader),
                RepLayoutCmdType.RepMovement => netFieldInfo.MovementAttribute != null?netBitReader.SerializeRepMovement(
                    locationQuantizationLevel : netFieldInfo.MovementAttribute.LocationQuantizationLevel,
                    rotationQuantizationLevel : netFieldInfo.MovementAttribute.RotationQuantizationLevel,
                    velocityQuantizationLevel : netFieldInfo.MovementAttribute.VelocityQuantizationLevel) : netBitReader.SerializeRepMovement(),
                    _ => ReadDataType(netFieldInfo.Attribute.Type, netBitReader, netFieldInfo.PropertyInfo.PropertyType),
            };

            if (data != null && !netBitReader.IsError)
            {
                var typeAccessor = TypeAccessor.Create(obj.GetType());
                typeAccessor[obj, netFieldInfo.PropertyInfo.Name] = data;
            }
        }
Beispiel #5
0
        private static void AddUnknownField(string exportName, string exportType, string group, uint handle, NetBitReader netBitReader)
        {
            HashSet <UnknownFieldInfo> fields = new HashSet <UnknownFieldInfo>();

            if (!UnknownNetFields.TryAdd(group, fields))
            {
                UnknownNetFields.TryGetValue(group, out fields);
            }

            fields.Add(new UnknownFieldInfo(FixInvalidNames(exportName), exportType, netBitReader.GetBitsLeft(), handle));
        }
Beispiel #6
0
        private static Array ReadArrayField(object obj, NetFieldExportGroup netfieldExportGroup, NetFieldInfo fieldInfo, NetBitReader netBitReader)
        {
            uint arrayIndexes = netBitReader.ReadIntPacked();

            Type             elementType = fieldInfo.PropertyInfo.PropertyType.GetElementType();
            RepLayoutCmdType replayout   = RepLayoutCmdType.Ignore;

            NetFieldGroupInfo groupInfo = null;

            if (_netFieldGroupInfo.ContainsKey(elementType))
            {
                groupInfo = _netFieldGroupInfo[elementType];
            }
            else
            {
                if (!_primitiveTypeLayout.TryGetValue(elementType, out replayout))
                {
                    replayout = RepLayoutCmdType.Ignore;
                }
                else
                {
                    if (elementType == typeof(DebuggingObject))
                    {
                    }
                }
            }


            Array arr = Array.CreateInstance(elementType, arrayIndexes);

            while (true)
            {
                uint index = netBitReader.ReadIntPacked();

                if (index == 0)
                {
                    if (netBitReader.GetBitsLeft() == 8)
                    {
                        uint terminator = netBitReader.ReadIntPacked();

                        if (terminator != 0x00)
                        {
                            //Log error

                            return(arr);
                        }
                    }

                    return(arr);
                }

                --index;

                if (index >= arrayIndexes)
                {
                    //Log error

                    return(arr);
                }

                object data = null;

                if (groupInfo != null)
                {
                    data = Activator.CreateInstance(elementType);
                }

                while (true)
                {
                    uint handle = netBitReader.ReadIntPacked();

                    if (handle == 0)
                    {
                        break;
                    }

                    handle--;

                    if (netfieldExportGroup.NetFieldExports.Length < handle)
                    {
                        return(arr);
                    }

                    NetFieldExport export  = netfieldExportGroup.NetFieldExports[handle];
                    uint           numBits = netBitReader.ReadIntPacked();

                    if (numBits == 0)
                    {
                        continue;
                    }

                    if (export == null)
                    {
                        netBitReader.SkipBits((int)numBits);

                        continue;
                    }

                    NetBitReader cmdReader = new NetBitReader(netBitReader.ReadBits(numBits))
                    {
                        EngineNetworkVersion = netBitReader.EngineNetworkVersion,
                        NetworkVersion       = netBitReader.NetworkVersion
                    };

                    //Uses the same type for the array
                    if (groupInfo != null)
                    {
                        ReadField(data, export, netfieldExportGroup, handle, cmdReader);
                    }
                    else //Probably primitive values
                    {
                        data = ReadDataType(replayout, cmdReader, elementType);
                    }
                }

                arr.SetValue(data, index);
            }
        }
Beispiel #7
0
        private static void SetType(object obj, Type netType, NetFieldInfo netFieldInfo, NetFieldExportGroup exportGroup, NetBitReader netBitReader)
        {
            object data = null;

            switch (netFieldInfo.Attribute.Type)
            {
            case RepLayoutCmdType.DynamicArray:
                data = ReadArrayField(obj, exportGroup, netFieldInfo, netBitReader);
                break;

            default:
                data = ReadDataType(netFieldInfo.Attribute.Type, netBitReader, netFieldInfo.PropertyInfo.PropertyType);
                break;
            }

            if (data != null)
            {
                TypeAccessor typeAccessor = TypeAccessor.Create(netType);
                typeAccessor[obj, netFieldInfo.PropertyInfo.Name] = data;
            }
        }
Beispiel #8
0
        private static object ReadDataType(RepLayoutCmdType replayout, NetBitReader netBitReader, Type objectType = null)
        {
            object data = null;

            switch (replayout)
            {
            case RepLayoutCmdType.Property:
                data = Activator.CreateInstance(objectType);
                (data as IProperty).Serialize(netBitReader);
                break;

            case RepLayoutCmdType.PropertyBool:
                data = netBitReader.SerializePropertyBool();
                break;

            case RepLayoutCmdType.PropertyName:
                netBitReader.Seek(netBitReader.Position + netBitReader.GetBitsLeft());
                break;

            case RepLayoutCmdType.PropertyFloat:
                data = netBitReader.SerializePropertyFloat();
                break;

            case RepLayoutCmdType.PropertyNativeBool:
                data = netBitReader.SerializePropertyNativeBool();
                break;

            case RepLayoutCmdType.PropertyNetId:
                data = netBitReader.SerializePropertyNetId();
                break;

            case RepLayoutCmdType.PropertyObject:
                data = netBitReader.SerializePropertyObject();
                break;

            case RepLayoutCmdType.PropertyPlane:
                throw new NotImplementedException("Plane RepLayoutCmdType not implemented");

            case RepLayoutCmdType.PropertyRotator:
                data = netBitReader.SerializePropertyRotator();
                break;

            case RepLayoutCmdType.PropertyString:
                data = netBitReader.SerializePropertyString();
                break;

            case RepLayoutCmdType.PropertyVector10:
                data = netBitReader.SerializePropertyVector10();
                break;

            case RepLayoutCmdType.PropertyVector100:
                data = netBitReader.SerializePropertyVector100();
                break;

            case RepLayoutCmdType.PropertyVectorNormal:
                data = netBitReader.SerializePropertyVectorNormal();
                break;

            case RepLayoutCmdType.PropertyVectorQ:
                data = netBitReader.SerializePropertyQuantizeVector();
                break;

            case RepLayoutCmdType.RepMovement:
                data = netBitReader.SerializeRepMovement();
                break;

            case RepLayoutCmdType.Enum:
                data = netBitReader.SerializeEnum();
                break;

            //Auto generation fix to handle 1-8 bits
            case RepLayoutCmdType.PropertyByte:
                data = (byte)netBitReader.ReadBitsToInt(netBitReader.GetBitsLeft());
                break;

            //Auto generation fix to handle 1-32 bits.
            case RepLayoutCmdType.PropertyInt:
                data = netBitReader.ReadBitsToInt(netBitReader.GetBitsLeft());
                break;

            case RepLayoutCmdType.PropertyUInt64:
                data = netBitReader.ReadUInt64();
                break;

            case RepLayoutCmdType.PropertyUInt16:
                data = (ushort)netBitReader.ReadBitsToInt(netBitReader.GetBitsLeft());
                break;

            case RepLayoutCmdType.PropertyUInt32:
                data = netBitReader.ReadUInt32();
                break;

            case RepLayoutCmdType.Pointer:
                switch (netBitReader.GetBitsLeft())
                {
                case 8:
                    data = (uint)netBitReader.ReadByte();
                    break;

                case 16:
                    data = (uint)netBitReader.ReadUInt16();
                    break;

                case 32:
                    data = netBitReader.ReadUInt32();
                    break;
                }
                break;

            case RepLayoutCmdType.PropertyVector:
                data = new FVector(netBitReader.ReadSingle(), netBitReader.ReadSingle(), netBitReader.ReadSingle());
                break;

            case RepLayoutCmdType.Ignore:
                netBitReader.Seek(netBitReader.Position + netBitReader.GetBitsLeft());
                break;
            }

            return(data);
        }
Beispiel #9
0
        public static void ReadField(object obj, NetFieldExport export, NetFieldExportGroup exportGroup, uint handle, NetBitReader netBitReader)
        {
            string group = exportGroup.PathName;

            string fixedExportName = FixInvalidNames(export.Name);

            if (!_netFieldGroups.ContainsKey(group))
            {
                AddUnknownField(fixedExportName, export?.Type, group, handle, netBitReader);

                return;
            }

            Type netType = _netFieldGroups[group];
            NetFieldGroupInfo netGroupInfo = _netFieldGroupInfo[netType];

            if (!netGroupInfo.Properties.ContainsKey(fixedExportName))
            {
                AddUnknownField(fixedExportName, export?.Type, group, handle, netBitReader);

                return;
            }

            NetFieldInfo netFieldInfo = netGroupInfo.Properties[fixedExportName];

            //Update if it finds a higher bit count or an actual type
            if (!String.IsNullOrEmpty(export.Type))
            {
                if (String.IsNullOrEmpty(netFieldInfo.Attribute.Info.Type))
                {
                    AddUnknownField(fixedExportName, export?.Type, group, handle, netBitReader);
                }
            }

            /*else if(netFieldInfo.Attribute.Info.BitCount < netBitReader.GetBitsLeft())
             * {
             *  if(String.IsNullOrEmpty(netFieldInfo.Attribute.Info.Type))
             *  {
             *      AddUnknownField(fixedExportName, export?.Type, group, handle, netBitReader);
             *  }
             * }*/

            SetType(obj, netType, netFieldInfo, exportGroup, netBitReader);
        }