public static T[] SerializeUbiArtObjectArray <T>(this IBinarySerializer s, T[] array, string name = null) where T : IBinarySerializable, new() { // Serialize the size array = s.SerializeArraySize <T, uint>(array, name: name); // Serialize the array array = s.SerializeObjectArray <T>(array, array.Length, name: name); // Return the array return(array); }
public static T[] SerializeUbiArtArray <T>(this IBinarySerializer s, T[] array, string name = null) { // Serialize the size array = s.SerializeArraySize <T, uint>(array, name: name); // Serialize the array values for (int i = 0; i < array.Length; i++) { array[i] = s.SerializeUbiArtGenericValue <T>(array[i], name: $"{nameof(array)}[{i}]"); } // Return the array return(array); }
/// <summary> /// Handles the serialization using the specified serializer /// </summary> /// <param name="s">The serializer</param> public void Serialize(IBinarySerializer s) { // Serialize the directory and file array sizes Directories = s.SerializeArraySize <string, int>(Directories, name: nameof(Directories)); Files = s.SerializeArraySize <OpenSpaceCntFileEntry, int>(Files, name: nameof(Files)); // Serialize header info IsXORUsed = s.Serialize <bool>(IsXORUsed, name: nameof(IsXORUsed)); IsChecksumUsed = s.Serialize <bool>(IsChecksumUsed, name: nameof(IsChecksumUsed)); XORKey = s.Serialize <byte>(XORKey, name: nameof(XORKey)); // Serialize the directory paths for (int i = 0; i < Directories.Length; i++) { Directories[i] = s.SerializeOpenSpaceEncryptedString(Directories[i], IsXORUsed ? XORKey : (byte)0, name: $"{nameof(Directories)}[{i}]"); } // Serialize the directory checksum DirChecksum = s.Serialize <byte>(DirChecksum, name: nameof(DirChecksum)); // Serialize the file info Files = s.SerializeObjectArray <OpenSpaceCntFileEntry>(Files, Files.Length, (s, o) => o.XORKey = IsXORUsed ? XORKey : (byte)0, name: nameof(Files)); }
/// <summary> /// Handles the serialization using the specified serializer /// </summary> /// <param name="s">The serializer</param> public void Serialize(IBinarySerializer s) { // Serialize and verify the magic header MagicHeader = s.Serialize <uint>(MagicHeader, name: nameof(MagicHeader)); if (MagicHeader != 0x50EC12BA) { throw new Exception("The IPK header is not valid"); } // Serialize version Version = s.Serialize <uint>(Version, name: nameof(Version)); // Serialize first unknown value Unknown1 = s.Serialize <uint>(Unknown1, name: nameof(Unknown1)); // Serialize second unknown value if version is above or equal to 8 if (Version >= 8) { Unknown2 = s.Serialize <uint>(Unknown2, name: nameof(Unknown2)); } // Serialize offset and file count BaseOffset = s.Serialize <uint>(BaseOffset, name: nameof(BaseOffset)); FilesCount = s.Serialize <uint>(FilesCount, name: nameof(FilesCount)); // Serialize unknown values Unknown3 = s.SerializeBool <uint>(Unknown3, name: nameof(Unknown3)); Unknown4 = s.SerializeBool <uint>(Unknown4, name: nameof(Unknown4)); Unknown5 = s.SerializeBool <uint>(Unknown5, name: nameof(Unknown5)); Unknown6 = s.Serialize <uint>(Unknown6, name: nameof(Unknown6)); if (s.GetSettings <UbiArtSettings>().Game == UbiArtGame.ValiantHearts) { Unknown9 = s.Serialize <uint>(Unknown9, name: nameof(Unknown9)); } Unknown7 = s.Serialize <uint>(Unknown7, name: nameof(Unknown7)); EngineVersion = s.Serialize <uint>(EngineVersion, name: nameof(EngineVersion)); if (SupportsCompressedBlock) { BlockSize = s.Serialize <uint>(BlockSize, name: nameof(BlockSize)); BlockCompressedSize = s.Serialize <uint>(BlockCompressedSize, name: nameof(BlockCompressedSize)); } // Serialize the file array size Files = s.SerializeArraySize <UbiArtIPKFileEntry, uint>(Files, name: nameof(Files)); // NOTE: So far this only appears to be the case for the bundle_pc32.ipk file used in Child of Light // TODO: Add logging when migrated to BinarySerializer //if (Files.Length != FilesCount) // Logger.Warn("The initial file count {0} does not match the file array size {1}", FilesCount, Files.Length); // Serialize the file entries Files = s.SerializeObjectArray <UbiArtIPKFileEntry>(Files, Files.Length, (s, o) => o.IPKVersion = Version, name: nameof(Files)); // TODO: Add logging when migrated to BinarySerializer //if (!IsSerializingHeaderSize && s.Stream.Position != BaseOffset) // Logger.Warn("Offset value {0} doesn't match file entry end offset {1}", BaseOffset, s.Stream.Position); }