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 %}
 |