summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstale <redkugelblitzin@gmail.com>2022-07-03 04:24:51 -0300
committerstale <redkugelblitzin@gmail.com>2022-07-03 04:24:51 -0300
commitf8735f5b539b991f8da9ec1b3e64966566d77477 (patch)
tree6a5a87bcabbff808a200bddc372ebca7ae420f83
parente933ae3795a27a0fad1f37189670c993d8b65f47 (diff)
sounds!
-rw-r--r--assets/client.js109
-rw-r--r--assets/explosion.opusbin0 -> 129846 bytes
-rw-r--r--assets/index.html23
-rw-r--r--assets/room.html3
-rw-r--r--src/conn.rs3
-rw-r--r--src/main.rs10
6 files changed, 106 insertions, 42 deletions
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 += `<br>Connection error: ${e}`; }
- s.onclose = function(e) { info_elem.innerHTML = "Connection closed"; }
+ s.onerror = function(e) { elem.info.innerHTML += `<br>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
--- /dev/null
+++ b/assets/explosion.opus
Binary files 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 @@
</form>
<div class="statusline">
<p id="miscinfo"></p>
+ <div>
+ <span id="volbutton" style="margin-right: 0">๐Ÿ”ˆ</span>
+ <input id="volslider" type="range" min="0" max="1" step="0.01"></div>
<a href="javascript:navigator.clipboard.writeText(window.location.href);alert('copied link to clipboard');">๐Ÿ”—share</p>
<a href="javascript:clear_ident();">new identity</p>
<a href="..">back to lobby</a>
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<WebSocket>), 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<dyn Error>> {
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<String,String>, conf: &Conf) -> R
rinfo.get("mineratio-n").and_then(|n| n.parse::<usize>().ok()),
rinfo.get("mineratio-d").and_then(|d| d.parse::<NonZeroUsize>().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::<NonZeroUsize>().ok()),
) {
if w.get()*h.get() > conf.limits.board_area {