private static void OpenArchive() { var fileInfo = new FileInfo(_archiveInput.Text); if (fileInfo.Exists) { _archiveInput.Enabled = false; _archiveInputBrowseButton.Enabled = false; _openCloseArchiveButton.Text = "Close archive"; _saveAsButton.Enabled = true; _archive = MpqArchive.Open(fileInfo.FullName, true); _archive.DiscoverFileNames(); var map = Map.Open(_archive); // _originScriptLanguage = map.Info.ScriptLanguage; var targetScriptLanguages = new HashSet <object>(new object[] { // ScriptLanguage.Jass, ScriptLanguage.Lua, }); _targetScriptLanguagesComboBox.Items.AddRange(targetScriptLanguages.OrderByDescending(patch => (int)patch).ToArray()); _targetScriptLanguagesComboBox.Enabled = true; if (_targetScriptLanguagesComboBox.Items.Count == 1) { _targetScriptLanguagesComboBox.SelectedIndex = 0; } } }
/// <exception cref="ArgumentException">Thrown when the <see cref="MpqArchive"/> does not contain an <see cref="Attributes"/> file.</exception> public static bool VerifyAttributes(this MpqArchive archive) { if (!archive.TryOpenFile(Attributes.FileName, out var attributesStream)) { throw new ArgumentException($"The archive must contain an {Attributes.FileName} file.", nameof(archive)); } using var reader = new BinaryReader(attributesStream); var attributes = reader.ReadAttributes(); var hasCrc32 = attributes.Flags.HasFlag(AttributesFlags.Crc32); var hasDateTime = attributes.Flags.HasFlag(AttributesFlags.DateTime); var count = 0; foreach (var mpqEntry in archive) { if (hasCrc32) { using var mpqEntryStream = archive.OpenFile(mpqEntry); var crc32 = mpqEntry.FileName == Attributes.FileName ? 0 : new Ionic.Crc.CRC32().GetCrc32(mpqEntryStream); if (crc32 != attributes.Crc32s[count]) { return(false); } } count++; } return((!hasCrc32 || attributes.Crc32s.Count == count) && (!hasDateTime || attributes.DateTimes.Count == count)); }
public void TestWithPreArchiveData() { var memoryStream = new MemoryStream(); var randomData = new byte[999]; randomData[100] = 99; memoryStream.Write(randomData, 0, randomData.Length); var randomFiles = new List <MpqFile>(); for (var i = 0; i < 35; i++) { var fileStream = new MemoryStream(); fileStream.Write(randomData, 0, randomData.Length); fileStream.Position = 0; randomFiles.Add(MpqFile.New(fileStream, $"file{i}")); } using var a = MpqArchive.Create(memoryStream, randomFiles); memoryStream.Position = 0; var archive = MpqArchive.Open(memoryStream); foreach (var file in archive.GetMpqFiles()) { file.MpqStream.Seek(100, SeekOrigin.Begin); Assert.AreEqual(99, file.MpqStream.ReadByte()); } archive.Dispose(); }
public void TestRecreatePKCompressed() { var inputArchivePath = TestDataProvider.GetFile(@"Maps\PKCompressed.w3x"); using var inputArchive = MpqArchive.Open(inputArchivePath); using var recreatedArchive = MpqArchive.Create( (Stream?)null, inputArchive.GetMpqFiles().ToArray(), (ushort)inputArchive.Header.HashTableSize, inputArchive.Header.BlockSize); for (var i = 0; i < inputArchive.Header.BlockTableSize; i++) { inputArchive.BaseStream.Position = inputArchive[i].FilePosition; recreatedArchive.BaseStream.Position = recreatedArchive[i].FilePosition; var size1 = inputArchive[i].CompressedSize; var size2 = recreatedArchive[i].CompressedSize; StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, size1 > size2 ? size1 : size2); } inputArchive.BaseStream.Position = 0; recreatedArchive.BaseStream.Position = 0; StreamAssert.AreEqual(inputArchive.BaseStream, recreatedArchive.BaseStream, MpqHeader.Size); }
public static void Main(string[] args) { if (args.Length != 1) { Console.WriteLine("usage: lsmpq.exe <mpq-file>"); Environment.Exit(0); } Mpq mpq = new MpqArchive(args[0]); StreamReader sr = new StreamReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("list.txt")); string entry; while ((entry = sr.ReadLine()) != null) { entry = entry.ToLower(); Stream mpq_stream = mpq.GetStreamForResource(entry); if (mpq_stream == null) { continue; } Console.WriteLine("{0} {1}", entry, mpq_stream.Length); mpq_stream.Dispose(); } }
/// <summary> /// Iterates all the data archives, extracting and BLT encoding all files /// <para>Patches are applied where applicable to get the most up-to-date variant of each file.</para> /// </summary> /// <param name="archives"></param> public void EnumerateDataArchives(IEnumerable <string> archives, bool applyTags = false) { Log.WriteLine("Exporting Data Archive files"); foreach (var archivename in archives) { using var mpq = new MpqArchive(archivename, FileAccess.Read); Log.WriteLine(" Exporting " + Path.GetFileName(mpq.FilePath)); if (TryGetListFile(mpq, out var files)) { mpq.AddPatchArchives(PatchArchives); ExportFiles(mpq, files, applyTags).Wait(); mpq.Dispose(); } else if (TryReadAlpha(mpq, archivename)) { mpq.Dispose(); } else { throw new FormatException(Path.GetFileName(archivename) + " HAS NO LISTFILE!"); } } }
public static Tuple <ReplayParseResult, Replay> ParseReplay(string fileName, bool deleteFile, ParseOptions parseOptions) { var replay = new Replay(); try { // File in the version numbers for later use. MpqHeader.ParseHeader(replay, fileName); if (!parseOptions.IgnoreErrors && replay.ReplayBuild < 32455) { return(new Tuple <ReplayParseResult, Replay>(ReplayParseResult.PreAlphaWipe, null)); } using (var archive = new MpqArchive(fileName)) ParseReplayArchive(replay, archive, parseOptions); if (deleteFile) { File.Delete(fileName); } return(ParseReplayResults(replay, parseOptions.IgnoreErrors, parseOptions.AllowPTR)); } catch { return(new Tuple <ReplayParseResult, Replay>(ReplayParseResult.ParserException, new Replay { ReplayBuild = replay.ReplayBuild })); } }
/// <summary> /// Extract the root directory files from Base-{OS}.MPQ /// </summary> /// <returns></returns> private bool ExtractBaseMPQ() { Program.Log("Extracting Base MPQ..."); string baseMPQ = $"Base-{MFILDownloader.CurrentSession.OS}.mpq"; string baseMPQpath = Path.Combine(_dataDirectory, baseMPQ); if (!File.Exists(baseMPQpath)) { Program.Log($"{baseMPQ} not found!", ConsoleColor.Red); return(false); } using (var mpq = new MpqArchive(baseMPQpath, FileAccess.Read)) { if (!TryGetFileList(mpq, true, out var files)) { Program.Log($"{baseMPQ} missing ListFile, manual extraction required.", ConsoleColor.Red); return(false); } foreach (var file in files) { mpq.ExtractFile(file, Path.Combine(_repo.DefaultDirectory, file)); } } return(true); }
public void TestStoreCompressedThenRetrieveFile(string filename) { var fileStream = File.OpenRead(filename); var mpqFile = new MpqFile(fileStream, filename, MpqFileFlags.Exists | MpqFileFlags.Compressed, BlockSize); var archive = MpqArchive.Create(new MemoryStream(), new List <MpqFile>() { mpqFile }); var openedArchive = MpqArchive.Open(archive.BaseStream); var openedStream = openedArchive.OpenFile(filename); // Reload file, since the filestream gets disposed when the mpqfile is added to an mpqarchive. fileStream = File.OpenRead(filename); Assert.AreEqual(fileStream.Length, openedStream.Length); using (var fileStreamReader = new StreamReader(fileStream)) { using (var openedStreamReader = new StreamReader(openedStream)) { StringAssert.Equals(fileStreamReader.ReadToEnd(), openedStreamReader.ReadToEnd()); } } }
/// <summary> /// Attempts to return a list of all files in the archive /// </summary> /// <param name="mpq"></param> /// <param name="files"></param> /// <returns></returns> private bool TryGetFileList(MpqArchive mpq, bool removeLists, out List <string> files) { files = new List <string>(); if (!mpq.HasFile("(ListFile)")) { return(false); } using (var file = mpq.OpenFile("(ListFile)")) using (var sr = new StreamReader(file)) { if (!file.CanRead || file.Length == 0) { return(false); } string[] filenames = sr.ReadToEnd().Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); files.AddRange(filenames); } if (removeLists) { files.RemoveAll(x => x.EndsWith(".lst")); } return(files.Count > 0); }
private async Task LoadMPQDBFiles() { lstFiles.DataSource = null; FileNames.Clear(); await Task.Factory.StartNew(() => { using (MpqArchive archive = new MpqArchive(filePath, FileAccess.Read)) { string line = string.Empty; using (MpqFileStream file = archive.OpenFile("(listfile)")) using (StreamReader sr = new StreamReader(file)) { while ((line = sr.ReadLine()) != null) { if (fileExtensions.Contains(Path.GetExtension(line).ToLower())) { FileNames.TryAdd(line, Path.GetFileName(line)); var ms = new MemoryStream(); archive.OpenFile(line).CopyTo(ms); Streams.TryAdd(line, ms); } } } } }); }
/** * Imports a file to the archive. * Deletes/imports to overwrite. * It imports from "in/" folder */ private void Import(String filename, MpqArchive archive) { try { Console.WriteLine("Importing file: in/" + filename); if (!File.Exists("in/" + filename)) { Console.WriteLine("File does not exist: in/" + filename + " skipping. . ."); return; } if (archive.HasFile(filename)) { // We need to delete because stormlib doesn't overwrite Console.WriteLine("File already exists, deleting"); archive.DeleteFile(filename); } Console.WriteLine("Inserting file"); archive.AddFileFromDisk("in/" + filename, filename); if (!archive.HasFile(filename)) { Console.WriteLine("Expected import file exists, but did not!"); return; } Console.WriteLine("Successfully imported in/" + filename + " as " + filename); } catch (Exception ex) { Console.WriteLine("Failed to import file " + filename + ": " + ex.Message); } }
public static Stream GetFile(string path) { if (File.Exists(path)) { return(File.OpenRead(path)); } else { // Assume file is contained in an mpq archive. var subPath = path; var fullPath = new FileInfo(path).FullName; while (!File.Exists(subPath)) { subPath = new FileInfo(subPath).DirectoryName; } var relativePath = fullPath.Substring(subPath.Length + (subPath.EndsWith("\\") ? 0 : 1)); var memoryStream = new MemoryStream(); using (var archive = MpqArchive.Open(subPath)) { archive.OpenFile(relativePath).CopyTo(memoryStream); } memoryStream.Position = 0; return(memoryStream); } }
public static Tuple <ReplayParseResult, Replay> ParseReplay(string fileName, bool ignoreErrors, bool deleteFile, bool allowPTRRegion = false) { try { var replay = new Replay(); // File in the version numbers for later use. MpqHeader.ParseHeader(replay, fileName); if (!ignoreErrors && replay.ReplayBuild < 32455) { return(new Tuple <ReplayParseResult, Replay>(ReplayParseResult.PreAlphaWipe, null)); } using (var archive = new MpqArchive(fileName)) ParseReplayArchive(replay, archive, ignoreErrors); if (deleteFile) { File.Delete(fileName); } return(ParseReplayResults(replay, ignoreErrors, allowPTRRegion)); } catch (Exception e) { return(new Tuple <ReplayParseResult, Replay>(ReplayParseResult.Exception, null)); } }
public static bool FileExists(MpqArchive archive, string path) { if (archive.FileExists(path)) { return(true); } // Check if file is contained in an mpq archive. var subPath = path; var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length; while (!archive.FileExists(subPath)) { var directoryName = new FileInfo(subPath).DirectoryName; if (directoryName.Length <= ignoreLength) { return(false); } subPath = directoryName.Substring(ignoreLength); } var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1)); using var subArchiveStream = archive.OpenFile(subPath); using var subArchive = MpqArchive.Open(subArchiveStream); return(FileExists(subArchive, relativePath)); }
/// <exception cref="FileNotFoundException"></exception> public static Stream GetFile(string path) { if (File.Exists(path)) { return(File.OpenRead(path)); } // Assume file is contained in an mpq archive. var subPath = path; var fullPath = new FileInfo(path).FullName; while (!File.Exists(subPath)) { subPath = new FileInfo(subPath).DirectoryName; if (subPath is null) { throw new FileNotFoundException($"File not found: {path}"); } } var relativePath = fullPath.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1)); using var archive = MpqArchive.Open(subPath); return(GetFile(archive, relativePath)); }
public static bool FileExists(string path) { if (File.Exists(path)) { return(true); } // Check if file is contained in an mpq archive. var subPath = path; var fullPath = new FileInfo(path).FullName; while (!File.Exists(subPath)) { subPath = new FileInfo(subPath).DirectoryName; if (subPath is null) { return(false); } } var relativePath = fullPath.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1)); using var archive = MpqArchive.Open(subPath); return(FileExists(archive, relativePath)); }
public static Tuple<ReplayParseResult, Replay> ParseReplay(string fileName, bool ignoreErrors, bool deleteFile) { try { var replay = new Replay(); // File in the version numbers for later use. MpqHeader.ParseHeader(replay, fileName); if (!ignoreErrors && replay.ReplayBuild < 32455) return new Tuple<ReplayParseResult, Replay>(ReplayParseResult.PreAlphaWipe, null); using (var archive = new MpqArchive(fileName)) ParseReplayArchive(replay, archive, ignoreErrors); if (deleteFile) File.Delete(fileName); return ParseReplayResults(replay, ignoreErrors); } catch { return new Tuple<ReplayParseResult, Replay>(ReplayParseResult.Exception, null); } }
/// <exception cref="FileNotFoundException"></exception> public static Stream GetFile(MpqArchive archive, string path) { if (archive.FileExists(path)) { return(GetArchiveFileStream(archive, path)); } // Assume file is contained in an mpq archive. var subPath = path; var ignoreLength = new FileInfo(subPath).FullName.Length - path.Length; while (!archive.FileExists(subPath)) { var directoryName = new FileInfo(subPath).DirectoryName; if (directoryName.Length <= ignoreLength) { throw new FileNotFoundException($"File not found: {path}"); } subPath = directoryName.Substring(ignoreLength); } var relativePath = path.Substring(subPath.Length + (subPath.EndsWith(@"\", StringComparison.Ordinal) ? 0 : 1)); using var subArchiveStream = archive.OpenFile(subPath); using var subArchive = MpqArchive.Open(subArchiveStream); return(GetArchiveFileStream(subArchive, relativePath)); }
/// <summary> /// Attempts to read the listfile if present /// </summary> /// <param name="mpq"></param> /// <param name="filteredlist"></param> /// <returns></returns> private bool TryGetListFile(MpqArchive mpq, out List <string> filteredlist) { filteredlist = new List <string>(); if (mpq.HasFile(LISTFILE_NAME)) { using (var file = mpq.OpenFile(LISTFILE_NAME)) using (var sr = new StreamReader(file)) { if (!file.CanRead || file.Length <= 1) { return(false); } while (!sr.EndOfStream) { filteredlist.Add(sr.ReadLine().WoWNormalise()); } } // remove the MPQ documentation files filteredlist.RemoveAll(RemoveUnwantedFiles); filteredlist.TrimExcess(); return(filteredlist.Count > 0); } return(false); }
public static Tuple <ReplayParseResult, Replay> ParseReplay(byte[] bytes, bool ignoreErrors = false, bool allowPTRRegion = false) { try { var replay = new Replay(); // File in the version numbers for later use. MpqHeader.ParseHeader(replay, bytes); if (!ignoreErrors && replay.ReplayBuild < 32455) { return(new Tuple <ReplayParseResult, Replay>(ReplayParseResult.PreAlphaWipe, null)); } using (var memoryStream = new MemoryStream(bytes)) using (var archive = new MpqArchive(memoryStream)) ParseReplayArchive(replay, archive, ignoreErrors); return(ParseReplayResults(replay, ignoreErrors, allowPTRRegion)); } catch { return(new Tuple <ReplayParseResult, Replay>(ReplayParseResult.Exception, null)); } }
/// <summary> /// Appends to or creates a MPQ file /// <para>Picks the appropiate version based on the build number.</para> /// </summary> /// <param name="filename"></param> /// <param name="version"></param> public void ToMPQ(string filename) { MpqArchiveVersion version = MpqArchiveVersion.Version2; if (this.Build <= (int)ExpansionFinalBuild.WotLK) { version = MpqArchiveVersion.Version2; } else if (this.Build <= (int)ExpansionFinalBuild.MoP) { version = MpqArchiveVersion.Version4; } else { MessageBox.Show("Only clients before WoD support MPQ archives."); return; } try { MpqArchive archive = null; if (File.Exists(filename)) { switch (ShowOverwriteDialog("You've selected an existing MPQ archive.\r\nWhich action would you like to take?", "Existing MPQ")) { case DialogResult.Yes: //Append archive = new MpqArchive(filename, FileAccess.Write); break; case DialogResult.No: //Overwrite archive = MpqArchive.CreateNew(filename, version); break; default: return; } } else { archive = MpqArchive.CreateNew(filename, version); } string tmpPath = Path.Combine(TEMP_FOLDER, TableStructure.Name); string fileName = Path.GetFileName(FilePath); string filePath = Path.Combine("DBFilesClient", fileName); new DBReader().Write(this, tmpPath); archive.AddFileFromDisk(tmpPath, filePath); int retval = archive.AddListFile(filePath); archive.Compact(filePath); archive.Flush(); archive.Dispose(); } //Save the file catch (Exception ex) { MessageBox.Show($"Error exporting to MPQ archive {ex.Message}"); } }
public void Can_read_user_data() { var expected = TestUtil.LoadBytesFromTextFile("TestArchives/Archive1-UserDataHeader.txt"); var archive = ObjectMother.ReadTestFile(Testfile, "2gMBq3cvcyaO2PLK7QWjuiigSQE="); var userData = MpqArchive.ParseUserDataHeader(archive); Assert.That(userData.UserData, Is.EqualTo(expected)); }
private static MemoryStream GetArchiveFileStream(MpqArchive archive, string filePath) { var memoryStream = new MemoryStream(); archive.OpenFile(filePath).CopyTo(memoryStream); memoryStream.Position = 0; return(memoryStream); }
public static bool VerifyReplayMessageEventCleared(string fileName) { using (var archive = new MpqArchive(fileName)) { archive.AddListfileFilenames(); return(GetMpqFile(archive, "replay.message.events").Length == 1); } }
public MPQContentResolver(string rootDirectory) { this.RootDirectory = rootDirectory; fileSystem = new MpqFileSystem(); var archive = new MpqArchive(System.IO.Path.Combine(rootDirectory, "d2data.mpq")); fileSystem.Archives.Add(archive); }
public static byte[] GetMpqFile(MpqArchive archive, string fileName) { using (var mpqStream = archive.OpenFile(archive.Single(i => i.Filename == fileName))) { var buffer = new byte[mpqStream.Length]; mpqStream.Read(buffer, 0, buffer.Length); return(buffer); } }
private static byte[] GetMpqArchiveFileBytes(MpqArchive archive, string fileName) { using (var mpqStream = archive.OpenFile(archive.Single(i => i.Filename == fileName))) { var buffer = new byte[mpqStream.Length]; mpqStream.Read(buffer, 0, buffer.Length); return buffer; } }
public void Restore(string file) { using (MemoryStream stream = MpqArchive.Restore(file)) { using (FileStream streamOut = File.Create(file)) { stream.CopyTo(streamOut); } } }
public static void Main(string[] args) { string entry_name = args[1]; int entry = Int32.Parse(args[2]); Mpq mpq = new MpqArchive(args[0]); DumpIScript dumper = new DumpIScript(mpq); dumper.Dump(entry_name, entry); }
internal MpqStream(MpqArchive archive, MpqEntry entry) { _entry = entry; _stream = archive.BaseStream; _blockSize = archive.BlockSize; if (_entry.IsCompressed && !_entry.IsSingleUnit) LoadBlockPositions(); }
private static bool ExtractWDT(string fileName, out string outputWdtPath) { outputWdtPath = string.Empty; try { using (MpqArchive archive = new MpqArchive(fileName)) { byte[] buf = new byte[0x40000]; var outputName = Path.GetFileNameWithoutExtension(fileName); Console.WriteLine($"Extracting {outputName} ..."); foreach (MpqEntry entry in archive) { if (!entry.IsCompressed || entry.IsEncrypted) { continue; } entry.Filename = outputName; string srcFile = entry.Filename; outputWdtPath = Path.Combine(OutputDirectory, srcFile); // Copy to destination file using (Stream streamIn = archive.OpenFile(entry)) { using (Stream streamOut = new FileStream(outputWdtPath, FileMode.Create)) { while (true) { int cb = streamIn.Read(buf, 0, buf.Length); if (cb == 0) { break; } streamOut.Write(buf, 0, cb); Program.UpdateLoadingStatus(); } streamOut.Close(); } } } } return(true); } catch (Exception ex) { Console.WriteLine(ex.Message); } return(false); }
internal MpqStream(MpqArchive File, MpqArchive.Block Block) { this.mCurrentBlockIndex = -1; this.mBlock = Block; this.mStream = File.BaseStream; this.mBlockSize = File.BlockSize; if (this.mBlock.IsCompressed) { this.LoadBlockPositions(); } }
public void TestWithPreArchiveDataAndNoFiles() { var memoryStream = new MemoryStream(); var randomData = new byte[999]; memoryStream.Write(randomData, 0, randomData.Length); using var a = MpqArchive.Create(memoryStream, Array.Empty <MpqFile>(), new MpqArchiveCreateOptions()); memoryStream.Position = 0; MpqArchive.Open(memoryStream).Dispose(); }
public MpqArchive.FileInfo[] FilterList(MpqArchive.FileInfo[] List, string FilterPattern) { List<MpqArchive.FileInfo> list = new List<MpqArchive.FileInfo>(); FilterPattern = FilterPattern.ToLower(); foreach (MpqArchive.FileInfo info in List) { string str = info.Name.ToLower(); if ((FilterPattern.StartsWith("*") && str.EndsWith(FilterPattern.Substring(1))) || str.StartsWith(FilterPattern)) { list.Add(info); } } list.Sort(new MpqArchive.FileInfo.Comparer()); return list.ToArray(); }
public MpqArchive.FileInfo[] FilterList(MpqArchive.FileInfo[] List, string FilterPattern) { Regex regex = new Regex(FilterPattern, RegexOptions.IgnoreCase); List<MpqArchive.FileInfo> list = new List<MpqArchive.FileInfo>(); FilterPattern = FilterPattern.ToLower(); foreach (MpqArchive.FileInfo info in List) { string input = info.Name.ToLower(); if (regex.IsMatch(input)) { list.Add(info); } } list.Sort(new MpqArchive.FileInfo.Comparer()); return list.ToArray(); }
public MpqDirectory(IEnumerable<string> MpqArchives) { foreach (string str in MpqArchives) { if (File.Exists(str)) { MpqArchive archive = new MpqArchive(str); foreach (MpqArchive.FileInfo info in archive.Files) { if (!this.m_Mpq.ContainsKey(info)) { this.m_Mpq.Add(info, archive); } } } } }
static void Main(string[] args) { var heroesAccountsFolder = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), @"Heroes of the Storm\Accounts"); var randomReplayFileName = Directory.GetFiles(heroesAccountsFolder, "*.StormReplay", SearchOption.AllDirectories).OrderBy(i => Guid.NewGuid()).First(); // Use temp directory for MpqLib directory permissions requirements var tmpPath = Path.GetTempFileName(); File.Copy(randomReplayFileName, tmpPath, true); try { // Create our Replay object: this object will be filled as you parse the different files in the .StormReplay archive var replay = new Replay(); Heroes.ReplayParser.MpqHeader.ParseHeader(replay, tmpPath); using (var archive = new MpqArchive(tmpPath)) { archive.AddListfileFilenames(); ReplayDetails.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayDetails.FileName)); ReplayTrackerEvents.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayTrackerEvents.FileName)); ReplayInitData.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayInitData.FileName), partialParse: false); ReplayAttributeEvents.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayAttributeEvents.FileName)); if (replay.ReplayBuild >= 32455) ReplayGameEvents.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayGameEvents.FileName)); ReplayServerBattlelobby.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayServerBattlelobby.FileName)); ReplayMessageEvents.Parse(replay, GetMpqArchiveFileBytes(archive, ReplayMessageEvents.FileName)); Unit.ParseUnitData(replay); } // Our Replay object now has all currently available information Console.WriteLine("Replay Build: " + replay.ReplayBuild); Console.WriteLine("Map: " + replay.Map); foreach (var player in replay.Players.OrderByDescending(i => i.IsWinner)) Console.WriteLine("Player: " + player.Name + ", Win: " + player.IsWinner + ", Hero: " + player.Character + ", Lvl: " + player.CharacterLevel + (replay.ReplayBuild >= 32524 ? ", Talents: " + string.Join(",", player.Talents.OrderBy(i => i)) : "")); Console.WriteLine("Press Any Key to Close"); Console.Read(); } finally { if (File.Exists(tmpPath)) File.Delete(tmpPath); } }
public static Tuple<ReplayParseResult, Replay> ParseReplay(byte[] bytes, bool ignoreErrors = false) { try { var replay = new Replay(); // File in the version numbers for later use. MpqHeader.ParseHeader(replay, bytes); if (!ignoreErrors && replay.ReplayBuild < 32455) return new Tuple<ReplayParseResult, Replay>(ReplayParseResult.PreAlphaWipe, null); using (var memoryStream = new MemoryStream(bytes)) using (var archive = new MpqArchive(memoryStream)) ParseReplayArchive(replay, archive, ignoreErrors); return ParseReplayResults(replay, ignoreErrors); } catch { return new Tuple<ReplayParseResult, Replay>(ReplayParseResult.Exception, null); } }
internal WoWArchive(MpqArchive archive, WoWArchiveKind kind) { Archive = archive; Kind = kind; }
public void OpenPatchFile(string mpqArchive) { MpqArchive archive = new MpqArchive(mpqArchive); foreach (MpqArchive.FileInfo info in archive.Files) { if (!this.m_Mpq.ContainsKey(info)) { this.m_Mpq.Add(info, archive); } else { this.m_Mpq[info] = archive; } } }
public Stream OpenFile(MpqArchive.FileInfo file) { /* if (this.m_Cache.ContainsKey(file)) { if (this.m_Cache[file].CanRead) { return this.m_Cache[file]; } this.m_Cache.Remove(file); } */ if (this.FileExists(file)) { Stream stream = this.m_Mpq[file].OpenFile(file.Name); //this.m_Cache.Add(file, stream); return stream; } return null; }
/// <summary> /// Extracts files from the archive matching the pattern (if any) /// </summary> void ExtractArchive() { using(MpqArchive archive = new MpqArchive(archiveFile)) { // destination directory if(destDir == null || destDir == "") destDir = Directory.GetCurrentDirectory(); // default to current dir of not specified archive.AddListfileFilenames(); // setup external listfile if specified if (listFile != null && listFile != "") using (Stream s = File.OpenRead(listFile)) archive.AddFilenames(s); // buffers byte[] buf = new byte[0x40000]; if(!quietOutput) Console.WriteLine("Extracting to {0}", destDir); foreach(MpqEntry entry in archive) { // match pattern if (regex != null && !regex.Match(entry.Filename).Success) continue; if(!quietOutput) Console.Write(entry.Filename + " .. "); string srcFile = entry.Filename; if (stripPath) srcFile = Path.GetFileName(srcFile); // create destination directory string destFile = Path.Combine(destDir, srcFile); string absDestDir = Path.GetDirectoryName(destFile); CreateDirectory(absDestDir); // copy to destination file using(Stream stmIn = archive.OpenFile(entry)) { using(Stream stmOut = new FileStream(destFile, FileMode.Create)) { while(true) { int cb = stmIn.Read(buf, 0, buf.Length); if(cb == 0) break; stmOut.Write(buf, 0, cb); } stmOut.Close(); } } if(!quietOutput) Console.WriteLine("Done."); } } }
/// <summary> /// Lists the contents of the archive. /// </summary> void ListArchive() { using(MpqArchive archive = new MpqArchive(archiveFile)) { archive.AddListfileFilenames(); // setup external listfile if specified if(listFile != null && listFile != "") using (Stream s = File.OpenRead(listFile)) archive.AddFilenames(s); Console.WriteLine("ucmp. size cmp. size ratio cmp. type filename"); Console.WriteLine("---------- --------- ----- --------- --------"); foreach (MpqEntry entry in archive) { // match pattern if (regex != null && !regex.Match(entry.Filename).Success) continue; string srcFile = entry.Filename; if (stripPath) srcFile = Path.GetFileName(srcFile); // display info Console.WriteLine("{0, 10} {1, 9} {2, 5} {3, 9} {4}", entry.FileSize, entry.CompressedSize, CompressionRatioString(entry.FileSize, entry.CompressedSize), CompressionTypeString(entry.Flags), srcFile); } } }
public bool FileExists(MpqArchive.FileInfo file) { return (this.m_Mpq.ContainsKey(file) && this.m_Mpq[file].FileExists(file.Name)); }
public static bool VerifyReplayMessageEventCleared(string fileName) { using (var archive = new MpqArchive(fileName)) { archive.AddListfileFilenames(); return GetMpqFile(archive, "replay.message.events").Length == 1; } }
private static void ParseReplayArchive(Replay replay, MpqArchive archive, bool ignoreErrors) { archive.AddListfileFilenames(); // Replay Details ReplayDetails.Parse(replay, GetMpqFile(archive, ReplayDetails.FileName)); if (!ignoreErrors && (replay.Players.Length != 10 || replay.Players.Count(i => i.IsWinner) != 5)) // Filter out 'Try Me' games, any games without 10 players, and incomplete games return; else if (!ignoreErrors && replay.Timestamp < new DateTime(2014, 10, 6, 0, 0, 0, DateTimeKind.Utc)) // Technical Alpha replays return; // Replay Init Data ReplayInitData.Parse(replay, GetMpqFile(archive, ReplayInitData.FileName)); ReplayAttributeEvents.Parse(replay, GetMpqFile(archive, ReplayAttributeEvents.FileName)); replay.TrackerEvents = ReplayTrackerEvents.Parse(GetMpqFile(archive, ReplayTrackerEvents.FileName)); try { replay.GameEvents = ReplayGameEvents.Parse(GetMpqFile(archive, ReplayGameEvents.FileName), replay.ClientList, replay.ReplayBuild); replay.IsGameEventsParsedSuccessfully = true; } catch { replay.GameEvents = new List<GameEvent>(); } { // Gather talent selections var talentGameEventsDictionary = replay.GameEvents .Where(i => i.eventType == GameEventType.CHeroTalentSelectedEvent) .GroupBy(i => i.player) .ToDictionary( i => i.Key, i => i.Select(j => new Talent { TalentID = (int)j.data.unsignedInt.Value, TimeSpanSelected = j.TimeSpan }).OrderBy(j => j.TimeSpanSelected).ToArray()); foreach (var player in talentGameEventsDictionary.Keys) player.Talents = talentGameEventsDictionary[player]; } // Replay Server Battlelobby if (!ignoreErrors) ReplayServerBattlelobby.Parse(replay, GetMpqFile(archive, ReplayServerBattlelobby.FileName)); // Parse Unit Data using Tracker events Unit.ParseUnitData(replay); // Parse Statistics if (replay.ReplayBuild >= 40431) try { Statistics.Parse(replay); replay.IsStatisticsParsedSuccessfully = true; } catch { } // Replay Message Events // ReplayMessageEvents.Parse(replay, GetMpqFile(archive, ReplayMessageEvents.FileName)); // Replay Resumable Events // So far it doesn't look like this file has anything we would be interested in // ReplayResumableEvents.Parse(replay, GetMpqFile(archive, "replay.resumable.events")); }