Jump to content

Ghetto bot block


Recommended Posts

  • Premium

Moin,

I had some time again and wanted to try out an idea.

The code checks if the client is in focus and only then allows input.

Video:

https://metin2.download/video/A2zkHNRnXn2uVrGrb62DhkcZlXx8WEgn/.mp4

 

Code:

 

struct handle_data {
    unsigned long process_id;
    HWND window_handle;
};
BOOL is_main_window(HWND handle)
{
    return ((GetWindow(handle, GW_OWNER) == (HWND)0) && (IsWindowVisible(handle)));
}
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
    handle_data& data = *(handle_data*)lParam;
    unsigned long process_id = 0;
    GetWindowThreadProcessId(handle, &process_id);
    if (data.process_id != process_id) return TRUE;
    if (!is_main_window(handle)) return TRUE;
    auto s = GetWindowLong(handle, GWL_STYLE);
    if (!(s & WS_VISIBLE)) return TRUE;
    data.window_handle = handle;
    return FALSE;
}

HWND find_main_window(unsigned long process_id)
{
    handle_data data;
    data.process_id = process_id;
    data.window_handle = 0;
    EnumWindows(enum_windows_callback, (LPARAM)&data);
    if (data.window_handle != 0)
    {
        if (IsWindowVisible(data.window_handle))
        {
            return data.window_handle;
        }
    }
    return 0;
}
bool CPythonNetworkStream::SendCharacterStatePacket(const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg)
{
    NANOBEGIN
    if (!__CanActMainInstance())
        return true;
    if (GetActiveWindow() != find_main_window(GetCurrentProcessId()))
        return true;

This is a very bad method, e.g. you can't tab out and farm metins now.

However, it should stop any botter who is not actively "playing" and multiboxxer.

A proper solution is a good anticheat.

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 5
  • Confused 1
  • Love 6

🍆 Sura-Head 💯

Link to comment
Share on other sites

  • Forum Moderator
On 4/4/2021 at 11:16 PM, Anticheat said:
struct handle_data {
    unsigned long process_id;
    HWND window_handle;
};
BOOL is_main_window(HWND handle)
{
    return ((GetWindow(handle, GW_OWNER) == (HWND)0) && (IsWindowVisible(handle)));
}
BOOL CALLBACK enum_windows_callback(HWND handle, LPARAM lParam)
{
    handle_data& data = *(handle_data*)lParam;
    unsigned long process_id = 0;
    GetWindowThreadProcessId(handle, &process_id);
    if (data.process_id != process_id) return TRUE;
    if (!is_main_window(handle)) return TRUE;
    auto s = GetWindowLong(handle, GWL_STYLE);
    if (!(s & WS_VISIBLE)) return TRUE;
    data.window_handle = handle;
    return FALSE;
}

HWND find_main_window(unsigned long process_id)
{
    handle_data data;
    data.process_id = process_id;
    data.window_handle = 0;
    EnumWindows(enum_windows_callback, (LPARAM)&data);
    if (data.window_handle != 0)
    {
        if (IsWindowVisible(data.window_handle))
        {
            return data.window_handle;
        }
    }
    return 0;
}
bool CPythonNetworkStream::SendCharacterStatePacket(const TPixelPosition& c_rkPPosDst, float fDstRot, UINT eFunc, UINT uArg)
{
    NANOBEGIN
    if (!__CanActMainInstance())
        return true;
    if (GetActiveWindow() != find_main_window(GetCurrentProcessId()))
        return true;
data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

Thanks for the release, but this is a totally bad solution and useless code.

Already there's a function that checking if the application is active or not in CMSWindow class.

The variable m_isActive is set when WM_ACTIVATEAPP it's called, basically when a window belonging to a different application than the active window is about to be activated.

If you read a little bit the documentation of Win32 Api, you can find those.

WA_ACTIVE

  • Activated by some method other than a mouse click (for example, by a call to the SetActiveWindow function or by use of the keyboard interface to select the window)

WA_CLICKACTIVE

  • Activated by a mouse click.

So, all what you've to use, it's just 2 lines:

This is the hidden content, please

This method doesn't make sense for the metin2 gameplay anyway.

Also, this is something that made my day:

On 4/4/2021 at 11:16 PM, Anticheat said:

This is a very bad method.

[...]

A proper solution is a good anticheat.

e57a29e28ad01924464f31087c11039f.png

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 26
  • Not Good 1
  • Confused 1
  • Good 7
  • Love 5
Link to comment
Share on other sites

  • Premium
7 minutes ago, VegaS™ said:

Thanks for the release, but this is a totally bad solution and useless code.

Already there's a function that checking if the application is active or not in CMSWindow class.

The variable m_isActive is set when WM_ACTIVATEAPP it's called, basically when a window belonging to a different application than the active window is about to be activated.

If you read a little bit the documentation of Win32 Api, you can find those.

WA_ACTIVE

  • Activated by some method other than a mouse click (for example, by a call to the SetActiveWindow function or by use of the keyboard interface to select the window)

WA_CLICKACTIVE

  • Activated by a mouse click.

So, all what you've to use, it's just 2 lines:


bool CPythonNetworkStream::SendAttackPacket(UINT uMotAttack, DWORD dwVIDVictim)
{
	[...]
	if (!CPythonApplication::Instance().IsActive())
		return true;
	[...]
}

This method doesn't make sense for the metin2 gameplay anyway.

Also, this is something that made my day:

e57a29e28ad01924464f31087c11039f.png

My anticheat doesn't rely on any metin2 specific functions.

 

regarding to the comment of the code, 

yes its not practical, but there are more then enough servers with no anticheat,

where a bad solution is better then none.

 

Edited by Metin2 Dev
Core X - External 2 Internal
  • Metin2 Dev 1

🍆 Sura-Head 💯

Link to comment
Share on other sites

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.