Exemple #1
0
        internal bool Keep(FightLogic.ParseMode mode, EvtcParserSettings parserSettings)
        {
            // Remove target and approx based damage mods from PvP contexts
            if (this is BuffDamageModifierTarget || Approximate)
            {
                if (mode == FightLogic.ParseMode.WvW || mode == FightLogic.ParseMode.sPvP)
                {
                    return(false);
                }
            }
            if (Mode == DamageModifierMode.All)
            {
                return(true);
            }
            switch (mode)
            {
            case FightLogic.ParseMode.Unknown:
            case FightLogic.ParseMode.Instanced5:
            case FightLogic.ParseMode.Instanced10:
            case FightLogic.ParseMode.Benchmark:
                return(Mode == DamageModifierMode.PvE);

            case FightLogic.ParseMode.WvW:
                return(Mode == DamageModifierMode.WvW || Mode == DamageModifierMode.sPvPWvW);

            case FightLogic.ParseMode.sPvP:
                return(Mode == DamageModifierMode.sPvP || Mode == DamageModifierMode.sPvPWvW);
            }
            return(false);
        }
        internal bool Keep(FightLogic.ParseMode mode, EvtcParserSettings parserSettings)
        {
            if (Mode == DamageModifierMode.All)
            {
                if (mode == FightLogic.ParseMode.WvW && !parserSettings.DetailedWvWParse)
                {
                    return(!(this is BuffDamageModifierTarget));
                }
                return(true);
            }
            switch (mode)
            {
            case FightLogic.ParseMode.Unknown:
            case FightLogic.ParseMode.Instanced5:
            case FightLogic.ParseMode.Instanced10:
            case FightLogic.ParseMode.Benchmark:
                return(Mode == DamageModifierMode.PvE);

            case FightLogic.ParseMode.WvW:
                return(!(!parserSettings.DetailedWvWParse && this is BuffDamageModifierTarget) && (Mode == DamageModifierMode.WvW || Mode == DamageModifierMode.sPvPWvW));

            case FightLogic.ParseMode.sPvP:
                return(Mode == DamageModifierMode.sPvP || Mode == DamageModifierMode.sPvPWvW);
            }
            return(false);
        }
        // Constructors
        internal FightData(int id, AgentData agentData, EvtcParserSettings parserSettings, long start, long end)
        {
            LogStart  = start;
            LogEnd    = end;
            FightEnd  = end - start;
            TriggerID = id;
            switch (ArcDPSEnums.GetTargetID(id))
            {
            case ArcDPSEnums.TargetID.Mordremoth:
                Logic = new Mordremoth(id);
                break;

            //
            case ArcDPSEnums.TargetID.ValeGuardian:
                Logic = new ValeGuardian(id);
                break;

            case ArcDPSEnums.TargetID.Gorseval:
                Logic = new Gorseval(id);
                break;

            case ArcDPSEnums.TargetID.Sabetha:
                Logic = new Sabetha(id);
                break;

            case ArcDPSEnums.TargetID.Slothasor:
                Logic = new Slothasor(id);
                break;

            case ArcDPSEnums.TargetID.Zane:
            case ArcDPSEnums.TargetID.Berg:
            case ArcDPSEnums.TargetID.Narella:
                Logic = new BanditTrio(id);
                break;

            case ArcDPSEnums.TargetID.Matthias:
                Logic = new Matthias(id);
                break;

            /*case ParseEnum.TargetIDS.Escort:
             *  Logic = new Escort(id, agentData);
             *  break;*/
            case ArcDPSEnums.TargetID.KeepConstruct:
                Logic = new KeepConstruct(id);
                break;

            case ArcDPSEnums.TargetID.Xera:
                // some TC logs are registered as Xera
                if (agentData.GetNPCsByID((int)ArcDPSEnums.TrashID.HauntingStatue).Count > 0)
                {
                    TriggerID = (int)ArcDPSEnums.TrashID.HauntingStatue;
                    Logic     = new TwistedCastle((int)ArcDPSEnums.TargetID.DummyTarget);
                    break;
                }
                Logic = new Xera(id);
                break;

            case ArcDPSEnums.TargetID.Cairn:
                Logic = new Cairn(id);
                break;

            case ArcDPSEnums.TargetID.MursaatOverseer:
                Logic = new MursaatOverseer(id);
                break;

            case ArcDPSEnums.TargetID.Samarog:
                Logic = new Samarog(id);
                break;

            case ArcDPSEnums.TargetID.Deimos:
                Logic = new Deimos(id);
                break;

            case ArcDPSEnums.TargetID.SoullessHorror:
                Logic = new SoullessHorror(id);
                break;

            case ArcDPSEnums.TargetID.Desmina:
                Logic = new River((int)ArcDPSEnums.TargetID.DummyTarget);
                break;

            case ArcDPSEnums.TargetID.BrokenKing:
                Logic = new BrokenKing(id);
                break;

            case ArcDPSEnums.TargetID.SoulEater:
                Logic = new EaterOfSouls(id);
                break;

            case ArcDPSEnums.TargetID.EyeOfFate:
            case ArcDPSEnums.TargetID.EyeOfJudgement:
                Logic = new DarkMaze(id);
                break;

            case ArcDPSEnums.TargetID.Dhuum:
                // some eyes logs are registered as Dhuum
                if (agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.EyeOfFate).Count > 0 ||
                    agentData.GetNPCsByID((int)ArcDPSEnums.TargetID.EyeOfJudgement).Count > 0)
                {
                    TriggerID = (int)ArcDPSEnums.TargetID.EyeOfFate;
                    Logic     = new DarkMaze(TriggerID);
                    break;
                }
                Logic = new Dhuum(id);
                break;

            case ArcDPSEnums.TargetID.ConjuredAmalgamate:
            case ArcDPSEnums.TargetID.ConjuredAmalgamate_CHINA:
            case ArcDPSEnums.TargetID.CALeftArm_CHINA:
            case ArcDPSEnums.TargetID.CARightArm_CHINA:
                Logic     = new ConjuredAmalgamate(id);
                TriggerID = (int)ArcDPSEnums.TargetID.ConjuredAmalgamate;
                break;

            case ArcDPSEnums.TargetID.Kenut:
            case ArcDPSEnums.TargetID.Nikare:
                Logic = new TwinLargos(id);
                break;

            case ArcDPSEnums.TargetID.Qadim:
                Logic = new Qadim(id);
                break;

            case ArcDPSEnums.TargetID.Freezie:
                Logic = new Freezie(id);
                break;

            case ArcDPSEnums.TargetID.Adina:
                Logic = new Adina(id);
                break;

            case ArcDPSEnums.TargetID.Sabir:
                Logic = new Sabir(id);
                break;

            case ArcDPSEnums.TargetID.PeerlessQadim:
                Logic = new PeerlessQadim(id);
                break;

            //
            case ArcDPSEnums.TargetID.IcebroodConstruct:
                Logic = new IcebroodConstruct(id);
                break;

            case ArcDPSEnums.TargetID.FraenirOfJormag:
                Logic = new FraenirOfJormag(id);
                break;

            case ArcDPSEnums.TargetID.VoiceOfTheFallen:
            case ArcDPSEnums.TargetID.ClawOfTheFallen:
                Logic = new SuperKodanBrothers(id);
                break;

            case ArcDPSEnums.TargetID.Boneskinner:
                Logic = new Boneskinner(id);
                break;

            case ArcDPSEnums.TargetID.WhisperOfJormag:
                Logic = new WhisperOfJormag(id);
                break;

            case ArcDPSEnums.TargetID.VariniaStormsounder:
                Logic = new ColdWar(id);
                break;

            //
            case ArcDPSEnums.TargetID.MAMA:
                Logic = new MAMA(id);
                break;

            case ArcDPSEnums.TargetID.Siax:
                Logic = new Siax(id);
                break;

            case ArcDPSEnums.TargetID.Ensolyss:
                Logic = new Ensolyss(id);
                break;

            case ArcDPSEnums.TargetID.Skorvald:
                Logic = new Skorvald(id);
                break;

            case ArcDPSEnums.TargetID.Artsariiv:
                Logic = new Artsariiv(id);
                break;

            case ArcDPSEnums.TargetID.Arkk:
                Logic = new Arkk(id);
                break;

            case ArcDPSEnums.TargetID.AiKeeperOfThePeak:
                Logic = new AiKeeperOfThePeak(id);
                break;

            //
            case ArcDPSEnums.TargetID.WorldVersusWorld:
                Logic = new WvWFight(id, parserSettings.DetailedWvWParse);
                break;

            //
            case ArcDPSEnums.TargetID.MassiveGolem10M:
            case ArcDPSEnums.TargetID.MassiveGolem4M:
            case ArcDPSEnums.TargetID.MassiveGolem1M:
            case ArcDPSEnums.TargetID.VitalGolem:
            case ArcDPSEnums.TargetID.AvgGolem:
            case ArcDPSEnums.TargetID.StdGolem:
            case ArcDPSEnums.TargetID.ConditionGolem:
            case ArcDPSEnums.TargetID.PowerGolem:
            case ArcDPSEnums.TargetID.LGolem:
            case ArcDPSEnums.TargetID.MedGolem:
                Logic = new Golem(id);
                break;

            case ArcDPSEnums.TargetID.Instance:
                Logic = new Instance(id);
                break;

            //
            default:
                switch (ArcDPSEnums.GetTrashID(id))
                {
                case ArcDPSEnums.TrashID.HauntingStatue:
                    Logic = new TwistedCastle((int)ArcDPSEnums.TargetID.DummyTarget);
                    break;

                default:
                    // Unknown
                    Logic = new UnknownFightLogic(id);
                    break;
                }
                break;
            }
        }
        public CheckResult CheckLog(string filename)
        {
            try
            {
                var parser    = new EVTCParser();
                var processor = new LogProcessor();

                var bytes = ReadLogFileBytes(filename);

                var parsedLog = parser.ParseLog(bytes);
                var log       = processor.ProcessLog(parsedLog);
                var analyzer  = new LogAnalyzer(log);

                var encounter = log.EncounterData.Encounter;
                var mode      = analyzer.GetMode();
                var result    = analyzer.GetResult();
                var players   = analyzer.GetPlayers()
                                .Select(p => new LogPlayer
                {
                    CharacterName       = p.Name,
                    AccountName         = p.AccountName,
                    Profession          = p.Profession,
                    EliteSpecialization = p.EliteSpecialization,
                    Subgroup            = p.Subgroup
                }).ToList();
                var duration = analyzer.GetEncounterDuration();

                // This combination of builds resulted in logs that did not contain NPCs other than the main target.
                // There is not much of a point in checking these.
                // This outdated version of arcdps was commonly used for extended periods of time due to it being
                // the last version that had working arcdps build templates.
                if (log.EvtcVersion == "EVTC20191001" && (log.GameBuild ?? 0) >= 100565)
                {
                    return(new CheckResult
                    {
                        Ignored = true,
                        Correct = false,
                        ProcessingFailed = false,
                        Encounter = Result <Encounter> .UncheckedResult(encounter),
                        Mode = Result <EncounterMode> .UncheckedResult(mode),
                        Result = Result <EncounterResult> .UncheckedResult(result),
                        Players = Result <List <LogPlayer> > .UncheckedResult(players),
                        Duration = Result <TimeSpan> .UncheckedResult(duration)
                    });
                }

                var eiSettings = new EvtcParserSettings(false, false, true, false, false, 0);
                var eiParser   = new EvtcParser(eiSettings, eiApiController);
                var eiLog      = eiParser.ParseLog(new EIController(), new MemoryStream(bytes), out var eiFailureReason);
                if (eiLog == null)
                {
                    eiFailureReason.Throw();
                }

                var eiDuration = TimeSpan.FromMilliseconds(eiLog.FightData.FightEnd - eiLog.FightData.FightStart);
                var eiResult   = eiLog.FightData.Success ? EncounterResult.Success : EncounterResult.Failure;
                var eiPlayers  = eiLog.PlayerList
                                 .Where(p => p.Prof != "Sword")
                                 .Select(p =>
                {
                    Profession profession;
                    if (Enum.TryParse(p.Prof, out EliteSpecialization specialization))
                    {
                        profession = GameData.Characters.GetProfession(specialization);
                    }
                    else
                    {
                        specialization = EliteSpecialization.None;
                        if (!Enum.TryParse(p.Prof, out profession))
                        {
                            throw new Exception($"Unknown profession {p.Prof} found in Elite Insights data.");
                        }
                    }

                    return(new LogPlayer
                    {
                        CharacterName = p.Character,
                        // EI strips the leading : in account names, so we re-add it
                        AccountName = $":{p.Account}",
                        Profession = profession,
                        EliteSpecialization = specialization,
                        Subgroup = p.Group
                    });
                }).ToList();

                var eiMode = eiLog.FightData.IsCM ? EncounterMode.Challenge : EncounterMode.Normal;

                // There is no reasonable way to compare EI and Analytics encounters
                var encounterResult = Result <Encounter> .UncheckedResult(encounter);

                var resultResult = CheckResult
                                        ? Result <EncounterResult> .CheckedResult(eiResult, result)
                                        : Result <EncounterResult> .UncheckedResult(result);

                var modeResult = CheckMode
                                        ? Result <EncounterMode> .CheckedResult(eiMode, mode)
                                        : Result <EncounterMode> .UncheckedResult(mode);

                var playerResult = CheckPlayers
                                        ? players.ToHashSet().SetEquals(eiPlayers)
                                                ? Result <List <LogPlayer> > .CorrectResult(players)
                                                : Result <List <LogPlayer> > .IncorrectResult(eiPlayers, players)
                                        : Result <List <LogPlayer> > .UncheckedResult(players);

                var durationResult = CheckDuration
                                        ? (eiDuration - duration) < DurationEpsilon
                                                ? Result <TimeSpan> .CorrectResult(duration)
                                                : Result <TimeSpan> .IncorrectResult(eiDuration, duration)
                                        : Result <TimeSpan> .UncheckedResult(duration);

                bool correct = encounterResult.Correct && resultResult.Correct && modeResult.Correct && playerResult.Correct && durationResult.Correct;

                return(new CheckResult
                {
                    Correct = correct,
                    ProcessingFailed = false,
                    Encounter = encounterResult,
                    Mode = modeResult,
                    Result = resultResult,
                    Players = playerResult,
                    Duration = durationResult
                });
            }
            catch (TooShortException)
            {
                return(new CheckResult
                {
                    Ignored = true,
                    Correct = false
                });
            }
            catch (Exception e)
            {
                return(new CheckResult
                {
                    Correct = false,
                    ProcessingFailed = true,
                    ProcessingException = e
                });
            }
        }
Exemple #5
0
        internal DamageModifiersContainer(ulong build, FightLogic.ParseMode mode, EvtcParserSettings parserSettings)
        {
            var AllDamageModifiers = new List <List <DamageModifier> >
            {
                DamageModifier.ItemDamageModifiers,
                DamageModifier.GearDamageModifiers,
                DamageModifier.CommonDamageModifiers,
                DamageModifier.FightSpecificDamageModifiers,
                //
                RevenantHelper.DamageMods,
                HeraldHelper.DamageMods,
                RenegadeHelper.DamageMods,
                //
                WarriorHelper.DamageMods,
                BerserkerHelper.DamageMods,
                SpellbreakerHelper.DamageMods,
                //
                GuardianHelper.DamageMods,
                DragonhunterHelper.DamageMods,
                FirebrandHelper.DamageMods,
                //
                EngineerHelper.DamageMods,
                ScrapperHelper.DamageMods,
                HolosmithHelper.DamageMods,
                //
                ThiefHelper.DamageMods,
                DaredevilHelper.DamageMods,
                DeadeyeHelper.DamageMods,
                //
                RangerHelper.DamageMods,
                DruidHelper.DamageMods,
                SoulbeastHelper.DamageMods,
                //
                MesmerHelper.DamageMods,
                ChronomancerHelper.DamageMods,
                MirageHelper.DamageMods,
                //
                NecromancerHelper.DamageMods,
                ReaperHelper.DamageMods,
                ScourgeHelper.DamageMods,
                //
                ElementalistHelper.DamageMods,
                TempestHelper.DamageMods,
                WeaverHelper.DamageMods,
            };
            var currentDamageMods = new List <DamageModifier>();

            foreach (List <DamageModifier> boons in AllDamageModifiers)
            {
                currentDamageMods.AddRange(boons.Where(x => x.Available(build) && x.Keep(mode, parserSettings)));
            }
            DamageModifiersPerSource = currentDamageMods.GroupBy(x => x.Src).ToDictionary(x => x.Key, x => (IReadOnlyList <DamageModifier>)x.ToList());
            DamageModifiersByName    = currentDamageMods.GroupBy(x => x.Name).ToDictionary(x => x.Key, x =>
            {
                var list = x.ToList();
                if (list.Count > 1)
                {
                    throw new InvalidDataException("Same name present multiple times in damage mods - " + x.First().Name);
                }
                return(list.First());
            });
        }