2013-01-23 32 views
17

को नियंत्रित करने के लिए पाइथन कीप्रेस को अनुकरण करें, मैं अपने किनेक्ट और पायथन का उपयोग करके एक गेम (मेरे दो टेस्ट गेम हाफ लाइफ 2 और माइनक्राफ्ट) को नियंत्रित करने की कोशिश कर रहा हूं। सब कुछ एक चीज़ को छोड़कर काम करता है। गेम नकली माउस घटनाओं और अनुरूपित माउस आंदोलन का जवाब देगा (माउस घटनाओं को ctypes के माध्यम से किया जाता है और माउस आंदोलन pywin32 का उपयोग करके किया जाता है)। समस्या यह है कि गेम नकली कीप्रेस को अनदेखा करते हैं। वे दोनों चैट विंडो (माइनक्राफ्ट) या डेवलपर कंसोल (हाफ लाइफ 2) में नकली कीप्रेस को उठाएंगे, लेकिन वास्तविक गेम खेलने के दौरान नहीं।गेम

import win32com.client as client 
wsh = client.Dispatch('WScript.Shell') 
wsh.AppActivate(gameName) 
wsh.SendKeys(key) 

और:

import win32api 
win32api.keybd_event(keyHexCode, 0, 0) 

और:

import ctypes 
import time 

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)) 

मैं पिछले एक में कोड का कहना चाहिए

मैं keypresses भेजने के कई तरीके की कोशिश की है मेरा नहीं है, यह स्टैक ओवरफ्लो पर एक और सवाल है।

क्या कोई जानता है कि इनमें से कोई भी काम क्यों नहीं है और यह करने का सही तरीका क्या है?

+1

एक उचित प्रतिक्रिया के एवज में, मैं Minecraft के स्रोत की जाँच का सुझाव दे सकता अगर वहाँ कैसे कुंजीपटल घटनाओं को इकट्ठा किया और नियंत्रित किया जाता है में एक फर्क है को देखने के लिए चैट और गेमप्ले के बीच? जब मैं घर जाता हूं तो मैं खुद इसे देखने जा रहा हूं। – Logan

+0

मुझे इसके बारे में अपने पहले के बयान को वापस लेना होगा, वास्तव में माइनक्राफ्ट पर काम नहीं कर रहा है, सीटीपीएस सिस्टम के साथ। मैं अब आधा जीवन 2 की जांच करूंगा ... – user573949

+0

हाँ यह अभी भी काम नहीं कर रहा है। – user573949

उत्तर

3

यह संभावना है कि गेम DirectInput डिवाइस का उपयोग कर रहा है।

तो, गेम डायरेक्ट इनपुट कुंजी प्रेस की अपेक्षा कर रहा है। this forum thread की अंतिम पोस्ट के अनुसार, डायरेक्ट इनपुट स्कैनकोड का जवाब देता है, वीके नहीं। आप this tool का उपयोग कर डायरेक्ट इनपुट कुंजी प्रेस भेजने का प्रयास कर सकते हैं। देव स्रोत और विस्तृत स्पष्टीकरण भी प्रदान करता है।

यदि यह काम करता है, तो आप केवल वीके (list of scancodes) के बजाय उपयुक्त स्कैनकोड भेजने का प्रयास कर सकते हैं।

DirectPython नामक एक पुरानी परियोजना भी है जो आपको DirectX/DirectInput के साथ इंटरफ़ेस करने की अनुमति देती है।

+0

कि उपकरण के लिए डाउनलोड लिंक है: मैं अगर खेल does not को उच्च प्राथमिकता दी जाती है तो आपरेशन प्रणाली है और खेल, अपने आप ही प्रोसेसर के साथ संवाद कारण ऐसा आपरेशन प्रणाली does not यहां तक ​​कि कुछ कीबोर्ड इनपुट के बारे में पता लगता है सोच रहा हूँ मृत, क्या आप जानते हैं कि डायरेक्टपिपन के साथ वास्तव में डायरेक्ट इनपुट कुंजीपटल कैसे भेजना है? यह केवल उनके लिए सुनने के लिए स्थापित किया जाता है, उन्हें प्रेषित नहीं करता है। – user573949

19

मुझे अभी भी हाफ-लाइफ 2 में कीप्रेस को अनुकरण करने की कोशिश करने में एक ही समस्या थी। रॉबिन ने कहा, समाधान वीके के बजाय स्कैनकोड का उपयोग करना है।

मैंने अपना अंतिम कोड उदाहरण संपादित किया है जैसे कि यह स्कैनकोड का उपयोग करता है। मैं हाफ लाइफ 2 के साथ यह कोशिश की और यह सिर्फ ठीक काम करता है:

import ctypes 
import time 

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(0, hexKeyCode, 0x0008, 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(0, hexKeyCode, 0x0008 | 0x0002, 0, ctypes.pointer(extra)) 
    x = Input(ctypes.c_ulong(1), ii_) 
    ctypes.windll.user32.SendInput(1, ctypes.pointer(x), ctypes.sizeof(x)) 

# directx scan codes http://www.gamespp.com/directx/directInputKeyboardScanCodes.html 
while (True): 
    PressKey(0x11) 
    time.sleep(1) 
    ReleaseKey(0x11) 
    time.sleep(1)