Beispiel #1
0
        private static void ScreenshotBitBlt(IntPtr hWnd, ref DirectBitmap capture)
        {
            try
            {
                // get the hDC of the target window
                IntPtr hdcSrc = User32.GetDC(hWnd);
                // get the size
                Rectangle windowRect = new Rectangle();
                User32.GetWindowRect(hWnd, ref windowRect);
                int width  = windowRect.Right - windowRect.Left;
                int height = windowRect.Bottom - windowRect.Top;
                // create a device context we can copy to
                IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
                // create a bitmap we can copy it to,
                // using GetDeviceCaps to get the width/height
                IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);
                // select the bitmap object
                IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
                // bitblt over
                Gdi32.BitBlt(hdcDest, 1, 31, width - 10, height, hdcSrc, 0, 0, (uint)Gdi32.TernaryRasterOperations.SRCCOPY | (uint)Gdi32.TernaryRasterOperations.CAPTUREBLT);
                // restore selection
                Gdi32.SelectObject(hdcDest, hOld);

                if (capture != null)
                {
                    capture.Dispose();
                }
                capture = new DirectBitmap(hdcSrc, hBitmap);

                // clean up
                Gdi32.DeleteDC(hdcDest);
                User32.ReleaseDC(hWnd, hdcSrc);
                // free up the Bitmap object
                Gdi32.DeleteObject(hBitmap);
            }
            catch (ExternalException)
            {
                // Failed to capture window, usually because it was closed.
#if DEBUG
                CustomGameDebug.WriteLine("Failed to capture window. Is it closed?");
#endif
            }
        }
Beispiel #2
0
        private void ScreenshotBitBlt()
        {
            try
            {
                // get the hDC of the target window
                IntPtr hdcSrc = User32.GetDC(OverwatchHandle);
                // get the size
                int width  = Rectangles.ENTIRE_SCREEN.Width + Points.BITBLT_WINDOW_LOCATION.X;
                int height = Rectangles.ENTIRE_SCREEN.Height + Points.BITBLT_WINDOW_LOCATION.Y;
                // create a device context we can copy to
                IntPtr hdcDest = Gdi32.CreateCompatibleDC(hdcSrc);
                // create a bitmap we can copy it to,
                // using GetDeviceCaps to get the width/height
                IntPtr hBitmap = Gdi32.CreateCompatibleBitmap(hdcSrc, width, height);
                // select the bitmap object
                IntPtr hOld = Gdi32.SelectObject(hdcDest, hBitmap);
                // bitblt over
                Gdi32.BitBlt(hdcDest, Points.BITBLT_WINDOW_LOCATION.X, Points.BITBLT_WINDOW_LOCATION.Y, width, height, hdcSrc, 0, 0, (uint)Gdi32.TernaryRasterOperations.SRCCOPY | (uint)Gdi32.TernaryRasterOperations.CAPTUREBLT);
                // restore selection
                Gdi32.SelectObject(hdcDest, hOld);

                if (Capture != null)
                {
                    Capture.Dispose();
                }
                Capture = new DirectBitmap(hdcSrc, hBitmap);

                // clean up
                Gdi32.DeleteDC(hdcDest);
                User32.ReleaseDC(OverwatchHandle, hdcSrc);
                // free up the Bitmap object
                Gdi32.DeleteObject(hBitmap);
            }
            catch (ExternalException)
            {
                // Failed to capture window, usually because it was closed.
#if DEBUG
                CustomGameDebug.WriteLine("Failed to capture window. Is it closed?");
#endif
            }
        }
Beispiel #3
0
        /// <summary>
        /// Gets the current Overwatch event.
        /// </summary>
        /// <returns>The current Overwatch event as the Event enum.</returns>
        public static OWEvent GetCurrentEvent()
        {
            // Search for the "Event Has Ended" box.
            const string searchFor = "<span class=\"btn m-lg u-center-block margin-18 is-disabled\">EVENT HAS ENDED</span>";

            var eventPages = new Tuple <OWEvent, string>[]
            {
                new Tuple <OWEvent, string>(OWEvent.SummerGames, "https://playoverwatch.com/en-us/events/summer-games/"),
                new Tuple <OWEvent, string>(OWEvent.HalloweenTerror, "https://playoverwatch.com/en-us/events/halloween-terror/"),
                new Tuple <OWEvent, string>(OWEvent.WinterWonderland, "https://playoverwatch.com/en-us/events/winter-wonderland/"),
                new Tuple <OWEvent, string>(OWEvent.LunarNewYear, "https://playoverwatch.com/en-us/events/lunar-new-year/"),
                new Tuple <OWEvent, string>(OWEvent.Archives, "https://playoverwatch.com/en-us/events/archives/"),
                new Tuple <OWEvent, string>(OWEvent.Aniversary, "https://playoverwatch.com/en-us/events/anniversary/"),
            };

            using (var client = new System.Net.WebClient())
            {
                try
                {
                    for (int i = 0; i < eventPages.Length; i++)
                    {
#if DEBUG
                        CustomGameDebug.WriteLine($"Downloading data for {eventPages[i].Item1}");
#endif
                        // If the page does not contain the box, then the event is active.
                        if (!client.DownloadString(eventPages[i].Item2).Contains(searchFor))
                        {
                            return(eventPages[i].Item1);
                        }
                    }
                }
                catch (System.Net.WebException)
                {
                    throw new System.Net.WebException("Could not download event info from playoverwatch.com.");
                }
            }

            return(OWEvent.None);
        }
        /// <summary>
        /// Creates an Overwatch process using the currently logged in battle.net account.
        /// </summary>
        /// <param name="processInfo">Parameters for creating the process.</param>
        /// <returns>The created Overwatch process.</returns>
        public static Process StartOverwatch(OverwatchInfoAuto processInfo = null)
        {
            if (processInfo == null)
            {
                processInfo = new OverwatchInfoAuto();
            }

            if (!File.Exists(processInfo.BattlenetExecutableFilePath))
            {
                throw new FileNotFoundException(string.Format("Battle.net.exe's executable at {0} was not found. " +
                                                              "Change battlenetExeLocation to the location of the battle.net.exe executable.", processInfo.BattlenetExecutableFilePath));
            }

            Stopwatch startTime = new Stopwatch();

            // If battle.net is not started, start it.
            if (Process.GetProcessesByName("battle.net").Length == 0)
            {
#if DEBUG
                CustomGameDebug.WriteLine("No battle.net process found, starting battle.net.");
#endif

                Process battlenet = new Process();
                battlenet.StartInfo.FileName = processInfo.BattlenetExecutableFilePath;
                battlenet.Start();

                startTime.Start();
                // The battle.net app is fully started when there are 3 battle.net processes. Loop while there are less than 3.
                while (Process.GetProcessesByName("battle.net").Length < 3)
                {
                    if (startTime.ElapsedMilliseconds >= processInfo.MaxBattlenetStartTime || processInfo.MaxBattlenetStartTime == -1)
                    {
#if DEBUG
                        CustomGameDebug.WriteLine("Error: Battle.net took too long to start.");
#endif
                        throw new OverwatchStartFailedException("Battle.net took too long to start.");
                    }
                    Thread.Sleep(200);
                }
#if DEBUG
                CustomGameDebug.WriteLine("Finished starting Battle.net.");
#endif
            }
#if DEBUG
            else
            {
                CustomGameDebug.WriteLine("Battle.net process found.");
            }

            CustomGameDebug.WriteLine("Starting the Overwatch process.");
#endif

            Process[] processList = Process.GetProcessesByName("Overwatch");

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

            Process battlenetOW = new Process();
            // The arguments to start the game directly before August 2018:
            // battlenet.StartInfo.FileName = "battlenet://Pro";
            // The arguments after:
            battlenetOW.StartInfo.FileName  = processInfo.BattlenetExecutableFilePath;
            battlenetOW.StartInfo.Arguments = "--exec=\"launch Pro\"";
            battlenetOW.Start();

            startTime.Restart();

            while (startTime.ElapsedMilliseconds < processInfo.MaxOverwatchStartTime || processInfo.MaxOverwatchStartTime == -1)
            {
                Process[] newProcessList = Process.GetProcessesByName("Overwatch");

                for (int i = 0; i < newProcessList.Length; i++)
                {
                    if (processList.Contains(newProcessList[i]) == false)
                    {
                        Process owProcess = newProcessList[i];

                        WaitForVisibleProcessWindow(owProcess);
                        RestoreVideoSettings(processInfo.OverwatchSettingsFilePath, initialSettings);

                        if (processInfo.AutomaticallyCreateCustomGame)
                        {
                            DirectBitmap bmp = null;
                            if (WaitForMainMenu(processInfo.ScreenshotMethod, owProcess.MainWindowHandle, bmp, processInfo.MaxWaitForMenuTime))
                            {
#if DEBUG
                                CustomGameDebug.WriteLine("Finished starting Overwatch.");
#endif
                                CreateCustomGame(owProcess.MainWindowHandle);
                                if (bmp != null)
                                {
                                    bmp.Dispose();
                                }
                            }
                            else
                            {
#if DEBUG
                                CustomGameDebug.WriteLine("Could not start Overwatch, main menu did not load.");
#endif
                                if (bmp != null)
                                {
                                    bmp.Dispose();
                                }
                                if (processInfo.CloseOverwatchProcessOnFailure)
                                {
                                    owProcess.CloseMainWindow();
                                    owProcess.Close();
                                }
                                throw new OverwatchStartFailedException("Could not start Overwatch, main menu did not load.");
                            }
                        }
#if DEBUG
                        else
                        {
                            CustomGameDebug.WriteLine("Finished starting Overwatch.");
                        }
#endif

                        return(newProcessList[i]);
                    }
                }

                Thread.Sleep(200);
            }

#if DEBUG
            CustomGameDebug.WriteLine("Error: Overwatch took too long to start.");
#endif
            RestoreVideoSettings(processInfo.OverwatchSettingsFilePath, initialSettings);
            throw new OverwatchStartFailedException("Overwatch took too long to start.");
        }
        /// <summary>
        /// Creates an Overwatch process using the currently logged in battle.net account.
        /// </summary>
        /// <param name="processInfo">Parameters for creating the process.</param>
        /// <returns>The created Overwatch process.</returns>
        public static Process StartOverwatch(OverwatchInfoAuto processInfo = null)
        {
            // Return any Overwatch process that might already be running.
            Process foundProcess = GetOverwatchProcess();

            if (foundProcess != null)
            {
                return(foundProcess);
            }

            #region Argument check
            if (processInfo == null)
            {
                processInfo = new OverwatchInfoAuto();
            }

            // Check if the files in processInfo exist.
            if (!File.Exists(processInfo.BattlenetExecutableFilePath))
            {
                throw new FileNotFoundException($"Battle.net.exe's executable at {processInfo.BattlenetExecutableFilePath} was not found. " +
                                                "Change OverwatchInfoAuto.BattlenetExecutableFilePath to the location of the battle.net.exe executable.");
            }

            if (!File.Exists(processInfo.OverwatchSettingsFilePath))
            {
                throw new FileNotFoundException($"Overwatch's settings file at {processInfo.OverwatchSettingsFilePath} was not found. " +
                                                "Change OverwatchInfoAuto.OverwatchSettingsFilePath to the location of Overwatch's settings file.");
            }
            #endregion

            #region Start battle.net
            // If battle.net is not started, start it.
            if (Process.GetProcessesByName("battle.net").Length == 0)
            {
                CustomGameDebug.WriteLine("No battle.net process found, starting battle.net.");

                Process battlenet = new Process();
                battlenet.StartInfo.FileName = processInfo.BattlenetExecutableFilePath;
                battlenet.Start();

                // The battle.net app is fully started when there are 3 battle.net processes. Loop while there are less than 3.
                if (!SpinWait.SpinUntil(() =>
                {
                    return(Process.GetProcessesByName("battle.net").Length >= 3);
                }, processInfo.MaxBattlenetStartTime))
                {
                    // This code block will run if battle.net isn't finished setting up before the specified maximum time.
                    CustomGameDebug.WriteLine("Error: Battle.net took too long to start.");
                    throw new OverwatchStartFailedException("Battle.net took too long to start.");
                }
                CustomGameDebug.WriteLine("Finished starting Battle.net.");
            }
            else
            {
                CustomGameDebug.WriteLine("Battle.net process found.");
            }
            #endregion

            CustomGameDebug.WriteLine("Starting the Overwatch process.");

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

            try
            {
                try
                {
                    Process battlenetOW = new Process();
                    // The arguments to start the game directly before August 2018:
                    // battlenet.StartInfo.FileName = "battlenet://Pro";
                    // The arguments after:
                    battlenetOW.StartInfo.FileName  = processInfo.BattlenetExecutableFilePath;
                    battlenetOW.StartInfo.Arguments = "--exec=\"launch Pro\"";
                    battlenetOW.Start();

                    Process owProcess = null;

                    TimeSpan overwatchStartTimeSpan = new TimeSpan(0, 0, 0, 0, processInfo.MaxOverwatchStartTime);

                    if (!SpinWait.SpinUntil(() =>
                    {
                        owProcess = GetOverwatchProcess();
                        return(owProcess != null);
                    }, overwatchStartTimeSpan))
                    {
                        CustomGameDebug.WriteLine("Error: Overwatch took too long to start.");
                        throw new OverwatchStartFailedException("Overwatch took too long to start.");
                    }

                    // Wait for the window to be visible.
                    if (!SpinWait.SpinUntil(() =>
                    {
                        owProcess.Refresh();
                        return(!string.IsNullOrEmpty(owProcess.MainWindowTitle));
                    }, overwatchStartTimeSpan))
                    {
                        CustomGameDebug.WriteLine("Error: Overwatch took too long to start.");
                        throw new OverwatchStartFailedException("Overwatch took too long to start.");
                    }

                    RestoreVideoSettings(processInfo.OverwatchSettingsFilePath, initialSettings);
                    initialSettings = null;

                    if (processInfo.AutomaticallyCreateCustomGame)
                    {
                        CustomGame cg = new CustomGame(new CustomGameBuilder()
                        {
                            OpenChatIsDefault = false,
                            ScreenshotMethod  = processInfo.ScreenshotMethod,
                            OverwatchProcess  = owProcess
                        });

                        if (WaitForMainMenu(cg, processInfo.MaxWaitForMenuTime))
                        {
                            cg.CreateCustomGame();
                        }
                        else
                        {
                            CustomGameDebug.WriteLine("Could not start Overwatch, main menu did not load.");

                            if (processInfo.CloseOverwatchProcessOnFailure)
                            {
                                owProcess.CloseMainWindow();
                            }

                            throw new OverwatchStartFailedException("Could not start Overwatch, main menu did not load.");
                        }
                    }

                    CustomGameDebug.WriteLine("Finished starting Overwatch.");
                    return(owProcess);
                }
                finally
                {
                    CustomGameDebug.WriteLine("Restoring video settings.");
                    if (initialSettings != null)
                    {
                        RestoreVideoSettings(processInfo.OverwatchSettingsFilePath, initialSettings);
                    }
                }
            }
            catch (OverwatchClosedException)
            {
                CustomGameDebug.WriteLine("Could not start Overwatch, was closed during initialization.");
                throw new OverwatchStartFailedException("Could not start Overwatch, was closed during initialization.");
            }
        }