Making blazingly ⚡ fast Minecraft cheats
If you’re a fan of the Minecraft bedwars minigame, you know that the Hypixel server is the de facto place for cheaters. The whole fun of playing there is trying to set up the best cheats you can without getting banned, and whoever does - wins the round. It’s a fine line, but that’s what makes it fun, it allows for fair competition between different kinds of cheaters and hackers.
For a big fan of bedwars and Rust enjoyer like myself to compete fairly with other cheaters, the only choice was to make my own cheats…
Minecraft is a simple game and, at least in bedwars, a lot of the gameplay boils down to how fast you can click your mouse. You need to spam the mouse buttons both when attacking other players and when building bridges, which are the main parts of the game. I am not even joking when I say that before I started cheating I actually broke 2 (TWO!!) different mice in the span of about a year by playing bedwars intensely. This alone is enough reason to consider switching to an autoclicker. And that’s exactly what I made - an autoclicker, but no ordinary one.
An autoclicker is a simple concept - you activate it some way when you need it and it simulates fast mouse clicking. But before making it, a few questions arise:
- How do we want to activate it?
- What kind of clicking we want it to do? Maybe it should be possible for it to simulate keyboard events too? That would allow to completely automate bridge building!
My answer to all of these was YES.
I wanted my autoclicker to be activate-able by ANY sequence or combination of keyboard/mouse input, and once it is activated to be able to simulate ANY sequences or combinations of keyboard/mouse input. I wanted it to be possible to create something as simple as remapping a key to another, and something as complex as automatically and continuously building a bridge while a key is pressed and stopping when it’s released.
A simple program with a configuration file wouldn’t work obviously, so I decided to use an actual programming language for the configuration of each rule. And I chose Rust.
Loading the autoclicker rules
After a long time pondering (not really…) I decided to have the configuration as dynamic libraries (
.dlls) that will be loaded at runtime and react to user input by simulating other input.
The reason was that I love unsafe Rust, FFI and can never pass up an opportunity to debug segmentation faults.
A great crate for that is
libloading, and for watching the filesystem to load and remove rules at runtime
notify is perfect.
The design I settled on was each dynamic-library/rule/macro exporting a function like this:
Incro is the name of this project (INput maCROs),
evdev is an input event interface on Linux systems that allows to monitor all device input (and simulate it via
evdev-uinput). Since I am personally using Linux, I am not going to bother with other platforms.
As you can see, the function is called each time a new input event is registered, then the dynamic-library/rule/macro can decide how to react to it, maybe ignore, maybe update some inner state, and maybe start SPAMMING the fuck out of your mouse. And then it returns a
true if the original event should be “absorbed”,
false if it should be forwarded and re-emited.
Being able to “absorb” events means that we have to GRAB the input devices, instead of just monitoring them. Grabbing means that no other applications will receive their events.
Anyone who has worked with programs that grab input devices know that it’s a real pain in the ass and the first thing you have to do before starting to work is slap something like this in the beginning of your program:
This is important if you don’t want to reboot your computer every time you run the program and something goes wrong, because all input devices are grabbed you literally can’t do anything not even close the program, and 5 seconds is usually more than enough to test whatever you need to test.
The reason I needed the ability to “absorb” events (and in turn to grab the devices) was so it would be possible to, for example, spam a mouse button while the same button in reality is pressed and held. If you hold a button on one mouse and try clicking it on another, nothing will happen, so you must hide the fact that the first (real) mouse is being held, by grabbing the device and absorbing the events.
The structure of the project is starting to become clear:
- Load all dynamic-libraries/rules/macros from a directory
- Grab all input devices
- Create a virtual input device
- When input is registered, run the
eventcallback from each rule/macro
- If all of them return
false, re-emit the event from the virtual device, otherwise just absorb it.
As for the rules/macros:
- If you want to simply remap a key, just return
trueand emit the event you want.
- If you want to simulate some sequence of events with delays, you spawn a thread and do it there.
That introduces a question - how do you stop the new thread once it’s time? For example, for a simple autoclicker that spams left mouse button while it is being held in reality, we would want the code to look something like this:
These are wise words. And Rust doesn’t provide a way to easily “cancel” a thread. The closest way is to periodically check an atomic bool in the thread and if its true then end execution. But we don’t want every other line in our code to be a check, so I made a wrapper around
Basically it takes a closure just like
thread::spawn would and returns a
ThreadHandle which is basically the atomic with a
Drop implementation that sets it to
true. It also gives the closure a different
Incro instance - one that is aware of the thread it’s for (it also has access to the same atomic). Now we can modify our
Incro::emit function to check the atomic every time it’s called:
We also make it return
ControlFlow which is perfect for this situation, since it works with the try
Now our thread code can look like this:
Now we can easily stop the spawned thread by dropping it’s handle, and we know on what points it can stop (the
If we have a situation where we press a key and then release it after a delay, it’s likely that at some point the thread will need to stop during that brief moment in-between, and we dont want to leave the key pressed, so we can do this:
force_emit is the same as
emit but without the check we just added (original version). So now if space is pressed it will be released regardless, and the only point where our thread can stop is before pressing space.
And there you have it! A BLAZINGLY FAST ⚡ autoclicker with FEARLESS CONCURRENCY 🚀
Not only can you cheat in Minecraft with it, you can cheat in any game, or just program wild macros for your keyboard.
As fast as our autoclicker is, the rest of the programs on your computer are much slower for some reason, and you can’t really simulate very precise input. I really wanted to automate “god-bridging” in Minecraft, which requires very precisely timed mouse clicks, to a precision of a few milliseconds, and even though Incro can do that easily, the rest of the stack doesn’t react correctly - random delays appear, some events get “glued”. I don’t know if this limitation is introduced by my desktop environment (I use KDE, tried both wayland and X11), or maybe Minecraft itself.
Be sure to check out
Incro and give it a try maybe. Hope you found this post interesting and fun!