/// <summary>
        /// Enumerates local files in the WoW directory
        /// </summary>
        /// <param name="searchPattern"></param>
        /// <returns></returns>
        public IEnumerable <IFormat> Enumerate(string searchPattern, bool useParallelization = true)
        {
            searchPattern = Utils.CorrectSearchPattern(searchPattern);

            var fileReader = new FileReader(_build, _options);
            var files      = Directory.EnumerateFiles(_directory, searchPattern, SearchOption.AllDirectories);

            bool   includeFileInfo = _options.ParseMode.HasFlag(ParseMode.FileInfo);
            string localDir        = _directory + Path.DirectorySeparatorChar;

            ConcurrentBag <IFormat> resultSet = new ConcurrentBag <IFormat>();

            ParallelOptions options = new ParallelOptions()
            {
                MaxDegreeOfParallelism = useParallelization ? -1 : 1
            };

            Parallel.ForEach(files, options, file =>
            {
                string filename = file.Replace(localDir, "", _comparison).WoWNormalize();

                // validate search criteria
                if (Utils.IsInvalidFile(filename, _options))
                {
                    return;
                }

                using var md5    = MD5.Create();
                using var stream = File.OpenRead(file);
                using var bs     = new BufferedStream(stream);
                Structures.Meta.FileInfo entry = new Structures.Meta.FileInfo()
                {
                    Build = _build.Build,
                    Name  = filename
                };

                if (includeFileInfo)
                {
                    entry.Checksum = md5.ComputeHash(stream).ToChecksum();
                    entry.Created  = Utils.GetLocalFileCreated(filename);
                    entry.Size     = (uint)stream.Length;
                }

                resultSet.Add(fileReader.Read(bs, entry));
            });

            return(resultSet);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Parses the archive file.
        /// </summary>
        /// <param name="mpq"></param>
        /// <param name="filename"></param>
        /// <param name="overridename">Alpha MPQ filename override.</param>
        /// <returns></returns>
        private IFormat ReadFileImpl(MpqArchive mpq, string filename, string overridename = null)
        {
            using var md5    = MD5.Create();
            using var stream = mpq.OpenFile(overridename ?? filename);
            if (stream == null || !stream.CanRead || stream.Length <= 1)
            {
                return(null);
            }

            // validate filesize limit
            if (_options.MaxFileSize > 0 && stream.Length > _options.MaxFileSize)
            {
                return(null);
            }

            Structures.Meta.FileInfo entry = new Structures.Meta.FileInfo()
            {
                Build = _build.Build,
                Name  = filename.WoWNormalize()
            };

            if (_options.ParseMode.HasFlag(ParseMode.FileInfo))
            {
                entry.Checksum = stream.GetMd5Hash();
                if (string.IsNullOrWhiteSpace(entry.Checksum) || entry.Checksum == EMPTY_CHECKSUM)
                {
                    entry.Checksum = md5.ComputeHash(stream).ToChecksum();
                }
                entry.Created = stream.CreatedDate;
                entry.Size    = (uint)stream.Length;
            }

            stream.FileName = filename;

            using var bs = new BufferedStream(stream);
            return(_fileReader.Read(bs, entry));
        }