mirror of
https://github.com/zumbiepig/MineXLauncher.git
synced 2025-06-07 23:24:48 +00:00
,
This commit is contained in:
parent
bfb131d4ea
commit
01d1aebe64
@ -1,3 +1,2 @@
|
||||
src/game/
|
||||
!src/game/web/*.html
|
||||
src/resources/mods/downloads/
|
||||
|
@ -1,5 +1,4 @@
|
||||
{
|
||||
"printWidth": 120,
|
||||
"useTabs": true,
|
||||
"singleQuote": true
|
||||
}
|
||||
|
6
.vscode/extensions.json
vendored
6
.vscode/extensions.json
vendored
@ -1,3 +1,7 @@
|
||||
{
|
||||
"recommendations": ["oven.bun-vscode", "dbaeumer.vscode-eslint", "esbenp.prettier-vscode"]
|
||||
"recommendations": [
|
||||
"oven.bun-vscode",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode"
|
||||
]
|
||||
}
|
||||
|
23
build.ts
23
build.ts
@ -1,5 +1,12 @@
|
||||
import { build } from 'bun';
|
||||
import { mkdirSync, readdirSync, statSync, writeFileSync, readFileSync, rmSync } from 'fs';
|
||||
import {
|
||||
mkdirSync,
|
||||
readdirSync,
|
||||
statSync,
|
||||
writeFileSync,
|
||||
readFileSync,
|
||||
rmSync,
|
||||
} from 'fs';
|
||||
import { resolve, dirname, basename } from 'path';
|
||||
import { minify } from 'html-minifier';
|
||||
import javascriptObfuscator from 'javascript-obfuscator';
|
||||
@ -34,7 +41,11 @@ srcFiles.forEach((file) => {
|
||||
if (file.endsWith('.ts')) bundleFiles.push(file);
|
||||
else if (isDev) copyFiles.push(file);
|
||||
else if (/\.(html|css|js|json)$/.test(strippedPath)) {
|
||||
if (strippedPath.startsWith('/game/offline/') || basename(strippedPath) === 'classes.js') copyFiles.push(file);
|
||||
if (
|
||||
strippedPath.startsWith('/game/offline/') ||
|
||||
basename(strippedPath) === 'classes.js'
|
||||
)
|
||||
copyFiles.push(file);
|
||||
else minifyFiles.push(file);
|
||||
} else copyFiles.push(file);
|
||||
});
|
||||
@ -76,7 +87,9 @@ if (!isDev) {
|
||||
|
||||
console.log(chalk.cyan('Obfuscating JavaScript...\n'));
|
||||
bundleFiles.forEach((file) => {
|
||||
const outputPath = file.replace(new RegExp(`^${srcDir}`), publicDir).replace(/\.ts$/, '.js');
|
||||
const outputPath = file
|
||||
.replace(new RegExp(`^${srcDir}`), publicDir)
|
||||
.replace(/\.ts$/, '.js');
|
||||
writeFileSync(
|
||||
outputPath,
|
||||
javascriptObfuscator
|
||||
@ -103,7 +116,9 @@ writeFileSync(
|
||||
assetsJsonPath,
|
||||
JSON.stringify(
|
||||
getFiles(publicDir).map((asset) => {
|
||||
return asset.replace(new RegExp(`^${publicDir}`), '').replace(/\/index\.html$/, '/');
|
||||
return asset
|
||||
.replace(new RegExp(`^${publicDir}`), '')
|
||||
.replace(/\/index\.html$/, '/');
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
10
server.ts
10
server.ts
@ -41,7 +41,11 @@ app.use(compression());
|
||||
|
||||
if (isDev) app.use(errorhandler());
|
||||
|
||||
app.use(serveFavicon(join(BASE_DIR, 'resources/images/icons/favicon.webp'), { maxAge: 86400 }));
|
||||
app.use(
|
||||
serveFavicon(join(BASE_DIR, 'resources/images/icons/favicon.webp'), {
|
||||
maxAge: 86400,
|
||||
}),
|
||||
);
|
||||
app.use(serveStatic(BASE_DIR));
|
||||
|
||||
app.use('/', indexRouter);
|
||||
@ -65,7 +69,9 @@ app
|
||||
.on('error', (error) => {
|
||||
if (error.code === 'EADDRINUSE') {
|
||||
console.error(
|
||||
chalk.red('EADDRINUSE') + chalk.gray(': ') + chalk.bold(`Failed to start server. Is port ${PORT} in use?`),
|
||||
chalk.red('EADDRINUSE') +
|
||||
chalk.gray(': ') +
|
||||
chalk.bold(`Failed to start server. Is port ${PORT} in use?`),
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
16
src/404.html
16
src/404.html
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
id="theme"
|
||||
onload="document.documentElement.style.display = ''"
|
||||
/>
|
||||
<meta name="theme-color" content="#333" />
|
||||
<script src="/resources/scripts/google-tag.js"></script>
|
||||
<script src="/resources/scripts/main.js"></script>
|
||||
@ -35,7 +43,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -58,17 +66,32 @@
|
||||
<div class="main-content">
|
||||
<div class="article-list">
|
||||
<div onclick="article.open('mc-server')">
|
||||
<img loading="lazy" src="/resources/images/icons/articles/mc-server.webp" />
|
||||
<img
|
||||
loading="lazy"
|
||||
src="/resources/images/icons/articles/mc-server.webp"
|
||||
/>
|
||||
<div class="details">
|
||||
<strong>How To Make An Eaglercraft Server</strong>
|
||||
<p>Have you ever wondered how to make an Eaglercraft Server? Read this article to find out how!</p>
|
||||
<p>
|
||||
Have you ever wondered how to make an Eaglercraft Server?
|
||||
Read this article to find out how!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div onclick="article.open('cloudflare-tunnel')">
|
||||
<img loading="lazy" src="/resources/images/icons/articles/cloudflare-tunnel.webp" />
|
||||
<img
|
||||
loading="lazy"
|
||||
src="/resources/images/icons/articles/cloudflare-tunnel.webp"
|
||||
/>
|
||||
<div class="details">
|
||||
<strong>Setting Up a Cloudflare Tunnel for an Eaglercraft Server</strong>
|
||||
<p>This brief guide walks you through configuring a Cloudflare Tunnel for your Eaglercraft server.</p>
|
||||
<strong
|
||||
>Setting Up a Cloudflare Tunnel for an Eaglercraft
|
||||
Server</strong
|
||||
>
|
||||
<p>
|
||||
This brief guide walks you through configuring a Cloudflare
|
||||
Tunnel for your Eaglercraft server.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -76,7 +99,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
@ -97,13 +122,22 @@
|
||||
<h1>How To Make An Eaglercraft Server</h1>
|
||||
<h5>Written by ServerDotSo and revised by zumbiepig</h5>
|
||||
<p>Have you ever wondered how to make an Eaglercraft Server?</p>
|
||||
<p>In this guide, we will be going over how to setup your own Eaglercraft server.</p>
|
||||
<p>
|
||||
In this guide, we will be going over how to setup your own
|
||||
Eaglercraft server.
|
||||
</p>
|
||||
<h3>Prerequisites</h3>
|
||||
<ul>
|
||||
<li>A server/computer with stable internet access and decent bandwidth</li>
|
||||
<li>
|
||||
A server/computer with stable internet access and decent bandwidth
|
||||
</li>
|
||||
<li>
|
||||
Java 17 installed (Get it from
|
||||
<a href="https://adoptium.net/temurin/releases/?version=17" target="_blank">here</a>)
|
||||
<a
|
||||
href="https://adoptium.net/temurin/releases/?version=17"
|
||||
target="_blank"
|
||||
>here</a
|
||||
>)
|
||||
</li>
|
||||
<li>Basic knowledge of your OS's command-line/terminal</li>
|
||||
<li>Access to your network router (for port forwarding)</li>
|
||||
@ -118,33 +152,52 @@
|
||||
>here</a
|
||||
>.
|
||||
</li>
|
||||
<li>Create a new directory for your server and place the Bungee JAR file in it</li>
|
||||
<li>
|
||||
Create a start script (e.g., <code>start.bat</code> for Windows or <code>start.sh</code> for Linux) with
|
||||
the following content:
|
||||
Create a new directory for your server and place the Bungee JAR
|
||||
file in it
|
||||
</li>
|
||||
<li>
|
||||
Create a start script (e.g., <code>start.bat</code> for Windows or
|
||||
<code>start.sh</code> for Linux) with the following content:
|
||||
<pre><code>java -Xms512M -Xmx512M -jar bungee.jar</code></pre>
|
||||
</li>
|
||||
<li>Run the start script to generate configuration files, then stop the server</li>
|
||||
<li>Edit the <code>config.yml</code> file to configure your proxy settings</li>
|
||||
<li>
|
||||
Run the start script to generate configuration files, then stop
|
||||
the server
|
||||
</li>
|
||||
<li>
|
||||
Edit the <code>config.yml</code> file to configure your proxy
|
||||
settings
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 2: Set Up Backend Server</h3>
|
||||
<ol>
|
||||
<li>Download a compatible Minecraft server JAR (e.g., Paper)</li>
|
||||
<li>Set up the backend server in a separate directory</li>
|
||||
<li>
|
||||
Create a start script (e.g., <code>start.bat</code> for Windows or <code>start.sh</code> for Linux) with
|
||||
the following content:
|
||||
Create a start script (e.g., <code>start.bat</code> for Windows or
|
||||
<code>start.sh</code> for Linux) with the following content:
|
||||
<pre><code>java -Xms1024M -Xmx1024M -jar server.jar</code></pre>
|
||||
</li>
|
||||
<li>Configure <code>server.properties</code> (Disable online mode, change the port, etc.)</li>
|
||||
<li>Configure <code>spigot.yml</code> to have this: <code>bungeecord: true</code></li>
|
||||
<li>
|
||||
If your server is on a different version than 1.8.8, you need to download the
|
||||
<a href="https://viaversion.com/setup" target="_blank">ViaVersion plugins</a>.
|
||||
Configure <code>server.properties</code> (Disable online mode,
|
||||
change the port, etc.)
|
||||
</li>
|
||||
<li>
|
||||
Add the backend server to your Bungee <code>config.yml</code> by scrolling to the servers section and
|
||||
editing/adding an entry for your server, such as <code>localhost:port</code>.
|
||||
Configure <code>spigot.yml</code> to have this:
|
||||
<code>bungeecord: true</code>
|
||||
</li>
|
||||
<li>
|
||||
If your server is on a different version than 1.8.8, you need to
|
||||
download the
|
||||
<a href="https://viaversion.com/setup" target="_blank"
|
||||
>ViaVersion plugins</a
|
||||
>.
|
||||
</li>
|
||||
<li>
|
||||
Add the backend server to your Bungee <code>config.yml</code> by
|
||||
scrolling to the servers section and editing/adding an entry for
|
||||
your server, such as <code>localhost:port</code>.
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 3: Install EaglerXBungee Plugin</h3>
|
||||
@ -157,14 +210,25 @@
|
||||
>here</a
|
||||
>.
|
||||
</li>
|
||||
<li>Place the downloaded JAR file in the Bungee server's <code>plugins</code> folder</li>
|
||||
<li>Restart the Bungee server to generate the plugin's configuration files</li>
|
||||
<li>Configure the EaglerXBungee plugin as needed (disabling online mode, etc.)</li>
|
||||
<li>
|
||||
Place the downloaded JAR file in the Bungee server's
|
||||
<code>plugins</code> folder
|
||||
</li>
|
||||
<li>
|
||||
Restart the Bungee server to generate the plugin's configuration
|
||||
files
|
||||
</li>
|
||||
<li>
|
||||
Configure the EaglerXBungee plugin as needed (disabling online
|
||||
mode, etc.)
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 4: Set Up Caddy</h3>
|
||||
<ol>
|
||||
<li>
|
||||
Download and install Caddy from <a href="https://caddyserver.com/download" target="_blank">here</a>.
|
||||
Download and install Caddy from
|
||||
<a href="https://caddyserver.com/download" target="_blank">here</a
|
||||
>.
|
||||
</li>
|
||||
<li>
|
||||
Create a file called Caddyfile with this configuration:
|
||||
@ -175,33 +239,42 @@
|
||||
<ol>
|
||||
<li>Access your router's admin panel</li>
|
||||
<li>
|
||||
Set up port forwarding for port <code>8081</code> (or whichever port you configured for EaglerXBungee) to
|
||||
your server's local IP address
|
||||
Set up port forwarding for port <code>8081</code> (or whichever
|
||||
port you configured for EaglerXBungee) to your server's local IP
|
||||
address
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 6: Domain Configuration (Optional)</h3>
|
||||
<p>If you want to use a custom domain:</p>
|
||||
<ol>
|
||||
<li>Purchase a domain from a domain registrar</li>
|
||||
<li>Set up an A record pointing to your server's public IPv4 address</li>
|
||||
<li>
|
||||
Edit the Caddyfile you made earlier, replacing <code>example.com</code> with your domain:
|
||||
Set up an A record pointing to your server's public IPv4 address
|
||||
</li>
|
||||
<li>
|
||||
Edit the Caddyfile you made earlier, replacing
|
||||
<code>example.com</code> with your domain:
|
||||
<pre><code>example.com {<br> reverse_proxy :8081<br>}</code></pre>
|
||||
</li>
|
||||
<li>Restart Caddy to apply these changes, using <code>caddy stop</code> and <code>caddy start</code>.</li>
|
||||
<li>
|
||||
Restart Caddy to apply these changes, using
|
||||
<code>caddy stop</code> and <code>caddy start</code>.
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 7: Connecting to Your Server</h3>
|
||||
<p>
|
||||
Players can connect to your server using an Eaglercraft client such as MineXLauncher, and entering your
|
||||
server's IP address or domain and port.
|
||||
Players can connect to your server using an Eaglercraft client such
|
||||
as MineXLauncher, and entering your server's IP address or domain
|
||||
and port.
|
||||
</p>
|
||||
<p>Examples:</p>
|
||||
<li><code>wss://localhost</code></li>
|
||||
<li><code>wss://example.com</code></li>
|
||||
<h3>Security Considerations</h3>
|
||||
<p>
|
||||
Ensure you keep all software (especially the EaglerXBungee plugin) up to date and properly secure your
|
||||
server to protect against potential vulnerabilities.
|
||||
Ensure you keep all software (especially the EaglerXBungee plugin)
|
||||
up to date and properly secure your server to protect against
|
||||
potential vulnerabilities.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@ -213,47 +286,76 @@
|
||||
<h1>Setting Up a Cloudflare Tunnel for an Eaglercraft Server</h1>
|
||||
<h5>Written by zumbiepig and SpeedSlicer</h5>
|
||||
<p>
|
||||
In this guide, we'll walk you through the steps to set up a Cloudflare Tunnel for your Eaglercraft server,
|
||||
which is running on <code>ws://localhost:8081</code>.
|
||||
In this guide, we'll walk you through the steps to set up a
|
||||
Cloudflare Tunnel for your Eaglercraft server, which is running on
|
||||
<code>ws://localhost:8081</code>.
|
||||
</p>
|
||||
<h3>Prerequisites</h3>
|
||||
<ul>
|
||||
<li>An Eaglercraft server running on <code>ws://localhost:8081</code></li>
|
||||
<li>Access to the computer your Eaglercraft server is running on</li>
|
||||
<li>
|
||||
An Eaglercraft server running on <code>ws://localhost:8081</code>
|
||||
</li>
|
||||
<li>
|
||||
Access to the computer your Eaglercraft server is running on
|
||||
</li>
|
||||
<li>A domain already linked to Cloudflare</li>
|
||||
</ul>
|
||||
<h3>Step 1: Access Cloudflare Tunnels</h3>
|
||||
<ol>
|
||||
<li>
|
||||
Go to the <a href="https://dash.cloudflare.com/" target="_blank">Dashboard</a> and log in to your
|
||||
Cloudflare account.
|
||||
Go to the
|
||||
<a href="https://dash.cloudflare.com/" target="_blank"
|
||||
>Dashboard</a
|
||||
>
|
||||
and log in to your Cloudflare account.
|
||||
</li>
|
||||
<li>
|
||||
Navigate to the <strong>Zero Trust</strong> page using the
|
||||
navigation bar on the left.
|
||||
</li>
|
||||
<li>
|
||||
Sign up for Cloudflare Zero Trust with the Free Plan if you have
|
||||
not already.
|
||||
</li>
|
||||
<li>
|
||||
Once you are in the dashboard, navigate to
|
||||
<strong>Networks</strong> > <strong>Tunnels</strong>.
|
||||
</li>
|
||||
<li>Navigate to the <strong>Zero Trust</strong> page using the navigation bar on the left.</li>
|
||||
<li>Sign up for Cloudflare Zero Trust with the Free Plan if you have not already.</li>
|
||||
<li>Once you are in the dashboard, navigate to <strong>Networks</strong> > <strong>Tunnels</strong>.</li>
|
||||
</ol>
|
||||
<h3>Step 2: Create a Tunnel</h3>
|
||||
<ol>
|
||||
<li>Click on <strong>Create a tunnel</strong>, and select <strong>Cloudflared</strong>.</li>
|
||||
<li>
|
||||
Click on <strong>Create a tunnel</strong>, and select
|
||||
<strong>Cloudflared</strong>.
|
||||
</li>
|
||||
<li>Click <strong>Next</strong>.</li>
|
||||
<li>Enter a name for the tunnel.</li>
|
||||
<li>
|
||||
Follow the instructions provided on the site to install the tunnel.<br />You should do these instructions
|
||||
on the computer that your Eaglercraft server is running on.
|
||||
Follow the instructions provided on the site to install the
|
||||
tunnel.<br />You should do these instructions on the computer that
|
||||
your Eaglercraft server is running on.
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 3: Configure Domain/Subdomain</h3>
|
||||
<ol>
|
||||
<li>Select the domain or subdomain you want to use for your server.</li>
|
||||
<li>
|
||||
Select the domain or subdomain you want to use for your server.
|
||||
</li>
|
||||
<li>Select <strong>HTTP</strong> for the type.</li>
|
||||
<li>Enter <code>localhost:8081</code> (or whatever port your server is running on) as the URL.</li>
|
||||
<li>
|
||||
Enter <code>localhost:8081</code> (or whatever port your server is
|
||||
running on) as the URL.
|
||||
</li>
|
||||
</ol>
|
||||
<h3>Step 4: Activate Tunnel and Proxy</h3>
|
||||
<ol>
|
||||
<li>Start your Eaglercraft server.</li>
|
||||
<li>In Eaglercraft, connect to the domain or subdomain you set up.</li>
|
||||
<li>
|
||||
You're all set! Players can now join your server using the domain that you linked your tunnel to.<br />Example:
|
||||
In Eaglercraft, connect to the domain or subdomain you set up.
|
||||
</li>
|
||||
<li>
|
||||
You're all set! Players can now join your server using the domain
|
||||
that you linked your tunnel to.<br />Example:
|
||||
<code>wss://example.com</code>
|
||||
</li>
|
||||
</ol>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -58,7 +66,9 @@
|
||||
<ul>
|
||||
<li onclick="navigate.home.game()">Game</li>
|
||||
<li onclick="navigate.home.clients()">Clients</li>
|
||||
<li class="selected" onclick="navigate.home.archive()">Archive</li>
|
||||
<li class="selected" onclick="navigate.home.archive()">
|
||||
Archive
|
||||
</li>
|
||||
<li onclick="navigate.home.downloads()">Offline Downloads</li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -67,7 +77,9 @@
|
||||
<div>
|
||||
<label for="18-client-version">1.8 versions:</label>
|
||||
<select id="18-client-version">
|
||||
<option disabled selected hidden value="">Select version</option>
|
||||
<option disabled selected hidden value="">
|
||||
Select version
|
||||
</option>
|
||||
<optgroup label="Releases">
|
||||
<option value="u35">u35</option>
|
||||
<option value="u34">u34</option>
|
||||
@ -118,7 +130,9 @@
|
||||
<div>
|
||||
<label for="15-client-version">1.5 versions:</label>
|
||||
<select id="15-client-version">
|
||||
<option disabled selected hidden value="">Select version</option>
|
||||
<option disabled selected hidden value="">
|
||||
Select version
|
||||
</option>
|
||||
<optgroup label="Service Packs">
|
||||
<option value="sp1.01">sp1.01</option>
|
||||
<option value="sp1">sp1</option>
|
||||
@ -198,7 +212,9 @@
|
||||
<div>
|
||||
<label for="b13-client-version">Select Beta 1.3 version:</label>
|
||||
<select id="b13-client-version">
|
||||
<option disabled selected hidden value="">Select version</option>
|
||||
<option disabled selected hidden value="">
|
||||
Select version
|
||||
</option>
|
||||
<optgroup label="Releases">
|
||||
<option value="23w49a">23w49a</option>
|
||||
<option value="22w22b">22w22b</option>
|
||||
@ -208,13 +224,19 @@
|
||||
</select>
|
||||
<button onclick="game.archive('b1.3')">Open</button>
|
||||
</div>
|
||||
<button onclick="window.open('https://archive.eaglercraft.rip/EaglercraftX_1.8/server/')">
|
||||
<button
|
||||
onclick="window.open('https://archive.eaglercraft.rip/EaglercraftX_1.8/server/')"
|
||||
>
|
||||
1.8 EaglerXBungee Jar
|
||||
</button>
|
||||
<button onclick="window.open('https://archive.eaglercraft.rip/Eaglercraft_1.5/server/')">
|
||||
<button
|
||||
onclick="window.open('https://archive.eaglercraft.rip/Eaglercraft_1.5/server/')"
|
||||
>
|
||||
Eaglercraft 1.5 Server
|
||||
</button>
|
||||
<button onclick="window.open('https://archive.eaglercraft.rip/Eaglercraft_b1.3/server/')">
|
||||
<button
|
||||
onclick="window.open('https://archive.eaglercraft.rip/Eaglercraft_b1.3/server/')"
|
||||
>
|
||||
Eaglercraft Beta 1.3 Server
|
||||
</button>
|
||||
</div>
|
||||
@ -222,7 +244,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -57,35 +65,52 @@
|
||||
<div class="top-nav">
|
||||
<ul>
|
||||
<li onclick="navigate.home.game()">Game</li>
|
||||
<li class="selected" onclick="navigate.home.clients()">Clients</li>
|
||||
<li class="selected" onclick="navigate.home.clients()">
|
||||
Clients
|
||||
</li>
|
||||
<li onclick="navigate.home.archive()">Archive</li>
|
||||
<li onclick="navigate.home.downloads()">Offline Downloads</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<img class="cover-image" src="/resources/images/covers/clients.webp" />
|
||||
<img
|
||||
class="cover-image"
|
||||
src="/resources/images/covers/clients.webp"
|
||||
/>
|
||||
</div>
|
||||
<div class="installations">
|
||||
<div>
|
||||
<span class="selector" onclick="versionSelector.toggle()">Select a client</span>
|
||||
<span class="selector" onclick="versionSelector.toggle()"
|
||||
>Select a client</span
|
||||
>
|
||||
<div class="options">
|
||||
<div onclick="game.select('/game/web/clients/eaglerforge/', 'EaglerForge')">
|
||||
<div
|
||||
onclick="game.select('/game/web/clients/eaglerforge/', 'EaglerForge')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/eaglerforge.webp" />
|
||||
<span>EaglerForge</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/web/clients/resent/', 'Resent Client')">
|
||||
<div
|
||||
onclick="game.select('/game/web/clients/resent/', 'Resent Client')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/resent.webp" />
|
||||
<span>Resent Client</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/web/clients/shadow/', 'Shadow Client')">
|
||||
<div
|
||||
onclick="game.select('/game/web/clients/shadow/', 'Shadow Client')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/shadow.webp" />
|
||||
<span>Shadow Client</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/web/clients/astra/', 'Astra Client')">
|
||||
<div
|
||||
onclick="game.select('/game/web/clients/astra/', 'Astra Client')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/astra.webp" />
|
||||
<span>Astra Client</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/web/clients/starlike/', 'Starlike Client')">
|
||||
<div
|
||||
onclick="game.select('/game/web/clients/starlike/', 'Starlike Client')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/starlike.webp" />
|
||||
<span>Starlike Client</span>
|
||||
</div>
|
||||
@ -96,7 +121,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -59,32 +67,75 @@
|
||||
<li onclick="navigate.home.game()">Game</li>
|
||||
<li onclick="navigate.home.clients()">Clients</li>
|
||||
<li onclick="navigate.home.archive()">Archive</li>
|
||||
<li class="selected" onclick="navigate.home.downloads()">Offline Downloads</li>
|
||||
<li class="selected" onclick="navigate.home.downloads()">
|
||||
Offline Downloads
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<div class="downloads">
|
||||
<h3>Downloads:</h3>
|
||||
<a href="/game/offline/main/EaglercraftL_1.9.html" download>1.9.4</a>
|
||||
<a href="/game/offline/main/EaglercraftX_1.8.html" download>1.8.8</a>
|
||||
<a href="/game/offline/main/Eaglercraft_1.5.html" download>1.5.2</a>
|
||||
<a href="/game/offline/main/Eaglercraft_1.2.5.html" download>1.2.5</a>
|
||||
<a href="/game/offline/main/Eaglercraft_b1.7.3.html" download>Beta 1.7.3</a>
|
||||
<a href="/game/offline/main/Eaglercraft_b1.3.html" download>Beta 1.3</a>
|
||||
<a href="/game/offline/main/Eaglercraft_a1.2.6.html" download>Alpha 1.2.6</a>
|
||||
<a href="/game/offline/main/Eaglercraft_Indev.html" download>Indev</a>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/EaglercraftL_1.9.html', 'EaglercraftL_1.9.html')"
|
||||
>1.9.4</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/EaglercraftX_1.8.html', 'EaglercraftX_1.8.html')"
|
||||
>1.8.8</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/Eaglercraft_1.5.html', 'Eaglercraft_1.5.html')"
|
||||
>1.5.2</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/Eaglercraft_1.2.5.html', 'Eaglercraft_1.2.5.html')"
|
||||
>1.2.5</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/Eaglercraft_b1.7.3.html', 'Eaglercraft_b1.7.3.html')"
|
||||
>Beta 1.7.3</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/Eaglercraft_b1.3.html', 'Eaglercraft_b1.3.html')"
|
||||
>Beta 1.3</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/Eaglercraft_a1.2.6.html', 'Eaglercraft_a1.2.6.html')"
|
||||
>Alpha 1.2.6</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/main/Eaglercraft_Indev.html', 'Eaglercraft_Indev.html')"
|
||||
>Indev</span
|
||||
>
|
||||
<br /><br />
|
||||
<a href="/game/offline/clients/EaglerForge.html" download>EaglerForge</a>
|
||||
<a href="/game/offline/clients/Resent_Client.html" download>Resent Client</a>
|
||||
<a href="/game/offline/clients/Shadow_Client.html" download>Shadow Client</a>
|
||||
<a href="/game/offline/clients/Astra_Client.html" download>Astra Client</a>
|
||||
<a href="/game/offline/clients/Starlike_Client.html" download>Starlike Client</a>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/clients/EaglerForge.html', 'EaglerForge.html')"
|
||||
>EaglerForge</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/clients/Resent_Client.html', 'Resent_Client.html')"
|
||||
>Resent Client</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/clients/Shadow_Client.html', 'Shadow_Client.html')"
|
||||
>Shadow Client</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/clients/Astra_Client.html', 'Astra_Client.html')"
|
||||
>Astra Client</span
|
||||
>
|
||||
<span
|
||||
onclick="downloadFile('/game/offline/clients/Starlike_Client.html', 'Starlike_Client.html')"
|
||||
>Starlike Client</span
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -63,11 +71,16 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<img class="cover-image" src="/resources/images/covers/minecraft.webp" />
|
||||
<img
|
||||
class="cover-image"
|
||||
src="/resources/images/covers/minecraft.webp"
|
||||
/>
|
||||
</div>
|
||||
<div class="installations">
|
||||
<div>
|
||||
<span class="selector" onclick="versionSelector.toggle()">Select a version</span>
|
||||
<span class="selector" onclick="versionSelector.toggle()"
|
||||
>Select a version</span
|
||||
>
|
||||
<div class="options">
|
||||
<div onclick="game.select('/game/web/main/1.9.4/', '1.9.4')">
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
@ -81,11 +94,15 @@
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>1.5.2</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/offline/main/Eaglercraft_1.2.5.html', '1.2.5')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/Eaglercraft_1.2.5.html', '1.2.5')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>1.2.5</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/web/main/b1.7.3/', 'Beta 1.7.3')">
|
||||
<div
|
||||
onclick="game.select('/game/web/main/b1.7.3/', 'Beta 1.7.3')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>Beta 1.7.3</span>
|
||||
</div>
|
||||
@ -105,7 +122,9 @@
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>Indev</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/web/main/classic/', 'Classic')">
|
||||
<div
|
||||
onclick="game.select('/game/web/main/classic/', 'Classic')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>Classic</span>
|
||||
</div>
|
||||
@ -116,7 +135,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,7 +4,11 @@
|
||||
<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="icon"
|
||||
type="image/webp"
|
||||
href="/resources/images/icons/favicon.webp"
|
||||
/>
|
||||
<link rel="stylesheet" href="/resources/styles/index.css" />
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<link rel="canonical" href="https://launcher.orionzleon.me/" />
|
||||
@ -19,7 +23,10 @@
|
||||
/>
|
||||
<meta property="og:title" content="MineXLauncher" />
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:image" content="/resources/images/icons/minexlauncher.webp" />
|
||||
<meta
|
||||
property="og:image"
|
||||
content="/resources/images/icons/minexlauncher.webp"
|
||||
/>
|
||||
<meta property="og:url" content="https://launcher.orionzleon.me/" />
|
||||
<meta
|
||||
property="og:description"
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -26,9 +34,14 @@
|
||||
<div class="main-panel">
|
||||
<span class="top-title">Mobile</span>
|
||||
<div class="main-content">
|
||||
<img class="cover-image" src="/resources/images/covers/minecraft.webp" />
|
||||
<img
|
||||
class="cover-image"
|
||||
src="/resources/images/covers/minecraft.webp"
|
||||
/>
|
||||
<div class="installations">
|
||||
<button onclick="game.play('/game/web/main/1.8.8/?mobile=true')">Play</button>
|
||||
<button onclick="game.play('/game/web/main/1.8.8/?mobile=true')">
|
||||
Play
|
||||
</button>
|
||||
<a
|
||||
class="play-button"
|
||||
style="text-decoration: none"
|
||||
@ -41,7 +54,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -64,12 +72,16 @@
|
||||
<div class="mod-list"></div>
|
||||
</div>
|
||||
<div class="installations">
|
||||
<button onclick="game.play('/game/web/clients/eaglerforge/')">Play</button>
|
||||
<button onclick="game.play('/game/web/clients/eaglerforge/')">
|
||||
Play
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -57,7 +65,9 @@
|
||||
<div class="top-nav">
|
||||
<ul>
|
||||
<li onclick="navigate.mods.mods()">Mods</li>
|
||||
<li class="selected" onclick="navigate.mods.resourcepacks()">Resource Packs</li>
|
||||
<li class="selected" onclick="navigate.mods.resourcepacks()">
|
||||
Resource Packs
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
@ -66,7 +76,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
id="theme"
|
||||
onload="document.documentElement.style.display = ''"
|
||||
/>
|
||||
<meta name="theme-color" content="#333" />
|
||||
<script src="/resources/scripts/google-tag.js"></script>
|
||||
<script src="/resources/scripts/main.js"></script>
|
||||
@ -35,7 +43,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
id="theme"
|
||||
onload="document.documentElement.style.display = ''"
|
||||
/>
|
||||
<meta name="theme-color" content="#333" />
|
||||
<script src="/resources/scripts/google-tag.js"></script>
|
||||
<script src="/resources/scripts/main.js"></script>
|
||||
@ -31,25 +39,38 @@
|
||||
</ul>
|
||||
</div>
|
||||
<div class="main-content">
|
||||
<img class="cover-image" src="/resources/images/covers/minecraft.webp" />
|
||||
<img
|
||||
class="cover-image"
|
||||
src="/resources/images/covers/minecraft.webp"
|
||||
/>
|
||||
</div>
|
||||
<div class="installations">
|
||||
<div>
|
||||
<span class="selector" onclick="versionSelector.toggle()">Select a version</span>
|
||||
<span class="selector" onclick="versionSelector.toggle()"
|
||||
>Select a version</span
|
||||
>
|
||||
<div class="options">
|
||||
<div onclick="game.select('/game/offline/main/EaglercraftL_1.9.html', '1.9.4')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/EaglercraftL_1.9.html', '1.9.4')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>1.9.4</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/offline/main/EaglercraftX_1.8.html', '1.8.8')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/EaglercraftX_1.8.html', '1.8.8')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>1.8.8</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/offline/main/Eaglercraft_1.5.html', '1.5.2')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/Eaglercraft_1.5.html', '1.5.2')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>1.5.2</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/offline/main/Eaglercraft_1.2.5.html', '1.2.5')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/Eaglercraft_1.2.5.html', '1.2.5')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>1.2.5</span>
|
||||
</div>
|
||||
@ -67,11 +88,15 @@
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>Beta 1.3</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/offline/main/Eaglercraft_a1.2.6.html', 'Alpha')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/Eaglercraft_a1.2.6.html', 'Alpha')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>Alpha 1.2.6</span>
|
||||
</div>
|
||||
<div onclick="game.select('/game/offline/main/Eaglercraft_Indev.html', 'Indev')">
|
||||
<div
|
||||
onclick="game.select('/game/offline/main/Eaglercraft_Indev.html', 'Indev')"
|
||||
>
|
||||
<img src="/resources/images/icons/clients/all.webp" />
|
||||
<span>Indev</span>
|
||||
</div>
|
||||
@ -82,7 +107,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -78,7 +78,11 @@
|
||||
},
|
||||
{
|
||||
"version": "1.2",
|
||||
"changelog": ["Added Eaglercraft 1.2.5", "Added more mods and resource packs", "Fix and optimize mobile site"]
|
||||
"changelog": [
|
||||
"Added Eaglercraft 1.2.5",
|
||||
"Added more mods and resource packs",
|
||||
"Fix and optimize mobile site"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "1.1",
|
||||
|
@ -7,11 +7,29 @@ window.addEventListener('load', function () {
|
||||
localesURI: `${window.location.pathname}/lang/`,
|
||||
serverWorkerURI: `${window.location.pathname}/worker_bootstrap.js`,
|
||||
worldsFolder: 'MAIN',
|
||||
servers: [{ serverName: 'BrickMC', serverAddress: 'wss://play.brickmc.net', hideAddress: false }],
|
||||
servers: [
|
||||
{
|
||||
serverName: 'BrickMC',
|
||||
serverAddress: 'wss://play.brickmc.net',
|
||||
hideAddress: false,
|
||||
},
|
||||
],
|
||||
relays: [
|
||||
{ addr: 'wss://relay.deev.is/', name: 'lax1dude relay #1', primary: relayId === 0 },
|
||||
{ addr: 'wss://relay.lax1dude.net/', name: 'lax1dude relay #2', primary: relayId === 1 },
|
||||
{ addr: 'wss://relay.shhnowisnottheti.me/', name: 'ayunami relay #1', primary: relayId === 2 },
|
||||
{
|
||||
addr: 'wss://relay.deev.is/',
|
||||
name: 'lax1dude relay #1',
|
||||
primary: relayId === 0,
|
||||
},
|
||||
{
|
||||
addr: 'wss://relay.lax1dude.net/',
|
||||
name: 'lax1dude relay #2',
|
||||
primary: relayId === 1,
|
||||
},
|
||||
{
|
||||
addr: 'wss://relay.shhnowisnottheti.me/',
|
||||
name: 'ayunami relay #1',
|
||||
primary: relayId === 2,
|
||||
},
|
||||
],
|
||||
mainMenu: {
|
||||
splashes: [
|
||||
|
@ -12,9 +12,21 @@ window.addEventListener('load', () => {
|
||||
{ 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 },
|
||||
{
|
||||
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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,10 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
} catch (A) {
|
||||
return !1;
|
||||
}
|
||||
})() || alert('WARNING: This script was created for mobile, and may break functionality in non-mobile browsers!'),
|
||||
})() ||
|
||||
alert(
|
||||
'WARNING: This script was created for mobile, and may break functionality in non-mobile browsers!',
|
||||
),
|
||||
(clientWindow.crouchLock = !1),
|
||||
(clientWindow.sprintLock = !1),
|
||||
(clientWindow.keyboardFix = !1),
|
||||
@ -136,7 +139,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
this,
|
||||
A,
|
||||
function (...A) {
|
||||
if (A[0].isValid || !clientWindow.keyboardFix) return I.apply(this, A);
|
||||
if (A[0].isValid || !clientWindow.keyboardFix)
|
||||
return I.apply(this, A);
|
||||
},
|
||||
...g,
|
||||
)
|
||||
@ -161,12 +165,18 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
(I.disabled = A), (g.disabled = !A);
|
||||
}
|
||||
(Event.prototype.preventDefault = function (A) {
|
||||
('hiddenInput' != document.activeElement.id || A) && ((this._preventDefault = e), this._preventDefault());
|
||||
('hiddenInput' != document.activeElement.id || A) &&
|
||||
((this._preventDefault = e), this._preventDefault());
|
||||
}),
|
||||
(clientWindow.fakelock = null),
|
||||
Object.defineProperty(Element.prototype, 'requestPointerLock', {
|
||||
value: function () {
|
||||
return (clientWindow.fakelock = this), document.dispatchEvent(new Event('pointerlockchange')), d(!0), !0;
|
||||
return (
|
||||
(clientWindow.fakelock = this),
|
||||
document.dispatchEvent(new Event('pointerlockchange')),
|
||||
d(!0),
|
||||
!0
|
||||
);
|
||||
},
|
||||
}),
|
||||
Object.defineProperty(Document.prototype, 'pointerLockElement', {
|
||||
@ -176,13 +186,22 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
}),
|
||||
Object.defineProperty(Document.prototype, 'exitPointerLock', {
|
||||
value: function () {
|
||||
return (clientWindow.fakelock = null), document.dispatchEvent(new Event('pointerlockchange')), d(!1), !0;
|
||||
return (
|
||||
(clientWindow.fakelock = null),
|
||||
document.dispatchEvent(new Event('pointerlockchange')),
|
||||
d(!1),
|
||||
!0
|
||||
);
|
||||
},
|
||||
}),
|
||||
(clientWindow.fakefull = null),
|
||||
Object.defineProperty(Element.prototype, 'requestFullscreen', {
|
||||
value: function () {
|
||||
return (clientWindow.fakefull = this), document.dispatchEvent(new Event('fullscreenchange')), !0;
|
||||
return (
|
||||
(clientWindow.fakefull = this),
|
||||
document.dispatchEvent(new Event('fullscreenchange')),
|
||||
!0
|
||||
);
|
||||
},
|
||||
}),
|
||||
Object.defineProperty(document, 'fullscreenElement', {
|
||||
@ -192,7 +211,11 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
}),
|
||||
Object.defineProperty(Document.prototype, 'exitFullscreen', {
|
||||
value: function () {
|
||||
return (clientWindow.fakefull = null), document.dispatchEvent(new Event('fullscreenchange')), !0;
|
||||
return (
|
||||
(clientWindow.fakefull = null),
|
||||
document.dispatchEvent(new Event('fullscreenchange')),
|
||||
!0
|
||||
);
|
||||
},
|
||||
});
|
||||
const c = document.createElement;
|
||||
@ -202,7 +225,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
return (
|
||||
'input' != A ||
|
||||
I ||
|
||||
(document.querySelectorAll('#fileUpload').forEach((A) => A.parentNode.removeChild(A)),
|
||||
(document
|
||||
.querySelectorAll('#fileUpload')
|
||||
.forEach((A) => A.parentNode.removeChild(A)),
|
||||
(g.id = 'fileUpload'),
|
||||
g.addEventListener(
|
||||
'change',
|
||||
@ -225,7 +250,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
);
|
||||
};
|
||||
let n = document.createElement('style');
|
||||
(n.id = 'inGameStyle'), (n.textContent = '\n.inGame {\ndisplay: none;\n}'), document.documentElement.appendChild(n);
|
||||
(n.id = 'inGameStyle'),
|
||||
(n.textContent = '\n.inGame {\ndisplay: none;\n}'),
|
||||
document.documentElement.appendChild(n);
|
||||
let o = document.createElement('style');
|
||||
function Z(A, I, g) {
|
||||
var i = document.createElement(g ?? 'button', !0);
|
||||
@ -254,7 +281,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
new Promise((A) => {
|
||||
if (document.querySelector(l)) return A(document.querySelector(l));
|
||||
const I = new MutationObserver((g) => {
|
||||
document.querySelector(l) && (I.disconnect(), A(document.querySelector(l)));
|
||||
document.querySelector(l) &&
|
||||
(I.disconnect(), A(document.querySelector(l)));
|
||||
});
|
||||
I.observe(document.documentElement, { childList: !0, subtree: !0 });
|
||||
})).then(() => {
|
||||
@ -265,9 +293,14 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
function (g) {
|
||||
g.preventDefault();
|
||||
const e = g.targetTouches[0];
|
||||
A || ((A = e.pageX), (I = e.pageY)), (g.movementX = e.pageX - A), (g.movementY = e.pageY - I);
|
||||
A || ((A = e.pageX), (I = e.pageY)),
|
||||
(g.movementX = e.pageX - A),
|
||||
(g.movementY = e.pageY - I);
|
||||
var C = clientWindow.fakelock
|
||||
? new MouseEvent('mousemove', { movementX: g.movementX, movementY: g.movementY })
|
||||
? new MouseEvent('mousemove', {
|
||||
movementX: g.movementX,
|
||||
movementY: g.movementY,
|
||||
})
|
||||
: new WheelEvent('wheel', { wheelDeltaY: g.movementY });
|
||||
i.dispatchEvent(C), (A = e.pageX), (I = e.pageY);
|
||||
},
|
||||
@ -282,15 +315,20 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
),
|
||||
d(null != clientWindow.fakelock);
|
||||
let e = Z('strafeRightButton', 'inGame', 'div');
|
||||
(e.style.cssText = 'left:20vh;bottom:20vh;'), document.body.appendChild(e);
|
||||
(e.style.cssText = 'left:20vh;bottom:20vh;'),
|
||||
document.body.appendChild(e);
|
||||
let c = Z('strafeLeftButton', 'inGame', 'div');
|
||||
(c.style.cssText = 'left:0vh;bottom:20vh;'), document.body.appendChild(c);
|
||||
(c.style.cssText = 'left:0vh;bottom:20vh;'),
|
||||
document.body.appendChild(c);
|
||||
let n = Z('forwardButton', 'inGame', 'div');
|
||||
(n.style.cssText = 'left:10vh;bottom:20vh;'),
|
||||
n.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
C('w', 'keydown'), e.classList.remove('hide'), c.classList.remove('hide'), n.classList.add('active');
|
||||
C('w', 'keydown'),
|
||||
e.classList.remove('hide'),
|
||||
c.classList.remove('hide'),
|
||||
n.classList.add('active');
|
||||
},
|
||||
!1,
|
||||
),
|
||||
@ -302,10 +340,17 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
g || (g = I.pageX);
|
||||
let i = I.pageX - g;
|
||||
10 * i > clientWindow.innerHeight
|
||||
? (e.classList.add('active'), c.classList.remove('active'), C('d', 'keydown'), C('a', 'keyup'))
|
||||
? (e.classList.add('active'),
|
||||
c.classList.remove('active'),
|
||||
C('d', 'keydown'),
|
||||
C('a', 'keyup'))
|
||||
: 10 * i < 0 - clientWindow.innerHeight
|
||||
? (c.classList.add('active'), e.classList.remove('active'), C('a', 'keydown'), C('d', 'keyup'))
|
||||
: (e.classList.remove('active'), c.classList.remove('active'));
|
||||
? (c.classList.add('active'),
|
||||
e.classList.remove('active'),
|
||||
C('a', 'keydown'),
|
||||
C('d', 'keyup'))
|
||||
: (e.classList.remove('active'),
|
||||
c.classList.remove('active'));
|
||||
},
|
||||
!1,
|
||||
),
|
||||
@ -403,7 +448,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
C('shift', 'keydown'),
|
||||
(clientWindow.crouchLock = !!clientWindow.crouchLock && null),
|
||||
(clientWindow.crouchTimer = setTimeout(function (A) {
|
||||
(clientWindow.crouchLock = null != clientWindow.crouchLock), M.classList.toggle('active');
|
||||
(clientWindow.crouchLock = null != clientWindow.crouchLock),
|
||||
M.classList.toggle('active');
|
||||
}, 1e3));
|
||||
},
|
||||
!1,
|
||||
@ -412,7 +458,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
'touchend',
|
||||
function (A) {
|
||||
clientWindow.crouchLock ||
|
||||
(C('shift', 'keyup'), M.classList.remove('active'), (clientWindow.crouchLock = !1)),
|
||||
(C('shift', 'keyup'),
|
||||
M.classList.remove('active'),
|
||||
(clientWindow.crouchLock = !1)),
|
||||
clearTimeout(clientWindow.crouchTimer);
|
||||
},
|
||||
!1,
|
||||
@ -436,7 +484,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
),
|
||||
document.body.appendChild(v);
|
||||
let m = Z('exitButton', 'inMenu');
|
||||
(m.style.cssText = 'top: 0vh; margin: auto; left: 0vh; right:8vh; width: 8vh; height: 8vh;'),
|
||||
(m.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 0vh; right:8vh; width: 8vh; height: 8vh;'),
|
||||
m.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
@ -461,28 +510,45 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
'beforeinput',
|
||||
function (A) {
|
||||
A.stopImmediatePropagation(), A.preventDefault(!0);
|
||||
let I = 'insertLineBreak' == A.inputType ? 'return' : null == A.data ? 'delete' : A.data.slice(-1);
|
||||
let I =
|
||||
'insertLineBreak' == A.inputType
|
||||
? 'return'
|
||||
: null == A.data
|
||||
? 'delete'
|
||||
: A.data.slice(-1);
|
||||
if (
|
||||
(clientWindow.lastKey ||
|
||||
(clientWindow.console.warn('Enabling blocking duplicate key events. Some functionality may be lost.'),
|
||||
(clientWindow.console.warn(
|
||||
'Enabling blocking duplicate key events. Some functionality may be lost.',
|
||||
),
|
||||
(clientWindow.inputFix = !0)),
|
||||
clientWindow.keyboardFix)
|
||||
)
|
||||
if ('insertLineBreak' == A.inputType) C('enter', 'keydown'), C('enter', 'keyup');
|
||||
if ('insertLineBreak' == A.inputType)
|
||||
C('enter', 'keydown'), C('enter', 'keyup');
|
||||
else {
|
||||
const g = A.inputType.slice(0, 1);
|
||||
if ('i' == g && A.data) {
|
||||
if (clientWindow.lastKey == I && clientWindow.blockNextInput && clientWindow.inputFix)
|
||||
if (
|
||||
clientWindow.lastKey == I &&
|
||||
clientWindow.blockNextInput &&
|
||||
clientWindow.inputFix
|
||||
)
|
||||
clientWindow.blockNextInput = !1;
|
||||
else {
|
||||
I.toLowerCase() != I
|
||||
? (C('shift', 'keydown'), C(I, 'keydown'), C(I, 'keyup'), C('shift', 'keyup'))
|
||||
? (C('shift', 'keydown'),
|
||||
C(I, 'keydown'),
|
||||
C(I, 'keyup'),
|
||||
C('shift', 'keyup'))
|
||||
: (C(I, 'keydown'), C(I, 'keyup')),
|
||||
(clientWindow.blockNextInput = !0);
|
||||
}
|
||||
} else
|
||||
('d' != g && A.data) ||
|
||||
(C('backspace', 'keydown'), C('backspace', 'keyup'), (clientWindow.blockNextInput = !1));
|
||||
(C('backspace', 'keydown'),
|
||||
C('backspace', 'keyup'),
|
||||
(clientWindow.blockNextInput = !1));
|
||||
}
|
||||
(clientWindow.lastKey = I), (h.value = ' ');
|
||||
},
|
||||
@ -504,7 +570,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
'Switching from keydown to input events due to invalid KeyboardEvent. Some functionality will be lost.',
|
||||
),
|
||||
(clientWindow.keyboardFix = !0),
|
||||
clientWindow.lastKey && (C(clientWindow.lastKey, 'keydown'), C(clientWindow.lastKey, 'keyup')));
|
||||
clientWindow.lastKey &&
|
||||
(C(clientWindow.lastKey, 'keydown'),
|
||||
C(clientWindow.lastKey, 'keyup')));
|
||||
},
|
||||
!1,
|
||||
),
|
||||
@ -513,7 +581,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
}),
|
||||
document.body.appendChild(h);
|
||||
let a = Z('keyboardButton', 'inMenu');
|
||||
(a.style.cssText = 'top: 0vh; margin: auto; left: 8vh; right:0vh; width: 8vh; height: 8vh;'),
|
||||
(a.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 8vh; right:0vh; width: 8vh; height: 8vh;'),
|
||||
a.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
@ -525,7 +594,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
'touchend',
|
||||
function (A) {
|
||||
A.preventDefault(),
|
||||
clientWindow.hiddenInputFocused ? h.blur() : (h.select(), (clientWindow.hiddenInputFocused = !0));
|
||||
clientWindow.hiddenInputFocused
|
||||
? h.blur()
|
||||
: (h.select(), (clientWindow.hiddenInputFocused = !0));
|
||||
},
|
||||
!1,
|
||||
),
|
||||
@ -626,7 +697,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
C('r', 'keydown'),
|
||||
(clientWindow.sprintLock = !!clientWindow.sprintLock && null),
|
||||
(clientWindow.sprintTimer = setTimeout(function (A) {
|
||||
(clientWindow.sprintLock = null != clientWindow.sprintLock), j.classList.toggle('active');
|
||||
(clientWindow.sprintLock = null != clientWindow.sprintLock),
|
||||
j.classList.toggle('active');
|
||||
}, 1e3));
|
||||
},
|
||||
!1,
|
||||
@ -635,14 +707,17 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
'touchend',
|
||||
function (A) {
|
||||
clientWindow.sprintLock ||
|
||||
(C('r', 'keyup'), j.classList.remove('active'), (clientWindow.sprintLock = !1)),
|
||||
(C('r', 'keyup'),
|
||||
j.classList.remove('active'),
|
||||
(clientWindow.sprintLock = !1)),
|
||||
clearTimeout(clientWindow.sprintTimer);
|
||||
},
|
||||
!1,
|
||||
),
|
||||
document.body.appendChild(j);
|
||||
let y = Z('pauseButton', 'inGame');
|
||||
(y.style.cssText = 'top: 0vh; margin: auto; left: 0vh; right: 32vh; width: 8vh; height: 8vh;'),
|
||||
(y.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 0vh; right: 32vh; width: 8vh; height: 8vh;'),
|
||||
y.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
@ -659,7 +734,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
),
|
||||
document.body.appendChild(y);
|
||||
let L = Z('chatButton', 'inGame');
|
||||
(L.style.cssText = 'top: 0vh; margin: auto; left: 0vh; right: 16vh; width: 8vh; height: 8vh;'),
|
||||
(L.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 0vh; right: 16vh; width: 8vh; height: 8vh;'),
|
||||
L.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
@ -669,7 +745,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
),
|
||||
document.body.appendChild(L);
|
||||
let N = Z('perspectiveButton', 'inGame');
|
||||
(N.style.cssText = 'top: 0vh; margin: auto; left: 0vh; right: 0vh; width: 8vh; height: 8vh;'),
|
||||
(N.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 0vh; right: 0vh; width: 8vh; height: 8vh;'),
|
||||
N.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
@ -686,7 +763,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
),
|
||||
document.body.appendChild(N);
|
||||
let U = Z('screenshotButton', 'inGame');
|
||||
(U.style.cssText = 'top: 0vh; margin: auto; left: 16vh; right: 0vh; width: 8vh; height: 8vh;'),
|
||||
(U.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 16vh; right: 0vh; width: 8vh; height: 8vh;'),
|
||||
U.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
@ -703,7 +781,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
),
|
||||
document.body.appendChild(U);
|
||||
let z = Z('coordinatesButton', 'inGame');
|
||||
(z.style.cssText = 'top: 0vh; margin: auto; left: 32vh; right: 0vh; width: 8vh; height: 8vh;'),
|
||||
(z.style.cssText =
|
||||
'top: 0vh; margin: auto; left: 32vh; right: 0vh; width: 8vh; height: 8vh;'),
|
||||
z.addEventListener(
|
||||
'touchstart',
|
||||
function (A) {
|
||||
|
@ -13,7 +13,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
}
|
||||
}
|
||||
if (!isMobile()) {
|
||||
alert('WARNING: This script was created for mobile, and may break functionality in non-mobile browsers!');
|
||||
alert(
|
||||
'WARNING: This script was created for mobile, and may break functionality in non-mobile browsers!',
|
||||
);
|
||||
}
|
||||
// TODO: consolidate all of these into a single object?
|
||||
window.crouchLock = false; // Used for crouch mobile control
|
||||
@ -191,7 +193,12 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
});
|
||||
window.dispatchEvent(evt);
|
||||
}
|
||||
function mouseEvent(number, state, element, event = { clientX: 0, clientY: 0, screenX: 0, screenY: 0 }) {
|
||||
function mouseEvent(
|
||||
number,
|
||||
state,
|
||||
element,
|
||||
event = { clientX: 0, clientY: 0, screenX: 0, screenY: 0 },
|
||||
) {
|
||||
element.dispatchEvent(
|
||||
new PointerEvent(state, {
|
||||
button: number,
|
||||
@ -277,7 +284,9 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
const element = this._createElement(type);
|
||||
if (type == 'input' && !ignore) {
|
||||
// We set the ingore flag to true when we create the hiddenInput
|
||||
document.querySelectorAll('#fileUpload').forEach((e) => e.parentNode.removeChild(e)); // Get rid of any left over fileUpload inputs
|
||||
document
|
||||
.querySelectorAll('#fileUpload')
|
||||
.forEach((e) => e.parentNode.removeChild(e)); // Get rid of any left over fileUpload inputs
|
||||
element.id = 'fileUpload';
|
||||
element.addEventListener(
|
||||
'change',
|
||||
@ -401,9 +410,15 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
function (e) {
|
||||
e.preventDefault(); // Prevents window zoom when using two fingers
|
||||
let primaryTouch;
|
||||
for (let touchIndex = 0; touchIndex < e.targetTouches.length; touchIndex++) {
|
||||
for (
|
||||
let touchIndex = 0;
|
||||
touchIndex < e.targetTouches.length;
|
||||
touchIndex++
|
||||
) {
|
||||
// Iterate through our touches to find a touch event matching the primary touch ID
|
||||
if (e.targetTouches[touchIndex].identifier == window.canvasPrimaryID) {
|
||||
if (
|
||||
e.targetTouches[touchIndex].identifier == window.canvasPrimaryID
|
||||
) {
|
||||
primaryTouch = e.targetTouches[touchIndex];
|
||||
break;
|
||||
}
|
||||
@ -412,7 +427,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
primaryTouch.distanceX = primaryTouch.clientX - canvasTouchStartX;
|
||||
primaryTouch.distanceY = primaryTouch.clientY - canvasTouchStartY;
|
||||
primaryTouch.squaredNorm =
|
||||
primaryTouch.distanceX * primaryTouch.distanceX + primaryTouch.distanceY * primaryTouch.distanceY;
|
||||
primaryTouch.distanceX * primaryTouch.distanceX +
|
||||
primaryTouch.distanceY * primaryTouch.distanceY;
|
||||
primaryTouch.movementX = primaryTouch.clientX - canvasTouchPreviousX;
|
||||
primaryTouch.movementY = primaryTouch.clientY - canvasTouchPreviousY;
|
||||
if (window.canvasTouchMode == 1) {
|
||||
@ -452,7 +468,11 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
);
|
||||
|
||||
function canvasTouchEnd(e) {
|
||||
for (let touchIndex = 0; touchIndex < e.changedTouches.length; touchIndex++) {
|
||||
for (
|
||||
let touchIndex = 0;
|
||||
touchIndex < e.changedTouches.length;
|
||||
touchIndex++
|
||||
) {
|
||||
// Iterate through changed touches to find primary touch
|
||||
if (e.changedTouches[touchIndex].identifier == window.canvasPrimaryID) {
|
||||
const primaryTouch = e.changedTouches[touchIndex];
|
||||
@ -477,11 +497,19 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
canvas.addEventListener('touchcancel', canvasTouchEnd, false); // TODO: Find out why this is different than touchend
|
||||
setButtonVisibility(window.fakelock != null); //Updates our mobile controls when the canvas finally loads
|
||||
// All of the touch buttons
|
||||
const strafeRightButton = createTouchButton('strafeRightButton', 'inGame', 'div');
|
||||
const strafeRightButton = createTouchButton(
|
||||
'strafeRightButton',
|
||||
'inGame',
|
||||
'div',
|
||||
);
|
||||
strafeRightButton.classList.add('strafeSize');
|
||||
strafeRightButton.style.cssText = 'left:24vh;bottom:22vh;';
|
||||
document.body.appendChild(strafeRightButton);
|
||||
const strafeLeftButton = createTouchButton('strafeLeftButton', 'inGame', 'div');
|
||||
const strafeLeftButton = createTouchButton(
|
||||
'strafeLeftButton',
|
||||
'inGame',
|
||||
'div',
|
||||
);
|
||||
strafeLeftButton.classList.add('strafeSize');
|
||||
strafeLeftButton.style.cssText = 'left:5.5vh;bottom:22vh;';
|
||||
document.body.appendChild(strafeLeftButton);
|
||||
@ -666,7 +694,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(inventoryButton);
|
||||
const exitButton = createTouchButton('exitButton', 'inMenu');
|
||||
exitButton.classList.add('smallMobileControl');
|
||||
exitButton.style.cssText = 'top: 0.5vh; margin: auto; left: 1vh; right:8vh;';
|
||||
exitButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 1vh; right:8vh;';
|
||||
exitButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
@ -712,10 +741,17 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
// For some reason beforeinput doesn't have the same deletion problems that input has on Android
|
||||
e.stopImmediatePropagation(); // Android ignores this and the prevent default, so this will probably be removed in the future
|
||||
e.preventDefault(true); // We pass a value because we've hijacked the prevent default function to have a "should bypass" boolean value
|
||||
const inputData = e.inputType == 'insertLineBreak' ? 'return' : e.data == null ? 'delete' : e.data.slice(-1); // Saves the last key press.
|
||||
const inputData =
|
||||
e.inputType == 'insertLineBreak'
|
||||
? 'return'
|
||||
: e.data == null
|
||||
? 'delete'
|
||||
: e.data.slice(-1); // Saves the last key press.
|
||||
if (!window.lastKey) {
|
||||
// When we first set hiddenInput's text contents to " " we can use this to check if Duplicate Mode is needed
|
||||
window.console.warn('Enabling blocking duplicate key events. Some functionality may be lost.');
|
||||
window.console.warn(
|
||||
'Enabling blocking duplicate key events. Some functionality may be lost.',
|
||||
);
|
||||
window.inputFix = true;
|
||||
}
|
||||
if (window.keyboardFix) {
|
||||
@ -727,7 +763,10 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
const sliceInputType = e.inputType.slice(0, 1); // Android doesn't constiently dispatch the correct inputType, but most of them either start with i for insert or d for delete, so this dumb solution should be good enough.
|
||||
if (sliceInputType == 'i' && e.data) {
|
||||
// Android sometimes always dispatches insertCompositionText inputTypes, so checking that e.data isn't null is necessary
|
||||
const isDuplicate = window.lastKey == inputData && window.blockNextInput && window.inputFix;
|
||||
const isDuplicate =
|
||||
window.lastKey == inputData &&
|
||||
window.blockNextInput &&
|
||||
window.inputFix;
|
||||
if (isDuplicate) {
|
||||
// If our key press matches the last unblocked key press and we are in duplicaye mode, ignore the input
|
||||
window.blockNextInput = false;
|
||||
@ -793,7 +832,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(hiddenInput);
|
||||
const keyboardButton = createTouchButton('keyboardButton', 'inMenu');
|
||||
keyboardButton.classList.add('smallMobileControl');
|
||||
keyboardButton.style.cssText = 'top: 0.5vh; margin: auto; left: 6vh; right:0vh;';
|
||||
keyboardButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 6vh; right:0vh;';
|
||||
keyboardButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
@ -936,7 +976,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(sprintButton);
|
||||
const pauseButton = createTouchButton('pauseButton', 'inGame');
|
||||
pauseButton.classList.add('smallMobileControl');
|
||||
pauseButton.style.cssText = 'top: 0.5vh; margin: auto; left: 0vh; right: 0vh;';
|
||||
pauseButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 0vh; right: 0vh;';
|
||||
pauseButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
@ -954,7 +995,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(pauseButton);
|
||||
const chatButton = createTouchButton('chatButton', 'inGame');
|
||||
chatButton.classList.add('smallMobileControl');
|
||||
chatButton.style.cssText = 'top: 0.5vh; margin: auto; left: 0vh; right: 14vh;';
|
||||
chatButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 0vh; right: 14vh;';
|
||||
chatButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
@ -965,7 +1007,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(chatButton);
|
||||
const perspectiveButton = createTouchButton('perspectiveButton', 'inGame');
|
||||
perspectiveButton.classList.add('smallMobileControl');
|
||||
perspectiveButton.style.cssText = 'top: 0.5vh; margin: auto; left: 0vh; right: 28vh;';
|
||||
perspectiveButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 0vh; right: 28vh;';
|
||||
perspectiveButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
@ -985,7 +1028,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(perspectiveButton);
|
||||
const screenshotButton = createTouchButton('screenshotButton', 'inGame');
|
||||
screenshotButton.classList.add('smallMobileControl');
|
||||
screenshotButton.style.cssText = 'top: 0.5vh; margin: auto; left: 28vh; right: 0vh;';
|
||||
screenshotButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 28vh; right: 0vh;';
|
||||
screenshotButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
@ -1005,7 +1049,8 @@ if (new URLSearchParams(window.location.search).get('mobile') === 'true') {
|
||||
document.body.appendChild(screenshotButton);
|
||||
const coordinatesButton = createTouchButton('coordinatesButton', 'inGame');
|
||||
coordinatesButton.classList.add('smallMobileControl');
|
||||
coordinatesButton.style.cssText = 'top: 0.5vh; margin: auto; left: 14vh; right: 0vh;';
|
||||
coordinatesButton.style.cssText =
|
||||
'top: 0.5vh; margin: auto; left: 14vh; right: 0vh;';
|
||||
coordinatesButton.addEventListener(
|
||||
'touchstart',
|
||||
function (e) {
|
||||
|
@ -12,9 +12,21 @@ window.addEventListener('load', () => {
|
||||
{ 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 },
|
||||
{
|
||||
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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -7,9 +7,21 @@ window.addEventListener('load', () => {
|
||||
localesURI: `${window.location.pathname}/lang/`,
|
||||
servers: [{ addr: 'wss://eagler.xyz', name: 'TemuzX' }],
|
||||
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 },
|
||||
{
|
||||
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,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
@ -1,6 +1,9 @@
|
||||
// @ts-nocheck
|
||||
window.addEventListener('load', function () {
|
||||
window.minecraftOpts = ['game_frame', `${window.location.pathname}/assets.epk`];
|
||||
window.minecraftOpts = [
|
||||
'game_frame',
|
||||
`${window.location.pathname}/assets.epk`,
|
||||
];
|
||||
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
window.minecraftOpts.push(urlParams.get('server') ?? undefined);
|
||||
|
@ -6,7 +6,9 @@ let articleAnimationLock = false;
|
||||
|
||||
const theme = {
|
||||
load: function (themeToLoad?: string) {
|
||||
const themeElement = document.querySelector('#theme') as HTMLLinkElement | null;
|
||||
const themeElement = document.querySelector(
|
||||
'#theme',
|
||||
) as HTMLLinkElement | null;
|
||||
if (themeElement)
|
||||
themeElement.href = themeToLoad
|
||||
? `/resources/styles/themes/${themeToLoad}.css`
|
||||
@ -81,7 +83,9 @@ const game = {
|
||||
'b1.3': 'b13-client-version',
|
||||
};
|
||||
const dropdown = clients[client]
|
||||
? (document.querySelector(`select[id='${clients[client]}']`) as HTMLSelectElement | null)
|
||||
? (document.querySelector(
|
||||
`select[id='${clients[client]}']`,
|
||||
) as HTMLSelectElement | null)
|
||||
: null;
|
||||
if (dropdown?.value) {
|
||||
selectedVersion = `https://archive.eaglercraft.rip/Eaglercraft${client === '1.8' ? 'X_1.8' : `_${client}`}/client/${dropdown.value}/index.html`;
|
||||
@ -160,8 +164,12 @@ const navigate = {
|
||||
|
||||
const article = {
|
||||
open: function (articleId: string) {
|
||||
const modal = document.querySelector(`.article[data-article-id='${articleId}']`) as HTMLElement | null;
|
||||
const modalContent = document.querySelector(`.article[data-article-id='${articleId}'] > div`) as HTMLElement | null;
|
||||
const modal = document.querySelector(
|
||||
`.article[data-article-id='${articleId}']`,
|
||||
) as HTMLElement | null;
|
||||
const modalContent = document.querySelector(
|
||||
`.article[data-article-id='${articleId}'] > div`,
|
||||
) as HTMLElement | null;
|
||||
if (!articleAnimationLock && modal && modalContent) {
|
||||
articleAnimationLock = true;
|
||||
modal.style.animation = '0.5s ease-in-out 1 normal article';
|
||||
@ -184,7 +192,9 @@ const article = {
|
||||
}
|
||||
},
|
||||
close: function (articleId: string) {
|
||||
const modal = document.querySelector(`.article[data-article-id='${articleId}']`) as HTMLElement | null;
|
||||
const modal = document.querySelector(
|
||||
`.article[data-article-id='${articleId}']`,
|
||||
) as HTMLElement | null;
|
||||
if (!articleAnimationLock && modal) {
|
||||
articleAnimationLock = true;
|
||||
modal.style.animation = '0.5s ease-in-out 1 reverse article-tempfix';
|
||||
@ -238,7 +248,10 @@ const storage = {
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
set: function (key: string, value: string | number | object | boolean | null | undefined) {
|
||||
set: function (
|
||||
key: string,
|
||||
value: string | number | object | boolean | null | undefined,
|
||||
) {
|
||||
const item = localStorage.getItem('minexlauncher');
|
||||
if (item === null) {
|
||||
const json: Record<string, unknown> = {};
|
||||
@ -268,7 +281,10 @@ const storage = {
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
set: function (key: string, value: string | number | object | boolean | null | undefined) {
|
||||
set: function (
|
||||
key: string,
|
||||
value: string | number | object | boolean | null | undefined,
|
||||
) {
|
||||
let item = sessionStorage.getItem('minexlauncher');
|
||||
if (item === null) {
|
||||
item = '{}';
|
||||
@ -309,7 +325,9 @@ const mods = {
|
||||
mods.push(mod);
|
||||
mods.sort();
|
||||
storage.local.set('mods', mods);
|
||||
const modInstallElem = document.querySelector(`.mod-list > div .links .install[data-mod-id='${modId}']`);
|
||||
const modInstallElem = document.querySelector(
|
||||
`.mod-list > div .links .install[data-mod-id='${modId}']`,
|
||||
);
|
||||
if (modInstallElem) {
|
||||
modInstallElem.textContent = 'Uninstall';
|
||||
modInstallElem.classList.add('installed');
|
||||
@ -317,7 +335,9 @@ const mods = {
|
||||
} else {
|
||||
mods.splice(modIndex, 1);
|
||||
storage.local.set('mods', mods);
|
||||
const modInstallElem = document.querySelector(`.mod-list > div .links .install[data-mod-id='${modId}']`);
|
||||
const modInstallElem = document.querySelector(
|
||||
`.mod-list > div .links .install[data-mod-id='${modId}']`,
|
||||
);
|
||||
if (modInstallElem) {
|
||||
modInstallElem.textContent = 'Install';
|
||||
modInstallElem.classList.remove('installed');
|
||||
@ -403,7 +423,9 @@ if (window.location.pathname === '/') {
|
||||
? '/mobile/'
|
||||
: '/home/game/';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', () => document.body.appendChild(iframe));
|
||||
document.addEventListener('DOMContentLoaded', () =>
|
||||
document.body.appendChild(iframe),
|
||||
);
|
||||
|
||||
/* document.addEventListener('load', () => {
|
||||
if (storage.local.get('offlineCache')) {
|
||||
@ -433,9 +455,12 @@ if (window.location.pathname === '/') {
|
||||
const titleBarText = document.querySelector('.title-bar');
|
||||
|
||||
const lastVersion = storage.local.get('lastVersion');
|
||||
const updateData = (await (await fetch('/resources/data/main.json')).json()).updates;
|
||||
const updateData = (await (await fetch('/resources/data/main.json')).json())
|
||||
.updates;
|
||||
const currentVersion = updateData[0].version;
|
||||
const changelog = updateData[0].changelog.map((change: string) => ` - ${change}`).join('\n');
|
||||
const changelog = updateData[0].changelog
|
||||
.map((change: string) => ` - ${change}`)
|
||||
.join('\n');
|
||||
|
||||
if (profileName) profileName.textContent = storage.local.get('username');
|
||||
if (titleBarText) titleBarText.textContent += ` ${currentVersion}`;
|
||||
@ -443,9 +468,14 @@ if (window.location.pathname === '/') {
|
||||
if (
|
||||
lastVersion &&
|
||||
// @ts-expect-error
|
||||
gt(coerce(currentVersion, { includePrerelease: true }), coerce(lastVersion, { includePrerelease: true }))
|
||||
gt(
|
||||
coerce(currentVersion, { includePrerelease: true }),
|
||||
coerce(lastVersion, { includePrerelease: true }),
|
||||
)
|
||||
) {
|
||||
alert(`MineXLauncher has been updated to v${currentVersion}!\n\nChanges in v${currentVersion}:\n${changelog}`);
|
||||
alert(
|
||||
`MineXLauncher has been updated to v${currentVersion}!\n\nChanges in v${currentVersion}:\n${changelog}`,
|
||||
);
|
||||
storage.local.set('lastVersion', currentVersion);
|
||||
}
|
||||
});
|
||||
@ -473,16 +503,28 @@ if (window.location.pathname === '/') {
|
||||
if (window.location.pathname === '/settings/') {
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const profileName = document.querySelector('.username');
|
||||
const usernameInput = document.querySelector('#username-input') as HTMLInputElement | null;
|
||||
const themeSelect = document.querySelector('#theme-select') as HTMLSelectElement | null;
|
||||
const offlineCheckbox = document.querySelector('#offline-checkbox') as HTMLInputElement | null;
|
||||
const adsCheckbox = document.querySelector('#ads-checkbox') as HTMLInputElement | null;
|
||||
const themeData: { id: string; name: string }[] = (await (await fetch('/resources/data/main.json')).json()).themes;
|
||||
const usernameInput = document.querySelector(
|
||||
'#username-input',
|
||||
) as HTMLInputElement | null;
|
||||
const themeSelect = document.querySelector(
|
||||
'#theme-select',
|
||||
) as HTMLSelectElement | null;
|
||||
const offlineCheckbox = document.querySelector(
|
||||
'#offline-checkbox',
|
||||
) as HTMLInputElement | null;
|
||||
const adsCheckbox = document.querySelector(
|
||||
'#ads-checkbox',
|
||||
) as HTMLInputElement | null;
|
||||
const themeData: { id: string; name: string }[] = (
|
||||
await (await fetch('/resources/data/main.json')).json()
|
||||
).themes;
|
||||
|
||||
if (usernameInput) {
|
||||
usernameInput.placeholder = storage.local.get('username') ?? '';
|
||||
usernameInput.addEventListener('input', () => {
|
||||
let username = usernameInput.value.replace(/[^A-Za-z0-9]/g, '_').substring(0, 16);
|
||||
let username = usernameInput.value
|
||||
.replace(/[^A-Za-z0-9]/g, '_')
|
||||
.substring(0, 16);
|
||||
usernameInput.value = username;
|
||||
while (username.length < 3) username += '_';
|
||||
|
||||
@ -499,7 +541,9 @@ if (window.location.pathname === '/settings/') {
|
||||
themeSelect?.appendChild(option);
|
||||
});
|
||||
themeSelect.value = storage.local.get('theme') ?? '';
|
||||
themeSelect.addEventListener('change', () => theme.set(themeSelect.value ?? 'default'));
|
||||
themeSelect.addEventListener('change', () =>
|
||||
theme.set(themeSelect.value ?? 'default'),
|
||||
);
|
||||
}
|
||||
|
||||
if (offlineCheckbox) {
|
||||
@ -523,22 +567,37 @@ if (window.location.pathname === '/settings/') {
|
||||
adsCheckbox.addEventListener('change', () => {
|
||||
storage.local.set('showAds', adsCheckbox.checked);
|
||||
const adsContainers = document.querySelectorAll('.ads-container');
|
||||
adsContainers.forEach((adsContainer: Element) => ((adsContainer as HTMLElement).style.display = 'none'));
|
||||
adsContainers.forEach(
|
||||
(adsContainer: Element) =>
|
||||
((adsContainer as HTMLElement).style.display = 'none'),
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (window.location.pathname === '/welcome/') {
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const setupForm = document.querySelector('#setup-form') as HTMLFormElement | null;
|
||||
const usernameInput = document.querySelector('#username-input') as HTMLInputElement | null;
|
||||
const themeSelect = document.querySelector('#theme-select') as HTMLSelectElement | null;
|
||||
const offlineCheckbox = document.querySelector('#offline-checkbox') as HTMLInputElement | null;
|
||||
const themeData: { id: string; name: string }[] = (await (await fetch('/resources/data/main.json')).json()).themes;
|
||||
const setupForm = document.querySelector(
|
||||
'#setup-form',
|
||||
) as HTMLFormElement | null;
|
||||
const usernameInput = document.querySelector(
|
||||
'#username-input',
|
||||
) as HTMLInputElement | null;
|
||||
const themeSelect = document.querySelector(
|
||||
'#theme-select',
|
||||
) as HTMLSelectElement | null;
|
||||
const offlineCheckbox = document.querySelector(
|
||||
'#offline-checkbox',
|
||||
) as HTMLInputElement | null;
|
||||
const themeData: { id: string; name: string }[] = (
|
||||
await (await fetch('/resources/data/main.json')).json()
|
||||
).themes;
|
||||
|
||||
if (setupForm) {
|
||||
if (usernameInput) {
|
||||
usernameInput.addEventListener('input', () => {
|
||||
const username = usernameInput.value.replace(/[^A-Za-z0-9]/g, '_').substring(0, 16);
|
||||
const username = usernameInput.value
|
||||
.replace(/[^A-Za-z0-9]/g, '_')
|
||||
.substring(0, 16);
|
||||
usernameInput.value = username;
|
||||
});
|
||||
}
|
||||
@ -550,13 +609,17 @@ if (window.location.pathname === '/settings/') {
|
||||
option.textContent = theme.name;
|
||||
themeSelect?.appendChild(option);
|
||||
});
|
||||
themeSelect.addEventListener('change', () => theme.load(themeSelect.value ?? 'default'));
|
||||
themeSelect.addEventListener('change', () =>
|
||||
theme.load(themeSelect.value ?? 'default'),
|
||||
);
|
||||
}
|
||||
|
||||
setupForm.addEventListener('submit', async (event) => {
|
||||
event.preventDefault();
|
||||
|
||||
let username = usernameInput?.value.replace(/[^A-Za-z0-9]/g, '_').substring(0, 16);
|
||||
let username = usernameInput?.value
|
||||
.replace(/[^A-Za-z0-9]/g, '_')
|
||||
.substring(0, 16);
|
||||
if (usernameInput) usernameInput.value = username ?? '';
|
||||
|
||||
if (!username) {
|
||||
@ -572,7 +635,8 @@ if (window.location.pathname === '/settings/') {
|
||||
storage.local.set('mods', []);
|
||||
storage.local.set(
|
||||
'lastVersion',
|
||||
(await (await fetch('/resources/data/main.json')).json()).updates[0].version,
|
||||
(await (await fetch('/resources/data/main.json')).json()).updates[0]
|
||||
.version,
|
||||
);
|
||||
|
||||
if (offlineCheckbox?.checked) {
|
||||
@ -588,9 +652,13 @@ if (window.location.pathname === '/settings/') {
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if (window.location.pathname === '/mods/mods/' || window.location.pathname === '/mods/resourcepacks/') {
|
||||
} else if (
|
||||
window.location.pathname === '/mods/mods/' ||
|
||||
window.location.pathname === '/mods/resourcepacks/'
|
||||
) {
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const addonType: 'mods' | 'resourcepacks' = window.location.pathname === '/mods/mods/' ? 'mods' : 'resourcepacks';
|
||||
const addonType: 'mods' | 'resourcepacks' =
|
||||
window.location.pathname === '/mods/mods/' ? 'mods' : 'resourcepacks';
|
||||
const data: {
|
||||
id: string;
|
||||
name: string;
|
||||
@ -607,15 +675,17 @@ if (window.location.pathname === '/settings/') {
|
||||
addon.name
|
||||
}</strong><p class="author">By <a href="${addon.authorLink}" target="_blank">${addon.author}</a></p><p class="description">${addon.description}</p></div><div class="links">${
|
||||
addonType === 'mods'
|
||||
? `<span class="download" onclick="downloadFile('/resources/mods/downloads/${addon.id}.js', '${addon.name}.js')">Download</span><span class="install" data-mod-id="${addon.id}" onclick="mods.toggle('${addon.id}')">Install</span>`
|
||||
: `<span class="download" onclick="downloadFile('/resources/mods/downloads/${addon.id}.zip' '${addon.name}.zip')">Download</span>`
|
||||
? `<span class="download" onclick="downloadFile('/resources/mods/downloads/${addon.id}.js', '${addon.name.replace('\\', '\\\\').replace("'", "\\'")}.js')">Download</span><span class="install" data-mod-id="${addon.id}" onclick="mods.toggle('${addon.id}')">Install</span>`
|
||||
: `<span class="download" onclick="downloadFile('/resources/mods/downloads/${addon.id}.zip', '${addon.name.replace('\\', '\\\\').replace("'", "\\'")}.zip')">Download</span>`
|
||||
}</div>`;
|
||||
modList?.appendChild(modItem);
|
||||
});
|
||||
|
||||
if (addonType === 'mods') {
|
||||
const installedMods = storage.local.get('mods') ?? [];
|
||||
const modElements = document.querySelectorAll('.mod-list > div .links .install');
|
||||
const modElements = document.querySelectorAll(
|
||||
'.mod-list > div .links .install',
|
||||
);
|
||||
modElements.forEach((element) => {
|
||||
const modId = (element as HTMLElement).dataset['modId'];
|
||||
if (installedMods.includes(`/resources/mods/downloads/${modId}.js`)) {
|
||||
@ -628,8 +698,9 @@ if (window.location.pathname === '/settings/') {
|
||||
} else if (window.location.pathname === '/updates/') {
|
||||
document.addEventListener('DOMContentLoaded', async () => {
|
||||
const updatesContainer = document.querySelector('.updates-container');
|
||||
const data: { version: string; changelog: string[] }[] = (await (await fetch('/resources/data/main.json')).json())
|
||||
.updates;
|
||||
const data: { version: string; changelog: string[] }[] = (
|
||||
await (await fetch('/resources/data/main.json')).json()
|
||||
).updates;
|
||||
data.forEach((update) => {
|
||||
const version = document.createElement('div');
|
||||
const name = document.createElement('strong');
|
||||
@ -651,5 +722,14 @@ if (window.location.pathname === '/settings/') {
|
||||
|
||||
if (window.location.hostname === null) {
|
||||
// Stop the minifier from removing these functions
|
||||
console.debug([navigate, query, versionSelector, game, mods, base64Gzip, article, downloadFile]);
|
||||
console.debug([
|
||||
navigate,
|
||||
query,
|
||||
versionSelector,
|
||||
game,
|
||||
mods,
|
||||
base64Gzip,
|
||||
article,
|
||||
downloadFile,
|
||||
]);
|
||||
}
|
||||
|
@ -77,11 +77,11 @@ body {
|
||||
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #ff6600;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #ff8533;
|
||||
}
|
||||
|
||||
|
@ -104,11 +104,11 @@ body {
|
||||
color: #e5a1b8;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #d0808e;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #e5a1b8;
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ body {
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
display: inline-block;
|
||||
background-color: #048239;
|
||||
color: #fff;
|
||||
@ -365,7 +365,8 @@ body {
|
||||
transition: background-color 0.3s;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
cursor: pointer;
|
||||
background-color: #00cc00;
|
||||
}
|
||||
|
||||
|
@ -103,12 +103,12 @@ body {
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #333;
|
||||
color: #e0e0e0;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #444;
|
||||
}
|
||||
|
||||
|
@ -87,11 +87,11 @@ body {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #4caf50;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #66bb6a;
|
||||
}
|
||||
|
||||
|
@ -81,11 +81,11 @@ body {
|
||||
color: #ffcc00;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #8b0000;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #ff4500;
|
||||
}
|
||||
|
||||
|
@ -81,11 +81,11 @@ body {
|
||||
color: #00ff00;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #00b000;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #00ff00;
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,7 @@ body {
|
||||
.installations div .selector,
|
||||
.installations div .installations div .options divs,
|
||||
.installations button,
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #111;
|
||||
border: 2px solid #00ff00;
|
||||
color: #00ff00;
|
||||
@ -41,14 +41,14 @@ body {
|
||||
.nav-bar li.selected,
|
||||
.installations div .options div:hover,
|
||||
.installations button:hover,
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #333;
|
||||
}
|
||||
|
||||
.installations div .selector:hover,
|
||||
.installations div .selector.open,
|
||||
.installations button:hover,
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
|
@ -45,10 +45,10 @@ body {
|
||||
border-color: #0077aa;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #00ccff;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #00e6ff;
|
||||
}
|
||||
|
@ -77,11 +77,11 @@ body {
|
||||
color: #b300b3;
|
||||
}
|
||||
|
||||
.downloads a {
|
||||
.downloads span {
|
||||
background-color: #4d0099;
|
||||
}
|
||||
|
||||
.downloads a:hover {
|
||||
.downloads span:hover {
|
||||
background-color: #8000ff;
|
||||
}
|
||||
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -62,7 +70,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -78,7 +86,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<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>
|
||||
@ -61,7 +69,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -4,9 +4,17 @@
|
||||
<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="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 = ''" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
id="theme"
|
||||
onload="document.documentElement.style.display = ''"
|
||||
/>
|
||||
<meta name="theme-color" content="#000000" />
|
||||
<script src="/resources/scripts/google-tag.js"></script>
|
||||
<script src="/resources/scripts/main.js"></script>
|
||||
@ -22,7 +30,11 @@
|
||||
<p>Let's get you setup.</p>
|
||||
<form id="setup-form">
|
||||
<label for="username-input">Username:</label>
|
||||
<input id="username-input" type="text" placeholder="Enter username" />
|
||||
<input
|
||||
id="username-input"
|
||||
type="text"
|
||||
placeholder="Enter username"
|
||||
/>
|
||||
<label for="theme-select">Theme:</label>
|
||||
<select id="theme-select">
|
||||
<option disabled hidden value=""></option>
|
||||
@ -36,7 +48,9 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom-bar">
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')">Join the MineXLauncher Discord</span>
|
||||
<span onclick="window.open('https://discord.gg/VRwbRJjXzt')"
|
||||
>Join the MineXLauncher Discord</span
|
||||
>
|
||||
<span>© 2024 MineXLauncher. All rights reserved.</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,9 @@
|
||||
{
|
||||
"extends": ["@tsconfig/bun", "@tsconfig/strictest"],
|
||||
"exclude": ["node_modules/", "public/", "src/game/", "src/resources/mods/downloads/"]
|
||||
"exclude": [
|
||||
"node_modules/",
|
||||
"public/",
|
||||
"src/game/",
|
||||
"src/resources/mods/downloads/"
|
||||
]
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user