/// <summary>
        /// Enumerates all non-archive local files, BLT encodes them and adds them to the InstallFile
        /// </summary>
        /// <param name="maxDegreeOfParallelism"></param>
        /// <returns></returns>
        public void ExportFiles(int maxDegreeOfParallelism = 15)
        {
            var results = new ConcurrentBag <CASRecord>();

            var block = new ActionBlock <string>(file =>
            {
                // strip the local path and normalise
                var name = file[(file.IndexOf(BaseDirectory, Comparison) + BaseDirectory.Length)..].WoWNormalise();

                // block table encode and export to the temp folder
                // then add appropiate tags
                var record  = BlockTableEncoder.EncodeAndExport(file, Options.TempDirectory, name);
                record.Tags = TagGenerator.GetTags(file);

                if (!EncodingCache.ContainsEKey(record.EKey))
                {
                    EncodingCache.AddOrUpdate(record);
                }
                else
                {
                    record.BLTEPath = "";
                }

                results.Add(record);
            },
Beispiel #2
0
        /// <summary>
        /// Extracts a collection of files from an archive and BLTE encodes them
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="filenames"></param>
        /// <param name="maxDegreeOfParallelism"></param>
        /// <returns></returns>
        private async Task ExportFiles(MpqArchive mpq, IEnumerable <string> filenames, bool applyTags = false, int maxDegreeOfParallelism = 150)
        {
            var block = new ActionBlock <string>(file =>
            {
                using var fs = mpq.OpenFile(file);

                // ignore PTCH files
                if (fs.Flags.HasFlag(MPQFileAttributes.PatchFile))
                {
                    return;
                }

                // patch has marked file for deletion so remove from filelist
                if (fs.Flags.HasFlag(MPQFileAttributes.DeleteMarker))
                {
                    FileList.TryRemove(file, out _);
                    return;
                }

                if (fs.CanRead && fs.Length > 0)
                {
                    var map = BlockTableEncoder.GetEMapFromExtension(file, fs.Length);

                    if (!EncodingCache.TryGetRecord(MD5Hash.Parse(fs.GetMD5Hash()), file, out var record))
                    {
                        record = BlockTableEncoder.EncodeAndExport(fs, map, Options.TempDirectory, file);
                        EncodingCache.AddOrUpdate(record);
                    }

                    if (applyTags)
                    {
                        record.Tags = TagGenerator.GetTags(file, fs);
                    }

                    record.EBlock.EncodingMap = map;
                    FileList.TryAdd(file, record);
                }
            },
                                                 new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = maxDegreeOfParallelism
            });

            foreach (var file in filenames)
            {
                if (!FileList.ContainsKey(file))
                {
                    block.Post(file);
                }
            }

            block.Complete();
            await block.Completion;
        }
Beispiel #3
0
        /// <summary>
        /// Iterates all loose files within the data directory and BLT encodes them
        /// </summary>
        /// <param name="filenames"></param>
        public void EnumerateLooseDataFiles(IEnumerable <string> filenames)
        {
            if (!filenames.Any())
            {
                return;
            }

            Log.WriteLine("Exporting loose Data files");

            var block = new ActionBlock <string>(file =>
            {
                var filename = GetInternalPath(file);

                var record  = BlockTableEncoder.EncodeAndExport(file, Options.TempDirectory, filename);
                record.Tags = TagGenerator.GetTags(file);

                if (!EncodingCache.ContainsEKey(record.EKey))
                {
                    EncodingCache.AddOrUpdate(record);
                }
                else
                {
                    record.BLTEPath = "";
                }

                FileList.TryAdd(filename, record);
            },
                                                 new ExecutionDataflowBlockOptions {
                MaxDegreeOfParallelism = 150
            });

            foreach (var f in filenames)
            {
                block.Post(f);
            }

            block.Complete();
            block.Completion.Wait();
        }