From f8735f5b539b991f8da9ec1b3e64966566d77477 Mon Sep 17 00:00:00 2001 From: stale Date: Sun, 3 Jul 2022 04:24:51 -0300 Subject: sounds! --- assets/client.js | 109 ++++++++++++++++++++++++++++++++++++-------------- assets/explosion.opus | Bin 0 -> 129846 bytes assets/index.html | 23 +++++++---- assets/room.html | 3 ++ src/conn.rs | 3 ++ src/main.rs | 10 +++-- 6 files changed, 106 insertions(+), 42 deletions(-) create mode 100644 assets/explosion.opus diff --git a/assets/client.js b/assets/client.js index 53689e0..fabff83 100644 --- a/assets/client.js +++ b/assets/client.js @@ -1,11 +1,38 @@ window.player = { uid: NaN }; -window.info_elem = document.getElementById("miscinfo"); -window.identform = document.getElementById("identform"); -window.statusline = document.getElementsByClassName("statusline")[0]; -window.bcont_elem = document.getElementById("board-container"); -window.board_elem = document.getElementById("board"); -window.cursor_frame = document.getElementById("cursor-frame"); +window.elem = { + info: document.getElementById("miscinfo"), + identform: document.getElementById("identform"), + statusline: document.getElementsByClassName("statusline")[0], + bcont: document.getElementById("board-container"), + board: document.getElementById("board"), + cursor_frame: document.getElementById("cursor-frame"), + volslider: document.getElementById("volslider") +}; + window.queued_pos = undefined; +window.assets = { + audio: { + explosion: registerMediaElem(new Audio("../explosion.opus")) + } +}; + +function registerMediaElem(melm) { + let record = { data: melm, loaded: false }; + melm.addEventListener("canplaythrough", e => { + record.loaded = true; + }); + return record; +} + +document.addEventListener('roomloading', function() { + //window.elem.info.innerHTML = "loading..."; + // TODO/FIXME: this should check all the assets, once we have more than one + if (assets.audio.explosion.loaded) { + room.socket = connect(); // drive the game with socket events from then on + } else { + setTimeout(function() { document.dispatchEvent(new Event('roomloading')) }, 500); + } +}); window.room = { name: undefined, @@ -20,8 +47,8 @@ window.room = { if (room.identity == null) { - statusline.style.display = "none"; - identform.style.display = "initial"; + elem.statusline.style.display = "none"; + elem.identform.style.display = "initial"; } else { join(); } @@ -33,9 +60,9 @@ function join() { room.identity.clr = document.getElementById("clr-in").value; localStorage.setItem("identity", JSON.stringify(room.identity)); } - identform.style.display = "none"; - room.socket = connect(); - statusline.style.display = "flex"; + elem.identform.style.display = "none"; + elem.statusline.style.display = "flex"; + document.dispatchEvent(new Event('roomloading')); } function clear_ident() { localStorage.removeItem("identity"); @@ -53,8 +80,8 @@ function connect() { let d = e.data; if (typeof d == "object") { d.arrayBuffer().then(acceptBoard); - info_elem.onclick = undefined; - info_elem.innerHTML = `${room.name} (${room.bconf.w}x${room.bconf.h}) >> Running, ${room.bconf.mine_ratio} tiles are mines`; + elem.info.onclick = undefined; + elem.info.innerHTML = `${room.name} (${room.bconf.w}x${room.bconf.h}) >> Running, ${room.bconf.mine_ratio} tiles are mines`; } else if (typeof e.data == "string") { let fields = d.split(" "); switch (fields[0]) { @@ -65,10 +92,12 @@ function connect() { let x = pdat[1][0]; let y = pdat[1][1]; let curs = room.cursors.get(oid); - if (oid != player.uid && curs != undefined) { - movCursor(curs, x, y); - } else { - console.log("livepos sys incoherent"); + if (oid != player.uid) { + if (curs != undefined) { + movCursor(curs, x, y); + } else { + console.log("livepos sys incoherent"); + } } }); } break; @@ -96,13 +125,14 @@ function connect() { createCursor(player.uid, name, room.identity.clr); } break; case "win": { - info_elem.innerHTML = "You win! Click here to play again."; - info_elem.onclick = e => { s.send("reset") }; + elem.info.innerHTML = "You win! Click here to play again."; + elem.info.onclick = e => { s.send("reset") }; } break; case "lose": { let badone = fields[1]; - info_elem.innerHTML = `You lost, ${badone} was blown up. Click here to retry.`; - info_elem.onclick = e => { s.send("reset") }; + elem.info.innerHTML = `You lost, ${badone} was blown up. Click here to retry.`; + elem.info.onclick = e => { s.send("reset") }; + assets.audio.explosion.data.play(); } break; case "logoff": { let oid = Number(fields[1]); @@ -113,8 +143,8 @@ function connect() { } } } - s.onerror = function(e) { info_elem.innerHTML += `
Connection error: ${e}`; } - s.onclose = function(e) { info_elem.innerHTML = "Connection closed"; } + s.onerror = function(e) { elem.info.innerHTML += `
Connection error: ${e}`; } + s.onclose = function(e) { elem.info.innerHTML = "Connection closed"; } return s; } @@ -163,7 +193,7 @@ function acceptBoard(data) { } last = room.board[i]; } - board_elem.innerHTML = split_board.join(""); + elem.board.innerHTML = split_board.join(""); room.cbounds = getBoardBounds(); } @@ -181,8 +211,8 @@ function createCursor(id, name, clr) { cursor.appendChild(nametag); cursor.classList.add('cursor'); cursor.style.color = clr; - document.getElementById('cursor-frame').append(cursor); - document.getElementById('cursor-frame').append(selection_window); + elem.cursor_frame.append(cursor); + elem.cursor_frame.append(selection_window); let c = { name: name, elem: cursor, selwin: selection_window }; if (id == window.player.uid) { document.addEventListener('mousemove', e => { @@ -207,7 +237,6 @@ function movCursor(c, bx, by) { } function movSelWin(win, bx, by) { let tpos = tilepos(bx,by); - console.log(tpos); if (tpos.x > (room.bconf.w - 1) || tpos.x < 0 || tpos.y > (room.bconf.h - 1) || tpos.y < 0) { win.style.display = "none"; } else { @@ -219,8 +248,8 @@ function movSelWin(win, bx, by) { win.style.height = room.bconf.tile_h + 'px'; } function getBoardBounds() { - let a = bcont_elem.getBoundingClientRect(); - let b = board_elem.getBoundingClientRect(); + let a = elem.bcont.getBoundingClientRect(); + let b = elem.board.getBoundingClientRect(); room.bconf.tile_w = b.width / room.bconf.w; room.bconf.tile_h = 48; return { @@ -234,13 +263,13 @@ window.onresize = () => { room.cbounds = getBoardBounds(); } -bcont_elem.onclick = function(e) { +elem.bcont.onclick = function(e) { let bcoords = pageToBoardPx(e.pageX, e.pageY); let tpos = tilepos(bcoords[0], bcoords[1]); let cmd = `reveal ${tpos.x} ${tpos.y}`; room.socket.send(cmd); } -bcont_elem.oncontextmenu = function(e) { +elem.bcont.oncontextmenu = function(e) { let bcoords = pageToBoardPx(e.pageX, e.pageY); let tpos = tilepos(bcoords[0], bcoords[1]); let cmd = `flag ${tpos.x} ${tpos.y}`; @@ -255,6 +284,18 @@ function tilepos(bx,by) { return { x: tilex, y: tiley }; } +function volChanged() { + let newVol = elem.volslider.value; + localStorage.setItem("audioVolume", JSON.stringify(newVol)); + for (i of Object.keys(assets.audio)) { + assets.audio[i].data.volume = newVol; + } +} +elem.volslider.onchange = volChanged; +let storedVol = localStorage.getItem("audioVolume"); +if (storedVol) { elem.volslider.value = JSON.parse(storedVol); } +volChanged(); + (function sendPos() { let qp = window.queued_pos; if (qp) { @@ -265,3 +306,9 @@ function tilepos(bx,by) { sendPos(); }, 16); })(); +(function heartbeat() { + setTimeout(function() { + room.socket.send("<3"); + heartbeat(); + }, 30000); +})(); diff --git a/assets/explosion.opus b/assets/explosion.opus new file mode 100644 index 0000000..a894d06 Binary files /dev/null and b/assets/explosion.opus differ diff --git a/assets/index.html b/assets/index.html index 9729132..7961bde 100644 --- a/assets/index.html +++ b/assets/index.html @@ -40,6 +40,7 @@ elem: document.getElementById('rlist'), map: new Map(), }; + let active_rids = []; let rspace = { elem: document.getElementById('rspace'), num: NaN, @@ -50,7 +51,8 @@ fetch('rlist').then(r => r.json()).then(info => { let rooms = info[0]; let pcounts = info[1]; - Object.keys(rooms).forEach(id => { + active_rids = Object.keys(rooms); + active_rids.forEach(id => { let room = rlist.map.get(id); if (!room) { room = { init: false }; } let rinfo = JSON.parse(rooms[id]); @@ -60,6 +62,13 @@ room.board_conf = rinfo.board_conf; rlist.map.set(id, room); }); + for (id of rlist.map.keys()) { + if (!active_rids.includes(id)) { + let r = rlist.map.get(id); + r.entry.remove(); + rlist.map.delete(id); + } + } callback(); }); fetch("rspace").then(resp => resp.text()).then(roomspace => { @@ -72,7 +81,7 @@ rlist.map.forEach((room, id) => { let full = room.pcount == room.pcapacity; if (!room.init) { - let entry = (full)? document.createElement('span') : document.createElement('a'); + room.entry = (full)? document.createElement('span') : document.createElement('a'); room.h1 = document.createElement("h1"); room.h1_txt = document.createTextNode(""); room.h1.appendChild(room.h1_txt); @@ -81,11 +90,11 @@ `${room.board_conf.w} by ${room.board_conf.h} with ${room.board_conf.mine_ratio[0]} in every ${room.board_conf.mine_ratio[1]} tiles mined` )); - entry.append(room.h1); - entry.append(room.h4); - entry.href = 'room/' + id; - rlist.elem.append(entry); - rlist.elem.append(document.createElement('br')); + room.entry.append(room.h1); + room.entry.append(room.h4); + room.entry.append(document.createElement('br')); + room.entry.href = 'room/' + id; + rlist.elem.append(room.entry); room.init = true; } let ptxt = `${room.pcount}/${room.pcapacity} players` + ((full)? " (full)" : ""); diff --git a/assets/room.html b/assets/room.html index e128bc7..e526c8b 100644 --- a/assets/room.html +++ b/assets/room.html @@ -19,6 +19,9 @@

+
+ ๐Ÿ”ˆ +
๐Ÿ”—share

new identity

back to lobby diff --git a/src/conn.rs b/src/conn.rs index 047d7db..89fd5e0 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -83,6 +83,9 @@ pub async fn drive_conn(conn: (Conn, SplitStream), rinfo: (RoomId, Ar x.zip(y) }; if let Some(cmd_name) = fields.next() { + if cmd_name == "<3" { + continue; // heartbeat, no need to handle it + } use crate::minesweeper::{Move,MoveType}; let mut players_lock = players.write().await; match players_lock.get_mut(&conn.addr) { diff --git a/src/main.rs b/src/main.rs index 2321289..e4ccc56 100644 --- a/src/main.rs +++ b/src/main.rs @@ -127,11 +127,13 @@ async fn tokio_main(conf: Conf) -> Result<(), Box> { let uid = RoomId::new_among(rooms.keys()); match room_from_form(uid.clone(), &rinfo, &conf) { - Ok((room, access)) => { - if access { + Ok((room, public)) => { + if public { pubs.write().await.insert(uid.clone(), serde_json::to_string(&room.conf).unwrap()); + println!("New public room: {:?}", room.conf); + } else { + println!("New private room: {:?}", room.conf); } - println!("New room: {:?}", room.conf); rooms.insert(uid.clone(), Arc::new(RwLock::new(room))); Ok( @@ -300,8 +302,8 @@ fn room_from_form(uid: RoomId, rinfo: &HashMap, conf: &Conf) -> R rinfo.get("mineratio-n").and_then(|n| n.parse::().ok()), rinfo.get("mineratio-d").and_then(|d| d.parse::().ok()), rinfo.get("public").map(|s| s == "on").unwrap_or(false), - rinfo.get("rborders").map(|s| s == "on").unwrap_or(false), rinfo.get("allsafe1move").map(|s| s == "on").unwrap_or(false), + rinfo.get("rborders").map(|s| s == "on").unwrap_or(false), rinfo.get("limit").and_then(|l| l.parse::().ok()), ) { if w.get()*h.get() > conf.limits.board_area { -- cgit v1.2.3