using System.Collections.Generic; using System.IO; using System.Linq; using JD.Core.ProjectManaging; using NUnit.Framework; using Packager.Parameters; using PluginCommon.Bundle; using Ubisoft.Collections; namespace Packager.Tasks { public class ExtractFilesFromBundleTask : Task { [Input("Bundle Directory", IOCardinality.Single, IOType.String)] public SingleReference InputdirectoryPath { get; set; } [Input("Path to Files containing the files to extract", IOCardinality.Multi, IOType.String)] public ReferenceList FileNames { get; set; } [Output("Output FileList", IOType.String)] public ReferenceList ExtractedFileList = new ReferenceList(); private readonly List _filesToExtract = new List(); public ExtractFilesFromBundleTask() { FileNames = new ReferenceList(); InputdirectoryPath = new SingleReference(); } protected override void StartInternal(BuildConfiguration profile, cookerWrapper cooker) { FileNames.ForEach(x => { _filesToExtract.AddRange(File.ReadAllLines(x)); }); var bundleDirectory = new DirectoryInfo(InputdirectoryPath.Value); var bundleList = bundleDirectory.GetFiles().Where(x => x.Name.EndsWith(".ipk")).Select(x => new Bundle(x.FullName)).ToList(); _filesToExtract.ForEach(file => { foreach (var bundle in bundleList) { if (IsFileInBundle(file, bundle)) { ExtractFilesFromBundle(file, bundle); break; } } }); bundleList.ForEach(x => x.Dispose()); } private bool IsFileInBundle(string file, Bundle bundle) { return bundle.FileList.Contains(file); } private void ExtractFilesFromBundle(string file, Bundle bundle) { var fileHeader = bundle.GetFileHeader(file); var outputFile = Path.Combine(TaskOutputFolder, file); var fileDirectory = Path.GetDirectoryName(outputFile); if (!Directory.Exists(fileDirectory)) { Directory.CreateDirectory(fileDirectory); } using (var fileStream = new StreamReader(bundle.OpenFile(fileHeader))) { var data = fileStream.ReadToEnd(); File.WriteAllText(outputFile, data); ExtractedFileList.Add(outputFile); } } } [TestFixture] [Ignore("")] public class TestExtractFilesFromBundles { private readonly ExtractFilesFromBundleTask _extractFilesFromBundle = new ExtractFilesFromBundleTask(); private const string FileName = "filesToExtract.txt"; private void CreateFile(List fileData) { System.IO.File.WriteAllLines(FileName, fileData); _extractFilesFromBundle.FileNames.Add(FileName); } private void CleanUp() { File.Delete(FileName); } [Test] public void TestCanExtractFilesFromBundle() { var extractFileList = new List { "cache/itf_cooked/pc/enginedata/gameconfig/gc_carousel_rules.json.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/localisationtrc.isg.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/padrumbleconfig.isg.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/rewardlist.isg.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/soundconfig.isg.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/statsconfig.isg.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/textconfig.isg.ckd", "cache/itf_cooked/pc/enginedata/gameconfig/zinput.isg.ckd", "cache/itf_cooked/pc/world/ui/objects/challenge_taunt_item/tuto/animations/fade_out.tape.ckd", "cache/itf_cooked/pc/world/ui/objects/dancer_profile_creation_avatar_item/animations/fade_out.tape.ckd", "cache/itf_cooked/pc/world/ui/objects/playlist_edition_control/common/animations/fade_out.tape.ckd" }; CreateFile(extractFileList); _extractFilesFromBundle.InputdirectoryPath .Value =Path.Combine(ProjectManager.Instance.CurrentProject.DataPath ,@"output\Pc_GameBundle"); ConfigureTask(); _extractFilesFromBundle.StartTaskTest(); Assert.IsTrue(_extractFilesFromBundle.ExtractedFileList.Count == 11); CleanUp(); } private void ConfigureTask() { _extractFilesFromBundle.TaskFolder = Path.Combine(DataPath.GetAbsolutePath("output"), "temp", "Test"); _extractFilesFromBundle.TaskOutputFolder = "Outputs"; if (!Directory.Exists(_extractFilesFromBundle.TaskOutputFolder)) Directory.CreateDirectory(_extractFilesFromBundle.TaskOutputFolder); } } }