/// <summary> /// Updates the archive with the modified files /// </summary> /// <param name="archive">The loaded archive data</param> /// <param name="outputFileStream">The file stream for the updated archive</param> /// <param name="files">The import data for the archive files</param> public void UpdateArchive(object archive, Stream outputFileStream, IEnumerable <IArchiveImportData> files) { RL.Logger?.LogInformationSource($"A CNT archive is being repacked..."); // Get the archive data var data = archive.CastTo <OpenSpaceCntData>(); // Create the file generator using var fileGenerator = new ArchiveFileGenerator <OpenSpaceCntFileEntry>(); // Set the current pointer position to the header size var pointer = data.GetHeaderSize(Settings); // Disable checksum data.IsChecksumUsed = false; data.DirChecksum = 0; // NOTE: We can't disable the XOR key entirely as that would disable it for the file bytes too, which would require them all to be decrypted // Reset XOR keys data.XORKey = 0; // Load each file foreach (var importData in files) { // Get the file entry var file = importData.FileEntryData.CastTo <OpenSpaceCntFileEntry>(); // Reset checksum and XOR key file.Checksum = 0; file.XORKey = 0; // Add to the generator fileGenerator.Add(file, () => { // Get the file bytes to write to the archive var bytes = importData.GetData(file); // Set the pointer file.Pointer = pointer; // Update the pointer by the file size pointer += file.Size; return(bytes); }); } // Write the files data.WriteArchiveContent(outputFileStream, fileGenerator); outputFileStream.Position = 0; // Serialize the data BinarySerializableHelpers.WriteToStream(data, outputFileStream, Settings, RCPServices.App.GetBinarySerializerLogger()); RL.Logger?.LogInformationSource($"The CNT archive has been repacked"); }
/// <summary> /// Updates the archive with the modified files /// </summary> /// <param name="archive">The loaded archive data</param> /// <param name="outputFileStream">The file stream for the updated archive</param> /// <param name="files">The import data for the archive files</param> public void UpdateArchive(object archive, Stream outputFileStream, IEnumerable <IArchiveImportData> files) { RL.Logger?.LogInformationSource($"An IPK archive is being repacked..."); // Get the archive data var data = archive.CastTo <UbiArtIpkData>(); // Create the file generator using var fileGenerator = new ArchiveFileGenerator <UbiArtIPKFileEntry>(); // Keep track of the current pointer position ulong currentOffset = 0; // Handle each file foreach (var importData in files) { // Get the file var file = importData.FileEntryData.CastTo <UbiArtIPKFileEntry>(); // Reset the offset array to always contain 1 item file.Offsets = new ulong[] { file.Offsets?.FirstOrDefault() ?? 0 }; // Set the count file.OffsetCount = (uint)file.Offsets.Length; // Add to the generator fileGenerator.Add(file, () => { // Get the file bytes to write to the archive var bytes = importData.GetData(file); // Set the offset file.Offsets[0] = currentOffset; // Increase by the file size currentOffset += file.ArchiveSize; return(bytes); }); } // Set the base offset data.BaseOffset = data.GetHeaderSize(Settings); // Write the files data.WriteArchiveContent(outputFileStream, fileGenerator, Config.ShouldCompress(data)); outputFileStream.Position = 0; // Serialize the data BinarySerializableHelpers.WriteToStream(data, outputFileStream, Settings, RCPServices.App.GetBinarySerializerLogger()); RL.Logger?.LogInformationSource($"The IPK archive has been repacked"); }
/// <summary> /// Loads the archive /// </summary> public void LoadArchive() { RL.Logger?.LogInformationSource($"The archive {DisplayName} is being loaded"); // Clear existing items ClearAndDisposeItems(); // Load the archive data ArchiveData = Manager.LoadArchive(ArchiveFileStream); // Load the archive var data = Manager.LoadArchiveData(ArchiveData, ArchiveFileStream); // Dispose the current generator ArchiveFileGenerator?.Dispose(); // Save the generator ArchiveFileGenerator = data.Generator; // Add each directory foreach (var dir in data.Directories) { // Check if it's the root directory if (dir.DirectoryName == String.Empty) { // Add the files Files.AddRange(dir.Files.Select(x => new ArchiveFileViewModel(x, this))); continue; } // Keep track of the previous item ArchiveDirectoryViewModel prevItem = this; // Enumerate each sub directory foreach (string subDir in dir.DirectoryName.Trim(Manager.PathSeparatorCharacter).Split(Manager.PathSeparatorCharacter)) { // Set the previous item and create the item if it doesn't already exist prevItem = prevItem.FindItem(x => x.ID == subDir) ?? prevItem.Add(subDir); } // Add the files prevItem.Files.AddRange(dir.Files.Select(x => new ArchiveFileViewModel(x, this))); } }
public override void Dispose() { // Cancel refreshing thumbnails ExplorerDialogViewModel.CancelRefreshingThumbnails = true; // Dispose base class base.Dispose(); // Dispose the stream ArchiveFileStream?.Dispose(); // Dispose every directory ClearAndDisposeItems(); // Dispose the generator ArchiveFileGenerator?.Dispose(); RL.Logger?.LogInformationSource($"The archive {DisplayName} has been disposed"); }