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); } }