private UnrealField ReadField(IntPtr address)
        {
            if (this._CachedFields.ContainsKey(address) == true)
            {
                return(this._CachedFields[address]);
            }

            UnrealClass uclass       = null;
            var         classAddress = this.ReadPointer(address + this.Configuration.ObjectClassOffset);

            if (classAddress != IntPtr.Zero &&
                classAddress != address)
            {
                uclass = this.ReadClass(classAddress);
            }

            if (this._CachedFields.ContainsKey(address) == true)
            {
                return(this._CachedFields[address]);
            }

            UnrealField field;

            switch (uclass.Path)
            {
            case "Core.ClassProperty":
            {
                field = new UnrealFields.ClassField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.ObjectProperty":
            {
                var objectField = new UnrealFields.ObjectField();
                field = objectField;
                this._CachedFields.Add(address, field);
                // TODO: move offset to config value
                objectField.PropertyClass = this.ReadClass(this.ReadPointer(address + 0x80));
                break;
            }

            case "Core.StructProperty":
            {
                var structField = new UnrealFields.StructField();
                field = structField;
                this._CachedFields.Add(address, field);
                // TODO: move offset to config value
                structField.Structure = this.ReadClass(this.ReadPointer(address + 0x80));
                break;
            }

            case "Core.ComponentProperty":
            {
                field = new UnrealFields.ComponentField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.ArrayProperty":
            {
                var arrayField = new UnrealFields.ArrayField();
                field = arrayField;
                this._CachedFields.Add(address, field);
                // TODO: move offset to config value
                arrayField.Inner = this.ReadField(this.ReadPointer(address + 0x80));
                break;
            }

            case "Core.BoolProperty":
            {
                var boolField = new UnrealFields.BoolField();
                field = boolField;
                this._CachedFields.Add(address, field);
                // TODO: move offset to config value
                boolField.BitFlag = this.Runtime.ReadValueS32(address + 0x80);
                break;
            }

            case "Core.ByteProperty":
            {
                field = new UnrealFields.ByteField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.IntProperty":
            {
                field = new UnrealFields.IntField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.FloatProperty":
            {
                field = new UnrealFields.FloatField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.StrProperty":
            {
                field = new UnrealFields.StrField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.NameProperty":
            {
                field = new UnrealFields.NameField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.ByteAttributeProperty":
            case "Core.IntAttributeProperty":
            case "Core.FloatAttributeProperty":
            case "Core.MapProperty":
            case "Core.DelegateProperty":
            case "Core.InterfaceProperty":
            {
                field = new UnrealFields.DummyField();
                this._CachedFields.Add(address, field);
                break;
            }

            default:
            {
                throw new NotImplementedException();
            }
            }

            field.Address       = address;
            field.VfTableObject = this.ReadPointer(address + 0);
            field.Name          = this.ReadName(address + this.Configuration.ObjectNameOffset);
            field.Class         = uclass;
            field.ArrayCount    = this.Runtime.ReadValueS32(address + 0x40); // TODO: move offset to config value
            field.Size          = this.Runtime.ReadValueS32(address + 0x44); // TODO: move offset to config value
            field.Offset        = this.Runtime.ReadValueS32(address + 0x60); // TODO: move offset to config value
            return(field);
        }
Example #2
0
        private UnrealField ReadField(IntPtr address)
        {
            if (this._CachedFields.ContainsKey(address) == true)
            {
                return(this._CachedFields[address]);
            }

            UnrealClass uclass       = null;
            var         classAddress = this.ReadPointer(address + this.Offsets.CoreObjectClass);

            if (classAddress != IntPtr.Zero && classAddress != address)
            {
                uclass = this.ReadClass(classAddress);
            }

            if (this._CachedFields.ContainsKey(address) == true)
            {
                return(this._CachedFields[address]);
            }

            UnrealField field;

            switch (uclass.Path)
            {
            case "Core.ClassProperty":
            {
                field = new UnrealFields.ClassField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.ObjectProperty":
            {
                var objectField = new UnrealFields.ObjectField();
                field = objectField;
                this._CachedFields.Add(address, field);
                var propertyClassAddress = this.ReadPointer(address + this.Offsets.CoreObjectPropertyPropertyClass);
                objectField.PropertyClass = this.ReadClass(propertyClassAddress);
                break;
            }

            case "Core.StructProperty":
            {
                var structField = new UnrealFields.StructField();
                field = structField;
                this._CachedFields.Add(address, field);
                var structAddress = this.ReadPointer(address + this.Offsets.CoreStructPropertyStruct);
                structField.Structure = this.ReadClass(structAddress);
                break;
            }

            case "Core.ComponentProperty":
            {
                field = new UnrealFields.ComponentField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.ArrayProperty":
            {
                var arrayField = new UnrealFields.ArrayField();
                field = arrayField;
                this._CachedFields.Add(address, field);
                var innerAddress = this.ReadPointer(address + this.Offsets.CoreArrayPropertyInner);
                arrayField.Inner = this.ReadField(innerAddress);
                break;
            }

            case "Core.BoolProperty":
            {
                var boolField = new UnrealFields.BoolField();
                field = boolField;
                this._CachedFields.Add(address, field);
                var bitFlagAddress = address + this.Offsets.CoreBoolPropertyBitFlag;
                boolField.BitFlag = this.Runtime.ReadValueS32(bitFlagAddress);
                break;
            }

            case "Core.ByteProperty":
            {
                field = new UnrealFields.ByteField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.IntProperty":
            {
                field = new UnrealFields.IntField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.FloatProperty":
            {
                field = new UnrealFields.FloatField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.StrProperty":
            {
                field = new UnrealFields.StringField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.NameProperty":
            {
                field = new UnrealFields.NameField();
                this._CachedFields.Add(address, field);
                break;
            }

            case "Core.ByteAttributeProperty":
            case "Core.IntAttributeProperty":
            case "Core.FloatAttributeProperty":
            case "Core.MapProperty":
            case "Core.DelegateProperty":
            case "Core.InterfaceProperty":
            {
                field = new UnrealFields.DummyField();
                this._CachedFields.Add(address, field);
                break;
            }

            default:
            {
                throw new NotImplementedException();
            }
            }

            var arrayCountAddress = address + this.Offsets.CoreFieldArrayCount;
            var sizeAddress       = address + this.Offsets.CoreFieldSize;
            var offsetAddress     = address + this.Offsets.CoreFieldOffset;

            field.Address       = address;
            field.VfTableObject = this.ReadPointer(address);
            field.Name          = this.ReadName(address + this.Offsets.CoreObjectName);
            field.Class         = uclass;
            field.ArrayCount    = this.Runtime.ReadValueS32(arrayCountAddress);
            field.Size          = this.Runtime.ReadValueS32(sizeAddress);
            field.Offset        = this.Runtime.ReadValueS32(offsetAddress);
            return(field);
        }