public static Replay ParseRejoin(string fileName) { try { using (var archive = new MpqArchive(fileName)) { archive.AddListfileFilenames(); var replay = new Replay(); // Replay Details ReplayDetails.Parse(replay, DataParser.GetMpqFile(archive, "save.details"), true); // Player level is stored there // does not exist in brawl if (archive.FileExists("replay.attributes.events")) { ReplayAttributeEvents.Parse(replay, DataParser.GetMpqFile(archive, "replay.attributes.events")); } return(replay); } } catch (Exception ex) { //TODO: WE REALLY DON't want to do this Debug.WriteLine(ex); return(null); } }
private void ListArchive() { using (MpqArchive archive = new MpqArchive(this.archiveFile)) { archive.AddListfileFilenames(); if ((this.listFile != null) && (this.listFile != "")) { using (Stream stream = File.OpenRead(this.listFile)) { archive.AddFilenames(stream); } } Console.WriteLine("ucmp. size cmp. size ratio cmp. type filename"); Console.WriteLine("---------- --------- ----- --------- --------"); foreach (MpqEntry entry in (IEnumerable <MpqEntry>)archive) { if ((this.regex == null) || this.regex.Match(entry.Filename).Success) { string filename = entry.Filename; if (this.stripPath) { filename = Path.GetFileName(filename); } Console.WriteLine("{0, 10} {1, 9} {2, 5} {3, 9} {4}", new object[] { entry.FileSize, entry.CompressedSize, this.CompressionRatioString((double)entry.FileSize, (double)entry.CompressedSize), this.CompressionTypeString(entry.Flags), filename }); } } } }
public static bool VerifyReplayMessageEventCleared(string fileName) { using (var archive = new MpqArchive(fileName)) { archive.AddListfileFilenames(); return(GetMpqFile(archive, "replay.message.events").Length == 1); } }
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); } } }
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 Replay ParseRejoin(string fileName) { try { var replay = new Replay(); var archive = new MpqArchive(fileName); archive.AddListfileFilenames(); // Replay Details ReplayDetails.Parse(replay, DataParser.GetMpqFile(archive, "save.details"), true); // Player level is stored there ReplayAttributeEvents.Parse(replay, DataParser.GetMpqFile(archive, "replay.attributes.events")); return(replay); } catch { // todo: eating exceptions is bad return(null); } }
/// <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); } } }
private static void ParseReplayArchive(Replay replay, MpqArchive archive, bool ignoreErrors) { archive.AddListfileFilenames(); // Replay Details ReplayDetails.Parse(replay, GetMpqFile(archive, ReplayDetails.FileName), ignoreErrors); 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.ClientListByUserID, 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.GetBattleTags(replay, GetMpqFile(archive, ReplayServerBattlelobby.FileName)); } // 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.IsGameEventsParsedSuccessfully = false; } } // 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")); }
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")); }
private void ExtractArchive() { using (MpqArchive archive = new MpqArchive(this.archiveFile)) { if ((this.destDir == null) || (this.destDir == "")) { this.destDir = Path.GetTempPath(); } archive.AddListfileFilenames(); if ((this.listFile != null) && (this.listFile != "")) { using (Stream stream = File.OpenRead(this.listFile)) { archive.AddFilenames(stream); } } byte[] buffer = new byte[0x40000]; if (!this.quietOutput) { Console.WriteLine("Extracting to {0}", this.destDir); } foreach (MpqEntry entry in (IEnumerable <MpqEntry>)archive) { if ((this.regex != null) && !this.regex.Match(entry.Filename).Success) { continue; } if (!this.quietOutput) { Console.Write(entry.Filename + " .. "); } string filename = entry.Filename; if (this.stripPath) { filename = Path.GetFileName(filename); } string path = Path.Combine(this.destDir, filename); string directoryName = Path.GetDirectoryName(path); this.CreateDirectory(directoryName); using (Stream stream2 = archive.OpenFile(entry)) { using (Stream stream3 = new FileStream(path, FileMode.Create)) { int num; Label_0135: num = stream2.Read(buffer, 0, buffer.Length); if (num != 0) { stream3.Write(buffer, 0, num); goto Label_0135; } stream3.Close(); } } if (!this.quietOutput) { Console.WriteLine("Done."); } } } }
/// <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."); } } }
private static void ParseReplayArchive(Replay replay, MpqArchive archive, bool ignoreErrors, bool fullParse = false) { archive.AddListfileFilenames(); // Replay Details ReplayDetails.Parse(replay, GetMpqFile(archive, ReplayDetails.FileName), ignoreErrors); if (!ignoreErrors) { if (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 (replay.Timestamp == DateTime.MinValue) { // Uncommon issue when parsing replay.details return; } else if (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)); Console.Write(replay.GameMode + " "); if (replay.GameMode != GameMode.QuickMatch && replay.GameMode == GameMode.TeamLeague && replay.GameMode != GameMode.HeroLeague && replay.GameMode == GameMode.UnrankedDraft) { fullParse = false; } ReplayAttributeEvents.Parse(replay, GetMpqFile(archive, ReplayAttributeEvents.FileName)); replay.TrackerEvents = ReplayTrackerEvents.Parse(GetMpqFile(archive, ReplayTrackerEvents.FileName)); List <string> nextBans = new List <string>(); int pickCount = 0; if (replay.GameMode == GameMode.HeroLeague || replay.GameMode == GameMode.TeamLeague || replay.GameMode == GameMode.UnrankedDraft) { foreach (var trackerEvent in replay.TrackerEvents) { try { if (trackerEvent.TrackerEventType == ReplayTrackerEvents.TrackerEventType.HeroBannedEvent) { replay.OrderedBans.Add(trackerEvent.Data.dictionary[0].blobText); } if (trackerEvent.TrackerEventType == ReplayTrackerEvents.TrackerEventType.HeroPickedEvent) { pickCount++; replay.OrderedPicks.Add(trackerEvent.Data.dictionary[0].blobText); } } catch { } if (pickCount == 10) { break; } } } if (!fullParse) { return; } replay.GameEvents = new List <GameEvent>(); try { replay.GameEvents = ReplayGameEvents.Parse(GetMpqFile(archive, ReplayGameEvents.FileName), replay.ClientListByUserID, replay.ReplayBuild, replay.ReplayVersionMajor); 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 && archive.Any(i => i.Filename == ReplayServerBattlelobby.FileName)) { //ReplayServerBattlelobby.GetBattleTags(replay, GetMpqFile(archive, ReplayServerBattlelobby.FileName)); 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 (Exception e) { replay.IsGameEventsParsedSuccessfully = false; } } // 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")); }
/// <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 static bool ExtractDBC() { try { Logger.Notice("Extracting DBC files..."); //Check if dbc.MPQ exist. if (!File.Exists(Paths.DBCMPQPath)) { Logger.Error($"Unable to locate dbc.MPQ at path {Paths.DBCMPQPath}, please check Config.txt and set a proper installation path."); return(false); } // Clean up output directory if neccesary. if (Directory.Exists(Paths.DBCLoadPath)) { Directory.Delete(Paths.DBCLoadPath, true); } using (MpqArchive archive = new MpqArchive(Paths.DBCMPQPath)) { archive.AddListfileFilenames(); foreach (var entry in archive) { if (!string.IsNullOrEmpty(entry.Filename)) { var outputFileName = Paths.Combine(Paths.DBCLoadPath, Path.GetFileName(entry.Filename)); var outputPlainName = Path.GetFileNameWithoutExtension(outputFileName); if (File.Exists(outputFileName)) { File.Delete(outputFileName); } if (InterestedDBC.Any(name => outputPlainName.ToLower().Equals(name.ToLower()))) { byte[] buf = new byte[0x40000]; using (Stream streamIn = archive.OpenFile(entry)) { using (Stream streamOut = new FileStream(outputFileName, FileMode.Create)) { while (true) { int cb = streamIn.Read(buf, 0, buf.Length); if (cb == 0) { break; } streamOut.Write(buf, 0, cb); } streamOut.Close(); } } Logger.Success($"Extracted DBC file [{entry.Filename}]."); } } } } return(true); } catch (Exception ex) { Logger.Error(ex.Message); Logger.Error(ex.StackTrace); if (ex.InnerException != null) { Logger.Error(ex.InnerException.Message); Logger.Error(ex.InnerException.StackTrace); } } return(false); }
public static bool ExtractDBC() { try { Console.WriteLine("Extracting DBC files..."); //Check if dbc.MPQ exist. if (!File.Exists(Globals.DBCPath)) { Console.WriteLine($"Unable to locate dbc.MPQ at path {Globals.DBCPath}, please check Config.txt and set a proper installation path."); return(false); } // Clean up output directory if neccesary. if (Directory.Exists(OutputPath)) { Directory.Delete(OutputPath, true); } Directory.CreateDirectory(OutputPath); using (MpqArchive archive = new MpqArchive(Globals.DBCPath)) { archive.AddListfileFilenames(); foreach (var entry in archive) { if (!string.IsNullOrEmpty(entry.Filename)) { var outputFileName = Path.Combine(OutputPath, Path.GetFileName(entry.Filename)); if (File.Exists(outputFileName)) { File.Delete(outputFileName); } if (entry.Filename.Equals("DBFilesClient\\AreaTable.dbc")) { byte[] buf = new byte[0x40000]; using (Stream streamIn = archive.OpenFile(entry)) { using (Stream streamOut = new FileStream(outputFileName, 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(); } } Console.WriteLine($"Extracted DBC file {entry.Filename}"); } } } } return(true); } catch (Exception ex) { Console.WriteLine(ex.Message); } return(false); }