gpt4 book ai didi

python - 使用 Python 将击键发送到 Windows 中的游戏?

转载 作者:太空狗 更新时间:2023-10-29 18:08:14 25 4
gpt4 key购买 nike

我一直在 Windows 环境中使用 Python,我编写了一个脚本来自动执行已知游戏中的某些任务。该任务涉及大量使用鼠标和键盘输入。

然而,上述脚本只有一个问题:它无法向应用程序发送击键。我已经尝试了至少 3 种不同的方法,我将在下面发布这些方法和一些变体(也阅读了十分之一的类似问题/答案,但无济于事)

第一个,使用win32api模块:

f = 0x46 # VirtualKey Code of the letter "F", see http://msdn.microsoft.com/en-us/library/windows/desktop/dd375731%28v=vs.85%29.aspx 

win32api.keybd_event(f,0,0,0) # holds the "F" key down
time.sleep(2) # waits 2 seconds
win32api.keybd_event(f,0,win32con.KEYEVENTF_KEYUP,0) # releases the key

它没有什么特别之处,在任何文本编辑器、浏览器中都能完美运行(输入“f”)...但是,如果我打开一个游戏,比如反恐精英,那么击键就会“丢失”-就像,没有任何反应。另一方面,如果我打开 Counter-Strike 的控制台,则击键得到注册(就像在记事本中一样)。在另一款游戏《英雄联盟》中测试,行为完全相同。在实际游戏中,没有检测到击键。但是,如果我打开聊天(仍在游戏中)并重新运行脚本,那么它就会被聊天注册。

进入第二种方法:

shell = win32com.client.Dispatch("WScript.Shell")
shell.SendKeys("F")

与上面的行为完全相同。在游戏以外的所有地方都可以正常工作,而且它只在聊天中有效。

第三种方法(归功于在另一个 stackoverflow 线程中发布它的人),使用 ctypes 模块更高级(调用 SendInput())。理论上,在这三个中,这个最接近模拟实际的物理按键:

SendInput = ctypes.windll.user32.SendInput

# C struct redefinitions
PUL = ctypes.POINTER(ctypes.c_ulong)
class KeyBdInput(ctypes.Structure):
_fields_ = [("wVk", ctypes.c_ushort),
("wScan", ctypes.c_ushort),
("dwFlags", ctypes.c_ulong),
("time", ctypes.c_ulong),
("dwExtraInfo", PUL)]

class HardwareInput(ctypes.Structure):
_fields_ = [("uMsg", ctypes.c_ulong),
("wParamL", ctypes.c_short),
("wParamH", ctypes.c_ushort)]

class MouseInput(ctypes.Structure):
_fields_ = [("dx", ctypes.c_long),
("dy", ctypes.c_long),
("mouseData", ctypes.c_ulong),
("dwFlags", ctypes.c_ulong),
("time",ctypes.c_ulong),
("dwExtraInfo", PUL)]

class Input_I(ctypes.Union):
_fields_ = [("ki", KeyBdInput),
("mi", MouseInput),
("hi", HardwareInput)]

class Input(ctypes.Structure):
_fields_ = [("type", ctypes.c_ulong),
("ii", Input_I)]

# Actuals Functions

def PressKey(hexKeyCode):

extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))

def ReleaseKey(hexKeyCode):

extra = ctypes.c_ulong(0)
ii_ = Input_I()
ii_.ki = KeyBdInput( hexKeyCode, 0x48, 0x0002, 0, ctypes.pointer(extra) )
x = Input( ctypes.c_ulong(1), ii_ )
ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x))


def KeyPress():
PressKey(0x46) # press F
time.sleep(.5)
ReleaseKey(0x46) #release F

...它也不起作用。奇怪的是,它显示出与前三个完全相同的行为:在任何文本编辑器/简单应用程序中工作,被游戏忽略或仅在游戏聊天部分注册。

如果我猜的话,我会说这些游戏正在以其他方式获取键盘事件,而这 3 种方法中的任何一种我都没有涉及,因此忽略这些方法。

如果有任何帮助,我将不胜感激。如果可能,请提供在 CS、英雄联盟或类似游戏中运行的代码的具体示例,以便我有一个起点。

最佳答案

您的游戏可能使用 DirectInput。使用这些方法之一尝试 DirectInput 扫描码。快速谷歌搜索给出了这个网站:http://www.gamespp.com/directx/directInputKeyboardScanCodes.html

关于python - 使用 Python 将击键发送到 Windows 中的游戏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23024525/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com