0.2.0: Server-Browser und Spiel-Ticket
- Seite Server: Liste der Website, Ping/Spieler direkt abgefragt, BEITRETEN und Direkt verbinden - Holt beim Spielen ein Spiel-Ticket und schreibt es in BSO.json Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -140,9 +140,12 @@ function showPage(name) {
|
||||
document.querySelectorAll("#nav [data-page]").forEach((b) => b.classList.toggle("on", b.dataset.page === name));
|
||||
const root = $("page");
|
||||
root.replaceChildren(h("p", { class: "muted" }, "Laden …"));
|
||||
({ home: renderHome, news: renderNews, settings: renderSettings })[name](root);
|
||||
({ home: renderHome, servers: renderServers, news: renderNews, settings: renderSettings })[name](root);
|
||||
}
|
||||
|
||||
// Anmeldung abgelaufen (z.B. beim Holen des Spiel-Tickets)
|
||||
on("loggedOut", () => showAuth());
|
||||
|
||||
// Fortschritt (Downloads)
|
||||
let progressBox = null;
|
||||
on("progress", (m) => {
|
||||
@@ -240,6 +243,66 @@ function serverCard(s) {
|
||||
h("label", { class: "switch" }, h("span", {}, "Beim Start verbinden", h("small", {}, "sonst im Spiel mit F8")), auto));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------- Server-Browser
|
||||
|
||||
let serverList = [];
|
||||
|
||||
async function renderServers(root) {
|
||||
const search = h("input", { placeholder: "Server suchen …", spellcheck: "false" });
|
||||
const refresh = h("button", { class: "btn small", type: "button" }, "Aktualisieren");
|
||||
const list = h("div", { class: "server-list" }, h("p", { class: "muted" }, "Server werden gesucht …"));
|
||||
const direct = h("input", { placeholder: "Adresse, z.B. bso.example.de:7777", spellcheck: "false" });
|
||||
const directJoin = h("button", { class: "btn small", type: "button" }, "Verbinden");
|
||||
directJoin.addEventListener("click", () => join(directJoin, direct.value));
|
||||
|
||||
root.replaceChildren(
|
||||
h("div", { class: "row", style: "justify-content:space-between;flex-wrap:wrap" }, h("h1", {}, "Server"),
|
||||
h("div", { class: "row", style: "min-width:320px" }, search, refresh)),
|
||||
list,
|
||||
h("div", { class: "card" }, h("h3", {}, "Direkt verbinden"), h("div", { class: "row" }, direct, directJoin)));
|
||||
|
||||
const draw = () => {
|
||||
const q = search.value.trim().toLowerCase();
|
||||
const rows = serverList.filter((s) => !q || s.name.toLowerCase().includes(q) || s.address.toLowerCase().includes(q));
|
||||
if (!rows.length) {
|
||||
list.replaceChildren(h("p", { class: "muted" }, serverList.length ? "Kein Server passt zur Suche." : "Gerade ist kein öffentlicher Server online."));
|
||||
return;
|
||||
}
|
||||
list.replaceChildren(...rows.map((s) => {
|
||||
const b = h("button", { class: "btn primary small", type: "button" }, "BEITRETEN");
|
||||
b.disabled = !s.compatible || s.players >= s.maxPlayers;
|
||||
b.addEventListener("click", () => join(b, s.address));
|
||||
const ping = s.ping == null ? h("span", { class: "muted" }, "–") : h("span", { class: s.ping < 80 ? "ok" : s.ping < 150 ? "warn" : "bad" }, s.ping + " ms");
|
||||
return h("div", { class: "server" },
|
||||
h("div", { class: "server-main" }, h("b", {}, s.name),
|
||||
h("span", { class: "muted small" }, s.description || s.address)),
|
||||
h("span", { class: "server-col" }, `${s.players}/${s.maxPlayers}`),
|
||||
h("span", { class: "server-col" }, ping),
|
||||
h("span", { class: "server-col muted small" }, s.compatible ? "v" + s.version : "andere Version"),
|
||||
b);
|
||||
}));
|
||||
};
|
||||
|
||||
const load = async () => {
|
||||
refresh.disabled = true;
|
||||
try { serverList = await call("servers"); draw(); }
|
||||
catch (e) { list.replaceChildren(h("p", { class: "error" }, e.message)); }
|
||||
finally { refresh.disabled = false; }
|
||||
};
|
||||
search.addEventListener("input", draw);
|
||||
refresh.addEventListener("click", load);
|
||||
await load();
|
||||
}
|
||||
|
||||
/** Beitreten: Server merken, Spiel starten, im Spiel automatisch verbinden. */
|
||||
function join(button, address) {
|
||||
if (!address.trim()) { toast("Adresse eingeben", true); return; }
|
||||
busy(button, async () => {
|
||||
await call("join", { address: address.trim() });
|
||||
toast("Bus-Simulator 2012 startet und verbindet mit " + address.trim() + " …");
|
||||
});
|
||||
}
|
||||
|
||||
async function renderNews(root) {
|
||||
let list;
|
||||
try { list = await call("releases"); }
|
||||
|
||||
Reference in New Issue
Block a user