Upload files to "semag/125"

This commit is contained in:
LEGALISE_PIRACY 2024-05-05 21:01:06 +00:00
parent 7b3f210f87
commit b27547b434
5 changed files with 346 additions and 0 deletions

5
semag/125/README.md Normal file
View 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
View 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
View 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;
}
}

View 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
View 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;
}
}