示例#1
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;
        }
示例#2
0
        /// <summary>
        /// Some alpha MPQs are hotswappable and only contain a single file and it's checksum
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="archivename"></param>
        private bool TryReadAlpha(MpqArchive mpq, string archivename)
        {
            // strip the local path and extension to get the filename
            var file = Path.ChangeExtension(GetInternalPath(archivename), null).WoWNormalise();

            if (FileList.ContainsKey(file))
            {
                return(true);
            }

            // add the filename as the listfile
            var internalname = Path.GetFileName(file);

            mpq.AddListFile(internalname);

            // read file if known
            if (mpq.HasFile(internalname))
            {
                using var fs = mpq.OpenFile(internalname);

                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);
                    }

                    record.EBlock.EncodingMap = map;
                    FileList.TryAdd(file, record);
                    return(true);
                }
            }

            return(false);
        }