public void Serialize(BinaryWriter writer, PackageFile package) { ClassPackage.Serialize(writer, package); ClassName.Serialize(writer, package); PackageRef.Serialize(writer, package); ObjectName.Serialize(writer, package); }
public override void Deserialize(BinaryReader reader, PackageFile package) { Guid = new PropertyGuid(); Guid.Deserialize(reader, package); Value = new PackageIndex(); Value.Deserialize(reader, package); }
public void Serialize(BinaryWriter writer, PackageFile package) { TryGetInstanceNum(); Index = package.Names.FindIndex(s => s.Name == Value); if (Index == -1) { var ent = new NameEntry(); ent.Name = Value; package.Names.Add(ent); Index = package.Names.FindIndex(s => s.Name == Value); if (Index == -1) { throw new Exception("Failed to add new FName for some reason!"); } } if (package.FNameCleanupInProgress) { package.Names[Index].InUse = true; if (package.UexpWriteInProgress) { package.UExpFnames.Add(new Tuple <FName, long>(this, writer.BaseStream.Position)); } } writer.Write(Index); writer.Write(InstanceNum); }
public virtual void DeserializeText(string text, PackageFile package) { var values = Shared.ProcessCsvRow(text).ToList(); var fields = GetType().GetFields().OrderBy(field => field.MetadataToken).ToList(); // hack to get fields in order of declaration (todo: use something less hacky, this might break mono?) int valueIdx = 0; for (int i = 0; i < fields.Count; i++) { var field = fields[i]; // TODO: need to provide a default value for hidden fields, else they may be left as null (which our serialization code doesn't like!) var settings = field.GetCustomAttribute <SerializerAttribute>(); if (settings != null && settings.Hidden) { continue; } if (FieldCanSerialize(field)) { object value = DeserializeValueText(field.FieldType, settings, package, values[valueIdx]); field.SetValue(this, value); } valueIdx++; } }
object DeserializeBool(SerializerAttribute settings, BinaryReader reader, PackageFile package, bool isListElement) { if (isListElement) { return(reader.ReadByte() != 0); } if (settings != null) { if (settings.Size == 1) { return(reader.ReadByte() != 0); } if (settings.Size == 2) { return(reader.ReadUInt16() != 0); } if (settings.Size == 4) { return(reader.ReadUInt32() != 0); } if (settings.Size == 8) { return(reader.ReadUInt64() != 0); } } return(reader.ReadUInt32() != 0); }
public void Serialize(BinaryWriter writer, PackageFile package) { Name.Serialize(writer, package); Type.Serialize(writer, package); writer.Write(Size); writer.Write(Index); }
// Reads PackageFile from a UAsset file, if UExp exists next to it then they'll be merged before reading static PackageFile ReadPackage(string UAssetPath, bool convertingFromCsv) { var UExpPath = Path.ChangeExtension(UAssetPath, ".uexp"); var uasset = File.ReadAllBytes(UAssetPath); var uassetLength = uasset.Length; if (File.Exists(UExpPath)) { var uexp = File.ReadAllBytes(UExpPath); var uexpLength = uexp.Length; Array.Resize(ref uasset, uasset.Length + uexp.Length); Array.Copy(uexp, 0, uasset, uassetLength, uexpLength); } using (var reader = new BinaryReader(new MemoryStream(uasset))) { var sum = new PackageFile(); if (convertingFromCsv) { sum.SkipPropertyDataLoad = true; } sum.Deserialize(reader); return(sum); } }
public void Deserialize(BinaryReader reader, PackageFile package) { HasGuid = reader.ReadByte(); if (HasGuid != 0) { Guid = reader.ReadBytes(0x10); } }
public void Deserialize(BinaryReader reader, PackageFile package) { Major = reader.ReadUInt16(); Minor = reader.ReadUInt16(); Patch = reader.ReadUInt16(); Changelist = reader.ReadUInt32(); Branch = reader.ReadFString(); }
public void Serialize(BinaryWriter writer, PackageFile package) { writer.Write(Major); writer.Write(Minor); writer.Write(Patch); writer.Write(Changelist); writer.WriteFString(Branch); }
public void Serialize(BinaryWriter writer, PackageFile package) { HasGuid = (byte)(Guid != null ? 1 : 0); writer.Write(HasGuid); if (Guid != null) { writer.Write(Guid); } }
public void Deserialize(BinaryReader reader, PackageFile package) { Name = new FName(); Name.Deserialize(reader, package); Type = new FName(); Type.Deserialize(reader, package); Size = reader.ReadInt32(); Index = reader.ReadInt32(); }
public string SerializeTextHeader(PackageFile package) { if (PropertiesData == null || PropertiesData.Count <= 0) { return(null); } return("RowName," + PropertiesData.First().Value.SerializeTextHeader(package)); }
public void DeserializeText(string text, PackageFile package) { Type?rowType = null; foreach (var prop in Properties) { if (prop.GetType() != typeof(ObjectProperty)) { continue; } var objectProperty = prop as ObjectProperty; if (!PackageFile.KnownTypes.TryGetValue(objectProperty.Value.ImportObject.ObjectName.Value, out rowType)) { if (!PackageFile.KnownTypes.TryGetValue("F" + objectProperty.Value.ImportObject.ObjectName.Value, out rowType)) { throw new Exception($"UAsset uses unknown struct type {objectProperty.Value.ImportObject.ObjectName.Value}!"); } } break; // probably shouldn't be doing this, hopefully all DQXI tables only contain a single ObjectProperty... } if (rowType == null) { throw new Exception("Failed to find rowType type!"); } text = text.Replace("\r\n", "\n"); var lines = text.Split('\n', StringSplitOptions.RemoveEmptyEntries); foreach (var line in lines) { // Read + remove RowName from the line var rowNameEndIdx = line.IndexOf(','); var key = line.Substring(0, rowNameEndIdx); var value = line.Substring(rowNameEndIdx + 1); var keyFName = new FName(key); ISerializableText rowValue; if (PropertiesData.ContainsKey(keyFName)) { rowValue = PropertiesData[keyFName]; } else { rowValue = Activator.CreateInstance(rowType) as ISerializableText; } rowValue.DeserializeText(value, package); PropertiesData[keyFName] = rowValue; } // TODO load values from text into class }
public void Serialize(BinaryWriter writer, PackageFile package) { ClassIndex.Serialize(writer, package); SuperIndex.Serialize(writer, package); if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_TemplateIndex_IN_COOKED_EXPORTS)) { TemplateIndex.Serialize(writer, package); } OuterIndex.Serialize(writer, package); ObjectName.Serialize(writer, package); writer.Write(ObjectFlags); if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES)) { writer.Write(SerialSize); } else { writer.Write((int)SerialSize); } if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES)) { writer.Write(SerialOffset); } else { writer.Write((int)SerialOffset); } writer.Write(bForcedExport); writer.Write(bNotForClient); writer.Write(bNotForServer); writer.Write(PackageGuid); writer.Write(PackageFlags); if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_LOAD_FOR_EDITOR_GAME)) { writer.Write(bNotAlwaysLoadedForEditorGame); } if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT)) { writer.Write(bIsAsset); } if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS)) { writer.Write(FirstExportDependency); writer.Write(SerializationBeforeSerializationDependencies); writer.Write(CreateBeforeSerializationDependencies); writer.Write(SerializationBeforeCreateDependencies); writer.Write(CreateBeforeCreateDependencies); } }
public void Deserialize(BinaryReader reader, PackageFile package) { ClassPackage = new FName(); ClassPackage.Deserialize(reader, package); ClassName = new FName(); ClassName.Deserialize(reader, package); PackageRef = new PackageIndex(); PackageRef.Deserialize(reader, package); ObjectName = new FName(); ObjectName.Deserialize(reader, package); }
public bool InUse; // set/reset during serialization so we can tell any unused entries public void Deserialize(BinaryReader reader, PackageFile package) { Name = reader.ReadFString(); if (!package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_NAME_HASHES_SERIALIZED)) { return; } NonCasePreservingHash = reader.ReadUInt16(); CasePreservingHash = reader.ReadUInt16(); }
public void Deserialize(BinaryReader reader, PackageFile package) { Index = reader.ReadInt32(); InstanceNum = reader.ReadInt32(); if (package.Names.Count > Index && Index >= 0) { Value = package.Names[Index].Name; } else { throw new Exception("Deserialized FName not found in UAsset header?"); } }
public void Deserialize(BinaryReader reader, PackageFile package) { ClassIndex = new PackageIndex(); ClassIndex.Deserialize(reader, package); SuperIndex = new PackageIndex(); SuperIndex.Deserialize(reader, package); if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_TemplateIndex_IN_COOKED_EXPORTS)) { TemplateIndex = new PackageIndex(); TemplateIndex.Deserialize(reader, package); } OuterIndex = new PackageIndex(); OuterIndex.Deserialize(reader, package); ObjectName = new FName(); ObjectName.Deserialize(reader, package); ObjectFlags = reader.ReadUInt32(); SerialSize = package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES) ? reader.ReadInt64() : reader.ReadInt32(); SerialOffset = package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_64BIT_EXPORTMAP_SERIALSIZES) ? reader.ReadInt64() : reader.ReadInt32(); bForcedExport = reader.ReadInt32(); bNotForClient = reader.ReadInt32(); bNotForServer = reader.ReadInt32(); PackageGuid = reader.ReadBytes(0x10); PackageFlags = reader.ReadUInt32(); if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_LOAD_FOR_EDITOR_GAME)) { bNotAlwaysLoadedForEditorGame = reader.ReadInt32(); } if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_COOKED_ASSETS_IN_EDITOR_SUPPORT)) { bIsAsset = reader.ReadInt32(); } if (package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_PRELOAD_DEPENDENCIES_IN_COOKED_EXPORTS)) { FirstExportDependency = reader.ReadInt32(); SerializationBeforeSerializationDependencies = reader.ReadInt32(); CreateBeforeSerializationDependencies = reader.ReadInt32(); SerializationBeforeCreateDependencies = reader.ReadInt32(); CreateBeforeCreateDependencies = reader.ReadInt32(); } }
public string SerializeText(PackageFile package, bool isMainElement) { // TODO: add a CSV header line from the type in PropertiesData? string[] lines = new string[PropertiesData.Count]; int i = 0; foreach (var kvp in PropertiesData) { lines[i] = $"{kvp.Key},{kvp.Value.SerializeText(package, isMainElement)}"; i++; } return(String.Join('\n', lines)); }
public void Deserialize(BinaryReader reader, PackageFile package) { Index = reader.ReadInt32(); int importIndex = (-Index) - 1; int exportIndex = Index - 1; if (IsImport() && package.Imports.Count > importIndex) { ImportObject = package.Imports[importIndex]; } if (IsExport() && package.Exports.Count > exportIndex) { ExportObject = package.Exports[exportIndex]; } }
public virtual void Serialize(BinaryWriter writer, PackageFile package) { var fields = GetType().GetFields().OrderBy(field => field.MetadataToken); // hack to get fields in order of declaration (todo: use something less hacky, this might break mono?) foreach (var field in fields) { if (!FieldCanSerialize(field)) { continue; } var settings = field.GetCustomAttribute <SerializerAttribute>(); var fieldType = field.FieldType.Name; SerializeValue(field.FieldType, settings, writer, package, field.GetValue(this)); } }
public virtual string SerializeText(PackageFile package, bool isMainElement) { var fields = GetType().GetFields().OrderBy(field => field.MetadataToken); // hack to get fields in order of declaration (todo: use something less hacky, this might break mono?) string retVal = ""; foreach (var field in fields) { var settings = field.GetCustomAttribute <SerializerAttribute>(); if (settings != null && settings.Hidden) { continue; } string valueText = "\"\""; if (FieldCanSerialize(field)) { valueText = SerializeValueText(field.FieldType, settings, package, field.GetValue(this)); // change outer escaped-quotes to regular quotes if (isMainElement && valueText.StartsWith("\"\"") && valueText.EndsWith("\"\"") && valueText.Length > 4) { valueText = "\"" + valueText.Substring(2, valueText.Length - 4) + "\""; } } // hack to escape anything that contains a comma, hope it doesn't break anything.. if (valueText.Contains(",") && !valueText.Contains("\"")) { valueText = "\"" + valueText + "\""; } retVal += valueText; retVal += ","; } // remove trailing comma if (retVal.Length > 0) { retVal = retVal.Substring(0, retVal.Length - 1); } return(retVal); }
public string SerializeTextHeader(PackageFile package) { var fields = GetType().GetFields().OrderBy(field => field.MetadataToken); // hack to get fields in order of declaration (todo: use something less hacky, this might break mono?) string retVal = ""; foreach (var field in fields) { var settings = field.GetCustomAttribute <SerializerAttribute>(); if (settings != null && settings.Hidden) { continue; } retVal += field.Name; retVal += ","; } // remove trailing comma if (retVal.Length > 0) { retVal = retVal.Substring(0, retVal.Length - 1); } return(retVal); }
public void Serialize(BinaryWriter writer, PackageFile package) { writer.WriteFString(Name); if (!package.Header.IsVersionOrGreater(UE4Versions.VER_UE4_NAME_HASHES_SERIALIZED)) { return; } if (Shared.HasNonASCIIChars(Name)) { NonCasePreservingHash = (ushort)(Shared.UE4Strihash_DEPRECATED_Wide(Name) & 0xFFFF); CasePreservingHash = (ushort)(Shared.UE4StrCrc32_Wide(Name) & 0xFFFF); } else { NonCasePreservingHash = (ushort)(Shared.UE4Strihash_DEPRECATED(Name) & 0xFFFF); CasePreservingHash = (ushort)(Shared.UE4StrCrc32(Name) & 0xFFFF); } writer.Write(NonCasePreservingHash); writer.Write(CasePreservingHash); }
void SerializeBool(SerializerAttribute settings, BinaryWriter writer, PackageFile package, object value, bool isListElement) { var val = (bool)value; if (isListElement) { writer.Write(val ? (byte)1 : (byte)0); return; } else { if (settings != null) { if (settings.Size == 1) { writer.Write(val ? (byte)1 : (byte)0); return; } if (settings.Size == 2) { writer.Write(val ? (ushort)1 : (ushort)0); return; } if (settings.Size == 4) { writer.Write(val ? (uint)1 : (uint)0); return; } if (settings.Size == 8) { writer.Write(val ? (ulong)1 : (ulong)0); return; } } } writer.Write(val ? (int)1 : (int)0); }
public string SerializeValueText(Type type, SerializerAttribute settings, PackageFile package, object value) { switch (type.Name) { case "String": // FString var str = (string)value; if (string.IsNullOrEmpty(str)) { return("\"\""); // hack to fix CSV regex not working properly with empty cells.. } return("\"" + str.Replace("\r", "\\\\r").Replace("\n", "\\\\n").Replace("\"", "\"\"") + "\""); case "Byte[]": var byt = (byte[])value; return(byt.ToHexString()); case "Boolean": return((bool)value ? "true" : "false"); case "Byte": return(((byte)value).ToString()); case "Int16": return(((short)value).ToString()); case "UInt16": return(((ushort)value).ToString()); case "Int32": return(((int)value).ToString()); case "UInt32": return(((uint)value).ToString()); case "Single": return(((float)value).ToString()); case "Double": return(((double)value).ToString()); case "Int64": return(((long)value).ToString()); case "UInt64": return(((ulong)value).ToString()); case "List`1": var elementType = type.GetGenericArguments()[0]; var list = value as IList; var result = ""; for (int i = 0; i < list.Count; i++) { result += SerializeValueText(elementType, settings, package, list[i]).Replace("\"", "\"\""); if (i + 1 < list.Count) { result += ","; } } result = "\"{" + result + "}\""; return(result); case "FName": var name = (FName)value; return(name.ToString()); default: if (type.IsEnum) { var enumStr = Enum.GetName(type, value); if (!string.IsNullOrEmpty(enumStr)) { return(enumStr); } // If Enum.GetName returned empty then the value isn't part of enum (and object struct is likely incorrect) // Fallback to the enums underlying type var enumType = Enum.GetUnderlyingType(type); return(SerializeValueText(enumType, settings, package, value)); } if (type.GetInterfaces().Contains(typeof(ISerializableText))) { var obj = value as ISerializableText; if (obj == null) { return("\"\""); } return("\"" + obj.SerializeText(package, false).Replace("\"", "\"\"") + "\""); } break; } return(null); }
public object DeserializeValue(Type type, SerializerAttribute settings, BinaryReader reader, PackageFile package, bool isListElement = false) { switch (type.Name) { case "String": // FString return(reader.ReadFString()); case "Byte[]": int sz = settings?.Size ?? 0; byte[] data = reader.ReadBytes(sz); return(data); case "Boolean": return(DeserializeBool(settings, reader, package, isListElement)); case "Byte": return(reader.ReadByte()); case "Int16": return(reader.ReadInt16()); case "UInt16": return(reader.ReadUInt16()); case "Int32": return(reader.ReadInt32()); case "UInt32": return(reader.ReadUInt32()); case "Single": return(reader.ReadSingle()); case "Double": return(reader.ReadDouble()); case "Int64": return(reader.ReadInt64()); case "UInt64": return(reader.ReadUInt64()); case "List`1": // TArray var elementType = type.GetGenericArguments()[0]; var listType = typeof(List <>).MakeGenericType(elementType); var list = Activator.CreateInstance(listType) as IList; int count = reader.ReadInt32(); for (int i = 0; i < count; i++) { list.Add(DeserializeValue(elementType, settings, reader, package, true)); } return(list); case "FName": var name = new FName(); name.Deserialize(reader, package); return(name); default: if (type.IsEnum) { var enumType = Enum.GetUnderlyingType(type); return(DeserializeValue(enumType, settings, reader, package)); } if (type.GetInterfaces().Contains(typeof(ISerializable))) { var obj = Activator.CreateInstance(type) as ISerializable; obj.Deserialize(reader, package); return(obj); } break; } return(null); }
public object DeserializeValueText(Type type, SerializerAttribute settings, PackageFile package, string value) { // strip quotes from around value if (value.StartsWith('"') && value.EndsWith('"')) { value = value.Substring(1, value.Length - 2); } value = value.Replace("\"\"", "\""); switch (type.Name) { case "String": return(value.Replace("\\\\r", "\r").Replace("\\\\n", "\n")); case "Byte[]": return(Shared.StringToByteArray(value)); case "Boolean": return(value == "1" || value == "true" || value == "yes"); case "Byte": return(byte.Parse(value)); case "Int16": return(short.Parse(value)); case "UInt16": return(ushort.Parse(value)); case "Int32": return(int.Parse(value)); case "UInt32": return(uint.Parse(value)); case "Single": return(float.Parse(value)); case "Double": return(double.Parse(value)); case "Int64": return(long.Parse(value)); case "UInt64": return(ulong.Parse(value)); case "List`1": // TArray var elementType = type.GetGenericArguments()[0]; var listType = typeof(List <>).MakeGenericType(elementType); var list = Activator.CreateInstance(listType) as IList; if (value != "{}") // not empty: { if (value.StartsWith('{') && value.EndsWith('}')) { value = value.Substring(1, value.Length - 2); } var values = Shared.ProcessCsvRow(value).ToList(); foreach (var val in values) { list.Add(DeserializeValueText(elementType, settings, package, val)); } } return(list); case "FName": return(new FName(value)); default: if (type.IsEnum) { object enumResult; if (Enum.TryParse(type, value, out enumResult)) { return(enumResult); } // if Enum.TryParse failed then the value isn't part of enum (and object struct is likely incorrect) // Fallback to the enums underlying type var enumType = Enum.GetUnderlyingType(type); return(DeserializeValueText(enumType, settings, package, value)); } if (type.GetInterfaces().Contains(typeof(ISerializableText))) { var obj = Activator.CreateInstance(type) as ISerializableText; obj.DeserializeText(value, package); return(obj); } break; } return(null); }
public void SerializeValue(Type type, SerializerAttribute settings, BinaryWriter writer, PackageFile package, object value, bool isListElement = false) { switch (type.Name) { case "String": // FString var str = (string)value; writer.WriteFString(str); break; case "Byte[]": writer.Write((byte[])value); break; case "Boolean": SerializeBool(settings, writer, package, value, isListElement); break; case "Byte": writer.Write((byte)value); break; case "Int16": writer.Write((short)value); break; case "UInt16": writer.Write((ushort)value); break; case "Int32": writer.Write((int)value); break; case "UInt32": writer.Write((uint)value); break; case "Single": writer.Write((float)value); break; case "Double": writer.Write((double)value); break; case "Int64": writer.Write((long)value); break; case "UInt64": writer.Write((ulong)value); break; case "List`1": var elementType = type.GetGenericArguments()[0]; var list = value as IList; writer.Write(list.Count); for (int i = 0; i < list.Count; i++) { SerializeValue(elementType, settings, writer, package, list[i], true); } break; case "FName": var name = (FName)value; name.Serialize(writer, package); break; default: if (type.IsEnum) { var enumType = Enum.GetUnderlyingType(type); SerializeValue(enumType, settings, writer, package, value); } if (type.GetInterfaces().Contains(typeof(ISerializable))) { var obj = value as ISerializable; obj.Serialize(writer, package); } break; } }