예제 #1
0
        public static Bitmap GetTemtemWindowScreenshot()
        {
            //Pointer to the Temtem Window
            IntPtr temtemWindow;

            //Get the currently focused window
            IntPtr focused = User32.GetForegroundWindow();

            //If we're not focusing a window
            if (focused == IntPtr.Zero)
            {
                return(null);
            }
            //Check if the focused window is Temtem
            StringBuilder windowName = new StringBuilder(100);

            User32.GetWindowText(focused, windowName, 100);
            User32.GetWindowThreadProcessId(focused, out uint focusedWindowProcessID); //Inline variable declaration
            string focusedWindowProcessName = Process.GetProcessById((int)focusedWindowProcessID).ProcessName;

            if (windowName.ToString().Equals(WINDOW_NAME) && focusedWindowProcessName.Equals(WINDOW_NAME))
            {
                temtemWindow = focused;
            }
            else
            {
                //We aren't in the right window
                return(null);
            }

            IntPtr hdcWindow = User32.GetDC(temtemWindow);

            User32.POINT lpPoint = new User32.POINT();

            User32.GetClientRect(temtemWindow, out User32.RECT bounds);
            User32.ClientToScreen(temtemWindow, ref lpPoint);

            try
            {
                Bitmap bmp = new Bitmap((bounds.right - bounds.left), (bounds.bottom - bounds.top));
                using (Graphics g = Graphics.FromImage(bmp))
                {
                    g.CopyFromScreen(lpPoint.X, lpPoint.Y, 0, 0, bmp.Size);
                    g.Flush();
                }

                //Release the device context
                User32.ReleaseDC(temtemWindow, hdcWindow);

                return(bmp);
            }
            catch (ArgumentException)
            {
                //This only seems to happen when the window is closing and we end up with a 0 width, 0 height game window rectangle
                //No intricate handling is necessary here, just return null and don't process it
                return(null);
            }
        }
예제 #2
0
        private List <Bitmap> GetOCRViewportImages(User32.POINT lpPoint, List <Rectangle> OCRViewports)
        {
            List <Bitmap> viewportImages = new List <Bitmap>();

            OCRViewports.ForEach(viewport => {
                Bitmap viewportBitmap = new Bitmap(viewport.Width, viewport.Height, PixelFormat.Format32bppArgb);
                using (Graphics g = Graphics.FromImage(viewportBitmap))
                {
                    g.CopyFromScreen(lpPoint.X + viewport.X, lpPoint.Y + viewport.Y, 0, 0, viewport.Size);
                }
                viewportImages.Add(viewportBitmap);
            });
            return(viewportImages);
        }
예제 #3
0
        private List <Color> GetBattleDetectionColors(TemtemWindowData windowData, User32.POINT lpPoint)
        {
            List <Color> detectionSpotColors = new List <Color>();

            using (Bitmap pixel = new Bitmap(1, 1, PixelFormat.Format32bppArgb))
            {
                using (Graphics g = Graphics.FromImage(pixel))
                {
                    for (int i = 0; i < 4; i++)
                    {
                        g.CopyFromScreen(new Point(lpPoint.X + windowData.detectionSpots[i].X, lpPoint.Y + windowData.detectionSpots[i].Y), new Point(0, 0), pixel.Size);
                        detectionSpotColors.Add(pixel.GetPixel(0, 0));
                    }
                }
            }
            return(detectionSpotColors);
        }
예제 #4
0
        public void Detect()
        {
            //Pointer to the Temtem Window
            IntPtr temtemWindow;

            //Get the currently focused window
            IntPtr focused = User32.GetForegroundWindow();

            //If we're not focusing a window
            if (focused == IntPtr.Zero)
            {
                return;
            }
            //Check if the focused window is Temtem
            StringBuilder windowName = new StringBuilder(100);

            User32.GetWindowText(focused, windowName, 100);
            User32.GetWindowThreadProcessId(focused, out uint focusedWindowProcessID); //Inline variable declaration
            string focusedWindowProcessName = Process.GetProcessById((int)focusedWindowProcessID).ProcessName;

            if (windowName.ToString().Equals(WINDOW_NAME) && focusedWindowProcessName.Equals(WINDOW_NAME))
            {
                temtemWindow = focused;
                //Here we check if this is one of our already detected windows and if not we add it
                if (!temtemWindows.ContainsKey(focusedWindowProcessID))
                {
                    temtemWindows.Add(focusedWindowProcessID, new TemtemWindowData {
                        detectionSpots = new List <Point>(),
                        OCRViewports   = new List <Rectangle>(),
                        gameWindowSize = new Size(0, 0),
                        detectedBattle = false
                    });
                }
            }
            else
            {
                //We aren't in the right window
                return;
            }

            IntPtr hdcWindow = User32.GetDC(temtemWindow);

            User32.POINT lpPoint = new User32.POINT();

            User32.GetClientRect(temtemWindow, out User32.RECT bounds);
            User32.ClientToScreen(temtemWindow, ref lpPoint);

            ////Release the device context
            User32.ReleaseDC(temtemWindow, hdcWindow);

            Rectangle gameWindowRect = new Rectangle(lpPoint.X, lpPoint.Y, (bounds.right - bounds.left), (bounds.bottom - bounds.top));

            if (gameWindowRect.Height == 0 || gameWindowRect.Width == 0)
            {
                //If the rectangle is 0 high or wide, we've got a closing/closed window or an error
                return;
            }
            //If the game window dimensions have changed we need to recalculate all the spots.
            //This shouldn't happen often
            if (!gameWindowRect.Size.Equals(temtemWindows[focusedWindowProcessID].gameWindowSize))
            {
                temtemWindows[focusedWindowProcessID].gameWindowSize = gameWindowRect.Size;
                RecalculateDetectionElements(temtemWindows[focusedWindowProcessID], gameWindowRect);
            }

            if (temtemWindows[focusedWindowProcessID].detectedBattle == false)
            {
                //We'll only test for battle if we aren't in a battle
                List <Color> pixelColors = GetBattleDetectionColors(temtemWindows[focusedWindowProcessID], lpPoint);

                //We'll also get the OCR reading spots right here. It's a waste of resources if we aren't detecting battle, but is faster and more reliable when we do
                List <Bitmap> viewportImages = GetOCRViewportImages(lpPoint, temtemWindows[focusedWindowProcessID].OCRViewports);

                if (((ColorDistance(pixelColors[0], spot1RGB) < maxAllowedColorDistance &&
                      ColorDistance(pixelColors[1], spot2RGB) < maxAllowedColorDistance) ||
                     (ColorDistance(pixelColors[2], spot3RGB) < maxAllowedColorDistance &&
                      ColorDistance(pixelColors[3], spot4RGB) < maxAllowedColorDistance)))
                {
                    temtemWindows[focusedWindowProcessID].detectedBattle = true;
                    //Do OCR operation. The OCR controller will dispose of the images so we're ok
                    List <string> results = ocrController.DoOCR(viewportImages);
                    results.ForEach(result => {
                        //Here we add the detected Temtem to the UI
                        tableController.AddTemtem(result);
                    });
                }
            }
            else if (temtemWindows[focusedWindowProcessID].detectedBattle == true)
            {
                //If we're in battle we'll test for being out of battle
                List <Color> pixelColors = GetOutOfBattleDetectionColors(temtemWindows[focusedWindowProcessID], lpPoint);

                if (ColorDistance(pixelColors[0], spot5RGB) < maxAllowedColorDistance &&
                    ColorDistance(pixelColors[1], spot6RGB) < maxAllowedColorDistance)
                {
                    //Set battle to false
                    temtemWindows[focusedWindowProcessID].detectedBattle = false;
                }
            }
        }