im trying to make a macro for this game i play on roblox
i tried some different modules for listening for inputs and simulating them
pynput worked great but i wanted to make it more effecient
i tried using keyboard and mouse modules, but sometimes they just,,, wouldnt work and i really dont understand why
so im trying now to use ctypes idrk what im doing so its easier to just show the code
if you run the code you would think it works perfectly... the keys are spammed and stuff just as you would expect, but in the game the keypresses just wont register. like in a browser if i run the macro i can see the keys are being pressed like it will type them, but it just wont pick them up on the roblox game lol, but it will type them in the roblox chatbox.
i really dont know what im doing sorry if the code is a mess, ive never shown my code to anyone before so idk whats going on
import ctypes
import sys
import time
from threading import Thread
class Macro:
def __init__(self, keys):
self.keys = keys
self.user32 = ctypes.windll.user32
self.VK_CODES = {
'esc': 0x1B, # ESC key
'f': 0x46, # F key
'c': 0x43, # C key
'r': 0x52, # R key
'v': 0x56, # V key
'g': 0x47, # G key
'1': 0x31, # 1 key
'2': 0x32, # 2 key
'end': 0x23, # END key
'home': 0x24, # HOME key
}
self.spam_thread = None
self.switch_thread = None
def click(self):
self.user32.mouse_event(0x02, 0, 0, 0, 0) # Mouse down
time.sleep(0.001) # Small delay between press and release
self.user32.mouse_event(0x04, 0, 0, 0, 0) # Mouse up
def press_and_release(self, key):
key = self.VK_CODES[key]
self.user32.keybd_event(key, 0, 0, 0) # key press
time.sleep(0.001) # Small delay between press and release
self.user32.keybd_event(key, 0, 0x02, 0) # key release
def spam(self):
try:
while True:
self.click()
for key in self.keys:
self.press_and_release(key)
time.sleep(0.1)
except SystemExit:
pass
def switch(self):
try:
while True:
time.sleep(0.3)
self.press_and_release("2")
time.sleep(0.3)
self.press_and_release("1")
except SystemExit:
pass
def toggle(self):
if self.spam_thread is None and self.switch_thread is None:
self.spam_thread = Thread(target=self.spam, daemon=True)
self.spam_thread.start()
self.switch_thread = Thread(target=self.switch, daemon=True)
self.switch_thread.start()
print("threads started!")
else:
ctypes.pythonapi.PyThreadState_SetAsyncExc(self.spam_thread.ident, ctypes.py_object(SystemExit))
self.spam_thread = None
ctypes.pythonapi.PyThreadState_SetAsyncExc(self.switch_thread.ident, ctypes.py_object(SystemExit))
self.switch_thread = None
print("threads closed!")
def add_listener(self, key, func, wait=False):
key = self.VK_CODES[key]
def wrapper():
while True:
if self.user32.GetAsyncKeyState(key) & 0x8000 != 0:
func()
while self.user32.GetAsyncKeyState(key) & 0x8000 != 0:
time.sleep(0.001)
time.sleep(0.001)
thread = Thread(target=wrapper, daemon=True)
thread.start()
if wait:
thread.join()
def listener(self):
self.add_listener("end", self.toggle)
self.add_listener("esc", sys.exit, wait=True)
def start(self):
print(sys.argv[0])
self.listener()
def main():
macro = Macro("frcv")
macro.start()
if __name__ == '__main__':
main()

