I've recently realized that Python's pynput module's key click doesn't get registered in certain software. However, physical key clicks work perfectly fine. This raises the question of how are the two different methods been recognized. I thought this would've been an answered question from a long time ago but I can't seem to find any post about this.
Let's take a random game such as Genshin for example. The "w" key on the keyboard would result in the character in the game moving forward. However, a program such as the following that "holds" down the "w" key doesn't get registered by the game.
from pynput.keyboard import Key, Controller
keyboard = Controller()
while True:
keyboard.press("w")
keyboard.release("w")
The two big questions that I have are:
What is the difference between physical key clicks and the program generate key clicks that allowed these softwares to distinguish which method is used?
Based on the answer to the first question, is there a way to bypass such a difference without tempering with the software's code (aka disguise program generated key clicks as physical key clicks)?
Thanks in advance!
Edit: If anyone has any idea on how this works, please let me know. Any help would be much appreciated!
I also encountered this problem when I was trying to write a small program to help myself in Genshin. After an excruciating search, I found these two questions: question1, question2
I'm not very sure how it exactly works, so I can only give you my conclusion: When we run Genshin, we give it admin rights. Programs without admin rights sort of can't interact with it.
To solve this problem, you can merge this into your code:
import ctypes, sys
def is_admin():
try:
return ctypes.windll.shell32.IsUserAnAdmin()
except:
return False
if is_admin():
# Code of your program here
else:
# Re-run the program with admin rights
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, " ".join(sys.argv), None, 1)
Then you need to make the code an executable with pyinstaller module. When you execute it, it will re-run and ask you for admin rights, then it can do its job on Genshin or other program.
There are certainly games that intentionally try to prevent the kind of cheating you're trying to do. How they do so depends on the operating system.
pynput on Windows, for example, uses the send_input API to inject keystrokes into the input system, but a sufficiently motivated application could be reading at a lower level, by using a keyboard filter driver to pull keystrokes before they get into the input system.
With such a design, there's nothing you can do in user mode to cheat the keys. You would need your own kernel driver, and even then it's not trivial to guarantee the order that the filters load.
Related
I see a lot of answers to this question online, but the only solution I have found uses the msvcrt module that (as I understand it) is only available for Windows.
I am making a simple python console game and I want to stop the user from typing anything while the application is loading or playing a simple animation as it tends to break the program.
Example:
import time
#disable input here
print('hi')
time.sleep(3)
print('3 seconds have gone by')
#enable input
I don't want to let the user roll their face over the keyboard and make everything messy and ugly. I know mac is very strict about this kind of stuff, is it even possible?
From the solution you linked I can see that you are only needing the msvcrt.getwch() function, so you could use the one from the getch module i.e. getch.getch().
I am writing long running program with simple GUI, the 99% of time I would like the program to work only as process, however sometimes I want to check the status, so is it possible to capture the keypress event in python?
For example I want to show the program window when I press Ctrl+Shift+Alt+Q, I expect to use app on Windows
Thank you
There are tutorials on how to create a key-logger with Python. They should help. But I do not know if that is the right way to go.
Also you could register shortcuts under a key combination on Windows.
You should be aware that Ctrl+Shift+Alt are handled independent of the keyboard layout and Q changes with the language.
With pywin32 you should be able to do that using Ctrl+Shift+Alt+F1 for example.
I have a tkinter program written in python 3.3.3. I see myself in the need of making the the program get focus when the user unlocks the computer. I don't really know how to go ahead and start with this, users have a .exe version of the program that I created with cxfreeze. I f i need to modify the .py and create another .exe, that wouldn't be a problem.
After some research I found that one can use the ctypes module to lock the computer, but it's not very helpful because i need to know if it is locked or unlocked. I also saw commands from win32com, but i can't seem to be able to find a way to trigger a command when it gets unlocked.
What is the best way to get focus on my program after the computer is unlocked??
Any help is greatly appreciated.
I cannot answer this specifically for 'unlock' event (if there even is one in the GUI; I can't find one by cursory search.).
But I think the real answer is to change the question. Having a program simply take focus when user unlocks the display is very un-Windows-ish behavior. The Windows user expects to see the desktop just as s/he left it before the display was locked -- why does s/he want to see your program on top when unlocking, regardless of why Windows might have locked the display?
Maybe you want to recast your program as something that runs in the background and pops up a notification (in the notification area on the right side of toolbar) when it wants user to do something?
I'm writing a text based RPG, and I am using Python 3.3.4. It will be played through the Python command line, with no graphics. I'm wanting to make it so that no matter what options the user is presented with, they have the capability of typing "exit" or "help" and exiting (or getting help information) respectively at any time during the game. So if they're in the middle of fighting some monster and the only options presented to them directly would be to attack, defend, or flee, they're still able to exit or get help. Same for once they leave that function and they're just moving around the map, or talking to NPCs. From what I've found, starting a thread that waits for "exit" to be entered is the best way to do that. If I'm wrong, please let me know! If not, please explain (or show me a guide) how I'm supposed to go about this because none of my ideas have worked.
I've attempted using the threading module, and _thread. I may not have implemented them correctly, and I have no code to show for my attempts as I just trashed it when it didn't work.
Thank you in advance.
Your game doesn't have to do any work in the background, so you do not need to spawn any additional threads. The main loop of your program will listen for user input, perform the action, and then prompt the user for their next action. It should look something like this:
while True:
input = get_user_input()
if input == 'exit':
break
next_actions = modify_game_state(input)
print "You can now do: %s" % next_actions
Edit: You should not have more than one thread accept user input. It's possible for one of the threads to gobble information that was intended for the other, so no matter what solution you decide on, don't add a thread that just checks if the user input was "exit", unless it reads all of the user input.
Looking back at this, I feel like an absolute idiot.
The proper way to handle this would be calling a function that accepts input and checks it against different expected strings or numerical values.
I just thought I'd answer this in a little more clear way than Stu did.
I am thinking of writing a python program that runs in the background and can inspect user's GUI events.
My requirements is very simple:
1) When user right click the mouse, it can show an option; and when this option is chosen, my program should know this event.
2) When user select a file and click some predefined key combination, my program should know this event.
What should I do? Is this a GUI program? I am also thinking that, this program maybe a daemon on the machine and can inspect the user's GUI event, but I am not sure how can I do this.
Thanks.
If you're talking about doing this stuff inside of a wxPython program, then it's all pretty simple. There's a PopupMenu widget for the first one and an AcceratorTable for the second one. If you're wanting to catch mouse and keyboard events outside of a wxPython program, then you have to go very low-level and hook into the OS itself, which means that there really isn't any good way to do it cross-platform. You'll probably want to look at ctypes and similar libraries for that sort of thing.
I've been researching this problem a bit and while I don't have a definite answer, I thought it would be good to share what I found.
First, according to the answers for this question, wxPython cannot track nor control the mouse position outside of the area controlled by the wxPython app. However, as we can see in the answers to this question, under certain circumstances it may be possible to create system-wide hot keys that wxPython can see (although we can also see that this is probably not the optimal solution).
So what will work for the OP? Well, build a cross platform application that does what the OP wants seems almost impossible so I will assume the OP is developing for MS Windows. Following the suggestions in those previous two questions, I looked into the PyWin32 API. It's a little hard to find documentation for it but this question offers some helpful links. A little more digging and I found this tutorial for system-wide hotkeys as well as the win32event.WaitForMultipleObjects and win32event.WaitForSingleObject methods which, if the OP can figure out the proper event, may be what the OP needs to catch menu clicks.
I know it's far from a complete answer but hopefully this can serve as a good jumping-off point for further research.