Except Print Screen C#

Asked

Viewed 3,160 times

11

There is a game called Tibia (In same window mode) that when trying to take a print screen the game ends up obscuring the image leaving only the whole black game screen independent if the print originated from the Printscreen key, or from some function via code c#.

I have tried some ways to capture the image of the game but without success.

I don’t know exactly what they do that can outshine only the window of the game in question.

I tried two ways:

Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height);
Graphics graphics = Graphics.FromImage(printscreen as Image);
graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size);

The second:

        public static Bitmap GetDesktopImage()
        {
            WIN32_API.SIZE size;

            IntPtr hDC = WIN32_API.GetDC(WIN32_API.GetDesktopWindow());
            IntPtr hMemDC = WIN32_API.CreateCompatibleDC(hDC);

            size.cx = WIN32_API.GetSystemMetrics(WIN32_API.SM_CXSCREEN);
            size.cy = WIN32_API.GetSystemMetrics(WIN32_API.SM_CYSCREEN);

            m_HBitmap = WIN32_API.CreateCompatibleBitmap(hDC, size.cx, size.cy);

            if (m_HBitmap != IntPtr.Zero)
            {
                IntPtr hOld = (IntPtr)WIN32_API.SelectObject(hMemDC, m_HBitmap);
                WIN32_API.BitBlt(hMemDC, 0, 0, size.cx, size.cy, hDC, 0, 0, WIN32_API.SRCCOPY);
                WIN32_API.SelectObject(hMemDC, hOld);
                WIN32_API.DeleteDC(hMemDC);
                WIN32_API.ReleaseDC(WIN32_API.GetDesktopWindow(), hDC);
                return System.Drawing.Image.FromHbitmap(m_HBitmap);
            }
            return null;
        }

public class WIN32_API
    {
        public struct SIZE
        {
            public int cx;
            public int cy;
        }
        public const int SRCCOPY = 13369376;
        public const int SM_CXSCREEN = 0;
        public const int SM_CYSCREEN = 1;

        [DllImport("gdi32.dll", EntryPoint = "DeleteDC")]
        public static extern IntPtr DeleteDC(IntPtr hDc);

        [DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
        public static extern IntPtr DeleteObject(IntPtr hDc);

        [DllImport("gdi32.dll", EntryPoint = "BitBlt")]
        public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp);

        [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleBitmap")]
        public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);

        [DllImport("gdi32.dll", EntryPoint = "CreateCompatibleDC")]
        public static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport("gdi32.dll", EntryPoint = "SelectObject")]
        public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);

        [DllImport("user32.dll", EntryPoint = "GetDesktopWindow")]
        public static extern IntPtr GetDesktopWindow();

        [DllImport("user32.dll", EntryPoint = "GetDC")]
        public static extern IntPtr GetDC(IntPtr ptr);

        [DllImport("user32.dll", EntryPoint = "GetSystemMetrics")]
        public static extern int GetSystemMetrics(int abc);

        [DllImport("user32.dll", EntryPoint = "GetWindowDC")]
        public static extern IntPtr GetWindowDC(Int32 ptr);

        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);
    }

Is there any other way to take print and avoid this obfuscation?

  • 1

    What is the type of blocking of this program? Does it block the print wind as a whole or blocks blurs its image? Without knowing which or how the program works it is difficult to post an assertive answer, being impossible to reproduce the behavior. And if the program does this blocking, it must be for some good reason... Should you really be trying to do this?

  • @Leandroangelo I edited the question explaining that it is only the window that comes out black and any other element is printed in print normally.

  • a screen recording program, works ?

  • I’ll try, but what’s the reason for the test?

  • try to understand how his lock works... rs

  • I did a search here... actually there’s a "battleye" service that does this blocking. An option to work around this problem is to set a hot key for the in-game printscreen, and in C#, read the destination folder and send the hot key

  • @Rovannlinhalis I even explored some of this option and it even works but I spend a lot of time processing the Getfiles() function to get the printscreen

  • 1

    use a FileSystemWatcher

  • @Rovannlinhalis Even using Filesystemwatcher got very badly optimized, it really needed something more direct as a printscreen itself. 500~800ms just until the game creates the file in the folder and I load this image to read. Time I can not lose :(

  • @Rovannlinhalis I tried to record the screen with OBS and yes it works

  • @Victorlaio why don’t you use the API of OBS then? Here has the wrapper for . NET.

  • giving a search, I read something about the battleye do a scan every 100 seconds and then pick up the processes that are capturing something from the game. I would do a test using this second code of yours, but running in different processes, one exe to capture the screen and another to process... then each capture will have a different pid or at least every time interval

  • I installed the game in a vm, and the second code works normally... at least in the introduction and tutorial... ok (win 7)

Show 8 more comments

1 answer

5


You won’t make it without understanding how Directx works before.

Games have an isolated rendering environment of the operating system, and in their code is using the Windows API to capture the image stream on the screen for a dedicated buffer. This will even work in games that run in window (or full window games without borders), since they are still being rendered in the operating system environment and not another.

When a Direct3d application goes into full screen mode (full screen and not window without borders), it gains full access to graphics hardware, thus creating a fully isolated rendering environment from the operating system. In this case, you will not be able to access the screen image [image buffer] without going through the video card before.

Nvidia hardware has Shadowplay. AMD hardware has Relive. Windows 10 itself has Xbox DVR. Everyone captures the image in isolation. The one on Xbox does different because it gets the image after it appears on the screen. Others capture before the image is displayed, after processing the video card.

Third-party recorders typically inject a library that guarantees the buffer copy to another destination, and can then capture the screen. They are not caught by anti-cheating systems because they are often known and protectors add exceptions to them.

In your case, you should use a third-party API to capture a dedicated game image. If you want to venture out and write your own, remember that it should be safe to go through the game’s anti-chat system.

Updating

I also saw that the Tibia has an anti-screenshot mechanism, in which locks screen shots independently whether it is full screen or window. But here found a way to circumvent this problem by calling the Tibia window, sending the screenshot command and getting the screenshot image.

[DllImport("user32.dll")]
extern bool PostMessage(IntPtr hWnd, UInt32 Msg, int wParam, int lParam);

[DllImport("user32.dll")]
static extern uint MapVirtualKey(uint uCode, uint uMapType);

void KeyDown(IntPtr hwnd, int vk_key)
{
    PostMessage(hwnd, WM_KEYDOWN, vk_key, (int)((MapVirtualKey((uint)vk_key, 0)) * 0x10000 + 1));
}

...

KeyDown(hWnd, 0x50);

After that, the screenshot will be available at ...\AppData\Local\Tibia\packages\Tibia\screenshots. You can use I/O to get the file.

Note that you must associate the key P for screenshots in the game.

  • I came to find this forum explaining what the guy did and I also performed this same action, but as I commented with Rovann Linhares, It takes me about 800ms from the moment the print is taken to the moment of her loading into the code and I have to keep checking practically every 500ms if anything has changed in the image. I wonder if you could help me with the OBS idea?

  • I think with it I could do what I need but I’m starting in the visual programming part.

  • Try to implement first. If you get stuck in a problem, come here at Sopt we will help you. Unfortunately, this is the only way I could get a print of your game and has the downside of catching time, but it’s the solution I was able to come up with.

  • 1

    Dude, I made a hack pro tibia once I picked up the pixel color at a certain point to know for example if the mana bar was full and then simulated typing the words of some magic to spend mana. It worked normally. I only used the windows api. If I could get the color of specific points of the screen should give to make a print too.

  • 1

    @Victorlaio if this answer solved the problem of this question, consider marking it as correct just below the voting buttons. Thank you!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.