I am trying to send keyboard inputs to Minecraft to move the player, however when I try using SendKeys.SendWait("W"); nothing happens. If I open the chat in Minecraft it types "W" in chat, however outside of chat my inputs seem to be ignored. Thanks.
Edit: I have tried using SendInput as well as InputSimulator both having the same effect.
Basically Windows has three protection ring. By doing SendKeys you are sending a ring 3 command to the application. However DirectX only listens to ring 0 and ring 1 (possibly ring 2) commands to reduce the fraction delay caused by command passing through a driver to application.
So in order to make DirectX games react to the event you sent you must send it at driver level. You can simulate a ring 2 driver input by pinvoke WINDOWS api SendInput with scan code (don't use virtual code).
If scan code doesn't work then the game might be blocking ring 2 commands for anti-hacking purpose. In that case you would need to write a driver + a virtual hardware to send ring 1 commands directly. (do not try this if you are not experienced. a Blue screen of death or even corrupted system may result if a mistake is made)
I solved it by using InputSimulatorPlus
https://github.com/TChatzigiannakis/InputSimulatorPlus
InputSimulator s = new InputSimulator();
s.Keyboard.KeyDown(VirtualKeyCode.VK_W);
this just runs forward, to stop use s.Keyboard.KeyUp(VirtualKeyCode.VK_W);
you can also use s.Keyboard.KeyPress(VirtualKeyCode.VK_W); and this will just click the "W" key.
Related
All,
Apologies in advance if this is an ill-informed question with lack of detailed examples of what I have tried to do so far - all the material I am finding on this topic seems to be out of scope of what I'm trying to do, or its just going right over my head (Learning resources on this are welcome!!).
What I am essentially trying to do is build a small program that will differentiate the input device used to create a user input on my Lenovo Win10 Machine that can run in the background and trigger scripts when certain conditions are met. In my case the input devices are a generic wireless/USB keyboard, and a USB Barcode scanner that acts as a HID Keyboard (The Barcode Scanners plugs directly into the machine, not via a keyboard).
The reason I need to differentiate the input is for example, if I have a script run every time an asterisk is printed from a scanned barcode I want the user to still be able to type an asterisk from the keyboard without triggering the script - Im restricted to using Code 128 barcodes so I also cant bypass this issue by adding characters to the barcodes to trigger the scripts that are not present on the keyboard.
In pseudo-code its essentially
start:
if inputdevice == keyboard 1
then
System.Diagnostics.Process.Start(myBatchFileName);
else
goto start;
Initially I tried to do this in VB, using some code I had previously used to listen to a COM Port to record output from an arduino -
Dim barcodescanner As SerialPort
barcodescanner = New SerialPort()
barcodescanner.PortName = "COMx"
barcodescanner.BaudRate = 9600
barcodescanner.Parity = Parity.None
barcodescanner.DataBits = 8
barcodescanner.StopBits = StopBits.One
Dim barcode As String
barcodescanner.Open()
barcode = barcodescanner.ReadLine()
barcodescanner.Close()
-however for reasons beyond me I cannot successfully use a virtual COM port for the scanner and record data this way, I also tried to create a virtual COM port using drivers from http://www.ftdichip.com/FTDrivers.htm but this was to no avail.
From some investigation I found some C# Classes, namely; InputEventArgs, InputDevice, RoutedEventArgs, that seem as if they could be used to resolve a device ID from an Input/Event that may allow be to harness some information I could use to flesh out and build the pseudo IF THEN ELSE loop above - but im struggling to use the classes and actually build any working code.
Does anyone have any suggestions as to how to do this?
In a perfect world if I could create a virtual COM port for the barcode scanner and listen to it using VB that would be ideal - but if not could anyone suggest a method of doing this in C# or point me to another method?
The problem is that a keyboard-emulating scanner and a keyboard work the same way and Windows does not allow you to find out which device actually sent the keystroke.
One way would be (if possible for your scanner):
Configure the scanner to work as COM port emulation (not possible with all scanners, only industrial ones support this normally)
Install the manufacturer's virtual COM port driver if necessary
Then you can actually open a COM port and communicate with the scanner as desired - you then, however, need to put the scanned strings into text fields yourself if required.
Second possible solution (if available for your device):
Configure the scanner to transmit a certain prefix or suffix along with the barcode content (most scanners can be configured to send a barcode identifier before the content, which is highly unlikely to be typed by the user)
Also configure the scanner to send CRLF or CR as last character
When you receive CRLF or CR, check whether the input starts with that prefix/ends with that suffix
If it does, remove the prefix/suffix from the text box and react to the "*" as desired.
So in this maze kind of game I'm making, I will show the maze to the player for 30 seconds.
What I don't want is that the player taking screenshot of the maze.
I want to do something like Snapchat, or Instagram, how it detects when you take a screenshot of a snap/story.
I'm using C#. It can also prevent user to take screenshot. I don't mind.
Is there a possible way to detect when the user takes screenshots or prevent it in Unity?
No, you can't detect this reliably. They also could make a photo with a digi cam. Furthermore there are endless ways to create a screenshot and the os has no "callback" to inform an application about that. You could try to detect the "print screen" key but as I said there are other screenshot / screen recording tools which could use any hotkey or no hotkey at all. I have never used Snapchat but it seems it's not safe either.
There are even monitors and video projectors which have a freeze mode to keep the current image. You could also run your browser in a virtual machine. There you can actually freeze the whole virtual PC or take screen shots from the virtual screen and an application running inside the VM has no way to even detect or prevent that.
I once had to do something similar. If you just want to do what snapchat did then it can be done but remember that as long as the app is running on anyone's device instead of your server, it can be de-compiled, modified and compiled again so this screenshot detection can be circumvented.
First of all you need to know this about Apple's rule:
2.5.9 Apps that alter or disable the functions of standard switches, such as the Volume Up/Down and Ring/Silent switches, or other native
user interface elements or behaviors will be rejected.
So, the idea of altering what happens when you take a screenshot is eliminated.
What you do is start the game, do the following when you are showing the show the maze to the player for 30 seconds:
On iOS:
Continuously check if the player presses the power and the home button at the-same time. If this happens, restart the game and show the maze to the player for 30 seconds again. Do it over and over again until player stops doing it. You can even disconnect or ban the player if you detect power + the home button press.
On Android:
Continuously check if the player presses the the power and volume down buttons at the-same time. Perform the-same action described above.
You cannot just do this with C#. You have to use make plugins for both iOS and Android devices. The plugin should use Java to the the detection on android and Object-C to do the detection for iOS. This is because the API required is not available in C#. You can then call the Java and Objective-C functions from C#.
Other improvement to make:
Check or external display devices and disable them when you are
showing the maze to the player for 30 seconds. Enable them back
during this time.
When you detect the screenshot button press as described above,
immediate take your own screenshot too. Loop through images on the player's picture gallery and load all the images taken that day.
Compare it with the screenshot you just took and see if they match.
If they do, you are now very sure that the player is trying to cheat.
Take action like banning the player, restarting the game or even
trolling the player by sending their screenshot to the other player. You can also use it as a proof to show that the user is cheating when they complain after being banned.
Finally, you can even go deeper by using OpenCV. When you are
showing the player the maze for 30 seconds, start the front camera of
the device and use OpenCV to continuously check if any object other
than the player's head is in front of the camera. If so, then the
player is trying to take a screenshot with another device. Take
action immediately. You can use machine language to train this.
How far to go depends on how much time you want to spend and how much you care about player's cheating online. The only thing to worry about is players de-compiling the game and removing those features but it is worth implementing.
My Android phone takes screenshots differently. I swipe down from the
top of the screen and select the "Capture" option.
Nothing is always the-same on Android. This is different on some older or different Android devices. You can detect swipe patterns on the screen. The best way to do this is to build a profile that handles each Android device from different manufactures.
For those commenting, this is possible to do. You must do it especially if it is a multiplayer game. Just because a game can be hacked does not mean that a programmer should not implement basic hack prevention mechanism. Basic hack prevention mechanism should be implemented then improved as you get feedback from players.
I am developing a C# application that gives the user the possibility to set some specific keystrokes that the applications will reproduce when it will be launched in execution. As far as I was testing my application in notepads or other simple programs it worked just using SendInput or InputSimulator, but as soon as I tried it with a video-game the emulated input could not be received by the game.
The strange thing is that actually the input is received by the game but only if I am using the game chat.
To be clearer I will make an example:
I set in my application to reproduce the key w.
I launch my application and then I launch a FPS game like CounterStrike.
When the applications emulates the pression of the w key my character in the game doesn't move! But if i click on the chat and try to write something in the chatbox the emulated input is recognized and I can see the "w"s being written in the chatbox.
Game engines usually don't get their input from the usual Windows API; since this one lets you read only one character at once. In games, however, you can press several keys at once. For instance you might press wa together in order to move your character in forward-left direction. Games check the keyboard state at each game loop instead of reading the characters which have been typed. The character “w” might have been typed only once, but the w key might have been in pressed-state during 8 loops. Game engines seem to access the keyboard through a low-level function. This is why commands like SendKeys injecting their keystrokes at a higher level have no effect.
so I have received an external motion controller device (Myo) and I wish to create an application where certain motions will basically simulate a keystroke or keypress globally (doesn't matter about what application). This will happen while my program is running in the background so it can receive motion inputs and output as a keyboard press.
An example would be if I were to be playing Baseball game in the foreground (also full screen) and I do a pitching motion, the program will output the key which will do a pitch in game (whichever key it might be).
I have looked into the SendKeys class in C# but I feel there might be limitations as to what it can do (specifically global keypress sending).
Is there a good way where I can possibly write a program so I can map the actions with my motion controller to a keypress using C#? It would also be good if it can do key_down and key_up for key holdings.
The most direct way to accomplish truly global key-presses is to emulate a keyboard. This will involve creating a keyboard driver that somehow provides access to your background program. However this involves kernel programming which is quite complex.
An alternative is to use the SendKeys API combined with some logic to find the currently active application.
I know this isn't a C# solution, but the Myo Script interface in Myo Connect was essentially built for this purpose and would probably be the easiest way of testing things out if nothing else.
To send a keyboard command using Myo Script you can use myo.keyboard() (docs here).
If you want the script to be active at all times, you will need to consistently return true in onForegroundWindowChange() and pay attention to the script's location in the application manager. Scripts at the top of the application manager will be checked first, so your script may lose out if there is another one above it that 'wants' control of a given application.
I have a "Symbol" brand barcode scanner (USB) and I am trying to capture the data it scans from a barcode into my application (which is running as a service -- with no textbox control, of course).
The catch is that : Whenever you scan something, it acts like a keyboard and outputs the digits to anything that has focus (i.e notepad, word, etc).
My question is: How do I perform this barcode scan in the background and put it in a variable that I can use in my in C#.
So far, the only api's that I've found are for the .NET CF and I need this to be a
windows service.
Basically, I want to be able to send certain keystrokes to an application if the barcode = "123456789-0111" without interfering with the current window that has focus. After my application reads the barcode in then it will look for a certain program (launch it and set focus) and send keystrokes. I am using Code 128.
The HID mode will be your best best.
Put the barcode reader in HID mode and make your service capture the reader. When data comes in take a look at it and if it is one of your special barcodes you can act on it.
If the data is not one of your special barcodes then inject them as keydown/keyup windows messages so that it will seem to work in the same fashion as in keyboard emulation mode.
Put the scanner into USB mode. This is generally done by scanning a series of barcodes in your manual or printed out from the software provided from symbol.
With the scanner plugged in/docked connect to windows update. You'll get an update specific to that scanner. It won't work if if the scanner is not plugged in.
The scanner should map to a com port. This has typically been com 2 on the machines I've set it up on.
Download JustinIO. For my scanner, useful COM settings: Baud Rate: 9600, ByteSize 8, StopBits: 1 Parity: 0
Create a new CommPort instance. Set up a thread that does something like:
StringBuilder sb;
byte[] b;
do
{
b = commPort.Read(1);
sb.Append(Encoding.ASCII.GetChars(b));
Thread.Sleep(20); //symbol is slow...
} while(b.Length > 0);
Note: that's much crunched down from the code that I'm actually using so you'll need to modify it for your application.
Send the string to your application via whatever method seems appropriate.
The scanner is configured as HID (human interface device) and emulating keyboard.
To access it through Symbol's API, you probably have to disactivate current communication mode and set it to native one - should be documented in the scanner manual. Then you can access it directly without input field.
PS. I have no Symbol's scanner, but this is common to many devices.
It really depends upon the barcode scanner's api, and that is specific to the vendor. You'll need to get the the api for the scanner from the vendor, if you can't find it on their site you should just email their support, though you might find you have to buy the api.
First..
Ignore the .NET CF info for now as it probably pertains to the actual handheld unit. The mode of operation, pretending to be a keyboard, is referred to classically as a 'keyboard wedge'.
Second..
What kind of barcode symbologies are you attempting to use? And for what purposes? Or, mor directly,...What do the barcodes look like when scanned? (Do they contain special leading and trailing characters?)
Third... keep it simple... avoid the API unless it is necessary...
In the past when I've had to interface with barcode scanners, I've used a very simple approach in that my data entry form has the property of KeyPreview true and contains a method to detect and direct input originating from the scanner (by examining starting and trailing characters) to the appropriate control. Most of the scanners I've dealt with were programmable (usually via barcodes) to pass a custom set of characters to signal beginning and end of scanned input.
I hope that helps....
Here is a CodeProject sample that demonstrates how to set up global mouse and keyboard hooks in C#:
http://www.codeproject.com/KB/cs/globalhook.aspx
You could add this code to your console application, and then just monitor all keyboard input, looking for the specific codes you need. No API fuss or muss.