public void DisplayReplay(Replay replay) { this.Text = "DotA H.I.T. Replay Browser/Parser: " + Path.GetFileName(replay.FileName); tabControl.SelectedTab = parseTabPage; DHRC.pfResetCount(); DHRC.pfStartCount(); ClearPreviousData(); PrepareMapImage(); DHRC.pfPrintRefreshCount("PrepareMapImage"); ParseLineups(replay); DHRC.pfPrintRefreshCount("ParseLineups"); DisplayTeams(replay); DHRC.pfPrintRefreshCount("DisplayTeams"); PlacePlayersOnTheMap(); DHRC.pfPrintRefreshCount("PlacePlayersOnTheMap"); DisplayDescription(replay); DHRC.pfPrintRefreshCount("DisplayDescription"); DisplayChat(replay); DHRC.pfPrintRefreshCount("DisplayChat"); DisplayStatistics(replay); DHRC.pfPrintRefreshCount("DisplayStatistics"); DisplayKillLog(replay); DHRC.pfPrintRefreshCount("DisplayKillLog"); InitPlugins(); DHRC.pfEndCount(); DHRC.pfResetCount(); }
private void okB_Click(object sender, EventArgs e) { if (!chatlogCB.Checked && !killLogCB.Checked && !statisticsCB.Checked) return; Replay replay = new Replay(path, mapRequiredEvent); string filename; string directory = Path.GetDirectoryName(path); string replayName = Path.GetFileNameWithoutExtension(path); string output = "The following files:" + Environment.NewLine + Environment.NewLine; if (chatlogCB.Checked) { filename = replayName + "_chatlog.txt"; string[] lines = ChatsToLines(replay.Chats); File.WriteAllLines(directory + "\\" + filename, lines, Encoding.UTF8); output += filename + Environment.NewLine; } if (killLogCB.Checked) { filename = replayName + "_killLog.txt"; string[] lines = KillsToLines(replay.Kills); File.WriteAllLines(directory + "\\" + filename, lines, Encoding.UTF8); output += filename + Environment.NewLine; } if (statisticsCB.Checked) { filename = replayName + "_stats.txt"; string[] lines = PlayerStatsToLines(replay.Players); File.WriteAllLines(directory + "\\" + filename, lines, Encoding.UTF8); output += filename + Environment.NewLine; } output += Environment.NewLine + "are saved to the same folder as the selected replay"; MessageBox.Show(output, "Replay Data Extraction Complete"); this.Close(); }
private void startB_Click(object sender, EventArgs e) { List<string> nicknames = new List<string>(); foreach (unit hero in heroes) if (hero.codeID == "AnyHero" && !string.IsNullOrEmpty(hero.name)) nicknames.Add(hero.name); resultsLV.Items.Clear(); if (!Directory.Exists(pathTextBox.Text)) { MessageBox.Show("Specified path does not exists"); return; } string[] files = Directory.GetFiles(pathTextBox.Text, "*.w3g", subfoldersCB.Checked ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly); startB.Enabled = false; resultsLV.BackColor = Color.WhiteSmoke; resultsLV.BeginUpdate(); SplashScreen splashScreen = new SplashScreen(); splashScreen.Show(); splashScreen.ShowText("Searching..."); int index = 0; Replay replay; foreach (string file in files) { index++; try { replay = new Replay(file); if (IsReplayMatchesCriteria(replay, nicknames)) { ListViewItem lvi = new ListViewItem(file); lvi.Tag = replay; resultsLV.Items.Add(lvi); } } catch { } splashScreen.ShowProgress((double)index, (double)files.Length); } splashScreen.Close(); resultsLV.EndUpdate(); resultsLV.BackColor = Color.AliceBlue; startB.Enabled = true; }
bool IsReplayMatchesCriteria(Replay replay, List<string> nicknames) { // all specified nicknames must be present in the replay bool Ok; foreach(string nickname in nicknames) { Ok = false; string regexNickname = string.IsNullOrEmpty(nickname) ? ".*" : nickname.Replace("*", ".*"); foreach (Player p in replay.Players) if (Regex.IsMatch(p.Name, regexNickname, RegexOptions.IgnoreCase)) { Ok = true; break; } if (!Ok) return false; } // all specified hero-nickname pairs must be present in the replay foreach (KeyValuePair<string,string> kvp in heroNicksCache) { Ok = false; string regexNickname = string.IsNullOrEmpty(kvp.Value) ? ".*" : kvp.Value.Replace("*", ".*"); foreach (Player p in replay.Players) { Hero hero = p.GetMostUsedHero(); if (hero != null && kvp.Key == hero.Name && Regex.IsMatch(p.Name, regexNickname, RegexOptions.IgnoreCase)) { Ok = true; break; } } if (!Ok) return false; } return true; }
protected void DisplayTeams(Replay replay) { sentinelTeamToolStrip.Items.Clear(); scourgeTeamToolStrip.Items.Clear(); foreach (Team t in replay.Teams) switch (t.Type) { case TeamType.Sentinel: displayTeam(sentinelTeamToolStrip, t); break; case TeamType.Scourge: displayTeam(scourgeTeamToolStrip, t); break; } versusLabel.Height = Math.Min(sentinelTeamToolStrip.PreferredSize.Height, scourgeTeamToolStrip.PreferredSize.Height); }
protected void ParseLineups(Replay rp) { if (Current.map == null) return; player sentinel = player.players[0]; player scourge = player.players[6]; unit sentinelTopTower = null; unit sentinelMidTower = null; unit sentinelBotTower = null; unit scourgeTopTower = null; unit scourgeMidTower = null; unit scourgeBotTower = null; // Sentinel Towers (Treant Protectors): // // e00R - level1 // e011 - level2 // e00S - level3 // e019 - level4 List<unit> sentinelLevel1Towers = new List<unit>(3); List<unit> sentinelLevel3Towers = new List<unit>(3); foreach (unit u in sentinel.units.Values) switch (u.codeID.Text) { case "e00R": sentinelLevel1Towers.Add(u); break; case "e00S": sentinelLevel3Towers.Add(u); break; } sentinelTopTower = GetTowerForLineUp(sentinelLevel1Towers, LineUp.Top, true); sentinelMidTower = GetTowerForLineUp(sentinelLevel1Towers, LineUp.Middle, true); sentinelBotTower = GetTowerForLineUp(sentinelLevel1Towers, LineUp.Bottom, true); // Scourge Towers (Spirit Towers): // // u00M - level1 // u00D - level2 // u00N - level3 // u00T - level4 List<unit> scourgeLevel1Towers = new List<unit>(3); List<unit> scourgeLevel3Towers = new List<unit>(3); foreach (unit u in scourge.units.Values) switch (u.codeID.Text) { case "u00M": scourgeLevel1Towers.Add(u); break; case "u00N": scourgeLevel3Towers.Add(u); break; } scourgeTopTower = GetTowerForLineUp(scourgeLevel1Towers, LineUp.Top, false); scourgeMidTower = GetTowerForLineUp(scourgeLevel1Towers, LineUp.Middle, false); scourgeBotTower = GetTowerForLineUp(scourgeLevel1Towers, LineUp.Bottom, false); // create rectangles that will be used to determine the player's lineup rect bottomRect = new rect( Math.Min(sentinelBotTower.x, scourgeBotTower.x), sentinelBotTower.y, Jass.Native.Constants.map.maxX, scourgeBotTower.y); // middle rectange will be calculated // as the rectange with Width = distance between middle towers // and Height = 990 (approximate value that should work fine for middle rectangle) // 990 ~== square_root(700^2 + 700^2), so X offset = 700 and Y offset = 700 rect middleRect = new rect( sentinelMidTower.x - 700, sentinelMidTower.y, scourgeMidTower.x, scourgeMidTower.y + 700); rect topRect = new rect( Jass.Native.Constants.map.minX, sentinelTopTower.y, Math.Max(scourgeTopTower.x, sentinelTopTower.x), scourgeTopTower.y); // create rectangles that will be used to determine the base area for each team // rectangle's vertices calculation will be based on coordinates of level3 towers rect sentinelBase = GetBaseRectFromTowers(sentinelLevel3Towers, true); rect scourgeBase = GetBaseRectFromTowers(scourgeLevel3Towers, false); setLineUpsForPlayers(rp, topRect, middleRect, bottomRect, sentinelBase, scourgeBase); }
protected void DisplayKillLog(Replay rp) { TimeSpan lastKillTime = TimeSpan.MinValue; killLogRTB.Clear(); UIRichTextEx.Default.ClearText(); if (rp.Kills.Count == 0) UIRichTextEx.Default.AddText("Not available for this replay", Color.White); else foreach (KillInfo ki in rp.Kills) { UIRichTextEx.Default.AddText(DHFormatter.ToString(ki.Time) + " ", UIFonts.boldArial8, (ki.Time.TotalSeconds - lastKillTime.TotalSeconds < 8) ? Color.Cyan : Color.LightSkyBlue); if (ki.Killer != null) { UIRichTextEx.Default.AddText(ki.Killer.Name, playerColorToColorChat(ki.Killer.Color)); UIRichTextEx.Default.AddText(" ("+ ki.Killer.GetMostUsedHeroClass() + ")", Color.White); } else UIRichTextEx.Default.AddText("Creeps", Color.White); UIRichTextEx.Default.AddText(" killed ", Color.White); UIRichTextEx.Default.AddText(ki.Victim.Name, playerColorToColorChat(ki.Victim.Color)); UIRichTextEx.Default.AddText(" (" + ki.Victim.GetMostUsedHeroClass() + ")", Color.White); UIRichTextEx.Default.AddNewLine(); lastKillTime = ki.Time; } killLogRTB.Rtf = UIRichTextEx.Default.CloseRtf(); }
protected void DisplayStatistics(Replay rp) { statisticsLV.Items.Clear(); statisticsLV.BeginUpdate(); foreach (Player p in rp.Players) if (!p.IsComputer && !p.IsObserver) { ListViewItem lvi = new ListViewItem(); lvi.Text = (p.SlotNo + 1) + ""; lvi.BackColor = playerColorToColorBG(p.Color); lvi.UseItemStyleForSubItems = false; lvi.Tag = p; Color bgColor = p.TeamType == TeamType.Sentinel ? Color.FromArgb(255,250,240) : Color.FromArgb(245, 255, 240); ListViewItem.ListViewSubItem lvi_Player = new ListViewItem.ListViewSubItem(); lvi_Player.Text = p.Name; lvi_Player.BackColor = bgColor; ListViewItem.ListViewSubItem lvi_Hero = new ListViewItem.ListViewSubItem(); if (p.Heroes.Count != 0) lvi_Hero.Text = DHFormatter.ToString(p.GetMostUsedHeroClass()); lvi_Hero.BackColor = bgColor; ListViewItem.ListViewSubItem lvi_APM = new ListViewItem.ListViewSubItem(); lvi_APM.Text = "" + (int)p.Apm; lvi_APM.BackColor = bgColor; ListViewItem.ListViewSubItem lvi_Kills = new ListViewItem.ListViewSubItem(); lvi_Kills.Text = p.gameCacheValues.ContainsKey("kills") ? p.getGCValue("kills").ToString() : p.getGCVStringValue("1", ""); lvi_Kills.BackColor = bgColor; ListViewItem.ListViewSubItem lvi_Deaths = new ListViewItem.ListViewSubItem(); lvi_Deaths.Text = p.gameCacheValues.ContainsKey("deaths") ? p.getGCValue("deaths").ToString() : p.getGCVStringValue("2", ""); lvi_Deaths.BackColor = bgColor; ListViewItem.ListViewSubItem lvi_creepKD = new ListViewItem.ListViewSubItem(); lvi_creepKD.Text = p.gameCacheValues.ContainsKey("creeps") ? (p.getGCValue("creeps") + " / " + p.getGCValue("denies")) : ""; if (lvi_creepKD.Text.Length == 0) lvi_creepKD.Text = p.gameCacheValues.ContainsKey("3") ? (p.getGCValue("3") + " / " + p.getGCValue("4")) : ""; lvi_creepKD.BackColor = bgColor; ListViewItem.ListViewSubItem lvi_wards = new ListViewItem.ListViewSubItem(); int[] ward_stats = getWardStatistics(p); if (ward_stats[0]!= 0) lvi_wards.Text = twoChars(ward_stats[0]) + " { "+ ward_stats[1] + " + " + ward_stats[2] + " }"; lvi_wards.Tag = ward_stats; lvi_wards.BackColor = bgColor; lvi.SubItems.AddRange(new ListViewItem.ListViewSubItem[]{ lvi_Player, lvi_Hero, lvi_APM, lvi_Kills, lvi_Deaths, lvi_creepKD, lvi_wards }); statisticsLV.Items.Add(lvi); } statisticsLV.EndUpdate(); }
void setLineUpsForPlayers(Replay rp, rect top, rect mid, rect bot, rect sentinelBase, rect scourgeBase) { // approximate creep spawn time int creepSpawnTime = GetFirstCreepAttackTime(rp, top, mid, bot); foreach (Team team in rp.Teams) switch (team.Type) { case TeamType.Sentinel: case TeamType.Scourge: List<int> alliedHeroes = GetListOfAlliedHeroes(team); foreach (Player p in team.Players) { location l = GetAverageLocation(p, (team.Type == TeamType.Sentinel ? sentinelBase : scourgeBase), alliedHeroes, creepSpawnTime); p.LineUpLocation = l; if (top.ContainsXY(l.x, l.y)) p.LineUp = LineUp.Top; else if (mid.ContainsXY(l.x, l.y)) p.LineUp = LineUp.Middle; else if (bot.ContainsXY(l.x, l.y)) p.LineUp = LineUp.Bottom; else p.LineUp = LineUp.JungleOrRoaming; } break; } }
protected void DisplayDescription(Replay rp) { // replay version infoLV.Items[0].SubItems[1].Text = "1." + rp.Version; // map name infoLV.Items[1].SubItems[1].Text = Path.GetFileName(rp.Map.Path); // map location infoLV.Items[2].SubItems[1].Text = Path.GetDirectoryName(rp.Map.Path); // host name infoLV.Items[3].SubItems[1].Text = rp.Host.Name; // game mode infoLV.Items[4].SubItems[1].Text = rp.GameMode; // game length infoLV.Items[5].SubItems[1].Text = DHFormatter.ToString(rp.GameLength); // sentinel players infoLV.Items[6].SubItems[1].Text = rp.GetTeamByType(TeamType.Sentinel).Players.Count.ToString(); // scourge players infoLV.Items[7].SubItems[1].Text = rp.GetTeamByType(TeamType.Scourge).Players.Count.ToString(); // winner string winner = "Winner info not found"; infoLV.Items[8].SubItems[1].ForeColor = Color.Black; foreach (Team t in rp.Teams) if (t.IsWinner) { winner = t.Type.ToString(); infoLV.Items[8].SubItems[1].ForeColor = (t.Type == TeamType.Sentinel) ? Color.Red : Color.Green; break; } infoLV.Items[8].SubItems[1].Text = winner; }
protected void DisplayChat(Replay replay) { chatlogRTB.Clear(); UIRichTextEx.Default.ClearText(); bool isPaused = false; foreach (ChatInfo ci in replay.Chats) if (ci.To != TalkTo.System) { UIRichTextEx.Default.AddText(DHFormatter.ToString(ci.Time) + " ", UIFonts.boldArial8, isPaused ? Color.Silver : UIColors.toolTipData); switch (ci.To) { case TalkTo.Allies: case TalkTo.All: case TalkTo.Observers: UIRichTextEx.Default.AddText("[" + ci.To.ToString() + "] ", Color.White); break; default: continue; } UIRichTextEx.Default.AddText(ci.From.Name + ": ", playerColorToColorChat(ci.From.Color)); UIRichTextEx.Default.AddText(ci.Message, Color.White); UIRichTextEx.Default.AddNewLine(); } else { switch (ci.Message) { case "pause": if (!isPaused) { isPaused = true; UIRichTextEx.Default.AddText(DHFormatter.ToString(ci.Time) + " ", UIFonts.boldArial8, Color.White); UIRichTextEx.Default.AddText(ci.From.Name + " ", playerColorToColorChat(ci.From.Color)); UIRichTextEx.Default.AddText("paused the game.", Color.White); UIRichTextEx.Default.AddNewLine(); } break; case "resume": if (isPaused) { isPaused = false; UIRichTextEx.Default.AddText(DHFormatter.ToString(ci.Time) + " ", UIFonts.boldArial8, Color.White); UIRichTextEx.Default.AddText(ci.From.Name + " ", playerColorToColorChat(ci.From.Color)); UIRichTextEx.Default.AddText("has resumed the game.", Color.White); UIRichTextEx.Default.AddNewLine(); } break; case "save": UIRichTextEx.Default.AddText(DHFormatter.ToString(ci.Time) + " ", UIFonts.boldArial8, Color.LightGreen); UIRichTextEx.Default.AddText("Game was saved by ", Color.White); UIRichTextEx.Default.AddText(ci.From.Name, playerColorToColorChat(ci.From.Color)); UIRichTextEx.Default.AddNewLine(); break; case "leave": UIRichTextEx.Default.AddText(DHFormatter.ToString(ci.Time) + " ", UIFonts.boldArial8, Color.White); UIRichTextEx.Default.AddText(ci.From.Name + " ", playerColorToColorChat(ci.From.Color)); UIRichTextEx.Default.AddText("has left the game.", Color.White); UIRichTextEx.Default.AddNewLine(); break; } } chatlogRTB.Rtf = UIRichTextEx.Default.CloseRtf(); }
int GetFirstCreepAttackTime(Replay rp, rect top, rect mid, rect bot) { List<string> dcCreeps = new List<string>(); // Sentinel creeps: // // esen - Treant // edry - Druid of the Talon dcCreeps.Add("esen"); dcCreeps.Add("edry"); // Scourge creeps: // // unec - Necromancer // ugho - Ghoul dcCreeps.Add("unec"); dcCreeps.Add("ugho"); int minCreepAttackTime = int.MaxValue; foreach (Player p in rp.Players) foreach (PlayerAction pa in p.Actions) if (pa.IsValidObjects) { string codeID1; rp.dcObjectsCodeIDs.TryGetValue(pa.Object1, out codeID1); if (codeID1 == null || dcCreeps.Contains(codeID1)) { if (top.ContainsXY(pa.X, pa.Y) || mid.ContainsXY(pa.X, pa.Y) || bot.ContainsXY(pa.X, pa.Y)) { minCreepAttackTime = Math.Min(minCreepAttackTime, pa.Time); break; // go to next player } } } return (minCreepAttackTime != int.MaxValue) ? minCreepAttackTime : 180000; // 180000 = 3 minutes (will be used in case of errors) }
private void PreviewReplay(string filename) { if (filename != null) { if (!dcReplayCache.TryGetValue(filename, out currentReplay)) { try { currentReplay = new Replay(filename, true); } catch { currentReplay = null; DisplayUserInfo(Color.Red, "The file", "is corrupt", false); } dcReplayCache[filename] = currentReplay; } DisplayReplayInfo(currentReplay); } else { currentReplay = null; DisplayReplayInfo(currentReplay); DisplayUserInfo(Color.FromArgb(33,136,235), "Select", "Replay File", false); } }
internal bool ParseReplay(string filename, bool TryReparseOnError) { if (filename == null) return false; if (Current.player != null) Current.player.selection.Clear(); DHCFG.Items["Path"]["ReplayLoad"] = Path.GetDirectoryName(filename); if (!dcReplayCache.TryGetValue(filename, out currentReplay) || currentReplay.IsPreview) { try { currentReplay = new Replay(filename, MapRequired); dcReplayCache[filename] = currentReplay; if (Current.mainForm.cbForm.unitsForm != null) Current.mainForm.cbForm.unitsForm.ReloadUnits(); } catch (Exception ex) { if (TryReparseOnError) if (ParseReplay(filename, false)) return true; // strange thing O_O Console.WriteLine(ex.Message); Console.WriteLine(ex.Source); Console.WriteLine(ex.StackTrace); Console.WriteLine(ex.TargetSite); MessageBox.Show("An error occured while parsing this replay"); currentReplay = null; return false; } } return true; }
internal void DisplayReplayInfo(Replay replay) { currentReplay = replay; if (replay != null) { mapTextBox.Text = replay.Map.Path; hostTextBox.Text = replay.Host.Name; foreach (Team t in replay.Teams) switch (t.Type) { case TeamType.Sentinel: FillPlayerList(sentinelRTB, t.Players); break; case TeamType.Scourge: FillPlayerList(scourgeRTB, t.Players); break; } string path = DHCFG.Items["Path"].GetStringValue("War3") + "\\" + mapTextBox.Text; if (File.Exists(path)) { DisplayUserInfo(Color.Green, "Ready", "for parsing",true); } else DisplayUserInfo(Color.Red, "Map file", "not found", false, true); } else { mapTextBox.Text = ""; hostTextBox.Text = ""; sentinelRTB.Clear(); scourgeRTB.Clear(); } }