205 lines
8.9 KiB
HTML
205 lines
8.9 KiB
HTML
{% extends 'pageWrapper.html' %}
|
|
{% import "macros.html" as macros %}
|
|
{% block head %}
|
|
<title>Multiworld {{ room.id|suuid }}</title>
|
|
{% if should_refresh %}<meta http-equiv="refresh" content="2">{% endif %}
|
|
<meta name="og:site_name" content="Archipelago">
|
|
<meta property="og:title" content="Multiworld {{ room.id|suuid }}">
|
|
<meta property="og:type" content="website" />
|
|
{% if room.seed.slots|length < 2 %}
|
|
<meta property="og:description" content="{{ room.seed.slots|length }} Player World
|
|
{% if room.last_port != -1 %}running on {{ config['HOST_ADDRESS'] }} with port {{ room.last_port }}{% endif %}">
|
|
{% else %}
|
|
<meta property="og:description" content="{{ room.seed.slots|length }} Players Multiworld
|
|
{% if room.last_port != -1 %}running on {{ config['HOST_ADDRESS'] }} with port {{ room.last_port }}{% endif %}">
|
|
{% endif %}
|
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename="styles/hostRoom.css") }}"/>
|
|
{% endblock %}
|
|
|
|
{% block body %}
|
|
{% include 'header/grassHeader.html' %}
|
|
<div id="host-room">
|
|
<span id="host-room-info">
|
|
{% if room.owner == session["_id"] %}
|
|
Room created from <a href="{{ url_for("view_seed", seed=room.seed.id) }}">Seed #{{ room.seed.id|suuid }}</a>
|
|
<br />
|
|
{% endif %}
|
|
{% if room.tracker %}
|
|
This room has a <a href="{{ url_for("get_multiworld_tracker", tracker=room.tracker) }}">Multiworld Tracker</a>
|
|
and a <a href="{{ url_for("get_multiworld_sphere_tracker", tracker=room.tracker) }}">Sphere Tracker</a> enabled.
|
|
<br />
|
|
{% endif %}
|
|
The server for this room will be paused after {{ room.timeout//60//60 }} hours of inactivity.
|
|
Should you wish to continue later,
|
|
anyone can simply refresh this page and the server will resume.<br>
|
|
{% if room.last_port == -1 %}
|
|
There was an error hosting this Room. Another attempt will be made on refreshing this page.
|
|
The most likely failure reason is that the multiworld is too old to be loaded now.
|
|
{% elif room.last_port %}
|
|
You can connect to this room by using <span class="interactive"
|
|
data-tooltip="This means address/ip is {{ config['HOST_ADDRESS'] }} and port is {{ room.last_port }}.">
|
|
'/connect {{ config['HOST_ADDRESS'] }}:{{ room.last_port }}'
|
|
</span>
|
|
in the <a href="{{ url_for("tutorial_landing")}}">client</a>.<br>
|
|
{% endif %}
|
|
</span>
|
|
{{ macros.list_patches_room(room) }}
|
|
{% if room.owner == session["_id"] %}
|
|
<div style="display: flex; align-items: center;">
|
|
<form method="post" id="command-form" style="flex-grow: 1; margin-right: 1em;">
|
|
<div class="form-group">
|
|
<label for="cmd"></label>
|
|
<input class="form-control" type="text" id="cmd" name="cmd"
|
|
placeholder="Server Command. /help to list them, list gets appended to log.">
|
|
<span class="loader"></span>
|
|
</div>
|
|
</form>
|
|
<a href="{{ url_for("display_log", room=room.id) }}">
|
|
Open Log File...
|
|
</a>
|
|
</div>
|
|
{% set log = get_log() -%}
|
|
{%- set log_len = log | length - 1 if log.endswith("…") else log | length -%}
|
|
<div id="logger" style="white-space: pre">{{ log }}</div>
|
|
<script>
|
|
let url = '{{ url_for('display_log', room = room.id) }}';
|
|
let bytesReceived = {{ log_len }};
|
|
let updateLogTimeout;
|
|
let updateLogImmediately = false;
|
|
let awaitingCommandResponse = false;
|
|
let logger = document.getElementById("logger");
|
|
|
|
function scrollToBottom(el) {
|
|
let bot = el.scrollHeight - el.clientHeight;
|
|
el.scrollTop += Math.ceil((bot - el.scrollTop)/10);
|
|
if (bot - el.scrollTop >= 1) {
|
|
window.clearTimeout(el.scrollTimer);
|
|
el.scrollTimer = window.setTimeout(() => {
|
|
scrollToBottom(el)
|
|
}, 16);
|
|
}
|
|
}
|
|
|
|
async function updateLog() {
|
|
try {
|
|
if (!document.hidden) {
|
|
updateLogImmediately = false;
|
|
let res = await fetch(url, {
|
|
headers: {
|
|
'Range': `bytes=${bytesReceived}-`,
|
|
}
|
|
});
|
|
if (res.ok) {
|
|
let text = await res.text();
|
|
if (text.length > 0) {
|
|
awaitingCommandResponse = false;
|
|
if (bytesReceived === 0 || res.status !== 206) {
|
|
logger.innerHTML = '';
|
|
}
|
|
if (res.status !== 206) {
|
|
bytesReceived = 0;
|
|
} else {
|
|
bytesReceived += new Blob([text]).size;
|
|
}
|
|
if (logger.innerHTML.endsWith('…')) {
|
|
logger.innerHTML = logger.innerHTML.substring(0, logger.innerHTML.length - 1);
|
|
}
|
|
logger.appendChild(document.createTextNode(text));
|
|
scrollToBottom(logger);
|
|
let loader = document.getElementById("command-form").getElementsByClassName("loader")[0];
|
|
loader.classList.remove("loading");
|
|
}
|
|
}
|
|
} else {
|
|
updateLogImmediately = true;
|
|
}
|
|
}
|
|
finally {
|
|
window.clearTimeout(updateLogTimeout);
|
|
updateLogTimeout = window.setTimeout(updateLog, awaitingCommandResponse ? 500 : 10000);
|
|
}
|
|
}
|
|
|
|
async function postForm(ev) {
|
|
/** @type {HTMLInputElement} */
|
|
let cmd = document.getElementById("cmd");
|
|
if (cmd.value === "") {
|
|
ev.preventDefault();
|
|
return;
|
|
}
|
|
/** @type {HTMLFormElement} */
|
|
let form = document.getElementById("command-form");
|
|
let req = fetch(form.action || window.location.href, {
|
|
method: form.method,
|
|
body: new FormData(form),
|
|
redirect: "manual",
|
|
});
|
|
ev.preventDefault(); // has to happen before first await
|
|
form.reset();
|
|
let loader = form.getElementsByClassName("loader")[0];
|
|
loader.classList.add("loading");
|
|
try {
|
|
let res = await req;
|
|
if (res.ok || res.type === 'opaqueredirect') {
|
|
awaitingCommandResponse = true;
|
|
window.clearTimeout(updateLogTimeout);
|
|
updateLogTimeout = window.setTimeout(updateLog, 100);
|
|
} else {
|
|
loader.classList.remove("loading");
|
|
window.alert(res.statusText);
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
loader.classList.remove("loading");
|
|
window.alert(e.message);
|
|
}
|
|
}
|
|
|
|
document.getElementById("command-form").addEventListener("submit", postForm);
|
|
updateLogTimeout = window.setTimeout(updateLog, 1000);
|
|
logger.scrollTop = logger.scrollHeight;
|
|
document.addEventListener("visibilitychange", () => {
|
|
if (!document.hidden && updateLogImmediately) {
|
|
updateLog();
|
|
}
|
|
})
|
|
</script>
|
|
{% endif %}
|
|
<script>
|
|
function updateInfo() {
|
|
let url = new URL(window.location.href);
|
|
url.search = "?update";
|
|
fetch(url)
|
|
.then(res => {
|
|
if (!res.ok) {
|
|
throw new Error(`HTTP error ${res.status}`);
|
|
}
|
|
return res.text()
|
|
})
|
|
.then(text => new DOMParser().parseFromString(text, 'text/html'))
|
|
.then(newDocument => {
|
|
["host-room-info", "slots-table"].forEach(function(id) {
|
|
const newEl = newDocument.getElementById(id);
|
|
const oldEl = document.getElementById(id);
|
|
if (oldEl && newEl) {
|
|
oldEl.innerHTML = newEl.innerHTML;
|
|
} else if (newEl) {
|
|
console.warn(`Did not find element to replace for ${id}`)
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
if (document.querySelector("meta[http-equiv='refresh']")) {
|
|
console.log("Refresh!");
|
|
window.addEventListener('load', function () {
|
|
for (let i=0; i<3; i++) {
|
|
window.setTimeout(updateInfo, Math.pow(2, i) * 2000); // 2, 4, 8s
|
|
}
|
|
window.stop(); // cancel meta refresh
|
|
})
|
|
}
|
|
</script>
|
|
</div>
|
|
{% endblock %}
|