Beispiel #1
0
 private static void LogUndesirableEvent(string p, CombatLogEventArgs e)
 {
     if (SingularSettings.Debug)
     {
         string sourceName;
         string destName;
         try
         {
             sourceName = e.SourceUnit.SafeName();
         }
         catch
         {
             sourceName = "unknown";
         }
         try
         {
             destName = e.DestUnit.SafeName();
         }
         catch
         {
             destName = "unknown";
         }
         Logger.WriteDiagnostic("Programmer Error - Combat Log Event {0}: filter out {1} - {2} {3} - {4} {5} on {6} {7}",
                                p,
                                e.EventName,
                                e.SourceGuid,
                                sourceName,
                                e.SpellName,
                                e.SpellId,
                                e.DestGuid,
                                destName
                                );
     }
 }
Beispiel #2
0
        private static void HandleCombatLog(object sender, LuaEventArgs args)
        {
            var e = new CombatLogEventArgs(args.EventName, args.FireTimeStamp, args.Args);

            //Logger.WriteDebug("[CombatLog] " + e.Event + " - " + e.SourceName + " - " + e.SpellName);
            switch (e.Event)
            {
            case "SPELL_AURA_APPLIED":
            case "SPELL_CAST_SUCCESS":
                if (e.SourceGuid != StyxWoW.Me.Guid)
                {
                    return;
                }

                // Update the last spell we cast. So certain classes can 'switch' their logic around.
                Spell.LastSpellCast = e.SpellName;
                //Logger.WriteDebug("Successfully cast " + Spell.LastSpellCast);

                // Force a wait for all summoned minions. This prevents double-casting it.
                if (SingularRoutine.MyClass == WoWClass.Warlock && e.SpellName.StartsWith("Summon "))
                {
                    StyxWoW.SleepForLagDuration();
                }
                break;

            case "SPELL_MISSED":
                if (e.Args[14].ToString() == "EVADE")
                {
                    Logger.Write("Mob is evading. Blacklisting it!");
                    Blacklist.Add(e.DestGuid, TimeSpan.FromMinutes(30));
                    if (StyxWoW.Me.CurrentTargetGuid == e.DestGuid)
                    {
                        StyxWoW.Me.ClearTarget();
                    }

                    BotPoi.Clear("Blacklisting evading mob");
                    StyxWoW.SleepForLagDuration();
                }
                break;
            }
        }
Beispiel #3
0
        private static void HandleEvadeBuggedMob(LuaEventArgs args, CombatLogEventArgs e)
        {
            WoWUnit unit = e.DestUnit;
            WoWGuid guid = e.DestGuid;

            if (unit == null && StyxWoW.Me.GotTarget())
            {
                unit = StyxWoW.Me.CurrentTarget;
                guid = StyxWoW.Me.CurrentTargetGuid;
                Logger.Write("Evade: bugged mob guid:{0}, so assuming current target instead", args.Args[7]);
            }

            if (unit != null)
            {
                if (!MobsThatEvaded.ContainsKey(unit.Guid))
                {
                    MobsThatEvaded.Add(unit.Guid, 0);
                }

                MobsThatEvaded[unit.Guid] = MobsThatEvaded[unit.Guid] + 1;
                if (MobsThatEvaded[unit.Guid] < SingularSettings.Instance.EvadedAttacksAllowed)
                {
                    Logger.Write("Mob {0} has evaded {1} times. Not blacklisting yet, but will count evades on {2:X0} for now", unit.SafeName(), MobsThatEvaded[unit.Guid], unit.Guid);
                }
                else
                {
                    const int MinutesToBlacklist = 5;

                    if (Blacklist.Contains(unit.Guid, BlacklistFlags.Combat))
                    {
                        Logger.Write(Color.LightGoldenrodYellow, "Mob {0} has evaded {1} times. Previously blacklisted {2:X0} for {3} minutes!", unit.SafeName(), MobsThatEvaded[unit.Guid], unit.Guid, MinutesToBlacklist);
                    }
                    else
                    {
                        string fragment = string.Format("Mob {0} has evaded {1} times", unit.SafeName(), MobsThatEvaded[unit.Guid]);
                        Logger.Write(Color.LightGoldenrodYellow, "{0}. Blacklisting {1:X0} for {2} minutes!", fragment, unit.Guid, MinutesToBlacklist);
                        Blacklist.Add(unit.Guid, BlacklistFlags.Combat, TimeSpan.FromMinutes(MinutesToBlacklist), "Singular - " + fragment);
                        if (!Blacklist.Contains(unit.Guid, BlacklistFlags.Combat))
                        {
                            Logger.Write(Color.Pink, "error: blacklist does not contain entry for {0} after Blacklist.Add", unit.SafeName());
                        }
                    }

                    if (BotPoi.Current.Guid == unit.Guid)
                    {
                        Logger.Write("EvadeHandling: Current BotPOI type={0} is Evading, clearing now...", BotPoi.Current.Type);
                        BotPoi.Clear("Singular recognized Evade bugged mob");
                    }

                    if (StyxWoW.Me.CurrentTargetGuid == guid)
                    {
                        foreach (var target in Targeting.Instance.TargetList)
                        {
                            if (Unit.ValidUnit(target) &&
                                !Blacklist.Contains(target.Guid, BlacklistFlags.Pull | BlacklistFlags.Combat) &&
                                unit.EvadedAttacksCount() < SingularSettings.Instance.EvadedAttacksAllowed
                                )
                            {
                                Logger.Write(Color.Pink, "Setting target to {0} to get off evade bugged mob!", target.SafeName());
                                target.Target();
                                return;
                            }
                        }

                        Logger.Write(Color.Pink, "BotBase has 0 entries in Target list not blacklisted -- nothing else we can do at this point!");
                        // StyxWoW.Me.ClearTarget();
                    }
                }
            }

            /// line below was originally in Evade logic, but commenting to avoid Sleeps
            // StyxWoW.SleepForLagDuration();
        }
Beispiel #4
0
        private static void HandleCombatLog(object sender, LuaEventArgs args)
        {
            // Since we hooked this in ctor, make sure we are the selected CC
            if (RoutineManager.Current.Name != SingularRoutine.Instance.Name)
            {
                return;
            }

            // convert args to usable form
            var  e           = new CombatLogEventArgs(args.EventName, args.FireTimeStamp, args.Args);
            bool itWasDamage = false;

            if (TrackDamage || SingularRoutine.CurrentWoWContext == WoWContext.Normal)
            {
                if (e.DestGuid == StyxWoW.Me.Guid && e.SourceGuid != StyxWoW.Me.Guid)
                {
                    long damageAmount = 0;
                    switch (e.EventName)
                    {
                    case "SWING_DAMAGE":
                        itWasDamage  = true;
                        damageAmount = (long)e.Args[11];
                        Logger.WriteDebug("HandleCombatLog(Damage): {0} = {1}", e.EventName, damageAmount);
                        break;

                    case "SPELL_DAMAGE":
                    case "SPELL_PERIODIC_DAMAGE":
                    case "RANGE_DAMAGE":
                        itWasDamage  = true;
                        damageAmount = (long)e.Args[14];
                        break;
                    }

                    if (TrackDamage)
                    {
                        if (itWasDamage)
                        {
                            Logger.WriteDebug("HandleCombatLog(Damage): {0} = {1}", e.EventName, damageAmount);
                        }
                        else
                        {
                            LogUndesirableEvent("On Character", e);
                        }

                        if (damageAmount > 0)
                        {
                            DamageHistory.Enqueue(new Damage(DateTime.UtcNow, damageAmount));
                        }
                    }

                    if (itWasDamage && SingularRoutine.CurrentWoWContext == WoWContext.Normal)
                    {
                        WoWUnit enemy = e.SourceUnit;
                        if (Unit.ValidUnit(enemy) && enemy.IsPlayer)
                        {
                            Logger.WriteDiagnostic("GankDetect: received {0} src={1} dst={2}", args.EventName, e.SourceGuid, e.DestGuid);

                            // if (guidLastEnemy != enemy.Guid || (TimeLastAttackedByEnemyPlayer - DateTime.UtcNow).TotalSeconds > 30)
                            {
                                guidLastEnemy = enemy.Guid;
                                string extra = "";
                                if (e.Args.GetUpperBound(0) >= 12)
                                {
                                    extra = string.Format(" using {0}", e.SpellName);
                                }

                                AttackedWithSpellSchool = WoWSpellSchool.None;
                                if (e.Args.GetUpperBound(0) >= 12)
                                {
                                    AttackedWithSpellSchool = e.SpellSchool;
                                }

                                Logger.WriteDiagnostic("GankDetect: attacked by Level {0} {1}{2}", enemy.Level, enemy.SafeName(), extra);
                                if (SingularSettings.Instance.TargetWorldPvpRegardless && (BotPoi.Current == null || BotPoi.Current.Guid != enemy.Guid))
                                {
                                    Logger.Write(LogColor.Hilite, "GankDetect: setting {0} as BotPoi Kill Target", enemy.SafeName());
                                    BotPoi.Current = new BotPoi(enemy, PoiType.Kill);
                                }
                            }

                            AttackingEnemyPlayer          = enemy;
                            TimeLastAttackedByEnemyPlayer = DateTime.UtcNow;
                        }
                    }
                }
            }

            // Logger.WriteDebug("[CombatLog] " + e.Event + " - " + e.SourceName + " - " + e.SpellName);

            switch (e.Event)
            {
            default:
                LogUndesirableEvent("From Character", e);
                break;

            // spell_cast_failed only passes filter in Singular debug mode
            case "SPELL_CAST_FAILED":
                Logger.WriteDiagnostic("[CombatLog] {0} {1}#{2} failure: '{3}'", e.Event, e.Spell.Name, e.SpellId, e.Args[14]);
                if (e.Args[14].ToString() == LocalizedLineOfSightFailure)
                {
                    WoWGuid guid = WoWGuid.Empty;
                    try
                    {
                        LastLineOfSightTarget = e.DestUnit;
                        guid = LastLineOfSightTarget == null ? WoWGuid.Empty : LastLineOfSightTarget.Guid;
                    }
                    catch
                    {
                    }

                    if (!guid.IsValid)
                    {
                        Logger.WriteFile("[CombatLog] no valid destunit so using CurrentTarget");
                        LastLineOfSightTarget = StyxWoW.Me.CurrentTarget;
                        guid = StyxWoW.Me.CurrentTargetGuid;
                    }

                    LastLineOfSightFailure = DateTime.UtcNow;
                    Logger.WriteFile("[CombatLog] cast failed due to los reported at {0} on target {1:X}", LastLineOfSightFailure.ToString("HH:mm:ss.fff"), e.DestGuid);
                }
                else if (e.Args[14].ToString() == LocalizedUnitNotInfrontFailure)
                {
                    WoWGuid guid = e.DestGuid;
                    LastUnitNotInfrontFailure = DateTime.UtcNow;
                    if (guid.IsValid && guid != WoWGuid.Empty)
                    {
                        LastUnitNotInfrontGuid = guid;
                        Logger.WriteFile("[CombatLog] not facing SpellTarget [{0}] at {1}", LastUnitNotInfrontGuid, LastUnitNotInfrontFailure.ToString("HH:mm:ss.fff"));
                    }
                    else
                    {
                        LastUnitNotInfrontGuid = Spell.LastSpellTarget;
                        Logger.WriteFile("[CombatLog] not facing LastTarget [{0}] at {1}", LastUnitNotInfrontGuid, LastUnitNotInfrontFailure.ToString("HH:mm:ss.fff"), guid);
                    }
                }
                else if (!MovementManager.IsMovementDisabled && StyxWoW.Me.Class == WoWClass.Warrior && e.Args[14].ToString() == LocalizedNoPathAvailableFailure)
                {
                    LastNoPathFailure = DateTime.UtcNow;
                    LastNoPathGuid    = StyxWoW.Me.CurrentTargetGuid;
                    if (!StyxWoW.Me.GotTarget())
                    {
                        Logger.WriteFile("[CombatLog] cast failed - no path available to current target");
                    }
                    else
                    {
                        Logger.WriteFile("[CombatLog] cast failed - no path available to {0}, heightOffGround={1}, pos={2}",
                                         StyxWoW.Me.CurrentTarget.SafeName(),
                                         StyxWoW.Me.CurrentTarget.HeightOffTheGround(),
                                         StyxWoW.Me.CurrentTarget.Location
                                         );
                    }
                }
                else if (!SingularRoutine.IsManualMovementBotActive && (StyxWoW.Me.Class == WoWClass.Druid || StyxWoW.Me.Class == WoWClass.Shaman))
                {
                    if (LocalizedShapeshiftMessages.ContainsKey(e.Args[14].ToString()))
                    {
                        string symbolicName = LocalizedShapeshiftMessages[e.Args[14].ToString()];
                        SuppressShapeshiftUntil = DateTime.UtcNow.Add(TimeSpan.FromSeconds(30));
                        Logger.Write(LogColor.Cancel, "/cancel{0} - due to Shapeshift Error '{1}' on cast, suppress form for {2:F1} seconds", StyxWoW.Me.Shapeshift.ToString().CamelToSpaced(), symbolicName, (SuppressShapeshiftUntil - DateTime.UtcNow).TotalSeconds);
                        Lua.DoString("CancelShapeshiftForm()");
                    }
                }
                else if (StyxWoW.Me.Class == WoWClass.Rogue && SingularSettings.Instance.Rogue().UsePickPocket)
                {
                    if (e.Args[14].ToString() == LocalizedNoPocketsToPickFailure)
                    {
                        HandleRogueNoPocketsError();
                    }
                }
                break;

            case "SPELL_AURA_APPLIED":
            case "SPELL_CAST_SUCCESS":
                if (e.SourceGuid != StyxWoW.Me.Guid)
                {
                    return;
                }

                // Update the last spell we cast. So certain classes can 'switch' their logic around.
                Spell.LastSpellCast = e.SpellName;
                Logger.WriteDebug("Storing {0} as last spell cast.", Spell.LastSpellCast);

                // following commented block should not be needed since rewrite of Pet summon
                //
                //// Force a wait for all summoned minions. This prevents double-casting it.
                //if (StyxWoW.Me.Class == WoWClass.Warlock && e.SpellName.StartsWith("Summon "))
                //{
                //    StyxWoW.SleepForLagDuration();
                //}
                break;

            case "SWING_MISSED":
                if (e.Args[11].ToString() == "EVADE")
                {
                    HandleEvadeBuggedMob(args, e);
                }
                else if (e.Args[11].ToString() == "IMMUNE")
                {
                    WoWUnit unit = e.DestUnit;
                    if (unit != null && !unit.IsPlayer)
                    {
                        Logger.WriteDebug("{0} is immune to Physical spell school", unit.Name);
                        SpellImmunityManager.Add(unit.Entry, WoWSpellSchool.Physical, e.Spell);
                    }
                }
                break;

            case "SPELL_MISSED":
            case "RANGE_MISSED":
                // Why log misses?  Because users of classes with DoTs testing on training dummies
                // .. that they don't have enough +Hit for will get DoT spam.  This allows easy
                // .. diagnosis of false reports of rotation issues where a user simply isn't geared
                // .. this happens more at the beginning of an expansion especially
                if (SingularSettings.Debug)
                {
                    Logger.WriteDebug(
                        "[CombatLog] {0} {1}#{2} {3}",
                        e.Event,
                        e.Spell.Name,
                        e.SpellId,
                        e.Args[14]
                        );
                }

                if (e.Args[14].ToString() == "EVADE")
                {
                    HandleEvadeBuggedMob(args, e);
                }
                else if (e.Args[14].ToString() == "IMMUNE")
                {
                    WoWUnit unit = e.DestUnit;
                    if (unit != null && !unit.IsPlayer)
                    {
                        Logger.WriteDebug("{0} is immune to {1} spell school", unit.Name, e.SpellSchool);
                        SpellImmunityManager.Add(unit.Entry, e.SpellSchool, e.Spell);
                    }

                    if (StyxWoW.Me.Class == WoWClass.Rogue && e.SpellId == 6770)
                    {
                        WoWUnit unitImmune = unit;
                        if (unitImmune == null)
                        {
                            unitImmune = ObjectManager.GetObjectByGuid <WoWUnit>(Singular.ClassSpecific.Rogue.Common.lastSapTarget);
                        }

                        Singular.ClassSpecific.Rogue.Common.AddEntryToSapImmuneList(unitImmune);
                    }
                }
                break;

            case "UNIT_DIED":
                if (StyxWoW.Me.CurrentTarget != null && e.DestGuid == StyxWoW.Me.CurrentTarget.Guid)
                {
                    Spell.LastSpellCast = "";
                }

                try
                {
                    WoWUnit        corpse = e.SourceUnit;
                    WoWPartyMember pm     = Unit.GroupMemberInfos.First(m => m.Guid == corpse.Guid);
                    Logger.WriteDiagnostic("Combat Log: UNIT_DIED - Role={0} {1}", pm.Role & (~WoWPartyMember.GroupRole.Leader), corpse.SafeName());
                }
                catch
                {
                }
                break;
            }
        }
Beispiel #5
0
        private static void HandleCombatLog(object sender, LuaEventArgs args)
        {
            var e = new CombatLogEventArgs(args.EventName, args.FireTimeStamp, args.Args);

            if (e.SourceGuid != StyxWoW.Me.Guid)
            {
                return;
            }

            // Logger.WriteDebug("[CombatLog] " + e.Event + " - " + e.SourceName + " - " + e.SpellName);

            switch (e.Event)
            {
            default:
                Logger.WriteDebug("[CombatLog] filter out this event -- " + e.Event + " - " + e.SourceName + " - " + e.SpellName);
                break;

            case "SPELL_CAST_FAILED":
                if (SingularSettings.Instance.EnableDebugLogging)
                {
                    Logger.WriteDebug("[CombatLog] {0}:{1} cast of {2}#{3} failed: '{4}'",
                                      e.SourceName,
                                      e.SourceGuid,
                                      e.SpellName,
                                      e.SpellId,
                                      e.Args[14]
                                      );
                }
                break;

            case "SPELL_AURA_APPLIED":
            case "SPELL_CAST_SUCCESS":
                if (e.SourceGuid != StyxWoW.Me.Guid)
                {
                    return;
                }

                // Update the last spell we cast. So certain classes can 'switch' their logic around.
                Spell.LastSpellCast = e.SpellName;
                //Logger.WriteDebug("Successfully cast " + Spell.LastSpellCast);

                // Force a wait for all summoned minions. This prevents double-casting it.
                if (StyxWoW.Me.Class == WoWClass.Warlock && e.SpellName.StartsWith("Summon "))
                {
                    StyxWoW.SleepForLagDuration();
                }
                break;

            case "SWING_MISSED":
                if (e.Args[11].ToString() == "EVADE")
                {
                    Logger.Write("Mob is evading swing. Blacklisting it!");
                    Blacklist.Add(e.DestGuid, TimeSpan.FromMinutes(30));
                    if (StyxWoW.Me.CurrentTargetGuid == e.DestGuid)
                    {
                        StyxWoW.Me.ClearTarget();
                    }

                    BotPoi.Clear("Blacklisting evading mob");
                    StyxWoW.SleepForLagDuration();
                }
                else if (e.Args[11].ToString() == "IMMUNE")
                {
                    WoWUnit unit = e.DestUnit;
                    if (unit != null && !unit.IsPlayer)
                    {
                        Logger.WriteDebug("{0} is immune to {1} spell school", unit.Name, e.SpellSchool);
                        SpellImmunityManager.Add(unit.Entry, e.SpellSchool);
                    }
                }
                break;

            case "SPELL_MISSED":
            case "RANGE_MISSED":
                // DoT casting spam can occur when running on test dummy with low +hit
                //  ..  and multiple misses occurring. this should help troubleshoot
                //  ..  false reports of flawed rotation
                if (SingularSettings.Instance.EnableDebugLogging)
                {
                    Logger.WriteFile(
                        "[CombatLog] {0} {1}#{2} {3}",
                        e.Event,
                        e.SpellName,
                        e.SpellId,
                        e.Args[14]
                        );
                }

                if (e.Args[14].ToString() == "EVADE")
                {
                    Logger.Write("Mob is evading ranged attack. Blacklisting it!");
                    Blacklist.Add(e.DestGuid, TimeSpan.FromMinutes(30));
                    if (StyxWoW.Me.CurrentTargetGuid == e.DestGuid)
                    {
                        StyxWoW.Me.ClearTarget();
                    }

                    BotPoi.Clear("Blacklisting evading mob");
                    StyxWoW.SleepForLagDuration();
                }
                else if (e.Args[14].ToString() == "IMMUNE")
                {
                    WoWUnit unit = e.DestUnit;
                    if (unit != null && !unit.IsPlayer)
                    {
                        Logger.WriteDebug("{0} is immune to {1} spell school", unit.Name, e.SpellSchool);
                        SpellImmunityManager.Add(unit.Entry, e.SpellSchool);
                    }
                }
                break;
            }
        }