2009-06-27 6 views
1

Je suis en train de développer une interface pour un add-on à un jeu. Je ne peux pas utiliser l'API du jeu (pour plusieurs raisons notamment le fait que le code doit être agnostique) et j'ai besoin d'une saisie au clavier de l'utilisateur. J'ai donc décidé d'utiliser un hook clavier (WH_KEYBOARD) pour traiter l'utilisateur entrée lorsque certaines conditions sont remplies.
Le problème est que si je peux recevoir et traiter l'entrée correctement, quand mon hook retourne TRUE au lieu de CallNextHookEx le système semble prendre beaucoup de temps (bien plus de 800ms) avant de laisser les choses se dérouler comme prévu et ce n'est pas acceptable car cela ne permet même pas une expérience de typage fluide. Ce que je dois faire est d'empêcher le message de la presse d'atteindre le WndProc, alors la question est: que puis-je faire pour atteindre ma cible sans nuire autant aux performances du jeu que le résultat sera inacceptable? En raison de conditions spécifiques (jeux utilisant des antichocs qui pourraient créer des problèmes avec mon code malgré qu'il ne soit pas lié à la tricherie) le sous-classement du wndproc actif n'est pas une option.KeyboardProc retourne TRUE provoque des baisses de performance

Répondre

0

Autant je n'aime pas répondre à ma propre question, j'ai trouvé la cause du retard. La pompe de messages des jeux avec lesquels j'ai testé mon code a été implémentée avec un certain temps (PeekMessage) {GetMessage ...} et la suppression du message d'entrée au clavier a bloqué GetMessage pour un certain temps. L'utilisation de PostMessage et de WM_NULL a permis d'empêcher le blocage de GetMessage.

2
  1. Vous devez d'abord votre DLL à injecter dans le processus cible, soit par des crochets, soit par any other way.

  2. Trouvez la poignée de fenêtre qui vous intéresse. Obtenez la procédure de fenêtre en cours de cette fenêtre en appelant GetWindowLongPtr (wnd, GWLP_WNDPROC) et enregistrez-le.

  3. Sous-classez la fenêtre en appelant SetWindowLongPtr (wnd, GWLP_WNDPROC, & NewWndProc) où NewWndProc est votre procédure de message implémentée par DLL.

intérieur NewWndProc vous voulez traiter les messages du clavier (il sont une douzaine d'entre eux, le type « d'entrée du clavier » dans l'index MSDN, je ne peux pas poster plus de 1 lien). Pour le reste des messages Windows, appelez la procédure de fenêtre d'origine que vous avez enregistrée pendant (3) et renvoyez la valeur renvoyée. Ne l'appelez pas directement, utilisez plutôt CallWindowProc. De cette façon, ce n'est pas très fiable, certains logiciels antivirus et anti-bot (par exemple, le client "warden") peuvent ne pas l'aimer, et le débogage peut être difficile.

Cependant, cela devrait fonctionner.

+0

Merci pour votre suggestion intelligente, mais comme vous l'avez souligné anticheats ne vont pas aimer cela et bien que je ne le fais pas à des fins de tricherie, je ne peux pas vraiment se permettre de déclencher des faux positifs. La bonne partie de l'accrochage au clavier est que les anticheats ne le signaleront pas car de nombreux programmes l'utilisent à des fins légitimes ... – em70

+0

Windows sous-classe est également utilisé par de nombreux programmes à des fins légitimes. – Soonts

0

Un crochet de clavier ne devrait pas ralentir. Il y a probablement quelque chose d'autre qui cause le retard de 800ms. Est-il encore lent si votre crochet ne fait rien et retourne simplement VRAI?

+0

Oui, juste retourner TRUE est suffisant pour provoquer le ralentissement en retournant FALSE même si je traite l'événement clavier n'a aucun impact sur les performances (mais ce n'est pas correct pour moi car les touches que je manipule ne devraient pas être traitées par le jeu). Je l'ai testé sur deux jeux différents avec des moteurs différents et les résultats sont les mêmes. – em70

0

Si vous voulez empêcher le message d'arriver à WndProc, vous devez sous-classer en utilisant SetWindowLong, de cette façon, vous serez en mesure d'attraper tous les messages et de décider si continuer leur route.

+0

Merci, mais comme indiqué ci-dessus, le sous-classement n'est pas une option. – em70