internal UnrealObjectShim(Engine engine, IntPtr address, UnrealClass uclass, string name, string path) { this._Engine = engine; this.Address = address; this.Class = uclass; this.Name = name; this.Path = path; this.Object = new UnrealObject(this); }
public bool IsA(UnrealClass uclass) { if (this.Class == null) { return(false); } return(this.Class == uclass || this.Class.IsA(uclass) == true); }
private UnrealClass ReadClass(IntPtr address) { if (this._CachedClasses.ContainsKey(address) == true) { return(this._CachedClasses[address]); } var uclass = new UnrealClass(); this._CachedClasses.Add(address, uclass); uclass.Address = address; uclass.VfTableObject = this.ReadPointer(address + 0); uclass.Name = this.ReadName(address + this.Configuration.ObjectNameOffset); uclass.Path = this.ReadPath(address); var classAddress = this.ReadPointer(address + this.Configuration.ObjectClassOffset); if (classAddress != IntPtr.Zero && classAddress != address) { uclass.Class = this.ReadClass(classAddress); } var fieldAddress = this.ReadPointer(address + this.Configuration.ClassFirstFieldOffset); var fields = new List <UnrealField>(); while (fieldAddress != IntPtr.Zero) { fields.Add(this.ReadField(fieldAddress)); fieldAddress = this.ReadPointer(fieldAddress + this.Configuration.FieldNextFieldOffset); } uclass.Fields = fields.ToArray(); return(uclass); }
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); }