MadCat
MadCat

Reputation: 119

Python - Pynput key press seems to not be the same as an actual key press

I am trying to code a very simple afk-farm-bot for a game. All it needs to do is pressing Space two times every few seconds. This works in writing software, such as the normal text editor, but it doesn't work in the game. There has to be a difference between pynput keyboard presses and normal ones, and I need to know what that difference is, in order to make my code work. Can you help me?

Here is the entire code I am using:

from pynput.keyboard import Key, Controller
import time
import random


keyboard = Controller()

print("NosTale-Bot started. Please Insert specifications:")
idelay = int(input("Initial Delay (ins sec): "))
tickGap = float(input("Tick Gap (in sec): "))
tickDivergence = float(input("Tick Divergence (in sec): "))
maxDuration = float(input("Max Duration (in min): "))

print("You have " + str(idelay) + " seconds to switch to NosTale.")
time.sleep(idelay)
sTime = time.time()
wTime = time.time()
rDivergence = -tickGap
tCounter = 0
while True:
    cTime = time.time() - wTime
    if (cTime >= tickGap + rDivergence):
        tCounter += 1
        print("Tick " + str(tCounter) + ": " + str(time.time() - sTime))
        keyboard.press(Key.space)
        keyboard.release(Key.space)
        time.sleep(0.05)
        keyboard.press(Key.space)
        keyboard.release(Key.space)
        rDivergence = (random.random()*tickDivergence*2-tickDivergence)
        wTime = time.time()

    if (time.time() - sTime >= maxDuration*60):
        break

Upvotes: 0

Views: 1374

Answers (2)

crazy_dave
crazy_dave

Reputation: 11

Yes, it's different. It seems that pynput uses keybd_event function to generate a WM_KEYUP or WM_KEYDOWN message.

The keyboard input can come from the local keyboard driver or from calls to the keybd_event function. If the input comes from a call to keybd_event, the input was "injected".

When a keyboard hook is set, the system callback will return a KBDLLHOOKSTRUCT structure. The 4th bit of the 'flag' field : Specifies whether the event was injected. The value is 1 if that is the case; otherwise, it is 0. Note that bit 1 is not necessarily set when bit 4 is set.

The listener of the pynput itself can catch the difference. With the win32_event_filter callback:

def win32_event_filter(msg, data):
if data.flags & 0x10:
    return False
return True

with Listener(
    on_press=on_press,
    on_release=on_release,
    win32_event_filter = win32_event_filter) as listener:
listener.join()

With win_32_event_filter callback, the pynput can distinguish the key events generated by its controller from the key events generated by a true keyboard, then the listener can shield them. Games can do the same things, of course.

Upvotes: 1

jizhihaoSAMA
jizhihaoSAMA

Reputation: 12672

Unfortunately,pynput module couldn't do its work in most game.It uses a junior listener thread.It seems it couldn't work in most game.

So to handle this problem,you can use AutoHotKey(A very useful tool,and easy to learn) to do that.My pynput script couldn't run in Overwatch.So I used to use AutoHotKey to control Overwatch successfully.

Upvotes: 0

Related Questions