예제 #1
0
        public void Start()
        {
            if (!Parent.IsStarted)
            {
                return;
            }

            if (!File.Exists(Location))
            {
                Logger.Instance.Write("File not found: {0}", Location);
                return;
            }

            _isStopped = false;
            // Ping check
            while (Settings.Default.ConnectionCheckPing && !ConnectionCheck.PingCheck() && !_isStopped)
            {
                Parent.Status = "Wait on internet connection";
                Logger.Instance.WriteGlobal("PingCheck: Waiting 10 seconds and trying again!");
                Thread.Sleep(10000);
            }

            // Check valid host
            while (Settings.Default.ConnectionCheckIpHost && !ConnectionCheck.CheckValidConnection() && !_isStopped)
            {
                Parent.Status = "Wait on host validation";
                Logger.Instance.WriteGlobal("ConnectionValidation: Waiting 10 seconds and trying again!");
                Thread.Sleep(10000);
            }

            // Check if we need to create a Diablo clone
            if (Parent.UseDiabloClone)
            {
                DiabloClone.Create(Parent);
            }

            Parent.Status = "Prepare Diablo"; // Update Status

            General.AgentKiller();            // Kill all Agent.exe processes

            // Prepare D3 for launch
            var agentDBPath = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) + @"\Battle.net\Agent\agent.db";

            if (File.Exists(agentDBPath))
            {
                Logger.Instance.Write("Deleting: {0}", agentDBPath);
                try
                {
                    File.Delete(agentDBPath);
                }
                catch (Exception ex)
                {
                    Logger.Instance.Write("Failed to delete! Exception: {0}", ex.Message);
                    DebugHelper.Exception(ex);
                }
            }

            // Copy D3Prefs
            if (!string.IsNullOrEmpty(Parent.D3PrefsLocation))
            {
                D3Prefs();
            }

            // Registry Changes
            RegistryClass.ChangeLocale(Parent.Diablo.Language); // change language
            RegistryClass.ChangeRegion(Parent.Diablo.Region);   // change region

            if (UseIsBoxer)
            {
                IsBoxerStarter();
            }
            else if (Settings.Default.UseD3Starter)
            {
                ApocD3Starter();
            }
            else
            {
                try
                {
                    var arguments = "-launch";
                    var pi        = new ProcessStartInfo(Location2, arguments)
                    {
                        WorkingDirectory = Path.GetDirectoryName(Location2)
                    };
                    pi = UserAccount.ImpersonateStartInfo(pi, Parent);
                    // Set working directory to executable location
                    Parent.Status = "Starting Diablo"; // Update Status
                    Proc          = Process.Start(pi);
                }
                catch (Exception ex)
                {
                    Parent.Stop();
                    DebugHelper.Exception(ex);
                    return;
                }
            }

            if (!UseIsBoxer) // Don't want to fight with isboxer
            {
                if (CpuCount != Environment.ProcessorCount)
                {
                    ProcessorAffinity = AllProcessors; // set it to all ones
                    CpuCount          = Environment.ProcessorCount;
                }
                Proc.ProcessorAffinity = (IntPtr)ProcessorAffinity;
            }


            if (_isStopped)
            {
                return;             // Halt here when bot is stopped while we where waiting for it to become active
            }
            // Wait for d3 to fully load
            var state    = (Settings.Default.UseD3Starter || UseIsBoxer ? 0 : 2);
            var handle   = IntPtr.Zero;
            var timedout = false;

            LimitStartTime(true); // reset startup time
            while ((!Proc.HasExited && state < 4))
            {
                if (timedout)
                {
                    return;
                }
                //Debug.WriteLine("Splash: " + FindWindow.FindWindowClass("D3 Splash Window Class", Proc.Id) + " Main:" + FindWindow.FindWindowClass("D3 Main Window Class", Proc.Id));
                switch (state)
                {
                case 0:
                    handle = FindWindow.FindWindowClass("D3 Splash Window Class", Proc.Id);
                    if (handle != IntPtr.Zero)
                    {
                        Logger.Instance.Write("Diablo:{0}: Found D3 Splash Window ({1})", Proc.Id, handle);
                        state++;
                        LimitStartTime(true);     // reset startup time
                    }
                    timedout = LimitStartTime();
                    break;

                case 1:
                    handle = FindWindow.FindWindowClass("D3 Splash Window Class", Proc.Id);
                    if (handle == IntPtr.Zero)
                    {
                        Logger.Instance.Write("Diablo:{0}: D3 Splash Window Closed ({1})", Proc.Id, handle);
                        state++;
                        LimitStartTime(true);     // reset startup time
                    }
                    timedout = LimitStartTime();
                    break;

                case 2:
                    handle = FindWindow.FindWindowClass("D3 Main Window Class", Proc.Id);
                    if (handle != IntPtr.Zero)
                    {
                        Logger.Instance.Write("Diablo:{0}: Found D3 Main Window ({1})", Proc.Id, handle);
                        state++;
                        LimitStartTime(true);     // reset startup time
                    }
                    timedout = LimitStartTime();
                    break;

                case 3:
                    if (CrashChecker.IsResponding(handle))
                    {
                        MainWindowHandle = handle;
                        state++;
                        LimitStartTime(true);     // reset startup time
                    }
                    timedout = LimitStartTime();
                    break;
                }
                Thread.Sleep(500);
            }
            if (timedout)
            {
                return;
            }

            if (Program.IsRunAsAdmin)
            {
                Proc.PriorityClass = General.GetPriorityClass(Priority);
            }
            else
            {
                Logger.Instance.Write(Parent, "Failed to change priority (No admin rights)");
            }
            // Continue after launching stuff
            Logger.Instance.Write("Diablo:{0}: Waiting for process to become ready", Proc.Id);

            var timeout = DateTime.Now;

            while (true)
            {
                if (General.DateSubtract(timeout) > 30)
                {
                    Logger.Instance.Write("Diablo:{0}: Failed to start!", Proc.Id);
                    Parent.Restart();
                    return;
                }
                Thread.Sleep(500);
                try
                {
                    Proc.Refresh();
                    if (Proc.WaitForInputIdle(100) || CrashChecker.IsResponding(MainWindowHandle))
                    {
                        break;
                    }
                }
                catch (Exception ex)
                {
                    DebugHelper.Exception(ex);
                }
            }

            if (!IsRunning)
            {
                return;
            }

            _lastRepsonse = DateTime.Now;

            Thread.Sleep(1500);
            if (NoFrame)
            {
                AutoPosition.RemoveWindowFrame(MainWindowHandle, true);          // Force remove window frame
            }
            if (ManualPosSize)
            {
                AutoPosition.ManualPositionWindow(MainWindowHandle, X, Y, W, H, Parent);
            }
            else if (Settings.Default.UseAutoPos)
            {
                AutoPosition.PositionWindows();
            }

            Logger.Instance.Write("Diablo:{0}: Process is ready", Proc.Id);

            // Demonbuddy start delay
            if (Settings.Default.DemonbuddyStartDelay > 0)
            {
                Logger.Instance.Write("Demonbuddy start delay, waiting {0} seconds", Settings.Default.DemonbuddyStartDelay);
                Thread.Sleep((int)Settings.Default.DemonbuddyStartDelay * 1000);
            }
        }