// ==UserScript==
// @name Arras.io Gamepad support
// @namespace Violentmonkey Scripts
// @match *://arras.io/*
// @grant none
// @version 1.2
// @author alexandra
// @description Allows you to use your Gamepad to play arras.io! Press F1 to toggle between active and disabled. Controls: Right thumb stick to move your tank, Left thumb stick to aim, RT to shoot, LT for right click, A for autofire, B for autospin, X for override and Y for taking control of other tanks. Setup "commandKeys" in the script to match your keybindings ingame.
// @run-at document-start
// @license MIT
// ==/UserScript==
let commandKeys = { // change this if you want
autofire: "KeyE",
autospin: "KeyC",
override: "KeyR",
takeControl: "KeyF"
}
let enabled = false
window.addEventListener("keydown", (e) => {
if (e.code === "F1") {
e.preventDefault()
enabled = !enabled
}
})
let windowListener = window.addEventListener
window.addEventListener = function(...args) {
let type = args[0]
if (type === "keydown" || type === "keyup") {
let callback = args[1]
args[1] = function(event) {
return callback.call(this, {
isTrusted: true,
key: event.key,
code: event.code,
preventDefault: function(){}
})
}
}
return windowListener.apply(this, args)
}
let cnvsElementListener = HTMLDivElement.prototype.addEventListener
HTMLDivElement.prototype.addEventListener = function(...args) {
let type = args[0]
if (type === "mousedown" || type === "mouseup" || type === "mousemove") {
let callback = args[1]
args[1] = function(event) {
return callback.call(this, {
isTrusted: true,
clientX: event.clientX,
clientY: event.clientY,
button: event.button,
preventDefault: function(){}
})
}
}
return cnvsElementListener.apply(this, args)
}
function keyEvent(key, type) {
window.dispatchEvent(new KeyboardEvent(type ? "keydown" : "keyup", {
code: key
}))
}
function mouseEvent(x, y, button, type) {
let event = new MouseEvent(type, {
clientX: x,
clientY: y,
button: button,
})
document.querySelector("#canvas").dispatchEvent(event)
}
function eightDirMoveTo(cx, cy, ex, ey) {
if (ex > cx) {
keyEvent("ArrowLeft", false)
keyEvent("ArrowRight", true)
} else if (ex < cx) {
keyEvent("ArrowLeft", true)
keyEvent("ArrowRight", false)
} else {
keyEvent("ArrowLeft", false)
keyEvent("ArrowRight", false)
}
if (ey > cy) {
keyEvent("ArrowUp", false)
keyEvent("ArrowDown", true)
} else if (ey < cy) {
keyEvent("ArrowUp", true)
keyEvent("ArrowDown", false)
} else {
keyEvent("ArrowUp", false)
keyEvent("ArrowDown", false)
}
}
let stsText = document.createElement("div")
stsText.style.position = "absolute"
stsText.style.margin = "15px"
stsText.style.color = "white"
stsText.style.fontSize = "20px"
stsText.style.fontWeight = "bold"
stsText.style.fontFamily = "Ubuntu"
stsText.textContent = "No Gamepad connected!"
stsText.style.textShadow = "-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black"
stsText.style.pointerEvents = "none"
let enText = document.createElement("div")
enText.style.position = "absolute"
enText.style.margin = "15px"
enText.style.color = "white"
enText.style.fontSize = "15px"
enText.style.fontWeight = "bold"
enText.style.fontFamily = "Ubuntu"
enText.textContent = "Disabled!"
enText.style.textShadow = "-1px 0 black, 0 1px black, 1px 0 black, 0 -1px black"
enText.style.top = "20px"
enText.style.pointerEvents = "none"
let crosshair = document.createElement("img")
crosshair.style.position = "absolute"
crosshair.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAXCAYAAADgKtSgAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAACjSURBVEhL1Y5BDsUgCEQ9SJe9/816Bqs2kAHFIrGLvmSSysD7Py2QIdvJ13H+S05ClFPCsKRKdbAvWUJI8W11JS74mL4XZq9YBzgn2nswHzJb9sx1J5gtmvIao2ORXuoS6J5id1iOgaJLoBPoJUT8I6DNjE4wW/TMdddhLY/k7W386BB9wHHMXPAhHuvviJjoRBjsS8KwZKdUg/LtfCuHOEjpBh0tTqQ2XaPuAAAAAElFTkSuQmCC"
crosshair.style.pointerEvents = "none"
crosshair.style.visibility = "hidden"
crosshair.style.margin = 0
let movArrow = document.createElement("img")
movArrow.style.position = "absolute"
movArrow.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAlCAYAAAAA7LqSAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAEaSURBVFhH1ZYJCgMhEAQ1//+zYUQXSTxanWsLFiEIWvaMJiiQyidKLKMUPQGRNSVFZimwr2slUmFb/1NGK9h6xzqRlqu9WCfScpWOqkhKy70ey9Q42Wp1RhWJEaqirVKjySoSxG8igBAsY9ojYKlBB23e7IAMsZzk4tYiGTCdId0eAU9JhNOLwNM7kjlNx51IBZR5JrkVIcASz5Pc9ciIVe+4TqRldbivEXl9IiSA/JVxLbLzprgVQVIoX8adCFpKZXygH1TuWuRKPxGoqIkQI5mdXhhhXlocEoSpCFhKW6aqfcKVQsvW5E3+DodEbhp6hqoIwPF+PL0jV4fqIRGWPVgnwnaQVomwryspQvRkRNaUFiFaGaH1QvgCHmRUMUA6MH0AAAAASUVORK5CYII="
movArrow.style.pointerEvents = "none"
movArrow.style.visibility = "hidden"
movArrow.style.margin = 0
movArrow.style.padding = 0
movArrow.style.transformOrigin = "center center"
movArrow.width = 40
document.addEventListener("DOMContentLoaded", () => {
document.body.appendChild(movArrow)
document.body.appendChild(crosshair)
document.body.appendChild(stsText)
document.body.appendChild(enText)
})
let gamepadControls = {
A: 0,
B: 0,
X: 0,
Y: 0
}
let gamepadRangeX = window.innerWidth
let gamepadRangeY = window.innerHeight
// buttons[0] A
// buttons[1] B
// buttons[2] X
// buttons[3] Y
// buttons[4] LB
// buttons[5] RB
// buttons[6] LT
// buttons[7] RT
let gamepad
setInterval(() => {
let gamepads = navigator.getGamepads().find((x) => x !== null)
if (gamepads) {
gamepad = gamepads
stsText.textContent = "Gamepad connected!"
} else {
gamepad = undefined
stsText.textContent = "No Gamepad connected!"
}
if (enabled) {
enText.textContent = "Enabled!"
if (gamepad) {
crosshair.style.visibility = "visible"
movArrow.style.visibility = "visible"
let target = gamepad.axes.slice(0, 2).map((x) => Math.round(x))
let cursorPos = gamepad.axes.slice(2, 4).map((x) => x + 1)
cursorPos[0] *= gamepadRangeX
cursorPos[1] *= gamepadRangeY
cursorPos[0] -= gamepadRangeX / 2
cursorPos[1] -= gamepadRangeY / 2
if (cursorPos[0] > window.innerWidth) cursorPos[0] = window.innerWidth
if (cursorPos[0] < 0) cursorPos[0] = 0
if (cursorPos[1] > window.innerHeight) cursorPos[1] = window.innerHeight
if (cursorPos[1] < 0) cursorPos[1] = 0
if (gamepad.buttons[6].pressed) {
keyEvent("ShiftLeft", true)
} else {
keyEvent("ShiftLeft", false)
}
if (gamepad.buttons[0].pressed) {
gamepadControls.A++
} else {
gamepadControls.A = 0
}
if (gamepad.buttons[1].pressed) {
gamepadControls.B++
} else {
gamepadControls.B = 0
}
if (gamepad.buttons[2].pressed) {
gamepadControls.X++
} else {
gamepadControls.X = 0
}
if (gamepad.buttons[3].pressed) {
gamepadControls.Y++
} else {
gamepadControls.Y = 0
}
if (gamepadControls.A === 1) {
keyEvent(commandKeys.autofire, true)
keyEvent(commandKeys.autofire, false)
}
if (gamepadControls.B === 1) {
keyEvent(commandKeys.autospin, true)
keyEvent(commandKeys.autospin, false)
}
if (gamepadControls.X === 1) {
keyEvent(commandKeys.override, true)
keyEvent(commandKeys.override, false)
}
if (gamepadControls.Y === 1) {
keyEvent(commandKeys.takeControl, true)
keyEvent(commandKeys.takeControl, false)
}
crosshair.style.left = cursorPos[0] - 11.5 + "px"
crosshair.style.top = cursorPos[1] - 11.5 + "px"
if (target[0] || target[1]) {
let dir = Math.atan2(target[1], target[0])
movArrow.style.transform = `rotate(${dir}rad)`
movArrow.style.left = ((window.innerWidth / 2) + Math.cos(dir) * 75) - 20 + "px"
movArrow.style.top = ((window.innerHeight / 2) + Math.sin(dir) * 75) - 15 + "px"
} else {
movArrow.style.visibility = "hidden"
}
eightDirMoveTo(0, 0, target[0], target[1])
mouseEvent(
cursorPos[0],
cursorPos[1],
0,
gamepad.buttons[7].pressed ? "mousedown" : "mouseup"
)
} else {
crosshair.style.visibility = "hidden"
movArrow.style.visibility = "hidden"
}
} else {
enText.textContent = "Disabled!"
crosshair.style.visibility = "hidden"
movArrow.style.visibility = "hidden"
}
})
// empty space wooo