Ejemplo n.º 1
0
        /************************************************************************************/
        protected override bool OnLogNarrative(ConsoleLogEventArgs NewArgs)
        {
            if (base.OnLogNarrative(NewArgs))
            {
                return(true);
            }

            if (m_iLastChestDisarmAttempted != -1)
            {
                if (NewArgs.OriginalLine.StartsWith("You disarm the trap on") ||
                    NewArgs.OriginalLine.StartsWith("You failed to disarm the trap on") ||
                    NewArgs.OriginalLine.StartsWith("You trigger the trap on"))
                {
                    if (m_NearbyChestDictionary.ContainsKey(m_iLastChestDisarmAttempted))
                    {
                        m_NearbyChestDictionary[m_iLastChestDisarmAttempted] = true;
                    }
                    m_iLastChestDisarmAttempted = -1;
                    Program.Log("Chest disarmed or triggered. Checking for others.");
                    return(true);
                }
            }

            return(false);
        }
 /************************************************************************************/
 /// <summary>
 /// This is meant to get called by the parse thread.
 /// </summary>
 /// <param name="NewEvent"></param>
 public static void EnqueueLogEvent(ConsoleLogEventArgs NewEvent)
 {
     s_ChatEventQueue.Enqueue(NewEvent);
     return;
 }
        /************************************************************************************/
        public static void Run()
        {
            s_ParseThread.Start();

            s_strSharedOverridesINIFilePath = Path.Combine(Program.ConfigurationFolderPath, "SharedOverrides.ini");
            if (!File.Exists(s_strSharedOverridesINIFilePath))
            {
                File.Create(s_strSharedOverridesINIFilePath).Close();
            }

            string strPreviousSubClass  = string.Empty;
            string strPreviousName      = string.Empty;
            bool   bFirstZoningFrame    = true;
            bool   bRunGarbageCollector = false;

            do
            {
                s_CurrentCycleTimestamp = DateTime.Now;

                /// Run this outside of the frame lock.
                if (bRunGarbageCollector)
                {
                    Program.RunGarbageCollector();
                    bRunGarbageCollector = false;
                }

                Frame.Wait(true);
                try
                {
                    /// Call the controller if we zone. During zoning, no game variables are assumed to be worth a damn.
                    /// We go straight to a string check for now instead of the property (which uses <int> conversion)
                    /// because the property has had a troubled past and returned buggy/invalid values.
                    if (s_EQ2.GetMember <string>("Zoning") != "0")
                    {
                        if (bFirstZoningFrame)
                        {
                            Program.Log("Zoning...");
                            bFirstZoningFrame = false;

                            ReleaseAllKeys();
                            s_RecentThrottledCommandCache.Clear();
                            if (s_Controller != null)
                            {
                                s_Controller.OnZoningBegin();
                            }

                            bRunGarbageCollector = true;
                        }
                        continue;
                    }
                    else
                    {
                        if (!UpdateStaticGlobals())
                        {
                            continue;
                        }

                        if (!bFirstZoningFrame)
                        {
                            Program.Log("Done zoning.");
                            bFirstZoningFrame = true;

                            if (s_Controller != null)
                            {
                                s_Controller.OnZoningComplete();
                            }

                            ApplyGameSettings();
                        }
                    }

                    try
                    {
                        /// An amazing little thing I discovered while watching console spam.
                        /// EQ2 will prefix your character name if you are watching a flythrough zone intro video.
                        /// Pressing Escape kills it.
                        if (Me.Group(0).Name.StartsWith("Flythrough_"))
                        {
                            Program.Log("Zone flythrough sequence detected, attempting to cancel with the Esc key...");
                            LavishScript.ExecuteCommand("press esc");
                            continue;
                        }
                    }
                    catch
                    {
                    }


                    /// Automatically accept a quest.
                    if (s_Controller != null && !string.IsNullOrEmpty(s_EQ2.PendingQuestName) && s_EQ2.PendingQuestName != "None")
                    {
                        Program.Log("Quest offered: \"{0}\".", s_EQ2.PendingQuestName);

                        if (s_Controller.m_ePositioningStance == PlayerController.PositioningStance.DoNothing)
                        {
                            Program.Log("Character is in do-nothing stance; ignoring offered quest.");
                        }
                        else
                        {
                            /// Stolen from "EQ2Quest.iss". The question I have: isn't AcceptPendingQuest() redundant then?
                            /// eq2ui_popup_rewardpack.xml
                            EQ2UIPage QuestPage = s_Extension.EQ2UIPage("Popup", "RewardPack");
                            if (QuestPage.IsValid)
                            {
                                EQ2UIElement QuestAcceptButton = QuestPage.Child("button", "RewardPack.Accept");
                                if (QuestAcceptButton.IsValid)
                                {
                                    Program.Log("Automatically accepting quest \"{0}\"...", s_EQ2.PendingQuestName);
                                    s_EQ2.AcceptPendingQuest();
                                    QuestAcceptButton.LeftClick();
                                }
                            }
                        }
                    }

                    unchecked { s_lFrameCount++; }

                    /// Make sure the parse engine always knows the current character name.
                    /// Unfortunately, there's no way to know the current language at this time.
                    if (Name != strPreviousName)
                    {
                        s_ParseThread.PostNewNameLanguageMessage(Name, ChatEventArgs.GameLanguageType.Unknown);
                        strPreviousName = Name;
                    }

                    /// If the subclass changes (startup, betrayal, etc), resync.
                    /// The null check on SubClass is because it comes up as null when reviving.
                    /// s_Controller is guaranteed to be non-null after this block (otherwise the program would have exited).
                    /// TODO: State variables contained in the prior controller will be lost. Maybe make them static?
                    if (!string.IsNullOrEmpty(Me.SubClass) && Me.SubClass != strPreviousSubClass)
                    {
                        Program.Log("New class found: \"{0}\"", Me.SubClass);
                        strPreviousSubClass     = Me.SubClass;
                        s_bRefreshKnowledgeBook = true;

                        switch (strPreviousSubClass.ToLower())
                        {
                        case "coercer": s_Controller = new CoercerController(); break;

                        case "defiler": s_Controller = new DefilerController(); break;

                        case "dirge": s_Controller = new DirgeController(); break;

                        case "fury": s_Controller = new FuryController(); break;

                        case "illusionist": s_Controller = new IllusionistController(); break;

                        case "inquisitor": s_Controller = new InquisitorController(); break;

                        case "mystic": s_Controller = new MysticController(); break;

                        case "templar": s_Controller = new TemplarController(); break;

                        case "troubador": s_Controller = new TroubadorController(); break;

                        case "warden": s_Controller = new WardenController(); break;

                        case "warlock": s_Controller = new WarlockController(); break;

                        case "wizard": s_Controller = new WizardController(); break;

                        default:
                        {
                            Program.Log("Unrecognized or unsupported subclass type: {0}.", Me.SubClass);
                            Program.Log("Will use generic controller without support for spells or combat arts.");
                            s_Controller = new PlayerController();
                            break;
                        }
                        }

                        /// Build the name of the INI file.
                        string strFileName = string.Format("{0}.{1}.ini", ServerName, Name);
                        s_strCurrentINIFilePath = Path.Combine(Program.ConfigurationFolderPath, strFileName);

                        if (File.Exists(s_strCurrentINIFilePath))
                        {
                            s_Controller.ReadINISettings();
                        }

                        s_Controller.WriteINISettings();

                        SetWindowText(string.Format("{0} ({1})", Name, Me.SubClass));

                        ApplyGameSettings();
                    }

                    /// If the size of the knowledge book changes, defer a resync.
                    /// NOTE: If the user equips or unequips an ability-changing item,
                    /// the ability table will be hosed but we'll have no way of knowing to force a refresh.
                    if (s_Controller.AbilityCountChanged)
                    {
                        s_bRefreshKnowledgeBook = true;
                    }

                    /// Only if the knowledge book is intact can we safely assume that regular actions are OK.
                    /// DoNextAction() might set s_bRefreshKnowledgeBook to true.  This is fine.
                    if (!s_bRefreshKnowledgeBook)
                    {
                        /// Handle all the log events that were generated by the parse thread so far.
                        ConsoleLogEventArgs NewArgs = null;
                        while (s_ChatEventQueue.Dequeue(ref NewArgs))
                        {
                            if (NewArgs is ChatEventArgs)
                            {
                                s_Controller.OnLogChat(NewArgs as ChatEventArgs);
                            }
                            else
                            {
                                s_Controller.OnLogNarrative(NewArgs);
                            }
                        }

                        s_Controller.DoNextAction();
                        s_Controller.UpdateEndOfRoundStatistics();
                    }

                    /// Do certain checks only every 5th frame.
                    if ((s_lFrameCount % 5) == 0)
                    {
                        /// Supposedly Process.VirtualMemorySize64 can return negative values because of casting bugs.
                        Process CurrentProcess           = Process.GetCurrentProcess();
                        long    lActualVirtualAllocation = CurrentProcess.VirtualMemorySize64;
                        if (lActualVirtualAllocation > (long)s_Controller.m_ulVirtualAllocationProcessTerminationThreshold &&
                            lActualVirtualAllocation < (long)(4 * CustomFormatter.GB))                             /// This check	is to prevent impossible values from causing crashes.
                        {
                            /// GAME OVER.
                            using (StreamWriter OutputFile = Program.OpenCrashLog())
                                OutputFile.WriteLine("Process terminating immediately: current virtual allocation is {0}.", CustomFormatter.FormatByteCount(CurrentProcess.VirtualMemorySize64, "0.00"));
                            CurrentProcess.Kill();
                        }

                        if (s_Controller.m_bKillBotWhenCamping && Me.IsCamping)
                        {
                            Program.Log("Camping detected; aborting bot!");
                            s_bContinueBot = false;
                        }
                    }
                }
                finally
                {
                    Frame.Unlock();
                }

                /// If we have to refresh the knowledge book, then do it outside of the main lock.
                /// This is because we'll use frame waits and can't risk breaking cached data.
                if (s_bRefreshKnowledgeBook)
                {
                    s_Controller.RefreshKnowledgeBook();
                    s_bRefreshKnowledgeBook = false;
                }

                /// Skip frames as configured.
                for (int iIndex = 0; iIndex < s_Controller.m_iFrameSkip; iIndex++)
                {
                    Frame.Wait(false);
                    unchecked { s_lFrameCount++; }
                }
            }while (s_bContinueBot);

            /// Don't overwrite files that already exist unless told to; people might have special comments in place.
            if (!File.Exists(s_strCurrentINIFilePath) || s_Controller.m_bWriteBackINI)
            {
                s_Controller.WriteINISettings();
            }

            Program.Log("Shutting down parser thread...");
            s_ParseThread.PostQuitMessageAndShutdownQueue(true);
            if (s_ParseThread.WaitForTermination(TimeSpan.FromSeconds(30.0)))
            {
                Program.Log("Parser thread terminated.");
            }
            else
            {
                Program.Log("Parser thread timed out.");
            }
            return;
        }
 private void OnConsoleLogEvent(object sender, ConsoleLogEventArgs e)
 {
     syncedQueue.Enqueue($"[{e.Date}][Process {e.ProcessId}] {e.Msg}");
 }
 /// <summary>
 /// The console logs from the javascript application
 /// </summary>
 /// <param name="sender"></param>
 /// <param name="e"></param>
 void onConsoleLog(object sender, ConsoleLogEventArgs e)
 {
     WriteToConsole("onConsoleLog");
 }
Ejemplo n.º 6
0
 /************************************************************************************/
 protected void ParseEngine_LineNotRecognized(object objSender, ConsoleLogEventArgs args)
 {
     PlayerController.EnqueueLogEvent(args);
     return;
 }