mirror of
https://github.com/zumbiepig/MineXLauncher.git
synced 2025-06-08 09:24:48 +00:00
shaun pls fix, the function works but not the button
This commit is contained in:
parent
369020cb53
commit
22ae488d08
@ -20,6 +20,7 @@
|
|||||||
"errorhandler": "^1.5.1",
|
"errorhandler": "^1.5.1",
|
||||||
"express": "^4.19.2",
|
"express": "^4.19.2",
|
||||||
"helmet": "^7.1.0",
|
"helmet": "^7.1.0",
|
||||||
|
"indexeddb-export-import": "^2.1.5",
|
||||||
"morgan": "^1.10.0",
|
"morgan": "^1.10.0",
|
||||||
"pako": "^2.1.0",
|
"pako": "^2.1.0",
|
||||||
"semver": "^7.6.3",
|
"semver": "^7.6.3",
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
105
src/console/index.html
Normal file
105
src/console/index.html
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" style="display: none">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>MineXLauncher</title>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/webp"
|
||||||
|
href="/resources/images/icons/favicon.webp"
|
||||||
|
/>
|
||||||
|
<link rel="stylesheet" href="/resources/styles/themes/default.css" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
id="theme"
|
||||||
|
onload="document.documentElement.style.display = ''"
|
||||||
|
/>
|
||||||
|
<script src="/resources/scripts/google-tag.js"></script>
|
||||||
|
<script src="/resources/scripts/main.js"></script>
|
||||||
|
<style>
|
||||||
|
.console .debug {
|
||||||
|
color: darkgray;
|
||||||
|
}
|
||||||
|
.console .log {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
.console .info {
|
||||||
|
color: blue;
|
||||||
|
}
|
||||||
|
.console .warn {
|
||||||
|
color: orange;
|
||||||
|
}
|
||||||
|
.console .error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="ads-container">
|
||||||
|
<ins
|
||||||
|
class="adsbygoogle"
|
||||||
|
style="display: block"
|
||||||
|
data-ad-client="ca-pub-1132419379737567"
|
||||||
|
data-ad-slot="3280170072"
|
||||||
|
data-ad-format="auto"
|
||||||
|
data-full-width-responsive="true"
|
||||||
|
></ins>
|
||||||
|
</div>
|
||||||
|
<div class="launcher">
|
||||||
|
<span class="title-bar">MineXLauncher</span>
|
||||||
|
<div class="content">
|
||||||
|
<div class="sidebar">
|
||||||
|
<span class="username"></span>
|
||||||
|
<nav class="nav-bar">
|
||||||
|
<li onclick="navigate.updates()">
|
||||||
|
<img src="/resources/images/icons/nav/updates.webp" />
|
||||||
|
<span>Updates</span>
|
||||||
|
</li>
|
||||||
|
<li class="selected" onclick="navigate.home.game()">
|
||||||
|
<img src="/resources/images/icons/nav/game.webp" />
|
||||||
|
<span>Game</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.servers()">
|
||||||
|
<img src="/resources/images/icons/nav/servers.webp" />
|
||||||
|
<span>Server List</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.mods.mods()">
|
||||||
|
<img src="/resources/images/icons/nav/mods.webp" />
|
||||||
|
<span>Mods</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.articles()">
|
||||||
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
|
<span>Tutorials</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.settings.general()">
|
||||||
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
|
<span>Settings</span>
|
||||||
|
</li>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="main-panel">
|
||||||
|
<div class="main-content">
|
||||||
|
<div class="console"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom-bar">
|
||||||
|
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||||
|
>Join the MineXLauncher Discord</span
|
||||||
|
>
|
||||||
|
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ads-container">
|
||||||
|
<ins
|
||||||
|
class="adsbygoogle"
|
||||||
|
style="display: block"
|
||||||
|
data-ad-client="ca-pub-1132419379737567"
|
||||||
|
data-ad-slot="3280170072"
|
||||||
|
data-ad-format="auto"
|
||||||
|
data-full-width-responsive="true"
|
||||||
|
></ins>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
// @ts-nocheck
|
|
||||||
window.addEventListener('load', () => {
|
|
||||||
const relayId = Math.floor(Math.random() * 3);
|
|
||||||
window.eaglercraftXOpts = {
|
|
||||||
container: 'game_frame',
|
|
||||||
assetsURI: `${window.location.pathname}/assets.epk`,
|
|
||||||
localesURI: `${window.location.pathname}/lang/`,
|
|
||||||
servers: [
|
|
||||||
{ addr: 'wss://mc.ricenetwork.xyz', name: 'Rice Network' },
|
|
||||||
{ addr: 'wss://mc.lamplifesteal.xyz', name: 'LampLifesteal' },
|
|
||||||
{ addr: 'wss://electronmc.club', name: 'Electron Network' },
|
|
||||||
{ addr: 'wss://play.brickmc.net', name: 'BrickMC' },
|
|
||||||
],
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
const storage = {
|
|
||||||
local: {
|
|
||||||
get: function (key: string) {
|
|
||||||
const item = localStorage.getItem('minexlauncher');
|
|
||||||
if (item !== null) {
|
|
||||||
const json = JSON.parse(item);
|
|
||||||
if (json[key] !== undefined) {
|
|
||||||
return json[key];
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const urlParams = new URLSearchParams(window.location.search);
|
|
||||||
window.eaglercraftXOpts.joinServer = urlParams.get('server') ?? undefined;
|
|
||||||
window.eaglercraftXOpts.Mods = storage.local.get('mods') ?? [];
|
|
||||||
|
|
||||||
history.replaceState({}, '', '/play');
|
|
||||||
main();
|
|
||||||
});
|
|
@ -1,5 +1,6 @@
|
|||||||
import { gt, coerce } from 'semver';
|
import { gt, coerce } from 'semver';
|
||||||
import { inflate, deflate } from 'pako';
|
import { inflate, deflate } from 'pako';
|
||||||
|
import idbExportImport from 'indexeddb-export-import';
|
||||||
|
|
||||||
let selectedVersion: string | undefined = undefined;
|
let selectedVersion: string | undefined = undefined;
|
||||||
let articleAnimationLock = false;
|
let articleAnimationLock = false;
|
||||||
@ -47,23 +48,78 @@ const versionSelector = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function consoleLog(
|
||||||
|
type: 'debug' | 'log' | 'info' | 'warn' | 'error',
|
||||||
|
msg: string,
|
||||||
|
) {
|
||||||
|
const consoleElement = document.querySelector('.console');
|
||||||
|
if (consoleElement) {
|
||||||
|
const messageElement = document.createElement('p');
|
||||||
|
messageElement.classList.add(type);
|
||||||
|
messageElement.innerText = msg;
|
||||||
|
consoleElement.appendChild(messageElement);
|
||||||
|
storage.session.set(
|
||||||
|
'console',
|
||||||
|
base64Gzip.compress(consoleElement.innerHTML),
|
||||||
|
);
|
||||||
|
consoleElement.scroll(0, consoleElement.scrollHeight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const game = {
|
const game = {
|
||||||
play: function (version?: string) {
|
play: function (version?: string) {
|
||||||
if (version) {
|
version = version ?? selectedVersion;
|
||||||
document.body.style.display = 'none';
|
if (!version) {
|
||||||
storage.session.set('lastGame', version);
|
|
||||||
// @ts-expect-error
|
|
||||||
window.top.location.href = version;
|
|
||||||
} else if (selectedVersion) {
|
|
||||||
document.body.style.display = 'none';
|
|
||||||
storage.session.set('lastGame', selectedVersion);
|
|
||||||
// @ts-expect-error
|
|
||||||
window.top.location.href = selectedVersion;
|
|
||||||
} else {
|
|
||||||
alert('Please select a version to play.');
|
alert('Please select a version to play.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
document.body.style.display = 'none';
|
||||||
|
storage.session.set('lastGame', selectedVersion);
|
||||||
|
|
||||||
|
window.open(version, '_blank', 'popup=true');
|
||||||
|
|
||||||
|
/*window.top.instanceWindow = window.open(version);
|
||||||
|
window.top.instanceWindow.onload = function () {
|
||||||
|
window.top.instanceWindow.history.replaceState({}, '', '/play');
|
||||||
|
window.top.instanceWindow.console.debug = (msg: string) =>
|
||||||
|
consoleLog('debug', msg);
|
||||||
|
window.top.instanceWindow.console.log = (msg: string) =>
|
||||||
|
consoleLog('log', msg);
|
||||||
|
window.top.instanceWindow.console.info = (msg: string) =>
|
||||||
|
consoleLog('info', msg);
|
||||||
|
window.top.instanceWindow.console.warn = (msg: string) =>
|
||||||
|
consoleLog('warn', msg);
|
||||||
|
window.top.instanceWindow.console.error = (msg: string) =>
|
||||||
|
consoleLog('error', msg);
|
||||||
|
};
|
||||||
|
const waitForCrash = setInterval(() => {
|
||||||
|
if (window.top.instanceWindow.closed) {
|
||||||
|
clearInterval(waitForCrash);
|
||||||
|
game.stop();
|
||||||
|
} else {
|
||||||
|
window.top.instanceWindow.document
|
||||||
|
.querySelectorAll('div')
|
||||||
|
.forEach((element: HTMLElement) => {
|
||||||
|
if (element.innerText.includes('Game Crashed!')) {
|
||||||
|
clearInterval(waitForCrash);
|
||||||
|
game.stop(element.innerHTML);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, 50);*/
|
||||||
},
|
},
|
||||||
|
/*stop: function (error?: string) {
|
||||||
|
if (window.top.instanceWindow) {
|
||||||
|
window.top.instanceWindow.onbeforeunload = null;
|
||||||
|
window.top.instanceWindow.close();
|
||||||
|
if (error) {
|
||||||
|
consoleLog('error', '\n\nMineXLauncher: Game crashed with error:');
|
||||||
|
consoleLog('error', error);
|
||||||
|
} else {
|
||||||
|
consoleLog('error', '\n\nMineXLauncher: Game process killed by user');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},*/
|
||||||
select: function (path: string, name?: string) {
|
select: function (path: string, name?: string) {
|
||||||
selectedVersion = path;
|
selectedVersion = path;
|
||||||
const selector = document.querySelector('.installations div .selector');
|
const selector = document.querySelector('.installations div .selector');
|
||||||
@ -135,6 +191,18 @@ const navigate = {
|
|||||||
window.location.href = navUrl;
|
window.location.href = navUrl;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
settings: {
|
||||||
|
general: function () {
|
||||||
|
const navUrl = '/settings/general/';
|
||||||
|
storage.session.set('lastPage', navUrl);
|
||||||
|
window.location.href = navUrl;
|
||||||
|
},
|
||||||
|
backups: function () {
|
||||||
|
const navUrl = '/settings/backups/';
|
||||||
|
storage.session.set('lastPage', navUrl);
|
||||||
|
window.location.href = navUrl;
|
||||||
|
},
|
||||||
|
},
|
||||||
articles: function () {
|
articles: function () {
|
||||||
const navUrl = '/articles/';
|
const navUrl = '/articles/';
|
||||||
storage.session.set('lastPage', navUrl);
|
storage.session.set('lastPage', navUrl);
|
||||||
@ -155,11 +223,6 @@ const navigate = {
|
|||||||
storage.session.set('lastPage', navUrl);
|
storage.session.set('lastPage', navUrl);
|
||||||
window.location.href = navUrl;
|
window.location.href = navUrl;
|
||||||
},
|
},
|
||||||
settings: function () {
|
|
||||||
const navUrl = '/settings/';
|
|
||||||
storage.session.set('lastPage', navUrl);
|
|
||||||
window.location.href = navUrl;
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const article = {
|
const article = {
|
||||||
@ -346,6 +409,117 @@ const mods = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const backups = {
|
||||||
|
export: async function () {
|
||||||
|
const exportData: {
|
||||||
|
cookies: Record<string, string>;
|
||||||
|
localStorage: Record<string, string>;
|
||||||
|
indexedDb: Record<string, string>;
|
||||||
|
} = {
|
||||||
|
cookies: {},
|
||||||
|
localStorage: { ...localStorage },
|
||||||
|
indexedDb: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
document.cookie.split('; ').forEach((cookie) => {
|
||||||
|
const pair = cookie.split('=');
|
||||||
|
if (pair[0] !== undefined && pair[1] !== undefined)
|
||||||
|
exportData.cookies[pair[0]] = pair[1];
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const dbInfo of await indexedDB.databases()) {
|
||||||
|
if (dbInfo.name)
|
||||||
|
indexedDB.open(dbInfo.name).onsuccess = (event) =>
|
||||||
|
(exportData.indexedDb[dbInfo.name ?? ''] =
|
||||||
|
idbExportImport.exportToJsonString(
|
||||||
|
(event.target as IDBOpenDBRequest).result,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = URL.createObjectURL(
|
||||||
|
new Blob([base64Gzip.compress(JSON.stringify(exportData))]),
|
||||||
|
);
|
||||||
|
const a = document.createElement('a');
|
||||||
|
a.href = url;
|
||||||
|
a.target = '_blank';
|
||||||
|
a.download = `MineXLauncher_${new Date().toLocaleDateString('en-GB').replace(/\//g, '-')}.backup`;
|
||||||
|
document.body.appendChild(a);
|
||||||
|
a.click();
|
||||||
|
document.body.removeChild(a);
|
||||||
|
URL.revokeObjectURL(url);
|
||||||
|
},
|
||||||
|
import: async function () {
|
||||||
|
await new Promise<File>((resolve, reject) => {
|
||||||
|
const fileInput = document.createElement('input');
|
||||||
|
fileInput.type = 'file';
|
||||||
|
fileInput.accept = '.backup';
|
||||||
|
fileInput.multiple = false;
|
||||||
|
fileInput.onchange = (event) => {
|
||||||
|
const file = (event.target as HTMLInputElement).files?.[0];
|
||||||
|
if (file) resolve(file);
|
||||||
|
else reject();
|
||||||
|
};
|
||||||
|
fileInput.oncancel = () => reject();
|
||||||
|
document.body.appendChild(fileInput);
|
||||||
|
fileInput.click();
|
||||||
|
document.body.removeChild(fileInput);
|
||||||
|
})
|
||||||
|
.then(async (file) => {
|
||||||
|
const importData = JSON.parse(base64Gzip.decompress(await file.text()));
|
||||||
|
|
||||||
|
// @ts-expect-error
|
||||||
|
if (typeof cookieStore !== 'undefined')
|
||||||
|
// @ts-expect-error
|
||||||
|
await cookieStore.getAll().then((cookies: object[]) =>
|
||||||
|
// @ts-expect-error
|
||||||
|
cookies.forEach((cookie) => cookieStore.delete(cookie)),
|
||||||
|
);
|
||||||
|
else
|
||||||
|
document.cookie
|
||||||
|
.split('; ')
|
||||||
|
.forEach(
|
||||||
|
(cookie) =>
|
||||||
|
(document.cookie = `${cookie.split('=')[0]}=; Path=/; Max-Age=0`),
|
||||||
|
);
|
||||||
|
|
||||||
|
localStorage.clear();
|
||||||
|
|
||||||
|
for (const dbInfo of await indexedDB.databases())
|
||||||
|
if (dbInfo.name) indexedDB.deleteDatabase(dbInfo.name);
|
||||||
|
|
||||||
|
for (const key in importData.localStorage)
|
||||||
|
if (importData.localStorage[key] !== undefined)
|
||||||
|
localStorage.setItem(key, importData.localStorage[key]);
|
||||||
|
|
||||||
|
for (const key in importData.cookies)
|
||||||
|
document.cookie = `${key}=${importData.cookies[key]}; Max-Age=${365 * 24 * 60 * 60}; Path=/; SameSite=Lax; Secure`;
|
||||||
|
|
||||||
|
if (Object.keys(importData.indexedDb).length > 0)
|
||||||
|
for (const dbName in importData.indexedDb) {
|
||||||
|
const dbRequest = indexedDB.open(dbName);
|
||||||
|
dbRequest.onsuccess = async (event) => {
|
||||||
|
const db = (event.target as IDBOpenDBRequest).result;
|
||||||
|
const transaction = db.transaction(
|
||||||
|
Array.from(db.objectStoreNames),
|
||||||
|
'readwrite',
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const storeName of Array.from(db.objectStoreNames))
|
||||||
|
transaction.objectStore(storeName).clear();
|
||||||
|
|
||||||
|
transaction.oncomplete = () =>
|
||||||
|
idbExportImport.importFromJsonString(
|
||||||
|
db,
|
||||||
|
importData.indexedDb[dbName],
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
window.top?.location.reload();
|
||||||
|
})
|
||||||
|
.catch((error) => console.error(error));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
const sw = {
|
const sw = {
|
||||||
register: function (url: string) {
|
register: function (url: string) {
|
||||||
if ('serviceWorker' in navigator) {
|
if ('serviceWorker' in navigator) {
|
||||||
@ -365,40 +539,16 @@ const sw = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const base64Gzip = {
|
const base64Gzip = {
|
||||||
decode: function (base64: string) {
|
compress: function (string: string): string {
|
||||||
// Decode Base64 to binary string
|
return btoa(
|
||||||
const binaryString = atob(base64);
|
String.fromCharCode(...deflate(new TextEncoder().encode(string))),
|
||||||
|
);
|
||||||
// Convert binary string to Uint8Array
|
|
||||||
const len = binaryString.length;
|
|
||||||
const bytes = new Uint8Array(len);
|
|
||||||
for (let i = 0; i < len; i++) {
|
|
||||||
bytes[i] = binaryString.charCodeAt(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use pako to decompress the Uint8Array
|
|
||||||
const decompressed = inflate(bytes, { to: 'string' });
|
|
||||||
|
|
||||||
return decompressed;
|
|
||||||
},
|
},
|
||||||
encode: function (inputString: string) {
|
decompress: function (string: string): string {
|
||||||
// Convert the input string to a Uint8Array
|
return inflate(
|
||||||
const encoder = new TextEncoder();
|
Uint8Array.from(atob(string), (c) => c.charCodeAt(0)),
|
||||||
const inputBytes = encoder.encode(inputString);
|
{ to: 'string' },
|
||||||
|
);
|
||||||
// Use pako to compress the Uint8Array
|
|
||||||
const compressedBytes = deflate(inputBytes);
|
|
||||||
|
|
||||||
// Convert the compressed Uint8Array to a binary string
|
|
||||||
let binaryString = '';
|
|
||||||
for (const byte of compressedBytes) {
|
|
||||||
binaryString += String.fromCharCode(byte);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Encode the binary string to Base64
|
|
||||||
const base64String = btoa(binaryString);
|
|
||||||
|
|
||||||
return base64String;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -435,6 +585,7 @@ if (window.location.pathname === '/') {
|
|||||||
}
|
}
|
||||||
}); */
|
}); */
|
||||||
document.addEventListener('load', () => sw.register('/sw.js'));
|
document.addEventListener('load', () => sw.register('/sw.js'));
|
||||||
|
window.addEventListener('beforeunload', () => game.stop());
|
||||||
|
|
||||||
window.addEventListener('beforeinstallprompt', (event) => {
|
window.addEventListener('beforeinstallprompt', (event) => {
|
||||||
// @ts-expect-error
|
// @ts-expect-error
|
||||||
@ -500,7 +651,7 @@ if (window.location.pathname === '/') {
|
|||||||
} */
|
} */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.location.pathname === '/settings/') {
|
if (window.location.pathname === '/settings/general/') {
|
||||||
document.addEventListener('DOMContentLoaded', async () => {
|
document.addEventListener('DOMContentLoaded', async () => {
|
||||||
const profileName = document.querySelector('.username');
|
const profileName = document.querySelector('.username');
|
||||||
const usernameInput = document.querySelector(
|
const usernameInput = document.querySelector(
|
||||||
@ -731,5 +882,6 @@ if (window.location.hostname === null) {
|
|||||||
base64Gzip,
|
base64Gzip,
|
||||||
article,
|
article,
|
||||||
downloadFile,
|
downloadFile,
|
||||||
|
backups,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
@ -699,6 +699,10 @@ body {
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.settings form[id='settings-backups'] {
|
||||||
|
padding-bottom: 60px;
|
||||||
|
}
|
||||||
|
|
||||||
.settings form button[type='submit'] {
|
.settings form button[type='submit'] {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
107
src/settings/backups/index.html
Normal file
107
src/settings/backups/index.html
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<!doctype html>
|
||||||
|
<html lang="en" style="display: none">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>MineXLauncher</title>
|
||||||
|
<link
|
||||||
|
rel="icon"
|
||||||
|
type="image/webp"
|
||||||
|
href="/resources/images/icons/favicon.webp"
|
||||||
|
/>
|
||||||
|
<link rel="stylesheet" href="/resources/styles/themes/default.css" />
|
||||||
|
<link
|
||||||
|
rel="stylesheet"
|
||||||
|
id="theme"
|
||||||
|
onload="document.documentElement.style.display = ''"
|
||||||
|
/>
|
||||||
|
<script src="/resources/scripts/google-tag.js"></script>
|
||||||
|
<script src="/resources/scripts/main.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="ads-container">
|
||||||
|
<ins
|
||||||
|
class="adsbygoogle"
|
||||||
|
style="display: block"
|
||||||
|
data-ad-client="ca-pub-1132419379737567"
|
||||||
|
data-ad-slot="3280170072"
|
||||||
|
data-ad-format="auto"
|
||||||
|
data-full-width-responsive="true"
|
||||||
|
></ins>
|
||||||
|
</div>
|
||||||
|
<div class="launcher">
|
||||||
|
<span class="title-bar">MineXLauncher</span>
|
||||||
|
<div class="content">
|
||||||
|
<div class="sidebar">
|
||||||
|
<span class="username"></span>
|
||||||
|
<nav class="nav-bar">
|
||||||
|
<li onclick="navigate.updates()">
|
||||||
|
<img src="/resources/images/icons/nav/updates.webp" />
|
||||||
|
<span>Updates</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.home.game()">
|
||||||
|
<img src="/resources/images/icons/nav/game.webp" />
|
||||||
|
<span>Game</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.servers()">
|
||||||
|
<img src="/resources/images/icons/nav/servers.webp" />
|
||||||
|
<span>Server List</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.mods.mods()">
|
||||||
|
<img src="/resources/images/icons/nav/mods.webp" />
|
||||||
|
<span>Mods</span>
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.articles()">
|
||||||
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
|
<span>Tutorials</span>
|
||||||
|
</li>
|
||||||
|
<li class="selected" onclick="navigate.settings.general()">
|
||||||
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
|
<span>Settings</span>
|
||||||
|
</li>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
<div class="main-panel">
|
||||||
|
<div class="top-nav">
|
||||||
|
<ul>
|
||||||
|
<li onclick="navigate.settings.general()">General</li>
|
||||||
|
<li class="selected" onclick="navigate.settings.backups()">
|
||||||
|
Backups
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="main-content">
|
||||||
|
<div class="settings">
|
||||||
|
<form id="settings-backups">
|
||||||
|
<h3>Backups</h3>
|
||||||
|
<p>
|
||||||
|
Save a backup of your launcher data.<br />Note: Backing up
|
||||||
|
worlds is not yet supported. Please export them from
|
||||||
|
Eaglercraft for now.
|
||||||
|
</p>
|
||||||
|
<button onclick="backups.export()">Export backup</button>
|
||||||
|
<button onclick="backups.import()">Import backup</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bottom-bar">
|
||||||
|
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||||
|
>Join the MineXLauncher Discord</span
|
||||||
|
>
|
||||||
|
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ads-container">
|
||||||
|
<ins
|
||||||
|
class="adsbygoogle"
|
||||||
|
style="display: block"
|
||||||
|
data-ad-client="ca-pub-1132419379737567"
|
||||||
|
data-ad-slot="3280170072"
|
||||||
|
data-ad-format="auto"
|
||||||
|
data-full-width-responsive="true"
|
||||||
|
></ins>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -55,14 +55,21 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li class="selected" onclick="navigate.settings()">
|
<li class="selected" onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
</nav>
|
</nav>
|
||||||
</div>
|
</div>
|
||||||
<div class="main-panel">
|
<div class="main-panel">
|
||||||
<span class="top-title">Settings</span>
|
<div class="top-nav">
|
||||||
|
<ul>
|
||||||
|
<li class="selected" onclick="navigate.settings.general()">
|
||||||
|
General
|
||||||
|
</li>
|
||||||
|
<li onclick="navigate.settings.backups()">Backups</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
<div class="main-content">
|
<div class="main-content">
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<form>
|
<form>
|
||||||
@ -72,15 +79,11 @@
|
|||||||
<select id="theme-select">
|
<select id="theme-select">
|
||||||
<option disabled hidden value=""></option>
|
<option disabled hidden value=""></option>
|
||||||
</select>
|
</select>
|
||||||
|
<!-- <label for="offline-checkbox">Enable offline use:</label>
|
||||||
|
<input id="offline-checkbox" type="checkbox" /> -->
|
||||||
|
<!-- <label for="ads-checkbox">Show ads:</label>
|
||||||
|
<input id="ads-checkbox" type="checkbox" /> -->
|
||||||
</form>
|
</form>
|
||||||
<!-- <div>
|
|
||||||
<label for="offline-checkbox">Enable offline use:</label>
|
|
||||||
<input id="offline-checkbox" type="checkbox" />
|
|
||||||
</div> -->
|
|
||||||
<!-- <div>
|
|
||||||
<label for="ads-checkbox">Show ads:</label>
|
|
||||||
<input id="ads-checkbox" type="checkbox" />
|
|
||||||
</div> -->
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -55,7 +55,7 @@
|
|||||||
<img src="/resources/images/icons/nav/articles.webp" />
|
<img src="/resources/images/icons/nav/articles.webp" />
|
||||||
<span>Tutorials</span>
|
<span>Tutorials</span>
|
||||||
</li>
|
</li>
|
||||||
<li onclick="navigate.settings()">
|
<li onclick="navigate.settings.general()">
|
||||||
<img src="/resources/images/icons/nav/settings.webp" />
|
<img src="/resources/images/icons/nav/settings.webp" />
|
||||||
<span>Settings</span>
|
<span>Settings</span>
|
||||||
</li>
|
</li>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user