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); }
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); }