Fonctionnement de la souris à l'aide de l'API Windows en Python

Déclencheur

Quand j'ai regardé une vidéo présentant la macro anti-recul d'un certain jeu FPS sur Twitter à la fin de l'année dernière, j'ai pensé qu'un ajustement régulier de la macro serait difficile ~~ C'était proche d'un outil frauduleux, mais en même temps c'était réglé à l'avance. Je me demandais si je pouvais faire quelque chose d'intéressant si je pouvais effectuer les mouvements du jeu.

essai et erreur

En Python, il existe des bibliothèques telles que PyAutoGUI et pynput qui font fonctionner la souris et le clavier, et vous pouvez facilement les utiliser et les automatiser en les utilisant. Cependant, le jeu auquel je jouais n'acceptait aucune opération. DirectX est-il impliqué? Après diverses recherches, j'ai trouvé un substitut appelé Serpent.AI qui permet à AI de jouer à des jeux. Serpent.AI semble utiliser le jeu avec l'API Win32, et le jeu auquel je joue pourrait fonctionner avec l'API Win32.

environnement

Ecrire le code

Il existe deux façons d'utiliser la souris avec l'API Win32.

  1. Utilisez SetCursorPos
  2. Utilisez SendInput

1. Utilisez SetCursorPos

Utilisez les ctypes de bibliothèque standard pour appeler l'API Win32 à partir de Python.

input_1.py


import ctypes

#SetCursorPos(x, y)
ctypes.windll.user32.SetCursorPos(200, 300)

Spécifiez simplement avec x, y (horizontal, vertical). La valeur de (0,0) augmente vers le coin inférieur droit en haut à gauche de l'écran. Ce code déplace le curseur sur x: 200 y: 300. Cependant, SetCursorPos ne peut pas faire fonctionner le jeu.

2. Utilisez SendInput

Vous pouvez déplacer, cliquer et saisir le curseur de la souris. Voir ici pour plus de détails sur son utilisation. Le code est [this](https://github.com/SerpentAI/SerpentAI/blob/b8eec1032c5b1134125fd1124387a3cd9f253d5f/serpent/input_controllers/native_win32_input_controller.py/fr/input_controller.py/serpent/input_controllers/native_win32_input_controller. -union-in-python-to-send-keyboard-events-in-windows) a été utilisé comme référence.

Déclarez la structure INPUT requise pour SendInput et la structure MOUSEINPUT qui contient des informations sur les opérations de la souris.

input_2.py


import ctypes

ULONG_PTR = ctypes.POINTER(ctypes.c_ulong)

#Informations sur les événements de la souris
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", ULONG_PTR)]


class INPUT(ctypes.Structure):
    _fields_ = [("type", ctypes.c_ulong),
                ("mi", MOUSEINPUT)]

Spécifie l'argument SendInput et le type de retour.

input_2.py


LPINPUT = ctypes.POINTER(INPUT)

SendInput = ctypes.windll.user32.SendInput
SendInput.argtypes = (ctypes.c_uint, LPINPUT, ctypes.c_int)
SendInput.restype = ctypes.c_uint

Si vous convertissez les coordonnées et plongez dans SendInput, le curseur de la souris se déplacera.

input_2.py


x, y = 200, 300
x = x * 65536 // 1920
y = y * 65536 // 1080
_mi = MOUSEINPUT(x, y, 0, (0x0001 | 0x8000), 0, None)
SendInput(1, INPUT(0, _mi), ctypes.sizeof(INPUT))

L'explication détaillée sera longue, Dans ces deux lignes, les coordonnées du curseur (200 300) sont converties en coordonnées de 0 à 65 535 (6826,18204). Le diviseur change en fonction de la résolution de l'écran. La division est arrondie vers le bas, mais je m'en fiche car ce n'est pas très différent de l'arrondissement. Comme cela sera décrit plus loin, il n'est nécessaire que pour le mouvement en coordonnées absolues.

input_2.py


x = x * 65536 // 1920 # x * 65536 //Résolution d'écran(côté)
y = y * 65536 // 1080 # y * 65536 //Résolution d'écran(Verticale)

La quantité de rotation de la roue est de 120, ce qui correspond à un cran d'une souris standard. Il n'y a aucun problème avec les entiers autres que les multiples de 120. Vous pouvez également faire défiler horizontalement. Plusieurs événements de souris peuvent être définis avec l'opérateur «|» de l'opérateur bit. J'ai résumé les éléments fréquemment utilisés dans le tableau. Cliquez ici pour plus de détails (https://docs.microsoft.com/ja-jp/windows/win32/api/winuser/ns-winuser-mouseinput)

valeur sens
0x8000 Utiliser des coordonnées absolues, des coordonnées relatives si non spécifiées
0x0001 Déplacer le curseur
0x0002 Appuyez sur le bouton gauche
0x0004 Relâchez le bouton gauche
0x0008 Appuyez sur le bouton droit
0x0010 Relâchez le bouton droit
0x01000 Défilement horizontal ou non
0x0800 Défilement vertical ou non

Une chose à noter ici. Le format des coordonnées change selon que vous utilisez des coordonnées absolues ou relatives. Lors de l'utilisation de coordonnées absolues, il est nécessaire de convertir en coordonnées de 0 à 65 535, mais lors de l'utilisation de coordonnées relatives, la conversion des coordonnées n'est pas nécessaire. Dans ce cas, il reste (200 300).

input_2.py


# MOUSEINPUT(coordonnée x,coordonnée y,Quantité de rotation de roue,Événement souris, 0, None)
_mi = MOUSEINPUT(x, y, 0, (0x0001 | 0x8000), 0, None)

Il existe trois types d'entrées, comme indiqué dans le tableau ci-dessous.

valeur sens
0 Entrée souris
1 La saisie au clavier
2 Entrée matérielle

input_2.py


# SendInput(1, INPUT(Type d'entrée, _mi), ctypes.sizeof(INPUT))
SendInput(1, INPUT(0, _mi), ctypes.sizeof(INPUT))

Résumé

Dans SendInput, vous pouvez utiliser le clavier en plus du fonctionnement de la souris, mais par souci de simplicité, nous nous sommes concentrés sur le fonctionnement de la souris. La prochaine fois, je vais l'expliquer, y compris le fonctionnement du clavier.

finalement

Je ne pense pas que ce soit pertinent pour quiconque lit cet article, mais le programme lui-même a été achevé il y a longtemps. Quand j'écrivais le programme, je ne pensais pas profondément à Yoshi si je déménageais, donc quand je l'ai regardé plus tard, c'était censé être Tondemonai. J'ai mis un commentaire. Alors, tout en organisant, j'ai écrit un article sur les principaux points du programme. Si vous écrivez un article comme celui-ci, vous ne l'oublierez pas.

Recommended Posts

Fonctionnement de la souris à l'aide de l'API Windows en Python
Essayez d'utiliser l'API Wunderlist en Python
Essayez d'utiliser l'API Kraken avec Python
Utilisation de venv dans un environnement Windows + Docker [Python]
Tweet à l'aide de l'API Twitter en Python
[Python] [Windows] Communication série en Python à l'aide de DLL
Obtenez des données Youtube en Python à l'aide de l'API Youtube Data
API Evernote en Python
API C en Python 3
Essayez d'utiliser l'API BitFlyer Ligntning en Python
Obtenir l'URL de l'image à l'aide de l'API Flickr en Python
Jugons les émotions à l'aide de l'API Emotion en Python
Essayez d'utiliser l'API ChatWork et l'API Qiita en Python
Essayez d'utiliser l'API DropBox Core avec Python
Hit API de Mastodon en Python
Importez un fichier JPG à l'aide de l'API Google Drive en Python
Paramètres initiaux lors de l'utilisation de l'API foursquare avec python
Obtenez des données LEAD à l'aide de l'API REST de Marketo en Python
OpenVINO utilisant l'API Python d'Inference Engine dans un environnement PC
API Blender Python dans Houdini (Python 3)
Utiliser l'API de recherche de la Bibliothèque du Parlement national en Python
Installation de Python en 2 lignes @Windows
Traduit à l'aide de googletrans en Python
Utilisation du mode Python dans le traitement
Prédire le sexe à partir du nom à l'aide de l'API Gender et de Pykakasi en Python
[Python] Afficher plusieurs fenêtres avec Tkinter
Programmation GUI en Python avec Appjar
Obtenir l'API arXiv en Python
Précautions lors de l'utilisation de Pit avec Python
Appuyez sur une commande en Python (Windows)
Acquisition de données à l'aide de l'API googlemap de python
Mettez MeCab dans "Windows 10; Python3.5 (64 bits)"
Frappez l'API Sesami en Python
[Python3] Google translate google translation sans utiliser l'API
Essayez d'utiliser l'API de Pleasant (python / FastAPI)
Essayez d'utiliser LevelDB avec Python (plyvel)
Windows10: Installation de la bibliothèque MeCab pour python
Créez Gmail en Python sans utiliser l'API
Utilisation de variables globales dans les fonctions python
Accédez à l'API Web en Python
Voyons voir l'utilisation de l'entrée en python
Puissance totale en Python (en utilisant functools)
Essayez d'utiliser l'API d'action de Python argparse
Implémentez rapidement l'API REST en Python
Exécutez Ansible à partir de Python à l'aide de l'API
Reconnaissance de caractères manuscrits à l'aide de KNN en Python
Accéder à l'API Twitter avec Python
Essayez d'utiliser LeapMotion avec Python
Recherche de priorité de profondeur à l'aide de la pile en Python
[Python] Opération de fichier utilisant l'instruction if
Lors de l'utilisation d'expressions régulières en Python
Création d'interface graphique en python avec tkinter 2
[SEO] Flux / exemple de code lors de l'utilisation de l'API Google Analytics en Python
Remarques sur l'utilisation d'OpenCV avec Windows10 Python 3.8.3.
Notes utilisant cChardet et python3-chardet dans Python 3.3.1.
Création d'interface graphique en python à l'aide de tkinter partie 1
Obtenir l'équilibre Suica en Python (en utilisant libpafe)
Pratique d'utilisation de ceci en Python (mauvais)
Hachez lentement les mots de passe en utilisant bcrypt en Python