538 lines
29 KiB
Plaintext
538 lines
29 KiB
Plaintext
<!DOCTYPE html>
|
|
|
|
|
|
|
|
<!--
|
|
|
|
This file is from ${date}, there is no official eagler download link anymore, check the websites and discords of your favorite eagler servers for new versions
|
|
|
|
Be aware that some server owners are lazy and do not update their client regularly
|
|
|
|
Compile it yourself here: https://gitlab.com/lax1dude/eaglercraftx-1.8/
|
|
|
|
-->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<html>
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="description" content="EaglercraftX 1.8 Offline" />
|
|
<meta name="keywords" content="eaglercraft, eaglercraftx, minecraft, 1.8, 1.8.8" />
|
|
<title>EaglercraftX 1.8</title>
|
|
<meta property="og:locale" content="en-US" />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:title" content="EaglercraftX 1.8 Offline" />
|
|
<meta property="og:description" content="this file is not a website, whoever uploaded it to this URL is a dumbass" />
|
|
<script type="text/javascript">
|
|
function initAPI(version) {
|
|
var ModAPI = {};
|
|
ModAPI.events = {};
|
|
ModAPI.events.types = ["event"];
|
|
ModAPI.events.listeners = { "event": [] };
|
|
ModAPI.globals = {};
|
|
ModAPI.version = version;
|
|
|
|
ModAPI.addEventListener = function AddEventListener(name, callback) {
|
|
if (!callback) {
|
|
throw new Error("Invalid callback!");
|
|
}
|
|
if (ModAPI.events.types.includes(name)) {
|
|
if (!Array.isArray(ModAPI.events.listeners[name])) {
|
|
ModAPI.events.listeners[name] = [];
|
|
}
|
|
ModAPI.events.listeners[name].push(callback);
|
|
console.log("Added new event listener.");
|
|
} else {
|
|
throw new Error("This event does not exist!");
|
|
}
|
|
};
|
|
|
|
ModAPI.removeEventListener = function removeEventListener(name, func, slow) {
|
|
if (!func) {
|
|
throw new Error("Invalid callback!");
|
|
}
|
|
if (!Array.isArray(ModAPI.events.listeners[name])) {
|
|
ModAPI.events.listeners[name] = [];
|
|
}
|
|
var targetArr = ModAPI.events.listeners[name];
|
|
if (!slow) {
|
|
if (targetArr.indexOf(func) !== -1) {
|
|
targetArr.splice(targetArr.indexOf(func), 1);
|
|
console.log("Removed event listener.");
|
|
}
|
|
} else {
|
|
var functionString = func.toString();
|
|
targetArr.forEach((f, i) => {
|
|
if (f.toString() === functionString) {
|
|
targetArr.splice(i, 1);
|
|
console.log("Removed event listener.");
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
ModAPI.events.newEvent = function newEvent(name) {
|
|
ModAPI.events.types.push(name);
|
|
};
|
|
|
|
ModAPI.events.callEvent = function callEvent(name, data) {
|
|
if (
|
|
!ModAPI.events.types.includes(name) ||
|
|
!Array.isArray(ModAPI.events.listeners[name])
|
|
) {
|
|
if (!Array.isArray(ModAPI.events.listeners[name])) {
|
|
if (ModAPI.events.types.includes(name)) {
|
|
ModAPI.events.listeners.event.forEach((func) => {
|
|
func({ event: name, data: data });
|
|
});
|
|
return;
|
|
}
|
|
return;
|
|
}
|
|
console.error(
|
|
"The ModAPI has been called with an invalid event name: " + name
|
|
);
|
|
console.error("Please report this bug to the repo.");
|
|
return;
|
|
}
|
|
ModAPI.events.listeners[name].forEach((func) => {
|
|
func(data);
|
|
});
|
|
ModAPI.events.listeners.event.forEach((func) => {
|
|
func({ event: name, data: data });
|
|
});
|
|
|
|
ModAPI.globals._initUpdate();
|
|
};
|
|
|
|
ModAPI.updateComponent = function updateComponent(component) {
|
|
if (
|
|
typeof component !== "string" ||
|
|
ModAPI[component] === null ||
|
|
ModAPI[component] === undefined
|
|
) {
|
|
return;
|
|
}
|
|
if (!ModAPI.globals || !ModAPI.globals.onGlobalsUpdate) {
|
|
return;
|
|
}
|
|
if (!ModAPI.globals.toUpdate) {
|
|
ModAPI.globals.toUpdate = [];
|
|
}
|
|
if (ModAPI.globals.toUpdate.indexOf(component) === -1) {
|
|
ModAPI.globals.toUpdate.push(component);
|
|
}
|
|
};
|
|
|
|
ModAPI.require = function require(component) {
|
|
if (typeof component !== "string") {
|
|
return;
|
|
}
|
|
if (!ModAPI.globals || !ModAPI.globals.onRequire) {
|
|
return;
|
|
}
|
|
ModAPI.globals.onRequire(component);
|
|
};
|
|
|
|
ModAPI.globals._initUpdate = function _initUpdate() {
|
|
if (!ModAPI.globals.toUpdate) {
|
|
ModAPI.globals.toUpdate = [];
|
|
}
|
|
ModAPI.globals.toUpdate.forEach((id) => {
|
|
ModAPI.globals.onGlobalsUpdate(id);
|
|
});
|
|
ModAPI.globals.toUpdate = [];
|
|
};
|
|
|
|
window.ModAPI = ModAPI;
|
|
}
|
|
</script>
|
|
<script type="text/javascript">
|
|
function loadLoader() {
|
|
window.ModLoader = function ModLoader(ModsArr) {
|
|
if (!window.eaglerMLoaderMainRun) {
|
|
var searchParams = new URLSearchParams(location.search);
|
|
searchParams.getAll("Mod").forEach((ModToAdd) => {
|
|
console.log(
|
|
"EaglerML: Adding Mod to loadlist from search params: " + ModToAdd
|
|
);
|
|
ModsArr.push(ModToAdd);
|
|
});
|
|
if (
|
|
!!eaglercraftXOpts &&
|
|
!!eaglercraftXOpts.Mods &&
|
|
Array.isArray(eaglercraftXOpts.Mods)
|
|
) {
|
|
eaglercraftXOpts.Mods.forEach((ModToAdd) => {
|
|
console.log(
|
|
"EaglerML: Adding Mod to loadlist from eaglercraftXOpts: " +
|
|
ModToAdd
|
|
);
|
|
ModsArr.push(ModToAdd);
|
|
});
|
|
}
|
|
window.eaglerMLoaderMainRun = true;
|
|
}
|
|
if (window.noLoadMods === true) {
|
|
ModsArr.splice(0, ModsArr.length);
|
|
}
|
|
function checkModsLoaded(totalLoaded, identifier) {
|
|
console.log(
|
|
"EaglerML: Checking if Mods are finished :: " +
|
|
totalLoaded +
|
|
"/" +
|
|
ModsArr.length
|
|
);
|
|
if (totalLoaded >= ModsArr.length) {
|
|
clearInterval(identifier);
|
|
window.ModGracePeriod = false;
|
|
if (
|
|
window.eaglerMLoaderMainRun &&
|
|
ModAPI &&
|
|
ModAPI.events &&
|
|
ModAPI.events.callEvent
|
|
) {
|
|
ModAPI.events.callEvent("load", {});
|
|
}
|
|
console.log(
|
|
"EaglerML: Checking if Mods are finished :: All Mods loaded! Grace period off."
|
|
);
|
|
}
|
|
}
|
|
function methodB(currentMod) {
|
|
try {
|
|
console.log("EaglerML: Loading " + currentMod + " via method B.");
|
|
var script = document.createElement("script");
|
|
script.src = currentMod;
|
|
script.setAttribute("data-Mod", currentMod);
|
|
script.setAttribute("data-isMod", true);
|
|
script.onerror = () => {
|
|
console.log(
|
|
"EaglerML: Failed to load " + currentMod + " via method B!"
|
|
);
|
|
script.remove();
|
|
totalLoaded++;
|
|
};
|
|
script.onload = () => {
|
|
console.log(
|
|
"EaglerML: Successfully loaded " + currentMod + " via method B."
|
|
);
|
|
totalLoaded++;
|
|
};
|
|
document.body.appendChild(script);
|
|
} catch (error) {
|
|
console.log(
|
|
"EaglerML: Oh no! The Mod " + currentMod + " failed to load!"
|
|
);
|
|
totalLoaded++;
|
|
}
|
|
}
|
|
window.ModGracePeriod = true;
|
|
var totalLoaded = 0;
|
|
var loaderCheckInterval = null;
|
|
ModsArr.forEach((c) => {
|
|
let currentMod = c;
|
|
console.log("EaglerML: Starting " + currentMod);
|
|
try {
|
|
var req = new XMLHttpRequest();
|
|
req.open("GET", currentMod);
|
|
req.onload = function xhrLoadHandler() {
|
|
console.log("EaglerML: Loading " + currentMod + " via method A.");
|
|
var script = document.createElement("script");
|
|
try {
|
|
script.src =
|
|
"data:text/javascript," + encodeURIComponent(req.responseText);
|
|
} catch (error) {
|
|
methodB(currentMod);
|
|
return;
|
|
}
|
|
script.setAttribute("data-Mod", currentMod);
|
|
script.setAttribute("data-isMod", true);
|
|
script.onerror = () => {
|
|
console.log(
|
|
"EaglerML: Failed to load " + currentMod + " via method A!"
|
|
);
|
|
script.remove();
|
|
totalLoaded++;
|
|
};
|
|
script.onload = () => {
|
|
console.log(
|
|
"EaglerML: Successfully loaded " + currentMod + " via method A."
|
|
);
|
|
totalLoaded++;
|
|
};
|
|
document.body.appendChild(script);
|
|
};
|
|
req.onerror = function xhrErrorHandler() {
|
|
methodB(currentMod);
|
|
};
|
|
req.send();
|
|
} catch (error) {
|
|
methodB(currentMod);
|
|
}
|
|
});
|
|
loaderCheckInterval = setInterval(() => {
|
|
checkModsLoaded(totalLoaded, loaderCheckInterval);
|
|
}, 500);
|
|
console.log(
|
|
"EaglerML: Starting to load " + ModsArr.length + " Mods..."
|
|
);
|
|
window.returntotalloadedmods = function returntotalloadedmods(){
|
|
return totalLoaded
|
|
}
|
|
};
|
|
}
|
|
</script>
|
|
<script type="text/javascript">
|
|
function displayGui() {
|
|
function gui() {
|
|
if (document.querySelector("#eaglerpl_gui")) {
|
|
document.querySelector("#eaglerpl_gui").remove();
|
|
}
|
|
localStorage.setItem(
|
|
"ml::Mods",
|
|
localStorage.getItem("ml::Mods") || "[]"
|
|
);
|
|
try {
|
|
localStorage.setItem(
|
|
"ml::Mods",
|
|
JSON.stringify(JSON.parse(localStorage.getItem("ml::Mods")))
|
|
);
|
|
} catch (error) {
|
|
localStorage.setItem("ml::Mods", "[]");
|
|
}
|
|
var Mods = JSON.parse(localStorage.getItem("ml::Mods"));
|
|
var container = document.createElement("div");
|
|
container.id = "eaglerpl_gui";
|
|
container.style = `width:100%; height: 100%; position: fixed; top: 0; left: 0; z-index: 10; color: white; font-family: Minecraftia, sans-serif; overflow-y: scroll; overflow-x: hidden; background-image: url(data:image/png;base64,UklGRhoBAABXRUJQVlA4TA0BAAAvn8AnAIWjtpEECdnA2N0DsTROy7xUqfrWw0jbyLkJKTz0+I20jTT/Bo89e1YR/Wfktm0Y+wNKLobT7QP/n/B7Z/naW26QHoTpHB7LFouyKHlzeHxfCStSuj9KdbC8z1IJ5iWiyQed48vtYJ+lUu0t4VwranS1XMIutSiLYlbb8G54uf2p3VPSfRZtSrlsPFjOzZZrd/us3B3uK+HcHJQql+xbLMrS/WqNpm6DeZ/VIPVYaN/KzUbp91nd9xl5pYu50dU2W417nbdTj5l2Ne92uM9qXNpyf6+oXkabHKXaZ1HS4Iaqpim+1KIJ+0M49/LjNbTGP5mrrMZEuc7Uzcb1ViOJ6TuOt4NGJs+zDgA=); background-color: rgb(60,60,60); background-blend-mode: multiply; background-size: 64px;`;
|
|
var title = document.createElement("h1");
|
|
title.style = "text-shadow: 0px 0px 4px;";
|
|
title.innerHTML = "Mod Manager";
|
|
var closeButton = document.createElement("a");
|
|
closeButton.style = `margin-left: 2rem; color: red;`;
|
|
closeButton.href = "javascript:void(0)";
|
|
closeButton.addEventListener("click", () => {
|
|
document.querySelector("#eaglerpl_gui").remove();
|
|
});
|
|
closeButton.innerHTML = "[X]";
|
|
title.appendChild(closeButton);
|
|
container.appendChild(title);
|
|
|
|
var warningPoster = document.createElement("p");
|
|
warningPoster.style = "font-size: 0.8rem; color: orangered;";
|
|
warningPoster.innerHTML =
|
|
"Warning: Installing Mods gives them full control over the game. Be cautious when installing them.<br>Mods that have been removed also need a reload to stop running in the background.";
|
|
container.appendChild(warningPoster);
|
|
|
|
var tipPoster = document.createElement("p");
|
|
tipPoster.style = "font-size: 0.8rem; color: yellow;";
|
|
tipPoster.innerHTML =
|
|
"Tip: if the mods say that they failed loading, try refreshing the gui";
|
|
container.appendChild(tipPoster);
|
|
|
|
var table = document.createElement("table");
|
|
table.style = "table-layout: fixed; width: 100%";
|
|
var headerRow = document.createElement("tr");
|
|
headerRow.style = "background: rgb(50,50,50);";
|
|
var urlBox = document.createElement("th");
|
|
urlBox.style = "text-align: center;";
|
|
urlBox.innerHTML = "URL";
|
|
headerRow.appendChild(urlBox);
|
|
var statusBox = document.createElement("th");
|
|
statusBox.style = "text-align: center; width: 15%;";
|
|
statusBox.innerHTML = "Status";
|
|
headerRow.appendChild(statusBox);
|
|
table.appendChild(headerRow);
|
|
|
|
Mods.forEach((url) => {
|
|
var row = document.createElement("tr");
|
|
row.style = `box-shadow: 0px 2px 0px grey;`;
|
|
var urlBox = document.createElement("td");
|
|
urlBox.style = "user-select: text;";
|
|
var textWrapper = document.createElement("div");
|
|
textWrapper.style = `max-width: 100%; overflow-wrap: anywhere; max-height: 3rem; overflow-y: scroll;`;
|
|
textWrapper.innerText = url;
|
|
urlBox.append(textWrapper);
|
|
row.appendChild(urlBox);
|
|
var statusBox = document.createElement("td");
|
|
statusBox.innerHTML = ((curl) => {
|
|
var targs = document.querySelectorAll("script[data-Mod]");
|
|
for (let i = 0; i < targs.length; i++) {
|
|
const elem = targs[i];
|
|
if (elem.getAttribute("data-Mod") === curl) {
|
|
return "LOADED";
|
|
}
|
|
}
|
|
return "FAILED";
|
|
})(url);
|
|
switch (statusBox.innerHTML) {
|
|
case "LOADED":
|
|
statusBox.style = "background-color: green; text-align: center;";
|
|
break;
|
|
case "FAILED":
|
|
statusBox.style = "background-color: dimgrey; text-align: center;";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
var binBtn = document.createElement("button");
|
|
binBtn.style =
|
|
"background: transparent; text-align: center; color: yellow; cursor: pointer; font-family: 'Minecraftia', sans-serif; text-decoration: underline; border: 0; margin-left: 1rem; font-size: 1rem;";
|
|
binBtn.innerHTML = "[X]";
|
|
binBtn.addEventListener("click", () => {
|
|
if (!window.confirm("Delete Mod?") || Mods.indexOf(url) === -1) {
|
|
return;
|
|
}
|
|
Mods.splice(Mods.indexOf(url), 1);
|
|
localStorage.setItem("ml::Mods", JSON.stringify(Mods));
|
|
gui();
|
|
});
|
|
statusBox.appendChild(binBtn);
|
|
row.appendChild(statusBox);
|
|
table.appendChild(row);
|
|
});
|
|
|
|
var addBtn = document.createElement("button");
|
|
addBtn.style =
|
|
"background: transparent; text-align: center; color: yellow; cursor: pointer; font-family: 'Minecraftia', sans-serif; text-decoration: underline; border: 0; margin-right: 1rem; font-size: 1rem;";
|
|
addBtn.innerHTML = "Add new";
|
|
addBtn.addEventListener("click", () => {
|
|
var newMod = window.prompt("URL of Mod: ", "http://example.com/example.js");
|
|
if (!newMod) {
|
|
return; //User pressed cancel
|
|
}
|
|
Mods.push(
|
|
newMod
|
|
);
|
|
localStorage.setItem("ml::Mods", JSON.stringify(Mods));
|
|
if(window.ModLoader){
|
|
ModLoader([newMod]);
|
|
}
|
|
gui();
|
|
});
|
|
|
|
var uploadBtn = document.createElement("button");
|
|
uploadBtn.style =
|
|
"background: transparent; text-align: center; color: yellow; cursor: pointer; font-family: 'Minecraftia', sans-serif; text-decoration: underline; border: 0; font-size: 1rem;";
|
|
uploadBtn.innerHTML = "Upload...";
|
|
uploadBtn.addEventListener("click", function uploadBtnListener() {
|
|
var filePicker = document.createElement("input");
|
|
filePicker.type = "file";
|
|
filePicker.accept = ".js";
|
|
filePicker.addEventListener("input", function onInput() {
|
|
if (filePicker.files[0]) {
|
|
var reader = new FileReader();
|
|
reader.addEventListener("load", function onModRead() {
|
|
var newMod = reader.result.replace(";base64", `;fs=${encodeURIComponent(filePicker.files[0].name) || "unknown"};base64`);
|
|
Mods.push(newMod);
|
|
localStorage.setItem("ml::Mods", JSON.stringify(Mods));
|
|
if(window.ModLoader){
|
|
ModLoader([newMod]);
|
|
}
|
|
gui();
|
|
});
|
|
reader.readAsDataURL(filePicker.files[0]);
|
|
}
|
|
});
|
|
filePicker.click();
|
|
});
|
|
|
|
container.appendChild(table);
|
|
container.appendChild(addBtn);
|
|
container.appendChild(uploadBtn);
|
|
|
|
var notice = document.createElement("a");
|
|
notice.innerHTML = "Refresh GUI";
|
|
notice.href = "javascript:void(0)";
|
|
notice.addEventListener("click", function reloadListener() {
|
|
setTimeout(gui, 500);
|
|
this.remove();
|
|
});
|
|
notice.style =
|
|
"color: yellow; display: block; margin-top: 2rem; width: 0; white-space: nowrap;";
|
|
container.appendChild(notice);
|
|
ModAPI.events.callEvent("gui", {});
|
|
document.body.appendChild(container);
|
|
}
|
|
gui();
|
|
}
|
|
</script>
|
|
<script type="text/javascript">
|
|
"use strict";
|
|
const relayId = Math.floor(Math.random() * 3);
|
|
|
|
// %%%%%%%%% launch options %%%%%%%%%%%%
|
|
|
|
window.eaglercraftXOpts = {
|
|
container: "game_frame",
|
|
worldsDB: "worlds",
|
|
relays: [
|
|
{ addr: "wss://relay.deev.is/", comment: "lax1dude relay #1", primary: relayId == 0 },
|
|
{ addr: "wss://relay.lax1dude.net/", comment: "lax1dude relay #2", primary: relayId == 1 },
|
|
{ addr: "wss://relay.shhnowisnottheti.me/", comment: "ayunami relay #1", primary: relayId == 2 }
|
|
]
|
|
};
|
|
|
|
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
|
|
|
</script>
|
|
<script type="text/javascript">
|
|
"use strict";
|
|
if(typeof window !== "undefined") window.eaglercraftXClientScriptElement = document.currentScript;
|
|
${classes_js}
|
|
</script>
|
|
<script type="text/javascript">
|
|
"use strict";
|
|
window.eaglercraftXOpts.assetsURI = ${assets_epk};
|
|
|
|
var launchInterval = -1;
|
|
var launchCounter = 1;
|
|
var launchCountdownNumberElement = null;
|
|
var launchCountdownProgressElement = null;
|
|
|
|
function launchTick() {
|
|
launchCountdownNumberElement.innerText = "" + Math.floor(6.0 - launchCounter * 0.06);
|
|
launchCountdownProgressElement.style.width = "" + launchCounter + "%";
|
|
if(++launchCounter > 100) {
|
|
clearInterval(launchInterval);
|
|
setTimeout(() => { document.getElementById("launch_countdown_screen").remove(); main(); }, 50);
|
|
}
|
|
}
|
|
|
|
window.addEventListener("load", () => {
|
|
launchCountdownNumberElement = document.getElementById("launchCountdownNumber");
|
|
launchCountdownProgressElement = document.getElementById("launchCountdownProgress");
|
|
launchInterval = setInterval(launchTick, 50);
|
|
});
|
|
function safeLaunch() {
|
|
window.noLoadMods = true;
|
|
clearInterval(launchInterval);
|
|
setTimeout(() => { document.getElementById("launch_countdown_screen").remove(); main(); }, 50);
|
|
}
|
|
</script>
|
|
<link type="image/png" rel="shortcut icon" href="data:image/png;base64,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" />
|
|
</head>
|
|
<body style="margin:0px;width:100vw;height:100vh;overflow:hidden;" id="game_frame">
|
|
<div style="margin:0px;width:100%;height:100%;font-family:sans-serif;display:flex;align-items:center;user-select:none;" id="launch_countdown_screen">
|
|
<div style="margin:auto;text-align:center;">
|
|
<h1>This file is from <span style="color:#AA0000;">${date}</span></h1>
|
|
<h2>Game will launch in <span id="launchCountdownNumber">5</span>...</h2>
|
|
<div style="border:2px solid black;width:100%;height:15px;padding:1px;margin-bottom:20vh;"><div id="launchCountdownProgress" style="background-color:#555555;width:0%;height:100%;"></div></div>
|
|
<a href="javascript:void(0)" onclick="safeLaunch()"><code>[load without mods]</code></a>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
</html>
|