public void Fight_Has_Correct_Timestamps() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); var t1 = DateTime.Now; tracker.HandleEvent(new LogHitEvent { Timestamp = t1, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 100 }); var t2 = t1.AddSeconds(3); tracker.HandleEvent(new LogMissEvent { Timestamp = t2, Source = PLAYER1, Target = "Mob1", Type = "dodge" }); var f = tracker.ActiveFights[0]; Assert.Equal(t1, f.StartedOn); Assert.Equal(t2, f.UpdatedOn); var t3 = t2.AddSeconds(3); tracker.HandleEvent(new LogDeathEvent { Timestamp = t3, Name = "Mob1" }); Assert.Equal(FightStatus.Killed, f.Status); Assert.Equal(t3, f.UpdatedOn); }
public void Two_Fights_Concurrent() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); Assert.Empty(tracker.ActiveFights); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 100 }); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER2, Target = "Mob1", Type = "slash", Amount = 100 }); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = "Mob1", Target = PLAYER1, Type = "slash", Amount = 100 }); Assert.Equal("Mob1", tracker.ActiveFights[0].Target.Name); Assert.Single(tracker.ActiveFights); tracker.HandleEvent(new LogMissEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob2", Type = "dodge" }); Assert.Equal("Mob2", tracker.ActiveFights[1].Target.Name); Assert.Equal(2, tracker.ActiveFights.Count); }
public void SumHits() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; chars.GetOrAdd(PLAYER2).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Amount = 100 }); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Amount = 200 }); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER2, Target = "Mob1", Amount = 350 }); //tracker.HandleEvent(new LogDeathEvent { Timestamp = DateTime.Now.AddSeconds(1), Name = "Mob1" }); var f = tracker.ActiveFights[0]; Assert.Equal(2, f.Participants.Count); Assert.Equal("Mob1", f.Target.Name); Assert.Equal(3, f.Target.InboundHitCount); Assert.Equal(650, f.Target.InboundHitSum); Assert.Equal(PLAYER1, f.Participants[0].Name); Assert.Equal(2, f.Participants[0].OutboundHitCount); Assert.Equal(300, f.Participants[0].OutboundHitSum); Assert.Equal(PLAYER2, f.Participants[1].Name); Assert.Equal(1, f.Participants[1].OutboundHitCount); Assert.Equal(350, f.Participants[1].OutboundHitSum); }
public void Ignore_Self_Hits() { var tracker = new FightTracker(new SpellParser(), new CharTracker()); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = PLAYER1, Amount = 100 }); Assert.Empty(tracker.ActiveFights); }
/// <summary> /// Perform timing tests on all trackers. /// </summary> public static void TimeTrackers(LogReader file, SpellParser spells) { var parser = new LogParser(); parser.Player = LogOpenEvent.GetPlayerFromFileName(file.Path); // load raw log lines once var events = new List <LogEvent>(); while (true) { var s = file.ReadLine(); if (s == null) { break; } var e = parser.ParseLine(s); if (e != null) { events.Add(e); } } ; Console.Error.WriteLine("Loaded {0} events", events.Count); // timer trackers var trackers = new List <Action <LogEvent> >(); var chars = new CharTracker(spells); trackers.Add(chars.HandleEvent); var fights = new FightTracker(spells, chars); trackers.Add(fights.HandleEvent); var buffs = new BuffTracker(spells); trackers.Add(buffs.HandleEvent); var loot = new LootTracker(); trackers.Add(loot.HandleEvent); // time individual trackers foreach (var t in trackers) { var ptimer = Stopwatch.StartNew(); var pcount = 0; foreach (var e in events) { t.Invoke(e); } Console.Error.WriteLine("{0,-20} {1,10} in {2}", t.Method.DeclaringType.Name, pcount, ptimer.Elapsed); } Console.WriteLine("***"); }
public void Raid_Joined() { var tracker = new FightTracker(new SpellParser(), new CharTracker()); tracker.HandleEvent(new LogOpenEvent { Player = PLAYER1 }); tracker.HandleEvent(new LogPartyEvent { Status = PartyStatus.RaidJoined, Name = PLAYER2 }); Assert.Equal("Raid", tracker.Party); }
public void Fight_Ignored_If_Foe_Unknown() { var tracker = new FightTracker(new SpellParser(), new CharTracker()); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 200 }); // since the tracker doesn't know if Player1 or Mob1 is the foe it // can't track the fight yet Assert.Empty(tracker.ActiveFights); }
public void PlayMultiple() { FightTracker tracker = Shared.GetFightTracker(); Stopwatch sw = new Stopwatch(); sw.Start(); List <Fight> resList = FightTracker.PlayMultiple(NumberOfSims, tracker); StringBuilder sb = new StringBuilder(); Shared.Locator().FightPlanF1.SetLineHits(resList.SelectMany(r => r.LineHits_Fighter1)); Shared.Locator().FightPlanF2.SetLineHits(resList.SelectMany(r => r.LineHits_Fighter2)); int wins = resList.Count(r => r.Result.Outcome == FightOutcome.Win); int draws = resList.Count(r => r.Result.Outcome == FightOutcome.Draw); int losses = resList.Count(r => r.Result.Outcome == FightOutcome.Loss); double wPCt = (wins + 0.5 * draws) / (wins + draws + losses); sb.AppendFormat("{0}-{1}-{2}, {3:0.0%}", wins, losses, draws, wPCt); sb.AppendLine(); foreach (var vk in resList.GroupBy(r => new { r.Result.Outcome, r.Result.ResultType }).OrderBy(r => r.Key.Outcome)) { sb.AppendFormat("{0} - {1}, {2}", vk.Key.Outcome, vk.Key.ResultType, vk.Count()); sb.AppendLine(); } //var v = resList.Select(r => r.RoundResults.Last().Fighter1Round.Cuts.Union(r.RoundResults.Last().Fighter2Round.Cuts)).SelectMany(c => c).ToList(); //foreach (var group in v.GroupBy(gp=> new { gp.Type, gp.Level}).OrderBy(gp=>gp.Key.Type).ThenBy(gp=>gp.Key.Level)) //{ // sb.AppendFormat("{0} - {1}, {2}", group.Key.Type, group.Key.Level, group.Count()); // sb.AppendLine(); //} //v = resList.Select(r => r.RoundResults.First().Fighter1Round.Cuts.Union(r.RoundResults.First().Fighter2Round.Cuts)).SelectMany(c => c).ToList(); //foreach (var group in v.GroupBy(gp => new { gp.Type, gp.Level }).OrderBy(gp => gp.Key.Type).ThenBy(gp => gp.Key.Level)) //{ // sb.AppendFormat("{0} - {1}, {2}", group.Key.Type, group.Key.Level, group.Count()); // sb.AppendLine(); //} //v = resList.Select(r => r.RoundResults.First(f=>f.RoundNumber == 2).Fighter1Round.Cuts.Union(r.RoundResults.First().Fighter2Round.Cuts)).SelectMany(c => c).ToList(); //foreach (var group in v.GroupBy(gp => new { gp.Type, gp.Level }).OrderBy(gp => gp.Key.Type).ThenBy(gp => gp.Key.Level)) //{ // sb.AppendFormat("{0} - {1}, {2}", group.Key.Type, group.Key.Level, group.Count()); // sb.AppendLine(); //} //int CutLevel = resList.Select(r => r.RoundResults.Last().Fighter1Round.CutLevel + r.RoundResults.Last().Fighter2Round.CutLevel).Sum(); //double cAverage = (double) CutLevel / (NumberOfSims * 2); //sb.AppendFormat("Cut level avg: {0:0.00}", cAverage); Shared.Locator().Main.OutputText = sb.ToString(); Console.WriteLine(string.Format("Done in {0} ms", sw.ElapsedMilliseconds)); }
public void Accepts_Nulls() { // some events have null references // make sure these don't throw an exception var tracker = new FightTracker(new SpellParser(), new CharTracker()); tracker.HandleEvent(new LogTauntEvent() { Source = PLAYER1, Target = null }); tracker.HandleEvent(new LogDeathEvent() { Name = PLAYER1, KillShot = null }); }
public void Death_of_Friend() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Amount = 100 }); tracker.HandleEvent(new LogDeathEvent { Timestamp = DateTime.Now, Name = PLAYER1 }); Assert.Single(tracker.ActiveFights); }
public void Raid_Left_Other() { var tracker = new FightTracker(new SpellParser(), new CharTracker()); tracker.HandleEvent(new LogOpenEvent { Player = PLAYER1 }); tracker.HandleEvent(new LogPartyEvent { Status = PartyStatus.RaidJoined, Name = PLAYER2 }); tracker.HandleEvent(new LogPartyEvent { Status = PartyStatus.RaidLeft, Name = PLAYER2 }); // since player2 is not the log owner, we should still be in the raid Assert.Equal("Raid", tracker.Party); }
public void Raid_Left_Self() { var tracker = new FightTracker(new SpellParser(), new CharTracker()); tracker.HandleEvent(new LogOpenEvent { Player = PLAYER1 }); tracker.HandleEvent(new LogPartyEvent { Status = PartyStatus.RaidJoined, Name = PLAYER2 }); tracker.HandleEvent(new LogPartyEvent { Status = PartyStatus.RaidLeft, Name = PLAYER1 }); // since player1 is the log owner, we must now drop the raid Assert.Equal("Group", tracker.Party); }
public void One_Fight() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 200 }); var f = tracker.ActiveFights[0]; Assert.Equal("Mob1", f.Name); Assert.Equal("Mob1", f.Target.Name); Assert.Equal(PLAYER1, f.Participants[0].Name); }
static void Main(string[] args) { Stopwatch timer = Stopwatch.StartNew(); var file = File.OpenText("d:/games/everquest/logs/eqlog_Rumstil_erollisi.txt"); //file.BaseStream.Position = file.BaseStream.Length - 5000000; var parser = new LogParser("Rumstil"); //parser.MinDate = DateTime.Today.AddDays(-14); //parser.OnEvent += LogHandler; parser.OnZone += LogHandler; parser.OnPlayerFound += LogHandler; //parser.OnPetOwner += LogHandler; //parser.OnFightHit += LogHandler; //parser.OnDeath += LogHandler; //parser.OnChat += LogHandler; //parser.OnHeal += LogHandler; parser.OnItemLooted += LogHandler; fights = new FightTracker(parser); fights.OnFightStarted += f => Console.WriteLine("--- {0}", f.Opponent.Name); fights.OnFightFinished += FightHandler; //var faction = new FactionTracker(parser); //parser.OnBeforeEvent += CheckMostCommon //parser.MaxDate = DateTime.Parse("5/19/2016 10:35:43"); //parser.OnAfterEvent += DebugCheck; parser.LoadFromFile(file); Console.Error.WriteLine("Parse completed in {0} - {1:N0} bytes ", timer.Elapsed, file.BaseStream.Length); Console.Error.WriteLine("Fights: {0}", fights.Fights.Count); //foreach (var f in faction) //{ // Console.Error.WriteLine("{0}", f); //} //var common = MostCommon.OrderByDescending(x => x.Value).Take(20); //foreach (var item in common) // Console.Error.WriteLine("{0} {1}", item.Key, item.Value); }
public void Check_DPS_Intervals() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); var start = DateTime.Today.AddHours(3).AddSeconds(34); var time = start; tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER1, Target = "Mob", Amount = 100 }); time = start.AddSeconds(1); tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER1, Target = "Mob", Amount = 50 }); time = start.AddSeconds(3); tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER1, Target = "Mob", Amount = 21 }); time = start.AddSeconds(4); tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER2, Target = "Mob", Amount = 35 }); var f = tracker.ActiveFights[0]; f.Finish(); // the whole fight is only 4 seconds long so far but since the hits // cross a 6 second wall clock interval we should split the hits into // two intervals Assert.Equal(4, f.Participants[0].Duration); Assert.Equal(150, f.Participants[0].DPS[0]); Assert.Equal(21, f.Participants[0].DPS[1]); Assert.Equal(1, f.Participants[1].Duration); Assert.Equal(0, f.Participants[1].DPS[0]); Assert.Equal(35, f.Participants[1].DPS[1]); }
public void Play() { FightTracker tracker = Shared.GetFightTracker(); Fight fight = null; // try // { fight = tracker.PlayFight(); // } // catch (Exception ex) // { //MessageBox.Show("Error - " + ex.Message); //return; // } StringBuilder sb = new StringBuilder(); Shared.Locator().FightResults.SetResults(fight); sb.Append(tracker.ToString()); sb.AppendLine(); sb.AppendLine(); foreach (Round res in fight.RoundResults) { sb.Append(res.PrintString()); sb.AppendLine(); } if (fight.Result.Outcome == FightOutcome.Draw) { sb.Append("The fight is a draw!"); } else if (fight.Result.Outcome == FightOutcome.Loss) { sb.Append("Fighter 2 wins"); } else { sb.Append("Fighter 1 wins"); } sb.AppendLine(); sb.AppendFormat("Total Score: Fighter 1 {0}, Fighter 2 {1}", fight.Fighter1Score, fight.Fighter2Score); sb.AppendLine(); this.OutputText = sb.ToString(); }
public void Dont_Double_Count_Self_Heal() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Amount = 100 }); tracker.HandleEvent(new LogHealEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = PLAYER1, Amount = 201 }); var f = tracker.ActiveFights[0]; Assert.Equal(201, f.Participants[0].InboundHealSum); Assert.Equal(201, f.Participants[0].OutboundHealSum); }
public void Death_of_Mob() { FightInfo f = null; var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.OnFightFinished += (args) => f = args; tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 100 }); tracker.HandleEvent(new LogDeathEvent { Timestamp = DateTime.Now.AddSeconds(1), Name = "Mob1" }); Assert.NotNull(f); Assert.Equal("Mob1", f.Target.Name); Assert.Empty(tracker.ActiveFights); }
public static FightTracker GetFightTracker() { Weebul.Core.Model.Fighter f1 = new Weebul.Core.Model.Fighter() { Stats = new FighterStats(Shared.Locator().Fighter1.SelectedFighter) }; Weebul.Core.Model.Fighter f2 = new Weebul.Core.Model.Fighter() { Stats = new FighterStats(Shared.Locator().Fighter2.SelectedFighter) }; Weebul.Core.Model.FightPlan fp1 = new Weebul.Core.Model.FightPlan() { FightPlanText = Shared.Locator().FightPlanF1.FightPlanText, WeblScript = new Scripting.WeblScript() }; Weebul.Core.Model.FightPlan fp2 = new Weebul.Core.Model.FightPlan() { FightPlanText = Shared.Locator().FightPlanF2.FightPlanText, WeblScript = new Scripting.WeblScript() }; if (!fp1.Validate()) { MessageBox.Show("Fight plan 1 is invalid"); return(null); } if (!fp2.Validate()) { MessageBox.Show("Fight plan 2 is invalid"); return(null); } FightTracker tracker = new FightTracker(f1, f2, fp1, fp2, Shared.Locator().Options.Options); return(tracker); }
public void Two_Fights_Back_to_Back_With_Same_Mob_Name() { var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 100 }); Assert.Single(tracker.ActiveFights); tracker.HandleEvent(new LogDeathEvent { Timestamp = DateTime.Now, Name = "Mob1" }); Assert.Empty(tracker.ActiveFights); // same mob name, but it should be treated as a new fight since it died tracker.HandleEvent(new LogHitEvent { Timestamp = DateTime.Now, Source = PLAYER1, Target = "Mob1", Type = "slash", Amount = 101 }); Assert.Single(tracker.ActiveFights); }
public void FightRoundTest() { for (int i = 1; i <= 50; i++) { Fighter f = new Fighter() { Stats = FighterRoundStatsTests.GetFighterStats() }; f.Stats.Weight = 135; FighterFight fFight = new FighterFight(f, new FightPlan() { Default = new FighterRoundPlan(4, 8, 8) }); Fighter f2 = new Fighter() { Stats = FighterRoundStatsTests.GetFighterStats() }; FighterFight fFight2 = new FighterFight(f2, new FightPlan() { Default = new FighterRoundPlan(4, 8, 8) }); FightPlan defPlan = new FightPlan() { Default = new FighterRoundPlan(5, 9, 6) }; FightOptions options = new FightOptions() { WeightClass = WeightClass.Light }; FightTracker tracker = new FightTracker(f, f2, defPlan, defPlan, options); tracker.PlayFight(); } }
static void Main(string[] args) { // load spells to give the trackers more context when processing log files // this is optional and can be skipped Console.Error.WriteLine("Loading spells..."); var spells = new SpellParser(); spells.Load("d:/games/everquest/spells_us.txt"); // generate an open event that stores the player name, server name, and file path // all trackers should receive this as their first event to signal that a new log file is being processed var open = LogOpenEvent.FromFileName("d:/games/everquest/logs/eqlog_Rumstil_erollisi.txt"); // create a CharTracker to help the FightTracker determine friends/foes var chars = new CharTracker(spells); chars.Files = new FileService(Path.GetDirectoryName(open.Path) + @"\..\"); chars.HandleEvent(open); // create a FightTracker to build fight summaries from various combat events var fights = new FightTracker(spells, chars); fights.HandleEvent(open); fights.OnFightStarted += ShowFight; fights.OnFightFinished += ShowFight; // create a log parser for converting log lines into events that can be passed to the trackers var parser = new LogParser(); parser.Player = open.Player; //parser.MinDate = DateTime.MinValue; //parser.MinDate = DateTime.Today.AddDays(-1).ToUniversalTime(); var timer = Stopwatch.StartNew(); var reader = File.OpenText(open.Path); while (true) { var line = reader.ReadLine(); if (line == null) { break; } // pass line to the parser and convert to an event // lines that cannot be parsed will be returned as nulls var e = parser.ParseLine(line); if (e == null) { continue; } // pass event to the trackers chars.HandleEvent(e); fights.HandleEvent(e); //if (e is LogRawEvent) Console.WriteLine(e); } ; fights.ForceFightTimeouts(); Console.Error.WriteLine("Parse completed in {0}", timer.Elapsed); }
/// <summary> /// Start monitoring a log file from a background task. /// </summary> private async void WatchFile(string path) { if (!File.Exists(path)) { return; } if (String.IsNullOrEmpty(LogOpenEvent.GetPlayerFromFileName(path))) { LogInfo($"Cannot open {path} because it doesn't use the standard naming convention."); return; } // cancel previous log parsing task if (cancellationSource != null) { cancellationSource.Cancel(); await Task.Delay(600); } // always disable auto uploads when opening a file to avoid accidentally uploading a lot of data chkAutoUpload.Checked = chkAutoUpload.Enabled = false; // we don't know where to find the spell_us.txt file until we open a log file // spells should be one folder down from the log folder if (!spells.IsReady) { var spellpath = Path.GetDirectoryName(path) + @"\..\spells_us.txt"; if (File.Exists(spellpath)) { LogInfo("Loading " + spellpath); spells.Load(spellpath); if (!spells.IsReady) { LogInfo("spells_us.txt could not be loaded. Class detection and buff tracking will not work properly."); } } else { LogInfo("spells_us.txt not found. Class detection and buff tracking will not work properly."); } } config.Write("filename", path); LogInfo("Loading " + path); var open = LogOpenEvent.FromFileName(path); var parser = new LogParser(); parser.Player = open.Player; // reset the trackers by creating new ones var charTracker = new CharTracker(spells); charTracker.Files = new FileService(Path.GetDirectoryName(path) + @"\..\"); charTracker.HandleEvent(open); charTracker.ImportPlayers(config.Read("chars:" + open.Server)); var fightTracker = new FightTracker(spells, charTracker); fightTracker.OnFightFinished += x => fightsQueue.Enqueue(x); fightTracker.AddTemplateFromResource(); fightTracker.HandleEvent(open); var lootTracker = new LootTracker(); lootTracker.OnLoot += x => lootQueue.Enqueue(x); lootTracker.HandleEvent(open); // reset UI lvFights.VirtualListSize = 0; fightList.Clear(); fightListSearchResults = null; toolStripStatusLabel1.Text = "-"; toolStripStatusLabel2.Text = "-"; // read roster files to assist player tracking if (!String.IsNullOrEmpty(open.Server)) { var files = new DirectoryInfo(Path.GetDirectoryName(path)).Parent .GetFiles("*_" + open.Server + "-*.txt") .Where(x => x.CreationTime > DateTime.Today.AddDays(-14)) .Take(20); var roster = RosterParser.Load(files); foreach (var who in roster) { charTracker.HandleEvent(who); } } // this handler runs in a background thread and must be threadsafe Action <string> handler = line => { var e = parser.ParseLine(line); if (e != null) { charTracker.HandleEvent(e); fightTracker.HandleEvent(e); lootTracker.HandleEvent(e); } }; // this event runs in the main app thread // https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread/18033198#18033198 var progress = new Progress <LogReaderStatus>(p => { toolStripStatusLabel1.Text = p.Percent.ToString("P0") + " " + p.Notes; var completed = p.Percent > 0.99; chkAutoUpload.Enabled = completed; }); cancellationSource = new CancellationTokenSource(); var reader = new BackgroundLogReader(path, cancellationSource.Token, handler, progress); try { await reader.Start(); } catch (Exception ex) { LogInfo("Error: " + ex.Message); LogInfo("Last Line: " + reader.LastLine); } //LogInfo("Closing " + path); // this log message can occur after the form has been disposed if (open.Server != null) { // save a list of players so that we have better information next time we run the parser var players = charTracker.ExportPlayers(); config.Write("chars:" + open.Server, players); } //await ProcessLogFileAsync(path); }
public void Raid_Matched() { var temp = new RaidTemplate() { Zone = "Crystallos, Lair of the Awakened", Name = "Kerafyrm", Mobs = new[] { "Kerafyrm the Awakened", "A wyvern assassin" }, EndsOnDeath = new[] { "Kerafyrm the Awakened" } }; var chars = new CharTracker(); chars.GetOrAdd(PLAYER1).Type = CharType.Friend; chars.GetOrAdd(PLAYER2).Type = CharType.Friend; var tracker = new FightTracker(new SpellParser(), chars); tracker.HandleEvent(new LogPartyEvent { Status = PartyStatus.RaidJoined, Name = PLAYER1 }); tracker.AddTemplate(temp); var results = new List <FightInfo>(); tracker.OnFightFinished += e => results.Add(e); // act var time = DateTime.Now; tracker.HandleEvent(new LogZoneEvent { Timestamp = time, Name = temp.Zone }); tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER1, Target = temp.Mobs[0], Amount = 100 }); tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER2, Target = temp.Mobs[1], Amount = 20 }); tracker.HandleEvent(new LogHitEvent { Timestamp = time, Source = PLAYER2, Target = "Unrelated Mob", Amount = 30 }); tracker.HandleEvent(new LogDeathEvent { Timestamp = time, Name = temp.EndsOnDeath[0] }); // assert var raids = results.OfType <RaidFightInfo>().ToArray(); Assert.Single(raids); Assert.Equal("Kerafyrm", raids[0].Name); Assert.Equal("Crystallos, Lair of the Awakened", raids[0].Zone); Assert.Equal(2, raids[0].MobCount); Assert.Equal(120, raids[0].HP); Assert.Single(tracker.ActiveFights); // the unrelated mob /* * * // this should be ignored * var f3 = new FightInfo() { Name = "Fippy Darkpaw", Zone = "Crystallos, Lair of the Awakened", Status = FightStatus.Killed }; * f3.Target.InboundHitSum = 20; * tracker.HandleFight(f3); * * // this should be included, and create a new raid * var f2 = new FightInfo() { Name = "A wyvern assassin", Zone = "Crystallos, Lair of the Awakened", Status = FightStatus.Killed }; * f2.Target.InboundHitSum = 10; * tracker.HandleFight(f2); * * // this should finish the raid * var f1 = new FightInfo() { Name = "Kerafyrm the Awakened", Zone = "Crystallos, Lair of the Awakened", Status = FightStatus.Killed }; * f1.Target.InboundHitSum = 100; * tracker.HandleFight(f1); * * Assert.Single(results); * Assert.Equal("Kerafyrm", results[0].Name); * Assert.Equal("Crystallos, Lair of the Awakened", results[0].Zone); * Assert.Equal(2, results[0].MobCount); * Assert.Equal(110, results[0].HP); * */ }