const markdown = require("marked").parse; let launcher = {}; var servercount; var playercount; var masterserver; // changes the main page, this is the tabs in the sidebar launcher.change_page = (page) => { let btns = document.querySelectorAll(".gamesContainer button"); let pages = document.querySelectorAll(".mainContainer .contentContainer"); for (let i = 0; i < pages.length; i++) { pages[i].classList.add("hidden"); } for (let i = 0; i < btns.length; i++) { btns[i].classList.add("inactive"); } pages[page].classList.remove("hidden"); btns[page].classList.remove("inactive"); bgHolder.setAttribute("bg", page); }; launcher.change_page(1) launcher.format_release = (notes) => { if (! notes) {return ""} let content = ""; if (notes.length === 1) { content = notes[0]; } else { for (let release of notes) { if (release.prerelease) {continue} let new_content = // release date new Date(release.published_at).toLocaleString() + "\n" + // release name `# ${release.name}` + "\n\n" + // actual release text/body release.body + "\n\n\n"; content += "
\n" + markdown(new_content, {breaks: true}) + "\n" + "
"; } content = content.replaceAll(/\@(\S+)/g, `@$1`); } return markdown(content, { breaks: true }); } // sets content of `div` to a single release block with centered text // inside it, the text being `lang(lang_key)` launcher.error = (div, lang_key) => { div.innerHTML = "
" + "

" + lang(lang_key) + "

" + "
"; } // updates the Viper release notes ipcRenderer.on("vp-notes", (event, response) => { if (! response) { return launcher.error( vpReleaseNotes, "request.no_vp_release_notes" ) } vpReleaseNotes.innerHTML = launcher.format_release(response); }); // updates the Northstar release notes ipcRenderer.on("ns-notes", (event, response) => { if (! response) { return launcher.error( nsRelease, "request.no_ns_release_notes" ) } nsRelease.innerHTML = launcher.format_release(response); }); launcher.load_vp_notes = async () => { ipcRenderer.send("get-vp-notes"); }; launcher.load_vp_notes(); launcher.load_ns_notes = async () => { ipcRenderer.send("get-ns-notes"); }; launcher.load_ns_notes(); // TODO: We gotta make this more automatic instead of switch statements // it's both not pretty, but adding more sections requires way too much // effort, compared to how it should be. launcher.show_vp = (section) => { if (!["main", "release", "info", "credits"].includes(section)) throw new Error("unknown vp section"); vpMainBtn.removeAttribute("active"); vpReleaseBtn.removeAttribute("active"); vpInfoBtn.removeAttribute("active"); vpMain.classList.add("hidden"); vpReleaseNotes.classList.add("hidden"); vpInfo.classList.add("hidden"); switch(section) { case "main": vpMainBtn.setAttribute("active", ""); vpMain.classList.remove("hidden"); break; case "release": vpReleaseBtn.setAttribute("active", ""); vpReleaseNotes.classList.remove("hidden"); break; case "info": vpInfoBtn.setAttribute("active", ""); vpInfo.classList.remove("hidden"); break; } } launcher.show_ns = (section) => { if (! ["main", "release", "mods"].includes(section)) { throw new Error("unknown ns section"); } nsMainBtn.removeAttribute("active"); nsModsBtn.removeAttribute("active"); nsReleaseBtn.removeAttribute("active"); nsMain.classList.add("hidden"); nsMods.classList.add("hidden"); nsRelease.classList.add("hidden"); switch(section) { case "main": nsMainBtn.setAttribute("active", ""); nsMain.classList.remove("hidden"); break; case "mods": nsModsBtn.setAttribute("active", ""); nsMods.style.display = "block"; nsMods.classList.remove("hidden"); break; case "release": nsReleaseBtn.setAttribute("active", ""); nsRelease.classList.remove("hidden"); break; } } // changes the active section on the currently active // `.contentContainer` in the direction specified // // `direction` can be: left or right launcher.relative_section = (direction) => { // the `.contentMenu` in the currently active tab let active_menu = document.querySelector( ".contentContainer:not(.hidden) .contentMenu" ) // get the currently active section let active_section = active_menu.querySelector("[active]"); // no need to do anything, if there's somehow no active section if (! active_section) {return} // these will be filled out let prev_section, next_section; // get list of all the sections let sections = active_menu.querySelectorAll("li"); for (let i = 0; i < sections.length; i++) { if (sections[i] != active_section) { continue; } // make `next_section` be the next element in `sections` next_section = sections[i + 1]; // if we're at the first iteration, use the last element in // `sections` as the previous section, otherwise make it the // element before this iteration if (i == 0) { prev_section = sections[sections.length - 1]; } else { prev_section = sections[i - 1]; } } // if we're going left, and a previous section was found, click it if (direction == "left" && prev_section) { prev_section.click(); } else if (direction == "right") { // click the next section, if one was found, otherwise just // assume that the first section is the next section, as the // active section is likely just the last section, so we wrap // around instead if (next_section) { next_section.click(); } else if (sections[0]) { sections[0].click(); } } } launcher.check_servers = async () => { serverstatus.classList.add("checking"); try { let host = "northstar.tf"; let path = "/client/servers"; // ask the masterserver for the list of servers, if this has // been done recently, it'll simply return the cached version let servers = JSON.parse( await request(host, path, "ns-servers", false) ) masterserver = true; playercount = 0; servercount = servers.length; for (let i = 0; i < servers.length; i++) { playercount += servers[i].playerCount } }catch (err) { playercount = 0; servercount = 0; masterserver = false; } serverstatus.classList.remove("checking"); if (servercount == 0 || ! servercount || ! playercount) {masterserver = false} let playerstr = lang("gui.server.players"); if (playercount == 1) { playerstr = lang("gui.server.player"); } if (masterserver) { serverstatus.classList.add("up"); serverstatus.innerHTML = `${servercount} ${lang("gui.server.servers")} - ${playercount} ${playerstr}`; } else { serverstatus.classList.add("down"); serverstatus.innerHTML = lang("gui.server.offline"); } }; launcher.check_servers() // refreshes every 5 minutes setInterval(() => { launcher.check_servers(); }, 300000) module.exports = launcher;