diff --git a/README.md b/README.md new file mode 100644 index 0000000..c0e3ff5 --- /dev/null +++ b/README.md @@ -0,0 +1,149 @@ +# rsi-clicker + +Scroll wheel **up** starts spamming left click. Scroll wheel **down** stops it. + +Clicks are injected through `/dev/uinput`, so they enter the kernel input +stack at the same layer as your real mouse. That's why this works under +KWin/Wayland and inside Proton, where `xdotool`, `xbindkeys` and `AutoKey` +do nothing at all. + +## Setup + +```fish +sudo pacman -S python-evdev +install -Dm755 rsi-clicker.py ~/.local/bin/rsi-clicker +rsi-clicker --doctor +``` + +`--doctor` checks every requirement and prints the exact command to fix +anything that's missing. Work down its list until everything reads `[ok]`. +For reference, the full set is: + +```fish +# 1. uinput at boot +echo uinput | sudo tee /etc/modules-load.d/uinput.conf +sudo modprobe uinput + +# 2. let your user write to it +echo 'KERNEL=="uinput", GROUP="input", MODE="0660", OPTIONS+="static_node=uinput"' \ + | sudo tee /etc/udev/rules.d/99-uinput.rules +sudo udevadm control --reload-rules && sudo udevadm trigger + +# 3. let your user read real input devices +sudo usermod -aG input $USER +``` + +Then **log out and back in** — group membership only applies to new sessions. +No root needed after that. + +## Run it + +```fish +rsi-clicker +``` + +That's the whole thing. Wheel up, it clicks. Wheel down, it stops. It prints +`▶ clicking` / `■ stopped` so you can see the state at a glance. + +## The one real gotcha: weapon swap + +Darktide binds the scroll wheel to weapon swap by default. So out of the box, +wheel-up will start the clicker **and** swap your weapon. Two ways to deal +with it — pick one. + +### Option A — rebind in-game (recommended) + +Settings → Controls, and set weapon swap to `1` / `2` / `3` instead of the +wheel. Most players do this anyway because slot-select is faster than +cycling. Nothing else needed; run `rsi-clicker` plain. + +### Option B — swallow the wheel entirely + +```fish +rsi-clicker --swallow-wheel +``` + +This takes an exclusive kernel grab on your mouse and re-emits everything — +motion, all buttons, side buttons — through the virtual device, minus the +wheel events. The game (and everything else) simply never sees a scroll. + +Worth knowing before you use it: + +- Scrolling stops working **everywhere** while it runs, not just in Darktide. + That includes your browser on the other monitor. Use it for a gaming + session, not as a login service. +- If the process dies for any reason — crash, `kill -9`, power of the + universe — the kernel releases the grab automatically when the file + descriptor closes. Your mouse cannot get stuck. Ctrl+C also releases it + cleanly and prints `mouse released`. + +## Options + +| Flag | Does | +|---|---| +| `--doctor` | Check setup, print fixes, exit. Start here. | +| `--list` | Show input devices and which is your mouse. | +| `--button left\|right\|middle` | Which button to spam. Default `left`. | +| `--cps N` | Clicks per second. Default `11`. | +| `--jitter 0-1` | Timing variance so the cadence isn't metronomic. Default `0.12`. | +| `--hold-ms N` | How long each click is held. Default `25`. Raise to `40` if the game misses clicks. | +| `--swallow-wheel` | Option B above. | +| `--max-duration N` | Auto-stop after N seconds of continuous clicking. | +| `--panic KEY` | Instantly quit. Default `KEY_F12`. | +| `--device PATH` | Force a specific mouse if auto-detect picks wrong. | +| `-v` | Extra detail on startup. | + +## Tuning for Darktide + +- **11 cps** is about the ceiling of sustained human clicking and feels + natural. Higher doesn't help — most weapons have an internal fire-rate cap + and extra clicks are just discarded. +- If clicks get eaten, `--hold-ms 40`. A 25 ms press can land entirely + between two frames when framerate dips, and on the 258V's integrated Arc + graphics you'll see dips in heavy hordes. +- `--max-duration 45` is a good safety net — if you alt-tab or die while it's + running, it stops on its own instead of clicking into your desktop. + +## Autostart for gaming sessions + +```fish +mkdir -p ~/.config/systemd/user +printf '%s\n' \ + '[Unit]' 'Description=rsi-clicker' \ + '[Service]' 'ExecStart=%h/.local/bin/rsi-clicker --cps 11' \ + 'Restart=on-failure' \ + '[Install]' 'WantedBy=default.target' \ + > ~/.config/systemd/user/rsi-clicker.service +systemctl --user daemon-reload +systemctl --user start rsi-clicker +``` + +`systemctl --user stop rsi-clicker` when you're done. I'd avoid +`enable --now` if you're using `--swallow-wheel`, for the reason above. + +## Troubleshooting + +**`Permission denied` / `--list` shows nothing** — run `--doctor`. Almost +always the `input` group without a re-login. Check with `groups | grep input`. + +**Wheel-up does nothing** — `--list` and confirm the device marked +`MOUSE, wheel` is really your mouse; pass `--device /dev/input/eventN` if +auto-detect grabbed a touchpad or a receiver's phantom interface. + +**Clicks work on desktop but not in-game** — `--hold-ms 40`, and make sure the +game window has focus. + +**Freespin wheel triggers erratically** — the script auto-detects high-res +wheels and accumulates to 120 units per detent, but a fully free-spinning +wheel (MX Master style) will fire multiple detents per flick. Switch the wheel +to ratcheted mode. + +## Worth repeating + +Fatshark's terms prohibit input automation. It's PvE so you're not affecting +anyone else's run, and kernel-level injection looks like ordinary hardware +input — but that's a risk you're choosing, not a free one. A mouse with +onboard macro firmware does the same job with nothing running at all. + +And if your hand actually *hurts* rather than just getting tired, the +autoclicker is treating a symptom. Worth having someone look at it.