private static void ProcessCreateError(List <Tuple <string, string> > initialSettings, OverwatchInfoManual info, Process process, DirectBitmap bmp, Exception ex)
 {
     if (info.CloseOverwatchProcessOnFailure)
     {
         process.CloseMainWindow();
         process.Close();
     }
     if (bmp != null)
     {
         bmp.Dispose();
     }
     RestoreVideoSettings(info.OverwatchSettingsFilePath, initialSettings);
     throw ex;
 }
        /// <summary>
        /// Creates a new Overwatch process by logging into an account. Since this requires your username and password, I recommend using <see cref="StartOverwatch(OverwatchInfoAuto)"/> instead.
        /// </summary>
        /// <param name="processInfo">Parameters for creating the process.</param>
        /// <returns>The created Overwatch process.</returns>
        public static Process StartOverwatch(OverwatchInfoManual processInfo)
        {
            if (processInfo == null)
            {
                throw new ArgumentNullException(nameof(processInfo));
            }

            int maxWaitTime = 5000;

            if (!File.Exists(processInfo.OverwatchExecutableFilePath))
            {
                throw new FileNotFoundException(string.Format("Overwatch's executable at {0} was not found. " +
                                                              "Change OverwatchProcessInfo.OverwatchExecutableFilePath to the location of the Overwatch executable.", processInfo.OverwatchExecutableFilePath));
            }

            if (!File.Exists(processInfo.OverwatchSettingsFilePath))
            {
                throw new FileNotFoundException(string.Format("Overwatch's settings at {0} was not found. " +
                                                              "Change OverwatchProcessInfo.OverwatchSettingsFilePath to the location of Overwatch's settings.", processInfo.OverwatchSettingsFilePath));
            }

            // Set the video settings.
            var initialSettings = ChangeVideoSettings(processInfo.OverwatchSettingsFilePath, VideoSettings.Item1, VideoSettings.Item2);

            Process OWProcess = new Process();

            OWProcess.StartInfo.FileName  = processInfo.OverwatchExecutableFilePath;
            OWProcess.StartInfo.Arguments = "-Displaymode 0";
            OWProcess.Start();

            // Wait for the window to start
            WaitForVisibleProcessWindow(OWProcess);

            // Show the window
            SetupWindow(OWProcess.MainWindowHandle, processInfo.ScreenshotMethod);

            Stopwatch elapsed = new Stopwatch();

            DirectBitmap bmp = null;

            elapsed.Start();
            while (true)
            {
                Screenshot(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, ref bmp);

                if (elapsed.ElapsedMilliseconds >= maxWaitTime)
                {
                    bmp.Dispose();
                    ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Failed to start Overwatch."));
                }

                // If the text input for the log in info is found, break out of the loop.
                if (bmp.CompareColor(407, 384, new int[] { 168, 168, 170 }, 10))
                {
                    break;
                }
                // If the log in button is yellow, there is not a connection.
                else if (bmp.CompareColor(Points.PRE_MAIN_MENU_LOGIN, Colors.CONFIRM, Fades.CONFIRM))
                {
                    ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Could not log in; no internet connection."));
                }
                Thread.Sleep(500);
            }
            elapsed.Reset();

            Thread.Sleep(100);

            // At this point login info is ready to be inputed
            TextInput(OWProcess.MainWindowHandle, processInfo.Username);
            KeyPress(OWProcess.MainWindowHandle, Keys.Tab);
            TextInput(OWProcess.MainWindowHandle, processInfo.Password);

            // Log in
            Thread.Sleep(50);
            Screenshot(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, ref bmp);
            if (bmp.CompareColor(Points.PRE_MAIN_MENU_LOGIN, Colors.CONFIRM, Fades.CONFIRM))
            {
                KeyPress(OWProcess.MainWindowHandle, Keys.Enter);
            }
            else
            {
                ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Could not log in with the input username or password."));
            }

            Thread.Sleep(500);

            elapsed.Start();
            while (true)
            {
                if (elapsed.ElapsedMilliseconds >= maxWaitTime)
                {
                    ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Failed to start Overwatch."));
                }

                Screenshot(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, ref bmp);
                if (bmp.CompareColor(469, 437, Colors.CONFIRM, Fades.CONFIRM) == false)
                {
                    break;
                }
                Thread.Sleep(500);
            }
            elapsed.Reset();

            Thread.Sleep(500);

            Screenshot(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, ref bmp);
            // Check if login failed
            // s0 will equal true and s1 will equal false if the login failed. s0 and s1 will equal true if an authenticator is required.
            bool s0 = bmp.CompareColor(518, 482, Colors.CONFIRM, Fades.CONFIRM); // "Cancel" button
            bool s1 = bmp.CompareColor(605, 475, Colors.CONFIRM, Fades.CONFIRM); // "Authenticate" button.

            if (s0 && !s1)
            {
                ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Could not log in with the input username or password."));
            }

            // Enter authenticator code if it is required
            if (s0 && s1)
            {
                if (String.IsNullOrEmpty(processInfo.Authenticator))
                {
                    ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Authenticator is required"));
                }

                TextInput(OWProcess.MainWindowHandle, processInfo.Authenticator);
                Thread.Sleep(10);
                KeyPress(OWProcess.MainWindowHandle, Keys.Enter);
                Thread.Sleep(500);

                elapsed.Start();
                while (true)
                {
                    if (elapsed.ElapsedMilliseconds >= maxWaitTime)
                    {
                        ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Failed to start Overwatch."));
                    }

                    Screenshot(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, ref bmp);
                    if (bmp.CompareColor(469, 437, Colors.CONFIRM, Fades.CONFIRM) == false)
                    {
                        break;
                    }
                    Thread.Sleep(500);
                }
                Thread.Sleep(500);

                Screenshot(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, ref bmp);
                if (bmp.CompareColor(518, 482, Colors.CONFIRM, Fades.CONFIRM))
                {
                    ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException(string.Format("Authenticator number \"{0}\" is invalid.", processInfo.Authenticator)));
                }
            }

            if (!WaitForMainMenu(processInfo.ScreenshotMethod, OWProcess.MainWindowHandle, bmp, maxWaitTime))
            {
                ProcessCreateError(initialSettings, processInfo, OWProcess, bmp, new OverwatchStartFailedException("Failed to start Overwatch."));
            }

            if (processInfo.AutomaticallyCreateCustomGame)
            {
                CreateCustomGame(OWProcess.MainWindowHandle);
            }

            // Reset the contrast to its initial value
            RestoreVideoSettings(processInfo.OverwatchSettingsFilePath, initialSettings);

            return(OWProcess);
        }