flameddogo99-eaglermobile/eaglermobile.user.js

353 lines
29 KiB
JavaScript
Raw Normal View History

2024-05-26 14:17:04 -07:00
// ==UserScript==
2024-05-26 15:03:18 -07:00
// @name Eagler Mobile
// @description Allows eaglercraft to run on mobile, adds touch controls, and fixes a few mobile-related crashes
2024-05-26 14:17:04 -07:00
// @author FlamedDogo99
2024-05-26 15:03:18 -07:00
// @namespace http://github.com/FlamedDogo99
// @downloadURL https://raw.githubusercontent.com/FlamedDogo99/EaglerMobile/main/eaglermobile.user.js
2024-05-26 15:03:18 -07:00
// @license Apache License 2.0 - http://www.apache.org/licenses/
2024-05-26 14:17:04 -07:00
// @match https://eaglercraft.com/mc/*
2024-05-26 15:03:18 -07:00
// @grant none
// @version 1.5
// @updateURL https://raw.githubusercontent.com/FlamedDogo99/EaglerMobile/main/eaglermobile.user.js
2024-05-26 14:17:04 -07:00
// @run-at document-start
// ==/UserScript==
2024-05-27 07:46:54 -07:00
function isMobile() {
try {
document.createEvent("TouchEvent");
return true;
} catch (e) {
return false;
}
}
if(!isMobile()){
alert("WARNING: This script was created for mobile, and may break functionality in non-mobile browsers!");
}
2024-05-26 14:17:04 -07:00
// Used for changing touchmove events to mousemove events
var previousTouchX = null;
var previousTouchY = null;
2024-05-26 14:17:04 -07:00
// Key and mouse events
function keyEvent(name, state) {
const keyName = name.toUpperCase().charCodeAt(0)
window.dispatchEvent(new KeyboardEvent(state, {
key: name,
keyCode: keyName,
which: keyName
}));
}
function shiftKeyEvent(state) {
2024-05-26 14:17:04 -07:00
window.dispatchEvent(new KeyboardEvent(state, {
keyCode: 16,
which: 16
}));
}
function mouseEvent(number, state, canvas) {
canvas.dispatchEvent(new PointerEvent(state, {"button": number}))
}
function wheelEvent(canvas, delta) {
canvas.dispatchEvent(new WheelEvent("wheel", {
"wheelDeltaY": delta
}));
}
function setButtonVisibility(pointerLocked) {
let inGameStyle = document.getElementById('inGameStyle');
let inMenuStyle = document.getElementById('inMenuStyle');
inGameStyle.disabled = pointerLocked;
inMenuStyle.disabled = !pointerLocked;
}
2024-05-26 14:17:04 -07:00
// POINTERLOCK
// When requestpointerlock is called, this dispatches an event, saves the requested element to window.fakelock, and unhides the touch controls
window.fakelock = null;
Element.prototype.requestPointerLock = function() {
window.fakelock = this
document.dispatchEvent(new Event('pointerlockchange'));
console.log("requested pointerlock")
setButtonVisibility(true);
2024-05-26 14:17:04 -07:00
return true
}
// Makes pointerLockElement return window.fakelock
Object.defineProperty(document, "pointerLockElement", {
get: function() {
return window.fakelock;
}
});
// When exitPointerLock is called, this dispatches an event, clears the
document.exitPointerLock = function() {
window.fakelock = null
2024-05-26 14:17:04 -07:00
document.dispatchEvent(new Event('pointerlockchange'));
setButtonVisibility(false);
2024-05-26 14:17:04 -07:00
return true
}
// FULLSCREEN
window.fakefull = null;
// Stops the client from crashing when fullscreen is requested
Element.prototype.requestFullscreen = function() {
window.fakefull = this
document.dispatchEvent(new Event('fullscreenchange'));
return true
}
Object.defineProperty(document, "fullscreenElement", {
get: function() {
return window.fakefull;
}
});
document.exitFullscreen = function() {
window.fakefull = null
document.dispatchEvent(new Event('fullscreenchange'));
return true
}
// FILE UPLOADING
// Safari doesn't recognize the element.click() used to display the file uplaoder as an action performed by the user, so it ignores it.
// This hijacks the element.createElement() function to add the file upload to the DOM, so the user can manually press the button again.
var oldCreate = document.createElement;
document.createElement = function(type) {
this.oldCreate = oldCreate;
var element = this.oldCreate(type);
if(type == "input") {
var newElement = document.querySelector('input');
if(!newElement) {
this.body.appendChild(element);
newElement = document.querySelector('input');
newElement.addEventListener('change', function(e) {
2024-05-27 07:46:54 -07:00
this.hidden = true;
2024-05-26 14:17:04 -07:00
})
}
newElement.value = null;
newElement.style.cssText ="position:absolute;left:0%;right:100%;top:0%;bottom:100%;width:100%;height:100%;background-color:rgba(255,255,255,0.5);";
newElement.hidden = false;
return newElement;
}
return this.oldCreate(type);
}
// CSS for touch screen buttons, along with fixing iOS's issues with 100vh ignoring the naviagtion bar, and actually disabling zoom because safari ignores user-scalable=no :(
let customStyle = document.createElement("style");
customStyle.textContent = `
.mobileControl {
2024-05-26 14:17:04 -07:00
position: absolute;
width: 9.5vh;
height: 9.5vh;
font-size:4vh;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
line-height: 0px;
padding:0px;
color: #ffffff;
text-shadow: 0.35vh 0.35vh #000000;
box-sizing: content-box;
image-rendering: pixelated;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAUCAYAAACnOeyiAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAUGVYSWZNTQAqAAAACAACARIAAwAAAAEAAQAAh2kABAAAAAEAAAAmAAAAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAACoAMABAAAAAEAAAAUAAAAABBl8JYAAAIvaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgp+x0mNAAAAU0lEQVQIHV2OXQoAIAiDdSIdt0N3iAiMfhz00IPzw01URWSdEtRabxe01ghmRlgrIwJ352TOSUg9ggdjDFqlFAJAF733z3pbqvqF34mISOsG8o8N3G8YG4Y+w98AAAAASUVORK5CYII=) no-repeat right center, url(data:image/png;base64,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
background-size: contain, cover;
outline:none;
2024-05-27 07:46:54 -07:00
box-shadow: none;
border: none;
2024-05-26 14:17:04 -07:00
}
.mobileControl:active {
2024-05-26 14:17:04 -07:00
position: absolute;
width: 9.5vh;
height: 9.5vh;
font-size:4vh;
-webkit-user-select: none;
-ms-user-select: none;
user-select: none;
line-height: 0px;
padding:0px;
color: #ffffff;
text-shadow: 0.35vh 0.35vh #000000;
box-sizing: content-box;
image-rendering: pixelated;
2024-05-27 07:46:54 -07:00
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAIAAAAUCAYAAACnOeyiAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAUGVYSWZNTQAqAAAACAACARIAAwAAAAEAAQAAh2kABAAAAAEAAAAmAAAAAAADoAEAAwAAAAEAAQAAoAIABAAAAAEAAAACoAMABAAAAAEAAAAUAAAAABBl8JYAAAIvaVRYdFhNTDpjb20uYWRvYmUueG1wAAAAAAA8eDp4bXBtZXRhIHhtbG5zOng9ImFkb2JlOm5zOm1ldGEvIiB4OnhtcHRrPSJYTVAgQ29yZSA2LjAuMCI+CiAgIDxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zIyI+CiAgICAgIDxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiCiAgICAgICAgICAgIHhtbG5zOmV4aWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20vZXhpZi8xLjAvIgogICAgICAgICAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+CiAgICAgICAgIDxleGlmOlBpeGVsWURpbWVuc2lvbj4yMDwvZXhpZjpQaXhlbFlEaW1lbnNpb24+CiAgICAgICAgIDxleGlmOlBpeGVsWERpbWVuc2lvbj4yPC9leGlmOlBpeGVsWERpbWVuc2lvbj4KICAgICAgICAgPGV4aWY6Q29sb3JTcGFjZT4xPC9leGlmOkNvbG9yU3BhY2U+CiAgICAgICAgIDx0aWZmOk9yaWVudGF0aW9uPjE8L3RpZmY6T3JpZW50YXRpb24+CiAgICAgIDwvcmRmOkRlc2NyaXB0aW9uPgogICA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgp+x0mNAAAAWUlEQVQIHV2OUQrAMAhDNaX01vverXYPL1IES9ca1o99GB8moioic5Xgup/dBWZGKKUQ5syIoNbKyRiDkLoEB9ydVmuNANBF7/1nnS1VpXWORgQnH+xA/vECGrAYeIZg8CAAAAAASUVORK5CYII=) no-repeat right center, url(data:image/png;base64,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
background-size: contain, cover;
2024-05-26 14:17:04 -07:00
outline:none;
2024-05-27 07:46:54 -07:00
box-shadow: none;
border: none;
2024-05-26 14:17:04 -07:00
}
html, body {
2024-05-27 07:46:54 -07:00
height: -webkit-fill-available !important;
touch-action: pan-x pan-y;
2024-05-26 14:17:04 -07:00
}
`;
document.documentElement.appendChild(customStyle);
// Lazy way to hide touch controls through CSS.
let inGameStyle = document.createElement("style");
inGameStyle.id = "inGameStyle";
inGameStyle.textContent = `
.inGame {
2024-05-26 14:17:04 -07:00
display: none;
}`;
document.documentElement.appendChild(inGameStyle);
let inMenuStyle = document.createElement("style");
inMenuStyle.id = "inMenuStyle";
inMenuStyle.textContent = `
.inMenu {
2024-05-26 14:17:04 -07:00
display: none;
}`;
document.documentElement.appendChild(inMenuStyle);
2024-05-26 14:17:04 -07:00
// The canvas is created by the client after it finishes unzipping and loading. When the canvas is created, this applies any necessary event listeners
function waitForElm(selector) {
return new Promise(resolve => {
if (document.querySelector(selector)) {
return resolve(document.querySelector(selector));
}
const observer = new MutationObserver(mutations => {
if (document.querySelector(selector)) {
observer.disconnect();
resolve(document.querySelector(selector));
}
});
observer.observe(document.documentElement, {
childList: true,
subtree: true
});
});
}
function createTouchButton(buttonClass, buttonDisplay, elementName) {
var touchButton = document.createElement(elementName ?? 'button');
touchButton.classList.add(buttonClass);
touchButton.classList.add(buttonDisplay);
touchButton.classList.add("mobileControl");
touchButton.addEventListener("touchmove", function(e){e.preventDefault()}, false);
return touchButton;
}
2024-05-26 14:17:04 -07:00
waitForElm('canvas').then(() => {insertCanvasElements()});
function insertCanvasElements() {
// Translates touchmove events to mousemove events when inGame, and touchmove events to wheele events when inMenu
2024-05-26 14:17:04 -07:00
var canvas = document.querySelector('canvas');
canvas.addEventListener("touchmove", (e) => {
const touch = e.targetTouches[0]; // We can get away with this because every other touch event will be on different elements
if (!previousTouchX) {
previousTouchX = touch.pageX;
previousTouchY = touch.pageY;
2024-05-26 14:17:04 -07:00
}
e.movementX = touch.pageX - previousTouchX;
e.movementY = touch.pageY - previousTouchY;
2024-05-28 07:08:27 -07:00
var evt = window.fakelock ? new MouseEvent("mousemove", {movementX: e.movementX, movementY: e.movementY}) : new WheelEvent("wheel", {"wheelDeltaY": e.movementY});
2024-05-26 14:17:04 -07:00
canvas.dispatchEvent(evt);
previousTouchX = touch.pageX;
previousTouchY = touch.pageY;
2024-05-26 14:17:04 -07:00
event.preventDefault();
}, false);
canvas.addEventListener("touchend", (e) => {
previousTouchX = null;
previousTouchY = null;
2024-05-26 14:17:04 -07:00
}, false)
//Updates button visibility on load
setButtonVisibility(window.fakelock != null);
2024-05-26 14:17:04 -07:00
// Adds all of the touch screen controls
// Theres probably a better way to do this but this works for now
let forwardButton = createTouchButton("forwardButton", "inGame");
forwardButton.textContent = "▲";
forwardButton.style.cssText = "left:10vh;bottom:20vh;"
forwardButton.addEventListener("touchstart", function(e){keyEvent("w", "keydown")}, false);
forwardButton.addEventListener("touchend", function(e){keyEvent("w", "keyup")}, false);
document.body.appendChild(forwardButton);
let rightButton = createTouchButton("rightButton", "inGame");
rightButton.textContent = "▶";
rightButton.style.cssText = "left:20vh;bottom:10vh;"
rightButton.addEventListener("touchstart", function(e){keyEvent("d", "keydown")}, false);
rightButton.addEventListener("touchend", function(e){keyEvent("d", "keyup")}, false);
document.body.appendChild(rightButton);
let leftButton = createTouchButton("leftButton", "inGame");
leftButton.textContent = "◀";
leftButton.style.cssText = "left: 0vh; bottom:10vh;"
leftButton.addEventListener("touchstart", function(e){keyEvent("a", "keydown")}, false);
leftButton.addEventListener("touchend", function(e){keyEvent("a", "keyup")}, false);
document.body.appendChild(leftButton);
let backButton = createTouchButton("backButton", "inGame");
backButton.textContent = "▼";
backButton.style.cssText = "left:10vh;bottom:0vh;"
backButton.addEventListener("touchstart", function(e){keyEvent("s", "keydown")}, false);
backButton.addEventListener("touchend", function(e){keyEvent("s", "keyup")}, false);
document.body.appendChild(backButton);
let jumpButton = createTouchButton("jumpButton", "inGame");
jumpButton.textContent = "⇧";
jumpButton.style.cssText = "right:10vh;bottom:10vh;"
jumpButton.addEventListener("touchstart", function(e){keyEvent(" ", "keydown")}, false);
jumpButton.addEventListener("touchend", function(e){keyEvent(" ", "keyup")}, false);
document.body.appendChild(jumpButton);
let crouchButton = createTouchButton("crouchButton", "inGame");
crouchButton.textContent = "⇩";
crouchButton.style.cssText = "left:10vh;bottom:10vh;"
crouchButton.addEventListener("touchstart", function(e){shiftKeyEvent("keydown")}, false);
crouchButton.addEventListener("touchend", function(e){shiftKeyEvent("keyup")}, false);
document.body.appendChild(crouchButton);
let inventoryButton = createTouchButton("inventoryButton", "inGame");
inventoryButton.textContent = "🎒";
inventoryButton.style.cssText = "right:0vh;bottom:0vh;"
inventoryButton.addEventListener("touchstart", function(e){keyEvent("e", "keydown")}, false);
inventoryButton.addEventListener("touchend", function(e){keyEvent("e", "keyup")}, false);
document.body.appendChild(inventoryButton);
let chatButton = createTouchButton("chatButton", "inGame");
chatButton.textContent = "💬";
chatButton.style.cssText = "right:0vh;top:0vh;"
chatButton.addEventListener("touchstart", function(e){keyEvent("t", "keydown")}, false);
chatButton.addEventListener("touchend", function(e){keyEvent("t", "keyup")}, false);
document.body.appendChild(chatButton);
let exitButton = createTouchButton("exitButton", "inAll");
exitButton.textContent = "⮐";
exitButton.style.cssText = "left:0vh;top:0vh;"
exitButton.addEventListener("touchstart", function(e){keyEvent("À", "keydown")}, false);
exitButton.addEventListener("touchend", function(e){keyEvent("À", "keyup")}, false);
document.body.appendChild(exitButton);
// input for keyboard button
let hiddenInput = document.createElement('input');
hiddenInput.id = "hiddenInput"
hiddenInput.style.cssText = "opacity:0;z-index:-99999";
document.body.appendChild(hiddenInput);
let keyboardButton = createTouchButton("keyboardButton", "inMenu");
keyboardButton.textContent = "⌨️";
keyboardButton.style.cssText = "left:10vh;top:0vh;"
keyboardButton.addEventListener("touchstart", function(e){e.preventDefault();hiddenInput.blur()}, false);
keyboardButton.addEventListener("touchend", function(e){hiddenInput.select()}, false);
document.body.appendChild(keyboardButton);
let placeButton = createTouchButton("placeButton", "inGame");
placeButton.textContent = "⊹";
placeButton.style.cssText = "right:0vh;bottom:20vh;"
placeButton.addEventListener("touchstart", function(e){mouseEvent(2, "mousedown", canvas)}, false);
placeButton.addEventListener("touchend", function(e){mouseEvent(2, "mouseup", canvas)}, false);
document.body.appendChild(placeButton);
let breakButton = createTouchButton("breakButton", "inGame");
breakButton.textContent = "🗡";
breakButton.style.cssText = "right:10vh;bottom:20vh;"
breakButton.addEventListener("touchstart", function(e){mouseEvent(0, "mousedown", canvas)}, false);
breakButton.addEventListener("touchend", function(e){mouseEvent(0, "mouseup", canvas)}, false);
document.body.appendChild(breakButton);
let selectButton = createTouchButton("selectButton", "inGame");
selectButton.textContent = "⬚";
selectButton.style.cssText = "right:20vh;bottom:20vh;"
selectButton.addEventListener("touchstart", function(e){mouseEvent(1, "mousedown", canvas)}, false);
selectButton.addEventListener("touchend", function(e){mouseEvent(1, "mouseup", canvas)}, false);
document.body.appendChild(selectButton);
let scrollUpButton = createTouchButton("scrollUpButton", "inGame");
scrollUpButton.textContent = "⇨";
scrollUpButton.style.cssText = "right:0vh;bottom:30vh;"
scrollUpButton.addEventListener("touchstart", function(e){wheelEvent(canvas, -10)}, false);
document.body.appendChild(scrollUpButton);
let scrollDownButton = createTouchButton("scrollDownButton", "inGame");
scrollDownButton.textContent = "⇦";
scrollDownButton.style.cssText = "right:10vh;bottom:30vh;"
scrollDownButton.addEventListener("touchstart", function(e){wheelEvent(canvas, 10)}, false);
document.body.appendChild(scrollDownButton);
let throwButton = createTouchButton("throwButton", "inGame");
throwButton.textContent = "Q";
throwButton.style.cssText = "right:0vh;bottom:10vh;"
throwButton.addEventListener("touchstart", function(e){keyEvent("q", "keydown")}, false);
throwButton.addEventListener("touchend", function(e){keyEvent("q", "keyup")}, false);
document.body.appendChild(throwButton);
2024-05-26 14:17:04 -07:00
}