mirror of
https://gitlab.com/skysthelimit.dev/selenite.git
synced 2025-06-15 10:12:06 -05:00
Upload files to "semag/125"
This commit is contained in:
parent
7b3f210f87
commit
b27547b434
5
semag/125/README.md
Normal file
5
semag/125/README.md
Normal file
@ -0,0 +1,5 @@
|
||||
# Browsercraft
|
||||
|
||||
This is a proof of concept of Minecraft running unmodified in the browser, using [CheerpJ](https://labs.leaningtech.com/cheerpj).
|
||||
|
||||
See [the website](https://browsercraft.cheerpj.com) for a live demo and more information.
|
31
semag/125/mc_server.html
Normal file
31
semag/125/mc_server.html
Normal file
@ -0,0 +1,31 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>CheerpJ test</title>
|
||||
<script src="mcutils.js"></script>
|
||||
<script src="https://cjrtnc.leaningtech.com/3_20231222_329/cj3loader.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="display" style="width:100%;height:100%;position:absolute;top:0;left:0px;"></div>
|
||||
<p id="ip"></p>
|
||||
<script>
|
||||
function ipCallback(ip)
|
||||
{
|
||||
document.getElementById("ip").textContent = "Server IP: "+ip;
|
||||
}
|
||||
async function runServer()
|
||||
{
|
||||
await cheerpjInit({tailscaleAuthKey:"tskey-auth-k9RsJp3CNTRL-xcmTEoqDeYjUVQpzCwwUejtL5bLq9MZVS",tailscaleIpCb:ipCallback});
|
||||
// TODO: Run with nogui
|
||||
cheerpjCreateDisplay(-1, -1, document.getElementById("display"));
|
||||
// The server needs to write a few files to its cwd, copy it over to /files/
|
||||
await installFile("https://piston-data.mojang.com/v1/objects/d8321edc9470e56b8ad5c67bbd16beba25843336/server.jar", "/files/server_1.2.5.jar");
|
||||
// Copy over a modified configuration allowing any client to connect
|
||||
await installFile("/server.properties", "/files/server.properties");
|
||||
await cheerpjRunJar("/files/server_1.2.5.jar");
|
||||
}
|
||||
runServer();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
192
semag/125/minecraft-web.js
Normal file
192
semag/125/minecraft-web.js
Normal file
@ -0,0 +1,192 @@
|
||||
/**
|
||||
* Downloads a file from a url and writes it to the CheerpJ filesystem.
|
||||
* @param {string} url
|
||||
* @param {string} destPath
|
||||
* @param {(downloadedBytes: number, totalBytes: number) => void} [progressCallback]
|
||||
* @returns {Promise<void>}
|
||||
*/
|
||||
async function downloadFileToCheerpJ(url, destPath, progressCallback) {
|
||||
const response = await fetch(url);
|
||||
const reader = response.body.getReader();
|
||||
const contentLength = +response.headers.get('Content-Length');
|
||||
|
||||
const bytes = new Uint8Array(contentLength);
|
||||
progressCallback?.(0, contentLength);
|
||||
|
||||
let pos = 0;
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done)
|
||||
break;
|
||||
bytes.set(value, pos);
|
||||
pos += value.length;
|
||||
progressCallback?.(pos, contentLength);
|
||||
}
|
||||
|
||||
// Write to CheerpJ filesystem
|
||||
return new Promise((resolve, reject) => {
|
||||
cheerpOSOpen(cjFDs, destPath, "w", fd => {
|
||||
cheerpOSWrite(cjFDs, fd, bytes, 0, bytes.length, w => {
|
||||
cheerpOSClose(cjFDs, fd);
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const template = document.createElement('template');
|
||||
template.innerHTML = `
|
||||
<style>
|
||||
:host {
|
||||
display: inline-block;
|
||||
aspect-ratio: 854 / 480;
|
||||
|
||||
background: black;
|
||||
color: #eee;
|
||||
color-scheme: dark;
|
||||
|
||||
width: 854px;
|
||||
height: 480px;
|
||||
}
|
||||
|
||||
:host([hidden]) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
canvas {
|
||||
width: inherit;
|
||||
height: inherit;
|
||||
}
|
||||
|
||||
.display {
|
||||
width: 854px;
|
||||
height: 480px;
|
||||
position: absolute;
|
||||
inset: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.intro {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
p {
|
||||
max-width: 60ch;
|
||||
}
|
||||
|
||||
.disclaimer {
|
||||
font-size: 0.8em;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 0.5em 1em;
|
||||
margin: 2em;
|
||||
}
|
||||
|
||||
progress {
|
||||
width: calc(100% - 2em);
|
||||
margin: 1em;
|
||||
}
|
||||
|
||||
*:focus {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
<canvas width="854" height="480" tabindex="-1"></canvas>
|
||||
<div class="display"></div>
|
||||
<div class="intro">
|
||||
<p>
|
||||
This is a proof-of-concept demo of Minecraft 1.2.5 running unmodified in the browser.
|
||||
</p>
|
||||
<p>
|
||||
Clicking the button below will download the client from mojang.com.
|
||||
By clicking it, you agree to the <a href="https://www.minecraft.net/eula">Minecraft EULA</a>.
|
||||
</p>
|
||||
<button>Play!</button>
|
||||
<div class="disclaimer">
|
||||
This is not an official Minecraft product. It is not approved by or associated with Mojang or Microsoft.
|
||||
</div>
|
||||
</div>
|
||||
<progress style="display: none"></progress>
|
||||
`;
|
||||
|
||||
export default class MinecraftClient extends HTMLElement {
|
||||
#canvas;
|
||||
#progress;
|
||||
#button;
|
||||
#display;
|
||||
#intro;
|
||||
#isRunning;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
const shadowRoot = this.attachShadow({ mode: 'open' });
|
||||
shadowRoot.appendChild(template.content.cloneNode(true));
|
||||
|
||||
this.#button = shadowRoot.querySelector('button');
|
||||
this.#button.addEventListener('click', () => this.run());
|
||||
|
||||
this.#canvas = shadowRoot.querySelector('canvas');
|
||||
this.#canvas.width = 854;
|
||||
this.#canvas.height = 480;
|
||||
this.#canvas.tabIndex = -1;
|
||||
this.#canvas.style.display = 'none';
|
||||
|
||||
this.#progress = shadowRoot.querySelector('progress');
|
||||
this.#progress.style.display = 'none';
|
||||
|
||||
this.#intro = shadowRoot.querySelector('.intro');
|
||||
|
||||
// CheerpJ needs an element to render to, but we are going to render to own canvas
|
||||
this.#display = shadowRoot.querySelector('.display');
|
||||
this.#display.setAttribute('style', 'width:100%;height:100%;position:absolute;top:0;left:0px;visibility:hidden;');
|
||||
cheerpjCreateDisplay(-1, -1, this.#display);
|
||||
|
||||
this.#isRunning = false;
|
||||
}
|
||||
|
||||
static register() {
|
||||
customElements.define('minecraft-client', this);
|
||||
}
|
||||
|
||||
/** @returns {Promise<number>} Exit code */
|
||||
async run() {
|
||||
if (this.#isRunning) {
|
||||
throw new Error('Already running');
|
||||
}
|
||||
|
||||
this.#intro.style.display = 'none';
|
||||
|
||||
this.#progress.style.display = 'unset';
|
||||
const jarPath = "/files/client_1.2.5.jar"
|
||||
await downloadFileToCheerpJ(
|
||||
"https://piston-data.mojang.com/v1/objects/4a2fac7504182a97dcbcd7560c6392d7c8139928/client.jar",
|
||||
jarPath,
|
||||
(downloadedBytes, totalBytes) => {
|
||||
this.#progress.value = downloadedBytes;
|
||||
this.#progress.max = totalBytes;
|
||||
}
|
||||
);
|
||||
this.#progress.style.display = 'none';
|
||||
|
||||
this.#canvas.style.display = 'unset';
|
||||
window.lwjglCanvasElement = this.#canvas;
|
||||
const exitCode = await cheerpjRunMain("net.minecraft.client.Minecraft", `/app/lwjgl-2.9.0.jar:/app/lwjgl_util-2.9.0.jar:${jarPath}`)
|
||||
|
||||
this.#canvas.style.display = 'none';
|
||||
this.#isRunning = false;
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
/** @returns {boolean} */
|
||||
get isRunning() {
|
||||
return this.#isRunning;
|
||||
}
|
||||
}
|
26
semag/125/server.properties
Normal file
26
semag/125/server.properties
Normal file
@ -0,0 +1,26 @@
|
||||
#Minecraft server properties
|
||||
#Sun Dec 17 14:36:54 CET 2023
|
||||
view-distance=10
|
||||
max-build-height=256
|
||||
server-ip=
|
||||
level-seed=
|
||||
allow-nether=true
|
||||
gamemode=0
|
||||
server-port=25565
|
||||
enable-rcon=false
|
||||
enable-query=false
|
||||
level-name=world
|
||||
motd=A Minecraft Server
|
||||
white-list=false
|
||||
pvp=true
|
||||
texture-pack=
|
||||
spawn-npcs=true
|
||||
spawn-animals=true
|
||||
generate-structures=true
|
||||
snooper-enabled=true
|
||||
difficulty=1
|
||||
level-type=DEFAULT
|
||||
spawn-monsters=true
|
||||
max-players=20
|
||||
online-mode=false
|
||||
allow-flight=false
|
92
semag/125/style.css
Normal file
92
semag/125/style.css
Normal file
@ -0,0 +1,92 @@
|
||||
html, body {
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
|
||||
font-family: system-ui, sans-serif;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "Minecrafter";
|
||||
src: url("fonts/minecrafter/Minecrafter.Reg.woff2"), sans-serif;
|
||||
}
|
||||
|
||||
header {
|
||||
background: #171615;
|
||||
color: white;
|
||||
padding: 1rem;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header h1 {
|
||||
color: #c6b8b4;
|
||||
font: 48px Minecrafter;
|
||||
transform: perspective(24px) translateZ(0) rotate3d(1, 0, 0, 2deg);
|
||||
text-shadow: 0px 5px 4px black;
|
||||
}
|
||||
|
||||
main {
|
||||
margin: 0 auto;
|
||||
padding: 1rem;
|
||||
max-width: 60ch;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
line-height: 1.4;
|
||||
}
|
||||
|
||||
main h2 {
|
||||
font-size: 1.5rem;
|
||||
margin: 1rem 0 0.5rem;
|
||||
}
|
||||
|
||||
main li {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
minecraft-client {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.controls {
|
||||
margin: 0.5rem 0;
|
||||
}
|
||||
|
||||
.controls > * {
|
||||
appearance: none;
|
||||
background: transparent;
|
||||
border: 0;
|
||||
cursor: pointer;
|
||||
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
.controls svg {
|
||||
stroke: #c6b8b4;
|
||||
}
|
||||
|
||||
.controls > *:hover svg {
|
||||
stroke: white;
|
||||
}
|
||||
|
||||
.mobile-only {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 854px) {
|
||||
.mobile-only {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.desktop-only {
|
||||
display: none;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user