let menusContainer = document.getElementById("menus"); var menus = {}; var shownMenus = []; var makeMenu = function () { module.exports.menuData = { "main": { "elements": [ { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.main.play.label"), "action": "open-menu", "action-args": ["play", 1] }, { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.main.settings.label"), "action": "open-menu", "action-args": ["settings", 1] }, { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.main.quit.label"), "action": "exit" } ] }, "play": { "elements": [ { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.play.singleplayer.label"), "action": "open-menu", "action-args": ["gamesel", 2] } ] }, "ingame": { "elements": [ { "type": "button", "label": "Resume", "action": "run", "runnable": function () { global.inputs[0].grab(); hideMenus(0); } }, { "type": "button", "label": "Quit", "action": "run", "runnable": global.quitGame } ] }, "gamesel": { "elements": [ { "type": "text", "id": "worldnameinput", "placeholder": "New World", "value": "New World", "action": "run", "runnable": function (event) { var newGameButton = global.document.getElementById("newgamebutton"); if (event.target.value.length < 1) { newGameButton.disabled = true; } else { newGameButton.disabled = false; } } }, { "type": "button", "id": "newgamebutton", "label": global.locales.getRawString(global.currentLanguage, "play.singleplayer.newgamebutton.label"), "action": "run", "runnable": function () { var worldNameInputBox = global.document.getElementById("worldnameinput"); var worldName = worldNameInputBox.value; if (worldName.length < 1) worldName = worldNameInputBox.placeholder; global.createWorld(worldName).then(function (world) { global.startGame(0, worldName); hideMenus(0); }); } }, { "type": "button", "id": "loadgamebutton", "label": global.locales.getRawString(global.currentLanguage, "play.singleplayer.loadgamebutton.label"), "action": "run", "runnable": function () { var fileSelector = document.createElement("input"); fileSelector.type = "file"; fileSelector.accept = "application/zip"; fileSelector.click(); fileSelector.onchange = function (event) { if (!this.files || !this.files[0]) return; this.files[0].arrayBuffer().then(function (buffer) { var fileU8 = new Uint8Array(buffer); global.openSave(fileU8).then(function (worldList) { for (var worldName in worldList) { if (worldList.hasOwnProperty(worldName)) { var world = worldList[worldName]; global.worlds[worldName] = world; var menuEntry = { "type": "button", "label": global.locales.getFormattedString( global.currentLanguage, "play.singleplayer.openworld.label", { "WORLD_NAME": worldName }), "action": "run", "runnable": (function (event) { hideMenus(0); global.startGame(0, this); }).bind(worldName) }; module.exports.menuData["gamesel"].elements.push(menuEntry); } } hideMenus(2); menus["gamesel"] = constructMenu("gamesel", module.exports.menuData["gamesel"]); showMenu("gamesel", 2); }).catch(function (error) { console.error(error); }); }).catch(function (error) { console.error(error); }); delete fileSelector; }; } } ] }, "settings": { "elements": [ { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.settings.user.label"), "action": "open-menu", "action-args": ["user-settings", 2] }, { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.settings.video.label"), "action": "open-menu", "action-args": ["video-settings", 2] }, { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.settings.audio.label"), "action": "open-menu", "action-args": ["audio-settings", 2] }, { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "menu.settings.input.label"), "action": "open-menu", "action-args": ["input-settings", 2] } ] }, "user-settings": { "elements": [ // { // "type": "text", // "name": "username", // "label": "Username", // "placeholder": "Username" // }, { "type": "button", "label": global.locales.getRawString(global.currentLanguage, "settings.user.login.label"), "action": "open-menu", "action-args": ["matrix-login", 3] } ] }, "matrix-login": { "expand": true, "elements": [ { "type": "text", "name": "homeserver-url", "id": "homeserverinput", "label": global.locales.getRawString(global.currentLanguage, "settings.login.homeserver-url.label"), "placeholder": "https://matrix.org/", "action": "run", "runnable": function (event) { var isValidURL = (/http.?:\/\/.+/g).test(event.target.value); var isValidMXID = (/@.+:.+/g).test(global.document.getElementById("mxidinput").value); var isValidPass = global.document.getElementById("mxpassinput").value.length > 0; var loginButton = global.document.getElementById("mxloginbutton"); if (isValidURL && isValidMXID && isValidPass) { loginButton.disabled = false; } else { loginButton.disabled = true; } } }, { "type": "text", "name": "mxid", "id": "mxidinput", "label": global.locales.getRawString(global.currentLanguage, "settings.login.mxid.label"), "placeholder": global.locales.getRawString(global.currentLanguage, "settings.login.mxid.placeholder"), "action": "run", "runnable": function (event) { var isValidURL = (/http.?:\/\/.+/g).test(global.document.getElementById("homeserverinput").value); var isValidMXID = (/@.+:.+/g).test(event.target.value); var isValidPass = global.document.getElementById("mxpassinput").value.length > 0; var loginButton = global.document.getElementById("mxloginbutton"); if (isValidURL && isValidMXID && isValidPass) { loginButton.disabled = false; } else { loginButton.disabled = true; } } }, { "type": "password", "name": "password", "id": "mxpassinput", "label": global.locales.getRawString(global.currentLanguage, "settings.login.password.label"), "placeholder": global.locales.getRawString(global.currentLanguage, "settings.login.password.placeholder"), "action": "run", "runnable": function (event) { var isValidURL = (/http.?:\/\/.+/g).test(global.document.getElementById("homeserverinput").value); var isValidMXID = (/@.+:.+/g).test(global.document.getElementById("mxidinput").value); var isValidPass = event.target.value.length > 0; var loginButton = global.document.getElementById("mxloginbutton"); if (isValidURL && isValidMXID && isValidPass) { loginButton.disabled = false; } else { loginButton.disabled = true; } } }, { "type": "button", "id": "mxloginbutton", "label": global.locales.getRawString(global.currentLanguage, "settings.user.login.label"), "disabled": true, "action": "run", "runnable": async function (event) { event.target.disabled = true; var username = global.document.getElementById("mxidinput").value .substring(1) .split(":")[0]; if (!("matrixClient" in global.core.modules["network"])) { var matrixClient = await global.core.modules["network"].initMatrixClient( global.document.getElementById("homeserverinput").value, global.document.getElementById("mxidinput").value ); } global.core.modules["network"].loginToMatrix( username, global.document.getElementById("mxpassinput").value ).then(function () { localStorage.setItem("matrix_baseurl", global.document.getElementById("homeserverinput").value); localStorage.setItem("matrix_mxid", global.document.getElementById("mxidinput").value); localStorage.setItem("matrix_is_connected", true); hideMenus(3); event.target.disabled = false; }).catch(function (error) { event.target.disabled = false; }); } } ] }, "video-settings": { "expand": true, "elements": [ { "type": "slider", "name": "fieldofview", "label": "Field of view", "value": 70, "minimum": 30, "maximum": 150, "step": 1, "change": function (event) { } } ] }, "audio-settings": { "expand": true, "elements": [ { "type": "slider", "name": "mastervolume", "label": "Master volume", "value": 100, "minimum": 0, "maximum": 100, "step": 1, "change": function (event) { } } ] } }; for (var name in module.exports.menuData) { if (module.exports.menuData.hasOwnProperty(name)) { var menu = module.exports.menuData[name]; menus[name] = constructMenu(name, menu); } } }; var constructMenu = function (name, data) { var menuElement = document.createElement("div"); menuElement.classList.add("menu"); for (var e = 0; e < data.elements.length; e++) { var element = data.elements[e]; let dom; switch (element.type) { case "button": dom = document.createElement("button"); dom.innerText = element.label; if ("disabled" in element) dom.disabled = element.disabled; switch (element.action) { case "open-menu": dom.onclick = (function (event) { showMenu(...this["action-args"]); }).bind(element); break; case "run": dom.onclick = element.runnable; break; case "exit": dom.classList.add("closebutton"); dom.onclick = closeGame; break; default: } break; case "text": dom = document.createElement("input"); dom.type = "text"; if (element.placeholder) dom.placeholder = element.placeholder; if ("action" in element) { switch (element.action) { case "run": dom.oninput = element.runnable; break; default: } } break; case "password": dom = document.createElement("input"); dom.type = "password"; if ("disabled" in element) dom.disabled = element.disabled; if (element.placeholder) dom.placeholder = element.placeholder; if ("action" in element) { switch (element.action) { case "run": dom.oninput = element.runnable; break; default: } } break; case "slider": dom = document.createElement("input"); dom.type = "range"; dom.name = element.name; if ("disabled" in element) dom.disabled = element.disabled; if (element.value) dom.value = element.value; if (element.minimum) dom.min = element.minimum; if (element.maximum) dom.max = element.maximum; if (element.step) dom.step = element.step; break; case "void": dom = document.createElement("div"); dom.classList.add("void"); break; default: } if (element.id) dom.id = element.id; if ((element.type != "button") && element.label) { domLabel = document.createElement("label"); domLabel.htmlFor = element.name; domLabel.innerText = element.label; menuElement.appendChild(domLabel); dom.name = element.name; dom.label = domLabel; } menuElement.appendChild(dom); } return menuElement; }; var showMenu = function (name, offset) { if (shownMenus.length > 0 && (!shownMenus[offset - 1])) return; if (shownMenus[offset] == menus[name]) { return hideMenus(offset); } else { hideMenus(offset); var displayOffset = 0; for (var m = 0; m < shownMenus.length; m++) { displayOffset += shownMenus[m].clientWidth; } menus[name].style.left = displayOffset + "px"; if (module.exports.menuData[name].expand) { menus[name].style.width = "calc(" + menusContainer.clientWidth + "px - " + (menusContainer.clientWidth - displayOffset) + "px)"; } else { menus[name].style.width = "" + 16 + "rem"; } menusContainer.appendChild(menus[name]); shownMenus.push(menus[name]); } }; var hideMenus = function (offset) { for (var m = shownMenus.length; m >= offset; --m) { if (shownMenus[m]) menusContainer.removeChild(shownMenus[m]); } shownMenus.splice(offset, shownMenus.length - offset); }; module.exports = { "menus": menus, "makeMenu": makeMenu, "constructMenu": constructMenu, "showMenu": showMenu, "hideMenus": hideMenus };