コード例 #1
0
        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);
        }
コード例 #2
0
        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);
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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);
        }
コード例 #5
0
ファイル: Utils.cs プロジェクト: rumstil/eqlogparser
        /// <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("***");
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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));
        }
コード例 #9
0
        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
            });
        }
コード例 #10
0
        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);
        }
コード例 #11
0
        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);
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
ファイル: Program.cs プロジェクト: bhyvex/eqlogparser
        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);
        }
コード例 #15
0
        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]);
        }
コード例 #16
0
        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();
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
ファイル: Shared.cs プロジェクト: DougOz/WeBLSimulator
        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);
        }
コード例 #20
0
        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);
        }
コード例 #21
0
        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();
            }
        }
コード例 #22
0
ファイル: Program.cs プロジェクト: rumstil/eqlogparser
        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);
        }
コード例 #23
0
ファイル: MainForm.cs プロジェクト: rumstil/eqlogparser
        /// <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);
        }
コード例 #24
0
        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);
             *
             */
        }