public UObject(BinaryReader data, FPackageFileSummary summary, bool pad = true, FObjectExport export = null) { while (true) { long position = data.BaseStream.Position; FName fName = LSerializer.Deserialize <FName>(data); fName.Ref(summary); if ((string)fName == "None") { break; } data.BaseStream.Position = position; FPropertyTag fPropertyTag = LSerializer.Deserialize <FPropertyTag>(data); data.BaseStream.Position = position; fPropertyTag.Ref(summary); fPropertyTag = VisitorFactory.Visit(data, fPropertyTag, summary); fPropertyTag.Ref(summary); Add(fPropertyTag); } if (pad) { data.BaseStream.Position += 4L; } if (export != null) { ObjectData = VisitorFactory.VisitSubtype(data, export, summary); } }
public override void UpdateIndex(string[] names, FPackageFileSummary summary) { base.UpdateIndex(names, summary); ArrayType.UpdateIndex(names, summary); if ((string)ArrayType == "StructProperty") { (Entries.First() as UStructProperty).UpdateIndex(names, summary); } else { if (Entries.Count <= 0) { return; } foreach (object entry in Entries) { switch ((string)ArrayType) { case "ByteProperty": case "NameProperty": case "EnumProperty": (entry as FName).UpdateIndex(names, summary); break; case "SoftObjectProperty": case "ObjectProperty": case "TextProperty": throw new NotImplementedException($"No indexer logic for {ArrayType}"); } } } }
public void BSerialize(BinaryWriter writer, FPackageFileSummary summary) { int index = summary.Names.Select((FNameEntry x, int i) => new { name = x.Name, index = i }).First(x => x.name.Equals("None")).index; FName instance = new FName { Index = index }; using (Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { FPropertyTag current = enumerator.Current; BSerializer.Serialize(writer, current.GetType(), current); current.BSerialize(writer, summary); } } BSerializer.Serialize(writer, typeof(FName), instance); if (ObjectData != null) { writer.BaseStream.Position += 4L; ObjectData.BSerialize(writer, summary); } }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { if (!Struct.GetType().IsArray) { SingleStruct(data, summary); return; } object[] array = Struct as object[]; object[] array2 = data as object[]; object[] array3 = new object[array2.Length]; if (UAsset.Options.Verbose && array.Length != array2.Length) { Console.WriteLine("Array size difference between base and JSON: " + base.Name?.Name + " -> " + StructName.Name); } VisitorFactory.StructVisitor value; bool flag = VisitorFactory.StructVisitors.TryGetValue(StructName.Name, out value); Type type = flag ? value.Target.GetType() : null; if (!flag && !UAsset.Options.ForceArrays) { return; } if (UAsset.Options.ForceArrays && UAsset.Options.Verbose) { Console.WriteLine("Forcing array " + base.Name?.Name + " -> " + StructName.Name + " with UObjects, integrity warning!"); } base.Size = 0; for (int i = 0; i < array2.Length; i++) { if (flag) { object obj = JsonConvert.DeserializeObject(array2[i].ToString(), type); array3[i] = (obj as IStructObject); base.Size += (obj as IStructObject).GetSize(); continue; } JObject jObject = JObject.Parse(array2[i].ToString()); List <KeyValuePair <string, object> > list = new List <KeyValuePair <string, object> >(jObject.Count - 1); string[] array4 = new string[jObject.Count - 1]; foreach (JProperty item in jObject.Properties()) { if (item.Name != "UTTypes") { list.Add(new KeyValuePair <string, object>(item.Name, item.Value)); } else { array4 = item.Value.ToString().Split(',').ToArray(); } } UObject uObject = new UObject(); for (int j = 0; j < list.Count; j++) { uObject.Add(JsonToProperty(list[j].Key, array4[j], list[j].Value, summary)); } array3[i] = uObject; base.Size += uObject.GetSize(); } Struct = array3; }
public void UpdateFromJSON(object jdata, FPackageFileSummary summary) { KeyValuePair <string, object>[] array = JsonConvert.DeserializeObject <KeyValuePair <string, object>[]>(jdata.ToString()); int num = 0; if (array.Length != base.Count && !UAsset.Options.AllowNewEntries) { throw new NotImplementedException("JSON data has different amount of keys!"); } if (array.Length < base.Count) { throw new NotImplementedException("Removal of the entries is not possible, fam"); } for (int i = base.Count; i < array.Length; i++) { FName fName = new FName(); fName.UpdateName(array[i].Key, summary); UObject uObject = new UObject { Name = fName }; foreach (FPropertyTag item in this.First().Value) { uObject.Add(DeepClone(item) as FPropertyTag); } Add(fName, uObject); } foreach (UObject value in base.Values) { value.UpdateFromJSON(array.ElementAt(num++).Value, summary); } }
public override void BSerialize(BinaryWriter writer, FPackageFileSummary summary) { if (Struct.GetType().IsArray) { object[] array = Struct as object[]; foreach (object obj in array) { IStructObject structObject = obj as IStructObject; if (structObject != null) { BSerializer.Serialize(writer, structObject.GetType(), structObject); } else { (obj as UObject)?.BSerialize(writer, summary); } } } else if (Struct is IStructObject) { BSerializer.Serialize(writer, Struct.GetType(), Struct); } else { (Struct as UObject)?.BSerialize(writer, summary); } }
public UObject(BinaryReader data, FPackageFileSummary summary, bool pad = true, FObjectExport export = null) { while (true) { var start = data.BaseStream.Position; #if DEBUG CachedPos.Add(start); #endif var name = LSerializer.Deserialize <FName>(data); name.Ref(summary); if (name == "None") { break; } data.BaseStream.Position = start; var tag = LSerializer.Deserialize <FPropertyTag>(data); data.BaseStream.Position = start; tag.Ref(summary); tag = VisitorFactory.Visit(data, tag, summary); tag.Ref(summary); Add(tag); } if (pad) { data.BaseStream.Position += 4; } if (export != null) { ObjectData = VisitorFactory.VisitSubtype(data, export, summary); } }
private void SingleStruct(object data, FPackageFileSummary summary) { IStructObject structObject = Struct as IStructObject; if (structObject != null) { Struct = JsonConvert.DeserializeObject(data.ToString(), Struct.GetType()); base.Size = structObject.GetSize(); return; } UObject uObject = Struct as UObject; if (uObject == null || !UAsset.Options.ForceArrays) { return; } if (UAsset.Options.Verbose) { Console.WriteLine($"Forcing Struct {base.Name?.Name} -> {StructName} update as a single UObject, integrity warning!"); } JObject jObject = JObject.Parse(data.ToString()); List <KeyValuePair <string, object> > list = new List <KeyValuePair <string, object> >(jObject.Count); foreach (JProperty item in jObject.Properties()) { list.Add(new KeyValuePair <string, object>(item.Name, item.Value)); } for (int i = 0; i < uObject.Count; i++) { uObject[i].UpdateFromJSON(list[i].Value, summary); } base.Size += uObject.GetSize(); }
PackageReader(BinaryReader uasset, BinaryReader uexp, Stream ubulk) { Loader = uasset; PackageFileSummary = new FPackageFileSummary(Loader); NameMap = SerializeNameMap(); ImportMap = SerializeImportMap(); ExportMap = SerializeExportMap(); DataExports = new IUExport[ExportMap.Length]; DataExportTypes = new FName[ExportMap.Length]; Loader = uexp; for (int i = 0; i < ExportMap.Length; i++) { FObjectExport Export = ExportMap[i]; { FName ExportType; if (Export.ClassIndex.IsNull) { ExportType = DataExportTypes[i] = ReadFName(); // check if this is true, I don't know if Fortnite ever uses this } else if (Export.ClassIndex.IsExport) { ExportType = DataExportTypes[i] = ExportMap[Export.ClassIndex.AsExport].SuperIndex.Resource.ObjectName; } else if (Export.ClassIndex.IsImport) { ExportType = DataExportTypes[i] = ImportMap[Export.ClassIndex.AsImport].ObjectName; } else { throw new FileLoadException("Can't get class name"); // Shouldn't reach this unless the laws of math have bent to MagmaReef's will } if (ExportType.String.Equals("BlueprintGeneratedClass")) { continue; } var pos = Position = Export.SerialOffset - PackageFileSummary.TotalHeaderSize; DataExports[i] = ExportType.String switch { "Texture2D" => new UTexture2D(this, ubulk, ExportMap.Sum(e => e.SerialSize) + PackageFileSummary.TotalHeaderSize), "CurveTable" => new UCurveTable(this), "DataTable" => new UDataTable(this), "FontFace" => new UFontFace(this, ubulk), "SoundWave" => new USoundWave(this, ubulk, ExportMap.Sum(e => e.SerialSize) + PackageFileSummary.TotalHeaderSize), "StringTable" => new UStringTable(this), _ => new UObject(this), }; #if DEBUG if (pos + Export.SerialSize != Position) { System.Diagnostics.Debug.WriteLine($"[ExportType={ExportType.String}] Didn't read {Export.ObjectName} correctly (at {Position}, should be {pos + Export.SerialSize}, {pos + Export.SerialSize - Position} behind)"); } #endif } } return; }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { Value = Convert.ToString(data); if (!string.IsNullOrEmpty(Value)) { base.Size = Value.FLengthWithNull() + 4; } }
public static object VisitEnumerable(BinaryReader reader, string type, FPackageFileSummary summary, int count) { if (EnumerableVisitors.TryGetValue(type, out var visitor)) { return(visitor(reader, summary, count)); } throw new NotImplementedException("No parser for " + type); }
public override void BSerialize(BinaryWriter writer, FPackageFileSummary summary) { writer.BaseStream.Position--; if (base.Size < 8) { writer.Write((short)(-256)); } }
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 override void Ref(FPackageFileSummary summary) { base.Ref(summary); EnumName.Ref(summary); if (Value is FName fn) { fn.Ref(summary); } }
public static void WriteEnumerable(BinaryWriter writer, string type, FPackageFileSummary summary, object value, int count) { if (EnumerableWriters.TryGetValue(type, out EnumerableWriter value2)) { value2(writer, summary, value, count); return; } throw new NotImplementedException("No parser for " + type); }
PackageReader(BinaryReader uasset, BinaryReader uexp, Stream ubulk) { Loader = uasset; PackageFileSummary = new FPackageFileSummary(Loader); NameMap = SerializeNameMap(); ImportMap = SerializeImportMap(); ExportMap = SerializeExportMap(); Exports = new IUExport[ExportMap.Length]; ExportTypes = new string[ExportMap.Length]; Loader = uexp; for (int i = 0; i < ExportMap.Length; i++) { var Export = ExportMap[i]; // Serialize everything, not just specifically assets // if (Export.bIsAsset) { // We need to get the class name from the import/export maps FName ObjectClassName; if (Export.ClassIndex.IsNull) { ObjectClassName = ReadFName(); // check if this is true, I don't know if Fortnite ever uses this } else if (Export.ClassIndex.IsExport) { ObjectClassName = ExportMap[Export.ClassIndex.AsExport].ObjectName; } else if (Export.ClassIndex.IsImport) { ObjectClassName = ImportMap[Export.ClassIndex.AsImport].ObjectName; } else { throw new FileLoadException("Can't get class name"); // Shouldn't reach this unless the laws of math have bent to MagmaReef's will } var pos = Position = Export.SerialOffset - PackageFileSummary.TotalHeaderSize; ExportTypes[i] = ObjectClassName.String; Exports[i] = ObjectClassName.String switch { "Texture2D" => new UTexture2D(this, ubulk, ExportMap.Sum(e => e.SerialSize) + PackageFileSummary.TotalHeaderSize), "CurveTable" => new UCurveTable(this), "DataTable" => new UDataTable(this), "FontFace" => new UFontFace(this, ubulk), "SoundWave" => new USoundWave(this, ubulk, ExportMap.Sum(e => e.SerialSize) + PackageFileSummary.TotalHeaderSize), "StringTable" => new UStringTable(this), _ => new UObject(this), }; if (pos + Export.SerialSize != Position) { System.Diagnostics.Debug.WriteLine($"Didn't read {Export.ObjectName} ({ObjectClassName}) correctly (at {Position}, should be {pos + Export.SerialSize}, {pos + Export.SerialSize - Position} behind)"); } } } return; }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { Value = Convert.ToSingle(data); if (Guid == null) { Guid = new FPropertyGuid { HasGuid = 0 }; } }
private void ReadSummary() { Summary = new FPackageFileSummary(); Summary.Serialize(this); Version = Summary.FileVersionUE4; NameMap = new List <string>(Summary.NameCount); ExportMap = new List <FObjectExport>(Summary.ExportCount); ImportMap = new List <FObjectImport>(Summary.ImportCount); GatherableTextDataMap = new List <FGatherableTextData>(Summary.GatherableTextDataCount); StringAssetReferences = new List <string>(Summary.StringAssetReferencesCount); }
public override void BSerialize(BinaryWriter writer, FPackageFileSummary summary) { if (EnumName.Name == "None") { writer.Write(Convert.ToByte(Value)); } else { BSerializer.Serialize(writer, typeof(FName), (FName)Value); } }
public FPackageFileSummary GetSummary() { if (this._packageFileSummary is null) { long lastPos = this._openAssetStream.Position; this._openAssetStream.Seek(0, SeekOrigin.Begin); this._packageFileSummary = FPackageFileSummary.Deserialize(this._openAssetStream); this._openAssetStream.Seek(lastPos, SeekOrigin.Begin); } return(this._packageFileSummary); }
public void UpdateIndex(string[] names, FPackageFileSummary summary) { using (Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { KeyValuePair <FName, UObject> current = enumerator.Current; current.Key.UpdateIndex(names, summary); current.Value.UpdateIndex(names, summary); } } }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { FName fName = Value as FName; if (fName != null) { fName.UpdateName(data.ToString(), summary); return; } Value = Convert.ToByte(data); throw new NotImplementedException("Cannot recalculate actual byte size for ByteProperty"); }
public void BSerialize(BinaryWriter writer, FPackageFileSummary summary) { writer.Write(base.Count); using (Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { KeyValuePair <FName, UObject> current = enumerator.Current; BSerializer.Serialize <FName>(writer, current.Key); current.Value.BSerialize(writer, summary); } } }
public void UpdateIndex(string[] names, FPackageFileSummary summary) { using (Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { enumerator.Current.UpdateIndex(names, summary); } } if (ObjectData != null) { ObjectData.UpdateIndex(names, summary); } }
public void BSerialize(BinaryWriter writer, FPackageFileSummary summary) { BSerializer.WriteFString(writer, Name); writer.Write(base.Count); using (Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { KeyValuePair <string, string> current = enumerator.Current; BSerializer.WriteFString(writer, current.Key); BSerializer.WriteFString(writer, current.Value); } } }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { var anon = JsonConvert.DeserializeAnonymousType(data.ToString(), new { Hash = string.Empty, Text = string.Empty }); if (!string.Equals(Value, anon.Text, StringComparison.OrdinalIgnoreCase)) { Value = anon.Text; Hash = (string.IsNullOrEmpty(Value) ? string.Empty : anon.Hash); base.Size = ((string.IsNullOrEmpty(Value) || string.IsNullOrEmpty(Hash)) ? 5 : (33 + Value.FLengthWithNull() + 4 + 4 + 8 + 1)); } }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { var anonymousTypeObject = new { Package = string.Empty, Path = string.Empty }; var anon = JsonConvert.DeserializeAnonymousType(data.ToString(), anonymousTypeObject); Package.UpdateName(anon.Package, summary); if (!string.Equals(Path, anon.Path, StringComparison.OrdinalIgnoreCase)) { Path = anon.Path; base.Size = 12 + Path.FLengthWithNull(); } }
public override void UpdateFromJSON(object data, FPackageFileSummary summary) { string newName = Convert.ToString(data); if (Value == null) { Value = new FName(); } if (Guid == null) { Guid = new FPropertyGuid { HasGuid = 0 }; } Value.UpdateName(newName, summary); }
public void UpdateFromJSON(object jdata, FPackageFileSummary summary) { if (ObjectData != null) { ObjectData.UpdateFromJSON(jdata, summary); return; } using (Enumerator enumerator = GetEnumerator()) { while (enumerator.MoveNext()) { FPropertyTag current = enumerator.Current; JObject.Parse(jdata.ToString()).TryGetValue(current.Name, StringComparison.OrdinalIgnoreCase, out JToken value); current.UpdateFromJSON(value, summary); } } }
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); }