Ejemplo n.º 1
0
 private bool UseLogEntry( CombatLogEntry entry )
 {
     return entry.SourceId.Value == this.sourceId
         || entry.TargetId.Value == this.sourceId;
 }
Ejemplo n.º 2
0
        public void ParseLine( string line )
        {
            try
            {
                if( string.IsNullOrEmpty( line ) ) return;
                if( line.Trim() == string.Empty ) return;

                // Regex expressions are slow, so we parse the
                // old-fashioned way.  It's about 4x faster.

                string timeStampText = line.Substring( 0, 8 );
                DateTime timeStamp = DateTime.ParseExact( timeStampText, "HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture );

                // If timestamp wraps around, increase day number
                if( timeStamp < previousTimestamp )
                {
                    this.dayBump++;
                }

                this.previousTimestamp = timeStamp;
                timeStamp = timeStamp.AddDays( dayBump );

                // Delineate the events between "Combat Begin" and "Combat End"
                // as "encounters."  Within each encounter, we list all participants.
                // Not perfect, but not sure how else to do it.
                if( line.EndsWith( "Combat Begin" ) )
                {
                    this.currentEncounter = new CombatEncounter();
                    this.currentEncounter.TimeStamp = timeStamp;
                    this.encounters.Add( this.currentEncounter );
                }
                else if( line.EndsWith( "Combat End" ) )
                {
                    if( this.currentEncounter != null )
                    {
                        // Analyze the encounter
                        foreach( CombatTarget target in currentEncounter.Entities )
                            target.Analyzer.Calculate();
                        if( this.EncounterEnded != null )
                            this.EncounterEnded( this,
                                new EncounterEndedArgs() { Encounter = currentEncounter } );
                    }
                    this.currentEncounter = null;
                }

                // First split the line into parts, breaking on commas.
                string[] parts = line.Split( ',' );

                if( parts.Length != 10 )
                {
                    // Should only be special cases "Combat Begin" or "Combat End"
                    return;
                }

                // We now have an array that looks something like this:
                // [0] 00:37:43: ( 5
                // [1] T=N#R=O#9223372041015909532
                // [2] T=N#R=O#9223372041015909532
                // [3] T=X#R=X#0
                // [4] T=X#R=X#0
                // [5] Corrupted Knight
                // [6] Corrupted Knight
                // [7] 0
                // [8] 458094657
                // [9] Soul Sickness ) Corrupted Knight's Soul Sickness heals Corrupted Knight for 0.

                // Sub-parse the first and last parts
                string categoryText = parts[0].Substring( 11 ).Trim();
                int parenIndex = parts[9].IndexOf( ')' );
                string abilityName = parts[9].Substring( 0, parenIndex - 1 ).Trim();
                string logMessage = parts[9].Substring( parenIndex + 1 ).Trim();

                // Fill in a log entry object
                CombatLogEntry entry = new CombatLogEntry();
                entry.TimeStamp = timeStamp;
                entry.Category = int.Parse( categoryText );
                entry.SourceId = new CombatId( parts[1].Trim() );
                entry.TargetId = new CombatId( parts[2].Trim() );
                entry.SourceParentId = new CombatId( parts[3].Trim() );
                entry.TargetParentId = new CombatId( parts[4].Trim() );
                entry.SourceName = parts[5].Trim();
                entry.TargetName = parts[6].Trim();
                entry.Damage = int.Parse( parts[7].Trim() );
                // We don't do anything with the ability ID (parts[8])
                entry.AbilityName = abilityName;
                entry.Message = logMessage;

                // Skip resurrects "Ekosan's Soul Walk heals Ekosan for 410."
                if( entry.IsHeal && entry.AbilityName == "Soul Walk" ) return;
                // Skip 'Weathered' whatever that is - "Smashy's Weathered heals Smashy for 558. (17 overheal)"
                if( entry.IsHeal && entry.AbilityName == "Weathered" ) return;

                if( entry.SourceName == string.Empty || entry.SourceName == "Unknown" ) return;
                if( entry.TargetName == string.Empty || entry.TargetName == "Unknown" ) return;

                if( logMessage.IndexOf( "Physical damage" ) >= 0 )
                    entry.DamageType = "Physical";
                else if( logMessage.IndexOf( "Air damage" ) >= 0 )
                    entry.DamageType = "Air";
                else if( logMessage.IndexOf( "Water damage" ) >= 0 )
                    entry.DamageType = "Water";
                else if( logMessage.IndexOf( "Fire damage" ) >= 0 )
                    entry.DamageType = "Fire";
                else if( logMessage.IndexOf( "Death damage" ) >= 0 )
                    entry.DamageType = "Death";
                else if( logMessage.IndexOf( "Life damage" ) >= 0 )
                    entry.DamageType = "Life";
                else if( logMessage.IndexOf( "Earth damage" ) >= 0 )
                    entry.DamageType = "Earth";

                //if( entry.IsInformation ) return;

                Match m;

                // Collect information from the log message itself.
                // Test for existence of keywords before doing the regex.
                // It's much, much faster.

                if( logMessage.IndexOf( "absorbed)" ) >= 0 )
                {
                    m = Regex.Match( logMessage, @"\((\d+) absorbed\)" );
                    if( m.Success ) entry.Absorbed = int.Parse( m.Groups[1].Value );
                }

                if( logMessage.IndexOf( "blocked)" ) >= 0 )
                {
                    m = Regex.Match( logMessage, @"\((\d+) blocked\)" );
                    if( m.Success ) entry.Blocked = int.Parse( m.Groups[1].Value );
                }

                if( logMessage.IndexOf( "overkill)" ) >= 0 )
                {
                    m = Regex.Match( logMessage, @"\((\d+) overkill\)" );
                    if( m.Success ) entry.Overkill = int.Parse( m.Groups[1].Value );
                }

                if( logMessage.IndexOf( "overheal)" ) >= 0 )
                {
                    m = Regex.Match( logMessage, @"\((\d+) overheal\)" );
                    if( m.Success ) entry.Overheal = int.Parse( m.Groups[1].Value );
                }

                // Record the source and target entities.

                if( this.currentEncounter != null )
                {
                    // Add this log message into the current encounter.
                    this.currentEncounter.Log.Add( entry );
                    this.allEncounter.Log.Add( entry );
                }

                CombatEntity sourceEntity = this.CountEntity( entry.SourceId, entry.SourceName, entry.SourceParentId );
                if( sourceEntity != null )
                {
                    if( sourceEntity.Class == null ) sourceEntity.Class = entry.SourceClass;
                    if( entry.IsHit ) sourceEntity.TotalDamage += entry.Damage;
                    if( entry.IsHeal ) sourceEntity.TotalHealing += entry.Damage;
                    sourceEntity.Analyzer.Log.Add( entry );
                    if( this.currentEncounter != null )
                    {
                        // Record source as a participant in current encounter
                        if( !this.currentEncounter.ContainsEntity( sourceEntity ) )
                            this.currentEncounter.AddEntity( sourceEntity );
                        if( !this.allEncounter.ContainsEntity( sourceEntity ) )
                            this.allEncounter.AddEntity( sourceEntity );
                    }
                }

                if( entry.TargetId != entry.SourceId )
                {
                    CombatEntity targetEntity = this.CountEntity( entry.TargetId, entry.TargetName, entry.TargetParentId );
                    if( sourceEntity != null && targetEntity != null )
                    {
                        targetEntity.Analyzer.Log.Add( entry );
                        CombatTarget target1 = sourceEntity.AddTarget( targetEntity );
                        if( target1 != null ) target1.Analyzer.Log.Add( entry );
                        CombatTarget target2 = targetEntity.AddTarget( sourceEntity );
                        if( target2 != null ) target2.Analyzer.Log.Add( entry );
                    }
                    if( this.currentEncounter != null )
                    {
                        // Record target as a participant in current encounter
                        if( !this.currentEncounter.ContainsEntity( targetEntity ) )
                            this.currentEncounter.AddEntity( targetEntity );
                        if( !this.allEncounter.ContainsEntity( targetEntity ) )
                            this.allEncounter.AddEntity( targetEntity );
                    }
                }
            }
            catch( Exception ex )
            {
                Console.WriteLine( line );
                throw;
            }
        }