public Match ParseReplay(string path) { using (var archive = Nmpq.MpqArchive.Open(path)) { try { Replay replay = new Replay(); ReplayInitData.Parse(replay, archive.ReadFile(InitData)); ReplayTrackerEvents.Parse(replay, archive.ReadFile(TrackerEvents)); ReplayDetails.Parse(replay, archive.ReadFile(Details)); ReplayAttributeEvents.Parse(replay, archive.ReadFile(AttributeEvents)); var player = replay.Players.First(p => p.Name == accountName); Match match = new Match(); match.FileName = path.Split('\\').Last(); match.Map = replay.Map; match.Win = player.IsWinner; match.Character = new Hero(player.Character, replay.ReplayLength); match.TimeStamp = replay.Timestamp; replay = null; return(match); } catch (Exception ex) { Logger.Log(string.Format("Error mapping {0}, exception details : {1}", path, ex.ToString())); return(null); } } }
private void ParseReplayTrackerEvents(StormReplay stormReplay, ArrayPool <byte> pool) { MpqHeroesArchiveEntry entry = _stormMpqArchive.GetEntry(ReplayTrackerEvents.FileName); int size = (int)entry.FileSize; byte[] poolBuffer = pool.Rent(size); Span <byte> buffer = new Span <byte>(poolBuffer).Slice(0, size); _stormMpqArchive.DecompressEntry(entry, buffer); ReplayTrackerEvents.Parse(stormReplay, buffer); pool.Return(poolBuffer); }
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); } } }