Last active
January 27, 2023 18:51
-
-
Save Overemployed/3595853329092ccff5fa2990c5dbde20 to your computer and use it in GitHub Desktop.
PIKVM mouse jiggler
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// assumes your mouse is in relative mode https://docs.pikvm.org/mouse/?h=relative#relative-mouse-on-v2-platform-otg-hid | |
// You may want to set your pikvm to support dual mode, so you can switch between absolute and relative | |
const { PIKVM_HOST, PIKVM_USER, PIKVM_PASSWORD, MOUSE_MODE = 'normal' } = process.env | |
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0; | |
import fetch from 'node-fetch'; | |
import { path } from "ghost-cursor"; | |
import websocket from 'websocket'; | |
const WebSocketClient = websocket.client | |
let connection; | |
let previous = { | |
x: 0, | |
y: 0 | |
} | |
let begin = true; | |
async function tracePath(vectors) { | |
const isPixelMode = MOUSE_MODE === 'pixel' | |
if (isPixelMode) { | |
const randomDirection = randomValue(1, 4) | |
let x = 0; | |
let y = 0; | |
switch (randomDirection) { | |
case 1: | |
x = 1 | |
y = 0 | |
break; | |
case 2: | |
x = -1 | |
y = 0 | |
break; | |
case 3: | |
x = 0 | |
y = 1 | |
break; | |
case 4: | |
default: | |
x = 0 | |
y = -1 | |
break; | |
} | |
await sendMouse({ x, y }); | |
await wait(randomValue(600, 5000)); | |
return | |
} | |
for (const v of vectors) { | |
const x = Math.floor(previous.x - v.x) | |
const y = Math.floor(previous.y - v.y) | |
try { | |
await sendMouse({ x, y }); | |
await wait(randomValue(10, 30)); | |
previous = v; | |
} catch (error) { | |
console.log(error.message); | |
} | |
} | |
} | |
async function sendMouse({ x, y }) { | |
console.log(x, y) | |
connection.send(`{ | |
"event_type":"mouse_relative", | |
"event":{ | |
"delta":[ | |
{"x":${x},"y":${y}} | |
], | |
"squash":true | |
} | |
}`) | |
} | |
async function connectTo() { | |
const client = new WebSocketClient(); | |
client.on('connectFailed', function(error) { | |
console.log('Connect Error: ' + error.toString()); | |
connectTo() | |
}); | |
client.on('connect', async function(conn) { | |
connection = conn | |
console.log(`Connected`); | |
connection.on('error', function(error) { | |
console.log(`Connection Error: ` + error.toString()); | |
connectTo() | |
}); | |
connection.on('close', function() { | |
console.log(`echo-protocol Connection Closed`); | |
connectTo() | |
}); | |
if (connection.connected) { | |
await updateMouseMode(true) | |
while (true) { | |
try { | |
const from = begin ? getRandomPoint() : previous | |
begin = false | |
await wait(randomValue(20, 5000)); | |
const to = getRandomPoint(); | |
const pathV = path(from, to); | |
await tracePath(pathV, connection); | |
} catch (e) { | |
console.log('Warning: stopping random mouse movements', e); | |
} | |
} | |
} | |
}) | |
await wait(1000) | |
console.log(`connectiong to ${PIKVM_HOST}, ${PIKVM_USER}, ${PIKVM_PASSWORD}`) | |
client.connect(`wss://${PIKVM_HOST}/api/ws?stream=0`, '', '', { | |
'X-KVMD-User': PIKVM_USER, | |
'X-KVMD-Passwd': PIKVM_PASSWORD | |
}) | |
} | |
function randomValue(min, max) { | |
min = Math.ceil(min); | |
max = ~~max; | |
return ~~(Math.random() * (max - min)) + min; | |
} | |
async function updateMouseMode(on) { | |
await fetch( | |
`https://${PIKVM_HOST}/api/hid/set_params?mouse_output=${on ? 'usb_rel' : 'usb'}` | |
, { | |
"headers": { | |
'X-KVMD-User': PIKVM_USER, | |
'X-KVMD-Passwd': PIKVM_PASSWORD | |
}, | |
"method": "POST" | |
}); | |
} | |
function getRandomPoint(){ | |
const height = 1920 | |
const width = 1080 | |
let paddingPercentage = 1 | |
const paddingWidth = (width * paddingPercentage) / 100; | |
const paddingHeight = (height * paddingPercentage) / 100; | |
const x = 0+ paddingWidth / 2 + Math.random() * (width - paddingWidth) | |
const y = 0+ paddingHeight / 2 + Math.random() * (height - paddingHeight) | |
return { | |
x: Math.floor(x), | |
y: Math.floor(y) | |
}; | |
} | |
function wait(time){ | |
return new Promise((resolve)=>{ | |
setTimeout(resolve, time) | |
}) | |
} | |
connectTo() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "jiggler", | |
"version": "1.0.0", | |
"description": "", | |
"main": "jiggler.mjs", | |
"scripts": { | |
"test": "echo \"Error: no test specified\" && exit 1" | |
}, | |
"author": "", | |
"license": "ISC", | |
"dependencies": { | |
"ghost-cursor": "^1.1.15", | |
"node-fetch": "^3.2.10", | |
"websocket": "^1.0.34" | |
} | |
} |
@overemployedswe Can you provide this script and how its used?
@arch1mede to set the mouse mode back to absolute I'm using this script here which was pretty much taken from the main jiggle script but I stripped everything jiggle related out:
const { PIKVM_HOST, PIKVM_USER, PIKVM_PASSWORD } = process.env;
process.env["NODE_TLS_REJECT_UNAUTHORIZED"] = 0;
import fetch from "node-fetch";
async function updateMouseMode() {
try {
await fetch(`https://${PIKVM_HOST}/api/hid/set_params?mouse_output=usb`, {
headers: {
"X-KVMD-User": PIKVM_USER,
"X-KVMD-Passwd": PIKVM_PASSWORD,
},
method: "POST",
});
} catch (e) {
console.log("ERROR: ", e);
}
}
updateMouseMode();
You call this script the exact same way you call the jiggler script by passing in the env variables nessecary, then when you run the script it makes an api call to the pikvm to set the mouse mode to absolute so its back to normal.
I don't have it yet but I plan to build an orchestration api to start & stop mouse jigglers via an api call so that I can utilize macropads to handle these scripts rather than needing to actually run a script in my terminal.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This is working for me with 2 PiKVM's
I am using a Mac Studio (M1 Max, 32GB)
Steps to take before running the script
npm i
to get the dependenciesnode jiggler.mjs
to run the scriptI would recommend when running jiggler.mjs you follow the above example where you provide the host, user & password.
Note: I've only tested/used MOUSE_MODE=normal.
I've also written a quick little script that puts my mouse mode back to absolute which can be done with pretty much the existing code in the jiggler.mjs script.