This script makes bonk.io playable on mobile.
目前為
// ==UserScript==
// @name bonk.io Mobile Mod
// @namespace http://tampermonkey.net/
// @version 1.1.2
// @description This script makes bonk.io playable on mobile.
// @author kitaesq
// @match https://bonk.io
// @icon https://www.google.com/s2/favicons?sz=64&domain=bonk.io
// @grant none
// ==/UserScript==
if (!window.kitaes) window.kitaes = {}
if (!window.kitaes.findElement){
window.kitaes.findElement = function(document, selector){return new Promise((res, rej) => {
let interval = setInterval(() => {
const el = document.querySelector(selector)
if (el){
clearInterval(interval)
res(el)
}
}, 100)
})}
}
if (!window.kitaes.requestIntercept) {
window.kitaes.requestIntercept = () => {
const send = XMLHttpRequest.prototype.send
XMLHttpRequest.prototype.send = function(body){
this.addEventListener("load", () => {
const event = new Event("kitaes-request")
event.body = body
event.request = this
window.dispatchEvent(event)
})
return send.apply(this, [body]);
};
console.log("Request interceptor loaded")
}
window.kitaes.requestIntercept()
}
if (!window.kitaes.fullscreen) {window.kitaes.fullscreen = async () => {
console.log("[Fullscreen mod] Loading fullscreen mod...")
const styleElem = document.createElement("style")
styleElem.textContent =
`body{
overflow: hidden;
visibility: hidden;
}
#maingameframe{
margin: 0 !important;
position: fixed;
top: 0 !important;
left: 0 !important;
right: 0 !important;
top: 0 !important;
}
#theme_container{
top: 36px;
visibility: visible;
}`
document.head.append(styleElem)
document.body.style.visibility = "hidden"
document.body.style.overflow = "hidden"
const maingameframe = await window.kitaes.findElement(document, "#maingameframe")
maingameframe.style.visibility = "visible"
maingameframe.style.marginTop = "0"
const iframeWait = (iframe) => (new Promise(res => iframe.addEventListener('load', res)));
if (maingameframe.contentDocument.URL === "about:blank") {
console.log("[Fullscreen mod] iframe is not loaded yet, waiting for iframe to load...")
await iframeWait(maingameframe)
console.log("[Fullscreen mod] iframe was loaded")
}
const fdocument = maingameframe.contentDocument
const fwindow = maingameframe.contentWindow
const fstyleElem = document.createElement("style")
fstyleElem.className = "kitaes-fullscreen-style"
fstyleElem.textContent =
`#bonkiocontainer{
width: 100% !important;
height: 100% !important;
border: none !important;
}
canvas{
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin: auto;
}
#xpbarcontainer{
top: -4px !important
}
#fullscreen_button{
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAABPSURBVEhLYxgFhAAjlAaD/0AAZWIARiCAMsGAWLVMUJpmgOYW4PQ2epAQArj0Dv0gorkFo2DgwWg+IAhobgHOOEAH6HFCrNrRomLYAwYGACfdIBnA7J6WAAAAAElFTkSuQmCC);
background-repeat: no-repeat;
background-position: center;
position: absolute;
top: 35px;
left: 0;
margin: 10px;
width: 40px;
height: 40px;
pointer-events: auto;
}
*{
touch-action: none;
user-select: none;
}`
const bonkioContainer = await window.kitaes.findElement(fdocument, "#bonkiocontainer")
fdocument.head.append(fstyleElem)
console.log("[Fullscreen mod] Style was injected")
const prettyMenu = await window.kitaes.findElement(fdocument, "#prettymenu")
const fullscreenBtn = document.createElement("div")
fullscreenBtn.id = "fullscreen_button"
fullscreenBtn.className = "brownButton brownButton_classic buttonShadow"
let isFullScreen = false
fullscreenBtn.onclick = () => {
if (!isFullScreen) {
document.body.requestFullscreen()
}
else{
document.exitFullscreen()
}
isFullScreen = !isFullScreen
}
prettyMenu.append(fullscreenBtn)
console.log("[Fullscreen mod] Fullscreen button was added")
const interval = setInterval(() => {
if (fdocument.body.lastElementChild.tagName !== "DIV" || fdocument.body.lastElementChild.className) return
fdocument.body.lastElementChild.style.top = "85px"
clearInterval(interval)
console.log("[Fullscreen mod] FPS counter was moved to the bottom")
console.log("[Fullscreen mod] Fullscreen mod was loaded")
}, 500)
}
window.kitaes.fullscreen()
}
if (!window.kitaes.mobile) {window.kitaes.mobile = async () => {
console.log("loading mobile mod...")
document.head.innerHTML += '<meta name="viewport" content="height=600px, initial-scale=0.5, maximum-scale=0.5">'
const maingameframe = await window.kitaes.findElement(document, "#maingameframe")
maingameframe.style.visibility = "visible"
maingameframe.style.marginTop = "0"
const iframeWait = (iframe) => (new Promise(res => iframe.addEventListener('load', res)));
if (maingameframe.contentDocument.URL === "about:blank") {
console.log("[Mobile mod] iframe is not loaded yet, waiting for iframe to load...")
await iframeWait(maingameframe)
console.log("[Mobile mod] iframe was loaded")
}
const fdocument = maingameframe.contentDocument
const fwindow = maingameframe.contentWindow
const buttonContainer = document.createElement("div")
Object.assign(buttonContainer.style, {
position: "fixed",
bottom: "30px",
right: "30px",
width: "220px",
height: "220px",
display: "flex",
flexWrap: "wrap",
justifyContent: "space-between",
alignItems: "space-between",
lineHeight: "70px",
fontSize: "40px"
})
const keybinds = {}
fwindow.addEventListener("kitaes-request", async (e) => {
if (e.request.responseURL !== "https://bonk2.io/scripts/login_legacy.php") return
const data = JSON.parse(e.request.responseText)
const x = "data:image/png;base64," + data.controls
const arrayBuffer = await (await fetch(x)).arrayBuffer()
const view = new DataView(arrayBuffer);
keybinds.up = view.getUint16(2)
keybinds.down = view.getUint16(6)
keybinds.left = view.getUint16(10)
keybinds.right = view.getUint16(14)
keybinds.heavy = view.getUint16(18)
keybinds.special = view.getUint16(22)
})
const buttons = [["↖", "↑", "↗"],
["←", " ", "→"],
["↙", "↓", "↘"]]
const touchId = {dpad: 0, heavy: 0, special: 0}
const activeDirKeys = {up: false, down: false, left: false, right: false}
const activeSpecialKeys = {heavy: false, special: false}
let isActive = false
function simulateKey(key, down) {
if (down === activeDirKeys[key]) return
activeDirKeys[key] = down
const event = document.createEvent("HTMLEvents");
event.initEvent("key" + (down ? "down" : "up"), true, false);
event.keyCode = keybinds[key]
fdocument.dispatchEvent(event);
}
function simulateKeys(keys, type) {
for (const key of keys){
simulateKey(key, type)
}
}
function releaseAllKeys(){
for (const a of Object.keys(keybinds)){
if (!activeDirKeys[a]) continue
simulateKey(a, false)
}
}
buttonContainer.ontouchstart = (e) => {
touchId.dpad = e.changedTouches[0].identifier
simulateKeys(e.target.keys, true)
isActive = true
console.log("down")
}
oncontextmenu = e => e.preventDefault()
fwindow.ontouchend = (e) => {
console.log("up")
if (e.changedTouches[0].identifier === touchId.dpad){
releaseAllKeys()
isActive = false
}
else if (e.changedTouches[0].identifier === touchId.heavy){
simulateKey("heavy", false)
}
else if (e.changedTouches[0].identifier === touchId.special){
simulateKey("special", false)
}
}
const gamerenderer = await window.kitaes.findElement(fdocument, "#gamerenderer")
const gameOverlay = document.createElement("div")
gameOverlay.addEventListener('contextmenu', e => e.preventDefault());
gameOverlay.style.zIndex = 99999
gameOverlay.style.position = "fixed"
gamerenderer.append(gameOverlay)
gameOverlay.append(buttonContainer)
const size = {height: "70px", width: "70px"}
for (let i = 0; i < 3; i++){
for (let j = 0; j < 3; j++){
if (j === 1 && i === 1) {
const div = document.createElement("div")
Object.assign(div.style, size)
buttonContainer.append(div)
continue
}
const keys = []
if (j === 0) keys.push("left")
else if (j === 2) keys.push("right")
if (i === 0) keys.push("up")
else if (i === 2) keys.push("down")
const button = document.createElement("div")
Object.assign(button.style, size)
button.keys = keys
button.textContent = buttons[i][j]
button.className = "brownButton brownButton_classic buttonShadow"
buttonContainer.append(button)
}
}
buttonContainer.ontouchmove = (e) => {
e = e.targetTouches[0]
const ContainerPos = buttonContainer.getBoundingClientRect()
const x = e.clientX - ContainerPos.x
const y = e.clientY - ContainerPos.y
releaseAllKeys()
if (x < 74) {
simulateKey("left", true)
}
else if (x > 147) {
simulateKey("right", true)
}
if (y < 74) {
simulateKey("up", true)
}
else if (y > 147) {
simulateKey("down", true)
}
}
const list = ["special", "heavy"]
const leftStyle = {height: "70px", width: "200px", fontSize: "30px", lineHeight: "70px", textTransform: "capitalize", position: "fixed", left: "30px"}
for (let i = 0; i < 2; i++){
const button = document.createElement("div")
button.className = "brownButton brownButton_classic buttonShadow"
button.key = list[i]
button.textContent = button.key
Object.assign(button.style, leftStyle)
button.style.bottom = (30 + (i * 100)) + "px"
button.ontouchstart = (e) => {
console.log(button.key)
simulateKey(button.key, true)
touchId[button.key] = e.changedTouches[0].identifier
}
gameOverlay.append(button)
}
}
window.kitaes.mobile()}