Add multiplayer to sample index.html
parent
cb985f0d51
commit
8a495e165d
|
@ -6,7 +6,7 @@ unpack_source SQLite
|
|||
|
||||
pushd "$BUILD_DIR/SQLite"
|
||||
export BUILD_CC="gcc"
|
||||
emconfigure ./configure --disable-shared --prefix="$INSTALL_DIR" cross_compiling=yes
|
||||
emconfigure ./configure --disable-tcl --disable-shared --prefix="$INSTALL_DIR" cross_compiling=yes
|
||||
emmake make
|
||||
emmake make install
|
||||
|
||||
|
|
|
@ -5,17 +5,60 @@
|
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<title>Minetest for the Web</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="temporary_console" class="console"></div>
|
||||
<body style="background-color: black">
|
||||
<div id="temporary_console" class="console" style="color: white"></div>
|
||||
<div id="launch_form" class="console" style="color: white; display: none;">
|
||||
<hr>
|
||||
<b>Select Network Proxy:</b>
|
||||
<select id="select_proxy">
|
||||
<!-- filled by javascript -->
|
||||
</select>
|
||||
|
||||
<hr>
|
||||
<b>Single Player:</b>
|
||||
<button id="launch_singleplayer">Launch</button>
|
||||
<br/>
|
||||
<hr>
|
||||
<b>Multiplayer:</b>
|
||||
<br/>
|
||||
<b>Player Name:</b>
|
||||
<input style="border: 2px solid black; width: 400px; height: 2em" type="text" id="multiplayer_username" required="" pattern="[A-Za-z0-9_-]{1,20}" maxlength="19" title="Alphanumeric, 19 characters max">
|
||||
<br/>
|
||||
<b>Game:</b>
|
||||
<select id="multiplayer_game">
|
||||
<option value="minetest_game">minetest_game</option>
|
||||
</select>
|
||||
<br/>
|
||||
<button id="launch_server">Launch Multiplayer Server</button>
|
||||
<br/>
|
||||
<span>After launch, copy the URL and use it to open clients. If the server is closed, the game ends.
|
||||
</span>
|
||||
|
||||
</div>
|
||||
<div id="join_form" class="console" style="color: white; display: none;">
|
||||
<b>Joining game:</b>
|
||||
<br/>
|
||||
<b>Player Name:</b>
|
||||
<input style="border: 2px solid black; width: 400px; height: 2em" type="text" id="join_username" required="" pattern="[A-Za-z0-9_-]{1,20}" maxlength="19" title="Alphanumeric, 19 characters max">
|
||||
<br/>
|
||||
<button id="join_launch">Join Game</button>
|
||||
</div>
|
||||
<script type="text/javascript" src="%__RELEASE_UUID__%/launcher.js"></script>
|
||||
<script type="text/javascript">
|
||||
document.body.style.backgroundColor = 'black';
|
||||
// Reduce memory and network usage
|
||||
const memorySavingConfig = `
|
||||
viewing_range = 85
|
||||
max_block_send_distance = 5
|
||||
max_block_generate_distance = 5
|
||||
`;
|
||||
|
||||
const launchForm = document.getElementById('launch_form');
|
||||
const joinForm = document.getElementById('join_form');
|
||||
const tcon = document.getElementById('temporary_console');
|
||||
tcon.style.color = 'white';
|
||||
function tcon_print(prefix, line) {
|
||||
if (prefix) {
|
||||
for (child of tcon.childNodes) {
|
||||
if (child.innerText.startsWith(prefix)) {
|
||||
if (child.nodeName == 'PRE' && child.innerText.startsWith(prefix)) {
|
||||
child.innerText = prefix + line;
|
||||
return;
|
||||
}
|
||||
|
@ -25,6 +68,142 @@
|
|||
p.innerText = prefix + line;
|
||||
tcon.appendChild(p);
|
||||
}
|
||||
|
||||
function wipePage() {
|
||||
launchForm.remove();
|
||||
joinForm.remove();
|
||||
tcon.remove();
|
||||
}
|
||||
|
||||
function enableLaunchForm() {
|
||||
if (join_code) {
|
||||
joinForm.style.display = 'block';
|
||||
} else {
|
||||
launchForm.style.display = 'block';
|
||||
}
|
||||
|
||||
const select_proxy = document.getElementById('select_proxy');
|
||||
const proxies = [
|
||||
[ "wss://na1.dustlabs.io/mtproxy", "North America" ],
|
||||
[ "wss://sa1.dustlabs.io/mtproxy", "South America" ],
|
||||
[ "wss://eu1.dustlabs.io/mtproxy", "Europe" ],
|
||||
[ "wss://ap1.dustlabs.io/mtproxy", "Asia" ],
|
||||
[ "wss://ap2.dustlabs.io/mtproxy", "Australia" ],
|
||||
];
|
||||
proxies.forEach((entry, index) => {
|
||||
const opt = document.createElement('option');
|
||||
opt.value = index;
|
||||
opt.innerText = entry[1];
|
||||
select_proxy.appendChild(opt);
|
||||
});
|
||||
|
||||
const launchSinglePlayer = document.getElementById('launch_singleplayer');
|
||||
launchSinglePlayer.addEventListener('click', () => {
|
||||
const proxyIndex = document.getElementById('select_proxy').value;
|
||||
const proxy = proxies[proxyIndex][0];
|
||||
wipePage();
|
||||
mtl.setProxy(proxy);
|
||||
mtl.launch(args);
|
||||
});
|
||||
|
||||
const launchServer = document.getElementById('launch_server');
|
||||
launchServer.addEventListener('click', async () => {
|
||||
const proxyIndex = document.getElementById('select_proxy').value;
|
||||
const username = document.getElementById('multiplayer_username').value;
|
||||
const game = document.getElementById('multiplayer_game').value;
|
||||
if (username.length == 0) {
|
||||
alert("Empty username");
|
||||
return;
|
||||
}
|
||||
wipePage();
|
||||
|
||||
const proxy = proxies[proxyIndex][0];
|
||||
mtl.setProxy(proxy);
|
||||
mtl.addPack(game);
|
||||
const [cmd, serverCode, clientCode] = await queryProxy(`MAKEVPN ${game}`, proxy);
|
||||
if (cmd != 'NEWVPN') {
|
||||
alert("Invalid response from proxy");
|
||||
return;
|
||||
}
|
||||
const args = new MinetestArgs();
|
||||
args.extra.push('--withserver');
|
||||
args.gameid = game;
|
||||
args.name = username;
|
||||
args.address = '127.0.0.1';
|
||||
args.port = 30000;
|
||||
args.go = true;
|
||||
history.pushState({}, "", `?proxy=${proxyIndex}&game=${game}&join=${clientCode}`);
|
||||
mtl.setVPN(serverCode, clientCode);
|
||||
mtl.setMinetestConf(memorySavingConfig);
|
||||
mtl.launch(args);
|
||||
});
|
||||
|
||||
const joinLaunch = document.getElementById('join_launch');
|
||||
joinLaunch.addEventListener('click', async () => {
|
||||
const username = document.getElementById('join_username').value;
|
||||
if (username.length == 0) {
|
||||
alert("Empty username");
|
||||
return;
|
||||
}
|
||||
wipePage();
|
||||
mtl.setProxy(proxies[join_proxy][0]);
|
||||
mtl.addPack(join_game);
|
||||
|
||||
const args = new MinetestArgs();
|
||||
args.gameid = join_game;
|
||||
args.name = username;
|
||||
args.address = '172.16.0.1';
|
||||
args.port = 30000;
|
||||
args.go = true;
|
||||
mtl.setVPN(null, join_code);
|
||||
mtl.setMinetestConf(memorySavingConfig);
|
||||
mtl.launch(args);
|
||||
});
|
||||
}
|
||||
|
||||
function queryProxy(cmd, proxy) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let finished = false;
|
||||
const ws = new WebSocket(proxy);
|
||||
ws.addEventListener('open', (event) => {
|
||||
ws.send(cmd);
|
||||
});
|
||||
ws.addEventListener('error', (event) => {
|
||||
alert('Error initiating proxy connection');
|
||||
finished = true;
|
||||
reject(new Error('Received error'));
|
||||
});
|
||||
ws.addEventListener('close', (event) => {
|
||||
if (!finished) {
|
||||
alert('Proxy connection closed unexpectedly');
|
||||
finished = true;
|
||||
reject(new Error('Received close'));
|
||||
}
|
||||
});
|
||||
ws.addEventListener('message', (event) => {
|
||||
if (typeof event.data !== 'string') {
|
||||
alert('Invalid message received from proxy');
|
||||
finished = true;
|
||||
reject(new Error('Invalid message'));
|
||||
return;
|
||||
}
|
||||
finished = true;
|
||||
ws.close();
|
||||
resolve(event.data.split(' '));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
let join_code = null;
|
||||
let join_proxy = null;
|
||||
let join_game = null;
|
||||
const peek_params = new URLSearchParams(window.location.search);
|
||||
if (peek_params.has("join")) {
|
||||
join_code = peek_params.get("join");
|
||||
join_game = peek_params.get("game");
|
||||
join_proxy = peek_params.get("proxy");
|
||||
}
|
||||
|
||||
const args = MinetestArgs.fromQueryString(window.location.search);
|
||||
tcon_print("", "Minetest Arguments: " + JSON.stringify(args.toArray(), null, ' '));
|
||||
tcon_print("", "Data Packs: " + JSON.stringify(args.packs, null, ' '));
|
||||
|
@ -41,16 +220,7 @@
|
|||
};
|
||||
mtl.onready = () => {
|
||||
tcon_print("", "READY!");
|
||||
const launchButton = document.createElement('button');
|
||||
launchButton.style.width = '300px';
|
||||
launchButton.style.height = '120px';
|
||||
launchButton.style.fontSize = '20pt';
|
||||
launchButton.innerText = 'Click to Launch';
|
||||
launchButton.addEventListener('click', () => {
|
||||
tcon.remove();
|
||||
mtl.launch(args);
|
||||
});
|
||||
tcon.appendChild(launchButton);
|
||||
enableLaunchForm();
|
||||
};
|
||||
mtl.onerror = (err) => {
|
||||
tcon_print("", "**************** FATAL ERROR ******************");
|
||||
|
|
Loading…
Reference in New Issue