Search code examples
pythonpyautoguirobloxpynput

Pydirectinput/Pynput/Pyautogui don't always press keys


So, I've been trying to make a macro for a game on Roblox and sometimes the inputs don't actually work? Why does this happen? I've tried this in pydirectinput, pynput and pyautogui, but they all don't work. I've been trying to do this for the past few hours and I would really love for somebody to help me out!

Here is my code (for pydirectinput):

import pydirectinput, threading, time, sys, os

# os._exit(404)

def press_key(key):
    pydirectinput.press(key)

def hold_key(key, s):
    pydirectinput.keyDown(key)
    time.sleep(s)
    pydirectinput.keyUp(key)

w = "w"
a = "a"
s = "s"
d = "d"
period = "."
comma =  ","

# def reset():
#     press_key("esc")
#     time.sleep(.1)
#     press_key(KeyCode(char="r"))
#     time.sleep(.1)
#     press_key(Key.enter)
#     time.sleep(.1)

def start():
    press_key(period)
    time.sleep(.1)
    press_key(period)
    hold_key(w, 2)
    time.sleep(1)
    press_key("space")
    time.sleep(.1)
    hold_key(w, 2)
    time.sleep(.5)
    press_key(comma)
    time.sleep(.1)
    press_key(comma)
    time.sleep(.3)
    hold_key(w, 1)
    time.sleep(.2)
    press_key(period)
    time.sleep(.1)
    press_key(period)
    time.sleep(.3)
    hold_key(w, .5)
    time.sleep(.3)
    press_key(period)
    time.sleep(.1)
    press_key(period)
    time.sleep(.2)
    hold_key(w, .3)
    time.sleep(.1)
    press_key("e")

def loop():
    print("loop")
    # while True:
    #     hold_key(w, 1)
    #     hold_key(a, 1)
    #     hold_key(s, 1)
    #     hold_key(d, 1)

time.sleep(2)
threading.Thread(target=start()).start()
time.sleep(2)
threading.Thread(target=loop).start()

Solution

  • I realize that this was posted 4 months ago with no answers, but here goes in case anyone finds your question if you haven't already found the answer and did not update your question. For most Games you need to past scan-codes or send inputs directly to the kernel as DirectX is a different API. Pyautogui won't work for some of it's input methods for DirectX games. FFXIV for example you can press keys from pyautogui but can't use Mouse movements from that library. Also some games like Maplestory for example completely ignores key strokes that's not coming from hardware API aka Kernel. And games with an anticheat software also block this. However, pydirectinput fixes this as it replaces pyautogui's win32 API method with Scan-Codes which is the same-ish as the OnScreen Keyboard. Just need to make sure you open the script as Administrator, if you run your script with an IDE open that as admin.

    Only thing I see wrong is with Threading:

    threading.Thread(target=start()).start()
    

    The problem with the Thread function in threading is that you can't pass arguments to it like normal in simple terms. You have to separate the arguments to it's "required" parameters. So as it is now it won't work. Because the start() function doesn't have any parameters. it's as simple as removing the bracket parenthesis for threading.

    threading.Thread(target=start).start()
    

    *Lets take the hold_key() function as an example: Hold 'w' key for 5 seconds

    threading.Thread(target=hold_key, args=('w', 5)).start()