public static LogWhoEvent Parse(LogRawEvent e) { var m = WhoRegex.Match(e.Text); if (m.Success) { return(new LogWhoEvent { Timestamp = e.Timestamp, Name = m.Groups[1].Value, Class = ParseClass(m.Groups[3].Success ? m.Groups[3].Value : null), Level = m.Groups[2].Success ? Int32.Parse(m.Groups[2].Value) : 0 }); } m = TargetPlayerRegex.Match(e.Text); if (m.Success) { return(new LogWhoEvent { Timestamp = e.Timestamp, Name = m.Groups[1].Value, }); } return(null); }
public static LogAAPurchaseEvent Parse(LogRawEvent e) { var m = Rank1Regex.Match(e.Text); if (m.Success) { return(new LogAAPurchaseEvent { Timestamp = e.Timestamp, Name = m.Groups[1].Value, Cost = Int32.Parse(m.Groups[2].Value) }); } m = Rank2Regex.Match(e.Text); if (m.Success) { return(new LogAAPurchaseEvent { Timestamp = e.Timestamp, Name = m.Groups[1].Value, Cost = Int32.Parse(m.Groups[2].Value) }); } return(null); }
public static LogZoneEvent Parse(LogRawEvent e) { var m = ZoneChangedRegex.Match(e.Text); if (m.Success) { var zone = m.Groups[1].Value; if (zone == "an area where levitation effects do not function" || zone == "an Arena (PvP) area" || zone == "an area where Bind Affinity is allowed" || zone == "an area where Bind Affinity is not allowed" || zone == "the Drunken Monkey stance adequately") { return(null); } return(new LogZoneEvent { Timestamp = e.Timestamp, Name = zone }); } return(null); }
public static LogLootEvent Parse(LogRawEvent e) { var m = ItemLootedRegex.Match(e.Text); if (m.Success) { return(new LogLootEvent { Timestamp = e.Timestamp, Char = e.FixName(m.Groups[1].Value), Item = m.Groups[3].Value.Trim(), Source = e.FixName(m.Groups[4].Value.Replace("'s corpse", "")), Qty = System.Char.IsDigit(m.Groups[2].Value[0]) ? Int32.Parse(m.Groups[2].Value) : 1, }); } m = ItemGrabbedRegex.Match(e.Text); if (m.Success) { return(new LogLootEvent { Timestamp = e.Timestamp, Char = e.FixName(m.Groups[1].Value), Item = m.Groups[2].Value.Trim(), Source = e.FixName(m.Groups[3].Value.Replace("'s corpse", "").TrimEnd()), Qty = 1, }); } return(null); }
public static LogOutputFileEvent Parse(LogRawEvent e) { var m = OutputRegex.Match(e.Text); if (m.Success) { return(new LogOutputFileEvent { Timestamp = e.Timestamp, FileName = e.FixName(m.Groups[1].Value), }); } return(null); }
public static LogRescuedEvent Parse(LogRawEvent e) { var m = RescueRegex.Match(e.Text); if (m.Success) { return(new LogRescuedEvent { Timestamp = e.Timestamp, Target = e.FixName(m.Groups[1].Value), }); } return(null); }
public static LogChatEvent Parse(LogRawEvent e) { var m = PrivateChatRegex.Match(e.Text); if (m.Success) { var source = e.FixName(m.Groups[1].Value); var channel = m.Groups[2].Value; if (channel == "you" || e.Text.StartsWith("You told")) { channel = "tell"; } if (channel == "party") { channel = "group"; } channel = Regex.Replace(channel, @":\d+$", ""); return(new LogChatEvent { Timestamp = e.Timestamp, Source = source, Channel = channel, Message = m.Groups[3].Value }); } m = PublicChatRegex.Match(e.Text); if (m.Success) { var source = e.FixName(m.Groups[1].Value); var channel = m.Groups[2].Value.TrimEnd('s'); if (channel == "says out of channel" || channel == "say out of channel") { channel = "ooc"; } return(new LogChatEvent { Timestamp = e.Timestamp, Source = source, Channel = channel, Message = m.Groups[3].Value }); } return(null); }
public static LogTwinEvent Parse(LogRawEvent e) { var m = TwincastRegex.Match(e.Text); if (m.Success) { return(new LogTwinEvent { Timestamp = e.Timestamp, Source = e.Player, Spell = m.Groups[1].Value }); } return(null); }
public static LogAAXPEvent Parse(LogRawEvent e) { var m = AAXPRegex.Match(e.Text); if (m.Success) { return(new LogAAXPEvent { Timestamp = e.Timestamp, Amount = Int32.Parse(m.Groups[1].Value), Total = Int32.Parse(m.Groups[2].Value) }); } return(null); }
public static LogCraftEvent Parse(LogRawEvent e) { var m = ItemCraftedRegex.Match(e.Text); if (m.Success) { return(new LogCraftEvent { Timestamp = e.Timestamp, Char = e.Player, Item = m.Groups[1].Value }); } return(null); }
public static LogShieldEvent Parse(LogRawEvent e) { var m = ShieldStartRegex.Match(e.Text); if (m.Success) { return(new LogShieldEvent { Timestamp = e.Timestamp, Target = e.FixName(m.Groups[1].Value.Replace("'s corpse", "")), Source = e.FixName(m.Groups[2].Value.Replace("'s corpse", "")), }); } return(null); }
public static LogCastingEvent Parse(LogRawEvent e) { // this short-circuit exit is here strictly as a speed optmization if (e.Text.IndexOf("begin", StringComparison.Ordinal) < 0 && e.Text.IndexOf("activate", StringComparison.Ordinal) < 0) { return(null); } var m = CastRegex.Match(e.Text); if (m.Success) { return(new LogCastingEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Spell = m.Groups[3].Value, Type = m.Groups[2].Value == "singing" ? CastingType.Song : CastingType.Spell }); } m = DiscRegex.Match(e.Text); if (m.Success) { return(new LogCastingEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Spell = m.Groups[2].Value, Type = CastingType.Disc }); } m = ObsoleteOtherCastRegex.Match(e.Text); if (m.Success) { return(new LogCastingEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Spell = m.Groups[3].Value, Type = m.Groups[2].Value == "sing a song" ? CastingType.Song : CastingType.Spell }); } return(null); }
public static LogLocationEvent Parse(LogRawEvent e) { var m = LocationRegex.Match(e.Text); if (m.Success) { return(new LogLocationEvent { Timestamp = e.Timestamp, Y = Int32.Parse(m.Groups[1].Value), X = Int32.Parse(m.Groups[2].Value), Z = Int32.Parse(m.Groups[3].Value) }); } return(null); }
// [Mon Mar 18 23:29:08 2019] Your guildmate Smiddy has completed Smithing (50) achievement. public static LogSkillEvent Parse(LogRawEvent e) { var m = SkillRegex.Match(e.Text); if (m.Success) { var skill = m.Groups[1].Value; return(new LogSkillEvent { Timestamp = e.Timestamp, Name = m.Groups[1].Value, Level = Int32.Parse(m.Groups[2].Value) }); } return(null); }
public static LogDiceRollEvent Parse(LogRawEvent e) { var m = RandomRegex.Match(e.Text); if (m.Success) { return(new LogDiceRollEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Min = Int32.Parse(m.Groups[2].Value), Max = Int32.Parse(m.Groups[3].Value), Roll = Int32.Parse(m.Groups[4].Value), }); } return(null); }
public static LogConEvent Parse(LogRawEvent e) { var m = ConRegex.Match(e.Text); if (m.Success) { return(new LogConEvent { Timestamp = e.Timestamp, Name = m.Groups[1].Value, Faction = m.Groups[3].Value, Strength = m.Groups[4].Value, Level = Int32.Parse(m.Groups[5].Value), Rare = m.Groups[2].Success }); } return(null); }
public static LogDeathEvent Parse(LogRawEvent e) { var m = DeathRegex3.Match(e.Text); if (m.Success) { return(new LogDeathEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value) }); } if (e.Text.IndexOf("slain", StringComparison.Ordinal) < 0) { return(null); } m = DeathRegex.Match(e.Text); if (m.Success) { return(new LogDeathEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value), KillShot = e.FixName(m.Groups[2].Value) }); } m = DeathRegex2.Match(e.Text); if (m.Success) { return(new LogDeathEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value), KillShot = e.Player }); } return(null); }
public static LogCritEvent Parse(LogRawEvent e) { if (e.Timestamp > MaxDate) { return(null); } var m = MeleeCriticalRegex.Match(e.Text); if (m.Success) { return(new LogCritEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Amount = Int32.Parse(m.Groups[2].Value), Sequence = LogCritSequence.BeforeHit }); } m = SpellCriticalRegex.Match(e.Text); if (m.Success) { // if others crits are on, the game will produce 2 versions of the critical message // we can ignore one of them (the 3rd party one) if (m.Groups[1].Value != e.Player) { return new LogCritEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Amount = Int32.Parse(m.Groups[2].Value), Sequence = LogCritSequence.AfterHit } } ; } return(null); } }
public static LogTauntEvent Parse(LogRawEvent e) { var m = TauntRegex.Match(e.Text); if (m.Success) { return(new LogTauntEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = e.FixName(m.Groups[2].Value), }); } m = CriticalTauntRegex.Match(e.Text); if (m.Success) { return(new LogTauntEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = e.FixName(m.Groups[2].Value), }); } m = AETauntRegex.Match(e.Text); if (m.Success) { return(new LogTauntEvent { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = null, }); } return(null); }
/// <summary> /// Process a single line from the log file and return an event that describes the line. /// If none of the event parsers can handle the line then a LogRawEvent will be returned. /// If the line is blank or the date is malformed then a null will be returned. /// </summary> public LogEvent ParseLine(string text) { if (String.IsNullOrEmpty(Player)) { throw new InvalidOperationException("Log owner player name must be set prior to parsing."); } if (String.IsNullOrEmpty(text)) { return(null); } // convert a raw log message line to a LogRawEvent (this can return a null) var raw = LogRawEvent.Parse(text); if (raw == null) { return(null); } raw.Player = Player; return(ParseEvent(raw)); }
/// <summary> /// Try to convert a LogRawEvent to a more specific type of event. /// </summary> private LogEvent ParseEvent(LogRawEvent raw) { // GamParse exports the first line in single fight log files as // [Mon Jan 01 01:01:01 1990] if (raw.Timestamp.Year == 1990) { raw.Timestamp = MinDate; } // ignore if timestamp out of range if (raw.Timestamp < MinDate || raw.Timestamp > MaxDate) { return(null); } // ignore spam if (Ignore.Contains(raw.Text, StringComparer.Ordinal)) { return(null); } // call each custom parser until one returns a non null result for (int i = 0; i < Parsers.Count; i++) { var result = Parsers[i](raw); if (result != null) { //OnEvent?.Invoke(result); return(result); } } // if no match was found then just return the raw event // this is useful for catching parsing left-overs that slipped through regex checks //OnEvent?.Invoke(raw); return(raw); }
// mission reward // [Tue Dec 21 22:05:13 2021] You receive 318 platinum. public static LogCoinEvent Parse(LogRawEvent e) { var m = LootRegex.Match(e.Text); if (m.Success) { var coin = new LogCoinEvent { Timestamp = e.Timestamp }; var amounts = AmountRegex.Matches(e.Text); foreach (Match amount in amounts) { var k = amount.Groups[2].Value; var v = Int32.Parse(amount.Groups[1].Value); if (k == "platinum") { coin.Platinum = v; } if (k == "gold") { coin.Gold = v; } if (k == "silver") { coin.Silver = v; } if (k == "copper") { coin.Copper = v; } } return(coin); } return(null); }
public static LogMissEvent Parse(LogRawEvent e) { // this short-circuit exit is here strictly as an optmization if (!e.Text.Contains(", but", StringComparison.Ordinal) && !e.Text.Contains("resist", StringComparison.Ordinal)) { return(null); } var m = MeleeMissRegex.Match(e.Text); if (m.Success) { var type = m.Groups[4].Value; if (type == "parries") { type = "parry"; } if (type == "magical skin absorbs the blow") { type = "rune"; } if (type == "INVULNERABLE") { type = "invul"; } if (type.StartsWith("blocks with")) { type = "shield"; } return(new LogMissEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = e.FixName(m.Groups[3].Value), Type = type, Mod = ParseMod(m.Groups[5].Value) }); } m = SelfResistRegex.Match(e.Text); if (m.Success) { return(new LogMissEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = e.Player, Type = "resist", Spell = m.Groups[2].Value }); } m = ResistRegex.Match(e.Text); if (m.Success) { return(new LogMissEvent() { Timestamp = e.Timestamp, Source = e.Player, Target = e.FixName(m.Groups[1].Value), Type = "resist", Spell = m.Groups[2].Value }); } return(null); }
public static LogHitEvent Parse(LogRawEvent e) { // this short-circuit exit is here strictly as a speed optimization // this is the slowest parser of all and wasting time here slows down parsing quite a bit // "Bob has taken 1 damage" -- minimum possible occurance is at character 15? //if (e.Text.Length < 30 || e.Text.IndexOf("damage", 15) < 0) if (e.Text.IndexOf("damage", StringComparison.Ordinal) < 0) { return(null); } LogEventMod mod = 0; var m = HitModRegex.Match(e.Text); if (m.Success) { mod = ParseMod(m.Groups[1].Value); } // rather than parsing self hits, we can use FixName to convert "yourself" //m = SelfDamageRegex.Match(e.Text); //if (m.Success) //{ // return new LogHitEvent() // { // Timestamp = e.Timestamp, // Source = e.FixName(m.Groups[1].Value), // Target = e.FixName(m.Groups[1].Value), // Amount = Int32.Parse(m.Groups[2].Value), // Spell = m.Groups[3].Value, // Type = "self" // }; //} m = MeleeHitRegex.Match(e.Text); if (m.Success) { var type = m.Groups[2].Value; if (type == "frenzy on" || type == "frenzies on") { type = "frenzy"; } return(new LogHitEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Type = type, //Target = e.FixName(m.Groups[3].Value), Target = m.Groups[3].Value == "himself" || m.Groups[3].Value == "herself" || m.Groups[3].Value == "itself" ? e.FixName(m.Groups[1].Value) : e.FixName(m.Groups[3].Value), Amount = Int32.Parse(m.Groups[4].Value), Mod = mod }); } m = NukeDamageRegex.Match(e.Text); if (m.Success) { return(new LogHitEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = e.FixName(m.Groups[2].Value), Amount = Int32.Parse(m.Groups[3].Value), Spell = m.Groups[4].Value, Type = "dd", Mod = mod }); } m = OwnDoTDamageRegex.Match(e.Text); if (m.Success) { return(new LogHitEvent() { Timestamp = e.Timestamp, Target = e.FixName(m.Groups[1].Value), Amount = Int32.Parse(m.Groups[2].Value), Source = e.Player, Spell = m.Groups[3].Value, Type = "dot", Mod = mod }); } m = OtherDoTDamageRegex.Match(e.Text); if (m.Success) { return(new LogHitEvent() { Timestamp = e.Timestamp, Target = e.FixName(m.Groups[1].Value), Amount = Int32.Parse(m.Groups[2].Value), Source = e.FixName(m.Groups[4].Value), Spell = m.Groups[3].Value, Type = "dot", Mod = mod }); } m = DamageShieldRegex.Match(e.Text); if (m.Success) { return(new LogHitEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[2].Value), Target = e.FixName(m.Groups[1].Value), Amount = Int32.Parse(m.Groups[3].Value), Type = "ds" }); } // this is obsolete but doesn't interfere with any current log messages and has minimal impact on parsing performance m = ObsoleteNukeDamageRegex.Match(e.Text); if (m.Success) { return(new LogHitEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = e.FixName(m.Groups[2].Value), Amount = Int32.Parse(m.Groups[3].Value), Type = "dd", Mod = mod }); } return(null); }
public static LogHealEvent Parse(LogRawEvent e) { // this short-circuit exit is here strictly as a speed optmization if (e.Text.IndexOf("heal", StringComparison.Ordinal) < 0) { return(null); } LogEventMod mod = 0; var m = HealModRegex.Match(e.Text); if (m.Success) { mod = ParseMod(m.Groups[1].Value); } m = HoTRegex.Match(e.Text); if (m.Success) { return(new LogHealEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = m.Groups[2].Value == "himself" || m.Groups[2].Value == "herself" || m.Groups[2].Value == "itself" ? e.FixName(m.Groups[1].Value) : e.FixName(m.Groups[2].Value), Amount = Int32.Parse(m.Groups[3].Value), FullAmount = m.Groups[4].Success ? Int32.Parse(m.Groups[4].Value) : Int32.Parse(m.Groups[3].Value), Spell = m.Groups[5].Success ? m.Groups[5].Value : null, Mod = mod }); } m = HoTRegexNoSource.Match(e.Text); if (m.Success) { return(new LogHealEvent() { Timestamp = e.Timestamp, Source = null, Target = e.FixName(m.Groups[1].Value), Amount = Int32.Parse(m.Groups[2].Value), FullAmount = m.Groups[3].Success ? Int32.Parse(m.Groups[3].Value) : Int32.Parse(m.Groups[2].Value), Spell = m.Groups[4].Success ? m.Groups[4].Value : null, Mod = mod }); } // InstantRegex will incorrectly capture the obsolete messages // the check for the '.' used to exclude them m = InstantRegex.Match(e.Text); if (m.Success && !m.Groups[1].Value.Contains('.')) { return(new LogHealEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = m.Groups[2].Value == "himself" || m.Groups[2].Value == "herself" || m.Groups[2].Value == "itself" ? e.FixName(m.Groups[1].Value) : e.FixName(m.Groups[2].Value), Amount = Int32.Parse(m.Groups[3].Value), FullAmount = m.Groups[4].Success ? Int32.Parse(m.Groups[4].Value) : Int32.Parse(m.Groups[3].Value), Spell = m.Groups[5].Success ? m.Groups[5].Value : null, Mod = mod }); } m = ObsoleteInstantRegex.Match(e.Text); if (m.Success) { return(new LogHealEvent() { Timestamp = e.Timestamp, Source = e.FixName(m.Groups[1].Value), Target = m.Groups[2].Value == "himself" || m.Groups[2].Value == "herself" || m.Groups[2].Value == "itself" ? e.FixName(m.Groups[1].Value) : e.FixName(m.Groups[2].Value), Amount = Int32.Parse(m.Groups[3].Value), FullAmount = m.Groups[4].Success ? Int32.Parse(m.Groups[4].Value) : Int32.Parse(m.Groups[3].Value), Spell = m.Groups[5].Success ? m.Groups[5].Value : null, Mod = mod }); } return(null); }
public static LogPartyEvent Parse(LogRawEvent e) { var m = XPRegex.Match(e.Text); if (m.Success) { var status = PartyStatus.SoloXP; if (m.Groups[1].Value == "party") { status = PartyStatus.GroupXP; } if (m.Groups[1].Value == "raid") { status = PartyStatus.RaidXP; } return(new LogPartyEvent { Timestamp = e.Timestamp, Name = e.Player, Status = status }); } m = PartyJoinedRegex.Match(e.Text); if (m.Success) { return(new LogPartyEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value), Status = m.Groups[2].Value == "raid" ? PartyStatus.RaidJoined : PartyStatus.GroupJoined }); } m = PartyLeftRegex.Match(e.Text); if (m.Success) { return(new LogPartyEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value), Status = m.Groups[2].Value == "raid" ? PartyStatus.RaidLeft : PartyStatus.GroupLeft }); } m = PartyKickRegex.Match(e.Text); if (m.Success) { return(new LogPartyEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value), Status = m.Groups[2].Value == "raid" ? PartyStatus.RaidLeft : PartyStatus.GroupLeft }); } m = ChannelRegex.Match(e.Text); if (m.Success) { return(new LogPartyEvent { Timestamp = e.Timestamp, Name = e.FixName(m.Groups[1].Value), Status = m.Groups[2].Value == "left" ? PartyStatus.ChannelLeft : PartyStatus.ChannelJoined }); } return(null); }