// Structs that don't use binary serialization // https://github.com/EpicGames/UnrealEngine/blob/7d9919ac7bfd80b7483012eab342cb427d60e8c9/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L2197 internal UObject(PackageReader reader, bool structFallback) { var props = new Dictionary <string, BaseProperty>(); while (true) { var Tag = new FPropertyTag(reader); if (Tag.Name.IsNone) { break; } var pos = reader.Position; props[Tag.Name.String] = BaseProperty.ReadProperty(reader, Tag, Tag.Type, ReadType.NORMAL); if (Tag.Size + pos != reader.Position) { Console.WriteLine($"Didn't read {Tag.Type.String} correctly (at {reader.Position}, should be {Tag.Size + pos}, {Tag.Size + pos - reader.Position} behind)"); reader.Position = Tag.Size + pos; } } Dict = props; if (!structFallback && reader.ReadInt32() != 0) { GUID = new FGuid(reader); } }
// https://github.com/EpicGames/UnrealEngine/blob/7d9919ac7bfd80b7483012eab342cb427d60e8c9/Engine/Source/Runtime/CoreUObject/Private/UObject/PropertyMap.cpp#L243 internal MapProperty(PackageReader reader, FPropertyTag tag) { Position = reader.Position; var NumKeysToRemove = reader.ReadInt32(); if (NumKeysToRemove != 0) { // Let me know if you find a package that has a non-zero NumKeysToRemove value //throw new NotImplementedException("Parsing of non-zero NumKeysToRemove maps aren't supported yet."); for (var i = 0; i < NumKeysToRemove; i++) { ReadAsValue(reader, tag, tag.InnerType, ReadType.MAP); } } var NumEntries = reader.ReadInt32(); var dict = new Dictionary <object, object>(NumEntries); for (int i = 0; i < NumEntries; i++) { dict[ReadAsValue(reader, tag, tag.InnerType, ReadType.MAP)] = ReadAsObject(reader, tag, tag.ValueType, ReadType.MAP); } Value = dict; }
internal static BaseProperty ReadAsObject(PackageReader reader, FPropertyTag tag, FName type, ReadType readType) { BaseProperty prop = type.String switch { "ByteProperty" => new ByteProperty(reader, tag, readType), "BoolProperty" => new BoolProperty(reader, tag, readType), "IntProperty" => new IntProperty(reader), "FloatProperty" => new FloatProperty(reader), "ObjectProperty" => new ObjectProperty(reader), "NameProperty" => new NameProperty(reader), "DelegateProperty" => new DelegateProperty(reader), "DoubleProperty" => new DoubleProperty(reader), "ArrayProperty" => new ArrayProperty(reader, tag), "StructProperty" => new StructProperty(reader, tag), "StrProperty" => new StrProperty(reader), "TextProperty" => new TextProperty(reader), "InterfaceProperty" => new InterfaceProperty(reader), //"MulticastDelegateProperty" => new MulticastDelegateProperty(reader, tag), //"LazyObjectProperty" => new LazyObjectProperty(reader, tag), "SoftObjectProperty" => new SoftObjectProperty(reader, readType), "AssetObjectProperty" => new SoftObjectProperty(reader, readType), "UInt64Property" => new UInt64Property(reader), "UInt32Property" => new UInt32Property(reader), "UInt16Property" => new UInt16Property(reader), "Int64Property" => new Int64Property(reader), "Int16Property" => new Int16Property(reader), "Int8Property" => new Int8Property(reader), "MapProperty" => new MapProperty(reader, tag), "SetProperty" => new SetProperty(reader, tag), "EnumProperty" => new EnumProperty(reader), _ => null, //throw new NotImplementedException($"Parsing of {type.String} types aren't supported yet."), }; return(prop); }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { var instance = LSerializer.Deserialize <UStructProperty>(reader); instance.Ref(summary); instance.Struct = (object)VisitorFactory.VisitStruct(reader, instance.StructName, summary) ?? new UObject(reader, summary, false, null); return(instance); }
public static FPropertyTag Visit(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { if (Visitors.TryGetValue(baseTag.Type.Name, out var visitor)) { return(visitor(reader, baseTag, summary)); } throw new NotImplementedException("No parser for " + baseTag.Type.Name); }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { UStructProperty uStructProperty = LSerializer.Deserialize <UStructProperty>(reader); uStructProperty.Ref(summary); uStructProperty.Struct = (((object)VisitorFactory.VisitStruct(reader, uStructProperty.StructName.Name, summary)) ?? ((object)new UObject(reader, summary, pad: false))); return(uStructProperty); }
internal SoftObjectProperty(PackageReader reader, FPropertyTag tag, ReadType readType) { Value = new FSoftObjectPath(reader); if (readType == ReadType.MAP) { reader.Position += 4; // skip ahead, putting the total bytes read to 16 } }
internal BoolProperty(PackageReader reader, FPropertyTag tag, ReadType readType) { Value = readType switch { ReadType.NORMAL => tag.BoolVal != 0, ReadType.MAP => reader.ReadByte() != 0, ReadType.ARRAY => reader.ReadByte() != 0, _ => throw new ArgumentOutOfRangeException(nameof(readType)), }; }
internal ByteProperty(PackageReader reader, FPropertyTag tag, ReadType readType) { Value = readType switch { ReadType.NORMAL => (byte)reader.ReadFName().Index, ReadType.MAP => (byte)reader.ReadUInt32(), ReadType.ARRAY => reader.ReadByte(), _ => throw new ArgumentOutOfRangeException(nameof(readType)), }; }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { var instance = LSerializer.Deserialize <USetProperty>(reader); instance.Ref(summary); var @base = reader.BaseStream.Position; instance.Entries = UArrayProperty.GetEntries(instance.Count, instance.ArrayType, reader, summary); reader.BaseStream.Position = @base + instance.Size - 8; return(instance); }
public UObject(IoPackageReader reader, string type, bool structFallback = false) { Dict = new Dictionary <string, object>(); var header = new FUnversionedHeader(reader); if (header.HasValues) { using var it = new FIterator(header); if (header.HasNonZeroValues) { FUnversionedType unversionedType = reader.GetOrCreateSchema(type); var num = 1; do { var(val, isNonZero) = it.Current; if (unversionedType.Properties.TryGetValue(val, out var props)) { var propertyTag = new FPropertyTag(props); if (isNonZero) { var key = Dict.ContainsKey(props.Name) ? $"{props.Name}_NK{num++:00}" : props.Name; var obj = BaseProperty.ReadAsObject(reader, propertyTag, propertyTag.Type, ReadType.NORMAL); Dict[key] = obj; } else { var key = Dict.ContainsKey(props.Name) ? $"{props.Name}_NK{num++:00}" : props.Name; var obj = BaseProperty.ReadAsZeroObject(reader, propertyTag, propertyTag.Type); Dict[key] = obj; } } else { Dict[val.ToString()] = null; } } while (it.MoveNext()); } else { #if DEBUG FConsole.AppendText(string.Concat("\n", type ?? "Unknown", ": ", reader.Summary.Name.String), "#CA6C6C", true); do { FConsole.AppendText($"Val: {it.Current.Val} (IsNonZero: {it.Current.IsNonZero})", FColors.Yellow, true); }while (it.MoveNext()); #endif } } if (!structFallback && reader.ReadInt32() != 0 /* && reader.Position + 16 <= maxSize*/) { reader.Position += FGuid.SIZE; } }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { USetProperty uSetProperty = LSerializer.Deserialize <USetProperty>(reader); uSetProperty.Ref(summary); long position = reader.BaseStream.Position; uSetProperty.Entries = UArrayProperty.GetEntries(uSetProperty.Count, uSetProperty.ArrayType, reader, summary); reader.BaseStream.Position = position + uSetProperty.Size - 8; return(uSetProperty); }
internal ByteProperty(PackageReader reader, FPropertyTag tag, ReadType readType) { Position = reader.Position; Value = readType switch { ReadType.NORMAL => tag.EnumName.IsNone ? reader.ReadByte().ToString() : reader.ReadFName().String, ReadType.MAP => (byte)reader.ReadUInt32(), ReadType.ARRAY => reader.ReadByte(), _ => throw new ArgumentOutOfRangeException(nameof(readType)), }; }
internal static void DeserializePropertiesTagged(List <FPropertyTag> properties, FAssetArchive Ar) { while (true) { var tag = new FPropertyTag(Ar, true); if (tag.Name.IsNone) { break; } properties.Add(tag); } }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { if (baseTag.Size < 8) { reader.BaseStream.Position += 0x19 + baseTag.Size; return(baseTag); } var instance = LSerializer.Deserialize <UTextProperty>(reader); instance.Ref(summary); return(instance); }
internal EnumProperty(PackageReader reader, FPropertyTag tag, ReadType readType) { Position = reader.Position; if (!(reader is IoPackageReader) || readType != ReadType.NORMAL) { Value = reader.ReadFName(); } else { var byteValue = tag.EnumType.String == "IntProperty" ? reader.ReadInt32() : reader.ReadByte(); Value = new FName(ByteToEnum(tag.EnumName.String, byteValue)); } }
internal EnumProperty(PackageReader reader, FPropertyTag tag) { Position = reader.Position; if (reader is IoPackageReader) { object byteValue = tag.EnumType.String == "IntProperty" ? reader.ReadInt32() : reader.ReadByte(); Value = new FName(ByteToEnum(tag.EnumName.String, byteValue)); } else { Value = reader.ReadFName(); } }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { UTextProperty uTextProperty = LSerializer.Deserialize <UTextProperty>(reader); if (baseTag.Size < 8) { reader.BaseStream.Position++; } else { reader.BaseStream.Position--; } uTextProperty.Ref(summary); return(uTextProperty); }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { UByteProperty uByteProperty = LSerializer.Deserialize <UByteProperty>(reader); uByteProperty.Ref(summary); if (uByteProperty.EnumName.Name == "None") { uByteProperty.Value = reader.ReadByte(); } else { uByteProperty.Value = LSerializer.Deserialize <FName>(reader); uByteProperty.Ref(summary); } return(uByteProperty); }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { var instance = LSerializer.Deserialize <UByteProperty>(reader); instance.Ref(summary); if (instance.EnumName == "None") { instance.Value = reader.ReadByte(); } else { instance.Value = LSerializer.Deserialize <FName>(reader); instance.Ref(summary); } return(instance); }
internal static List <FPropertyTag> DeserializePropertiesTagged(FAssetArchive Ar) { var properties = new List <FPropertyTag>(); while (true) { var tag = new FPropertyTag(Ar, true); if (tag.Name.IsNone) { break; } properties.Add(tag); } return(properties); }
public static FPropertyTag PropertyVisitor(BinaryReader reader, FPropertyTag baseTag, FPackageFileSummary summary) { UArrayProperty uArrayProperty = LSerializer.Deserialize <UArrayProperty>(reader); uArrayProperty.Ref(summary); long position = reader.BaseStream.Position; uArrayProperty.Entries = GetEntries(uArrayProperty.ArraySize, uArrayProperty.ArrayType, reader, summary); long position2 = reader.BaseStream.Position; if (position + uArrayProperty.Size - 4 != position2) { Console.WriteLine("WARNING: ARRAY SIZE OFFSHOOT!"); } reader.BaseStream.Position = position + uArrayProperty.Size - 4; return(uArrayProperty); }
internal BoolProperty(PackageReader reader, FPropertyTag tag, ReadType readType) { switch (readType) { case ReadType.NORMAL: Position = tag.Position; Value = tag.BoolVal != 0; break; case ReadType.MAP: case ReadType.ARRAY: Position = reader.Position; Value = reader.ReadByte() != 0; break; default: throw new ArgumentOutOfRangeException(nameof(readType)); } }
private FPropertyTag JsonToProperty(string name, string type, object value, FPackageFileSummary summary) { FPropertyTag fPropertyTag = null; switch (type) { case "FloatProperty": fPropertyTag = new UFloatProperty { Size = 4 }; break; case "UInt32Property": fPropertyTag = new UInt32Property { Size = 4 }; break; case "IntProperty": fPropertyTag = new UIntProperty { Size = 4 }; break; case "NameProperty": fPropertyTag = new UNameProperty { Size = 8 }; break; case "StrProperty": fPropertyTag = new UStrProperty(); break; default: throw new NotImplementedException("Dunno how to process " + type); } fPropertyTag.GenerateNew(name, type, summary); fPropertyTag.UpdateFromJSON(value, summary); return(fPropertyTag); }
// https://github.com/EpicGames/UnrealEngine/blob/bf95c2cbc703123e08ab54e3ceccdd47e48d224a/Engine/Source/Runtime/CoreUObject/Private/UObject/PropertySet.cpp#L216 internal SetProperty(PackageReader reader, FPropertyTag tag) { var NumKeysToRemove = reader.ReadInt32(); if (NumKeysToRemove != 0) { // Let me know if you find a package that has a non-zero NumKeysToRemove value throw new NotImplementedException("Parsing of non-zero NumKeysToRemove sets aren't supported yet."); } var NumEntries = reader.ReadInt32(); Value = new BaseProperty[NumEntries]; for (int i = 0; i < NumEntries; i++) { Value[i] = ReadProperty(reader, tag, tag.InnerType, ReadType.ARRAY); } }
// https://github.com/EpicGames/UnrealEngine/blob/bf95c2cbc703123e08ab54e3ceccdd47e48d224a/Engine/Source/Runtime/CoreUObject/Private/UObject/PropertySet.cpp#L216 internal SetProperty(PackageReader reader, FPropertyTag tag) { Position = reader.Position; var NumKeysToRemove = reader.ReadInt32(); for (int i = 0; i < NumKeysToRemove; i++) { ReadAsObject(reader, tag, tag.InnerType, ReadType.ARRAY); // read in the air? uh ok } var NumEntries = reader.ReadInt32(); Value = new object[NumEntries]; for (int i = 0; i < NumEntries; i++) { Value[i] = ReadAsObject(reader, tag, tag.InnerType, ReadType.ARRAY); } }
public static object Unwrap(object x) { object[] array = x as object[]; if (array != null) { return(array.Select(Unwrap).ToArray()); } UObject uObject = x as UObject; if (uObject != null) { return(uObject.ToDictionary(inStruct: true)); } IStructObject structObject = x as IStructObject; if (structObject != null) { return(structObject.Serialize()); } FName fName = x as FName; if (fName != null) { return(fName.GetValue()); } FPropertyTag fPropertyTag = x as FPropertyTag; if (fPropertyTag != null) { return(fPropertyTag.GetValue()); } Tuple <FPropertyTag, FPropertyTag> tuple = x as Tuple <FPropertyTag, FPropertyTag>; if (tuple != null) { return(new object[2] { tuple.Item1.GetValue(), tuple.Item2.GetValue() }); } return(x); }
internal ArrayProperty(PackageReader reader, FPropertyTag tag) { int length = reader.ReadInt32(); Value = new BaseProperty[length]; FPropertyTag InnerTag = default; // Execute if UE4 version is at least VER_UE4_INNER_ARRAY_TAG_INFO if (tag.InnerType.String == "StructProperty") { // Serialize a PropertyTag for the inner property of this array, allows us to validate the inner struct to see if it has changed InnerTag = new FPropertyTag(reader); } for (int i = 0; i < length; i++) { Value[i] = ReadProperty(reader, InnerTag, tag.InnerType, ReadType.ARRAY); } }
// Structs that don't use binary serialization // https://github.com/EpicGames/UnrealEngine/blob/7d9919ac7bfd80b7483012eab342cb427d60e8c9/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L2197 internal UObject(PackageReader reader, long maxSize, bool structFallback) { var props = new Dictionary <string, object>(); int i = 1; while (true) { var Tag = new FPropertyTag(reader); if (Tag.Name.IsNone) { break; } var pos = reader.Position; if (props.ContainsKey(Tag.Name.String)) // FortniteGame/Content/Balance/RarityData.uasset i really need this { props[$"{Tag.Name.String}_NK{i++}"] = BaseProperty.ReadProperty(reader, Tag, Tag.Type, ReadType.NORMAL) ?? null; // NK = NewKey } else { props[Tag.Name.String] = BaseProperty.ReadProperty(reader, Tag, Tag.Type, ReadType.NORMAL) ?? null; } if (props[Tag.Name.String] is null) { break; } if (Tag.Size + pos != reader.Position) { System.Diagnostics.Debug.WriteLine($"Didn't read {Tag.Type.String} correctly (at {reader.Position}, should be {Tag.Size + pos}, {Tag.Size + pos - reader.Position} behind)"); reader.Position = Tag.Size + pos; } } Dict = props; if (!structFallback && reader.ReadInt32() != 0 && reader.Position + 16 <= maxSize) { GUID = new FGuid(reader); } }
// Structs that don't use binary serialization // https://github.com/EpicGames/UnrealEngine/blob/7d9919ac7bfd80b7483012eab342cb427d60e8c9/Engine/Source/Runtime/CoreUObject/Private/UObject/Class.cpp#L2197 internal UObject(PackageReader reader, bool structFallback) { var properties = new Dictionary <string, object>(); int num = 1; while (true) { var Tag = new FPropertyTag(reader); if (Tag.Name.IsNone || Tag.Name.String == null) { break; } var pos = reader.Position; var obj = BaseProperty.ReadAsObject(reader, Tag, Tag.Type, ReadType.NORMAL) ?? null; var key = properties.ContainsKey(Tag.Name.String) ? $"{Tag.Name.String}_NK{num++:00}" : Tag.Name.String; properties[key] = obj; if (obj == null) { break; } if (Tag.Size + pos != reader.Position) { #if DEBUG System.Diagnostics.Debug.WriteLine($"Didn't read {key} correctly (at {reader.Position}, should be {Tag.Size + pos}, {Tag.Size + pos - reader.Position} behind)"); #endif reader.Position = Tag.Size + pos; } } Dict = properties; if (!structFallback && reader.ReadInt32() != 0 /* && reader.Position + 16 <= maxSize*/) { new FGuid(reader); } }