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 }); } }
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()); }); }