diff options
-rw-r--r-- | page.html | 162 | ||||
-rw-r--r-- | src/conn.rs | 38 |
2 files changed, 106 insertions, 94 deletions
@@ -11,8 +11,8 @@ src: url("font.ttf"); } #board-container { - font-size: 28pt; - line-height: 0.6em; + font-size: 36px; + line-height: 22px; } body { font-family: vt323, monospace; @@ -42,41 +42,44 @@ <body> <div class=""> <div id="board-container"> - <div id="board"></div> + <span id="board"></span> </div> <p id="miscinfo">Loading...</p> </div> </body> <script> window.id = NaN; - let wsproto = (window.location.protocol == "https:")? "wss:": "ws:"; - let s = new WebSocket(`${wsproto}//${window.location.hostname}:${window.location.port}${window.location.pathname}ws`); - let info_elem = document.getElementById("miscinfo"); - let board_elem = document.getElementById("board"); - let tile_w = 0; - let tile_h = 0; - let name = "anon"; - let clr = "#f03333"; - let last_packet = {}; - let cursors = new Map(); - let board = {}; - let board_bounds = {}; // init when we actually have the board loaded - function register() { - let name_in = document.getElementById("name-in"); - let clr_in = document.getElementById("clr-in"); - if (name_in.value.length > 0) { - name = name_in.value; - } - clr = clr_in.value; - s.send(`register ${name} ${clr}`); - } - s.onopen = function(e) { - info_elem.innerHTML = - `<input id="name-in" type="text"> + window.name = "anon"; + window.clr = "#f03333"; + window.info_elem = document.getElementById("miscinfo"); + window.info_elem.innerHTML =` + <input id="name-in" type="text" value="anon"> <input id="clr-in" type="color" value="#ffffff"></input> <button onclick=register()>Join</button>`; + window.board_elem = document.getElementById("board"); + window.bwidth = NaN; + window.bheight = NaN; + window.tile_w = NaN; + window.tile_h = NaN; + window.mine_ratio = "unk"; + window.socket = {}; + window.last_packet = {}; + window.cursors = new Map(); + window.board = {}; + window.board_bounds = {}; // init when we actually have the board loaded + function register() { + window.name = document.getElementById("name-in").value; + window.clr = document.getElementById("clr-in").value; + window.socket = connect(); } - s.onmessage = function(e) { + + function connect() { + let wsproto = (window.location.protocol == "https:")? "wss:": "ws:"; + let s = new WebSocket(`${wsproto}//${window.location.hostname}:${window.location.port}${window.location.pathname}ws`); + s.onopen = function() { + s.send(`register ${window.name} ${window.clr}`); + } + s.onmessage = function(e) { last_packet = e; let d = e.data; if (typeof d == "object") { @@ -85,42 +88,51 @@ info_elem.innerHTML = "Running"; } else if (typeof e.data == "string") { let fields = d.split(" "); - if (d.startsWith("pos")) { - let oid = Number(fields[1]); - let name = fields[2]; - let clr = fields[3]; - let x = fields[4]; - let y = fields[5]; - if (!cursors.has(oid)) { - createCursor(oid, name, clr); - } - let celem = cursors.get(oid).elem; - celem.style.left = x + 'px'; - celem.style.top = y + 'px'; - console.log(oid + name + clr + x + y); - } - else if (d.startsWith("id")) { - window.id = Number(fields[1]); - createCursor(id, name, clr); - } - else if (d.startsWith("win")) { - info_elem.innerHTML = "<p>You win! Reset?</p>"; - info_elem.onclick = e => { s.send("reset") }; - } - else if (d.startsWith("lose")) { - let badone = fields[1]; - info_elem.innerHTML = `<p>You lost, ${badone} was blown up. Reset?</p>`; - info_elem.onclick = e => { s.send("reset") }; - } - else if (d.startsWith("logoff")) { - let oid = fields[1]; - cursors.get(oid).elem.remove(); - cursors.delete(oid); + switch (fields[0]) { + case "pos": { + let oid = Number(fields[1]); + let name = fields[2]; + let clr = fields[3]; + let x = fields[4]; + let y = fields[5]; + if (!cursors.has(oid)) { + createCursor(oid, name, clr); + } + let celem = window.cursors.get(oid).elem; + celem.style.left = x + 'px'; + celem.style.top = y + 'px'; + } break; + case "regack": { + name = fields[1]; + id = Number(fields[2]); + let dims = fields[3].split("x"); + bwidth = Number(dims[0]); + bheight = Number(dims[1]); + mine_ratio = fields[4]; + createCursor(id, name, clr); + } break; + case "win": { + info_elem.innerHTML = "<p>You win! Click here to play again.</p>"; + info_elem.onclick = e => { s.send("reset") }; + } break; + case "lose": { + let badone = fields[1]; + info_elem.innerHTML = `<p>You lost, ${badone} was blown up. Click here to retry.</p>`; + info_elem.onclick = e => { s.send("reset") }; + } break; + case "logoff": { + let oid = fields[1]; + cursors.get(oid).elem.remove(); + cursors.get(oid).selwin.remove(); + cursors.delete(oid); + } break; } } } - s.onerror = function(e) { info_elem.innerHTML += `<br>error ${e}`; } - s.onclose = function(e) { info_elem.innerHTML = "Closed"; } + s.onerror = function(e) { info_elem.innerHTML += `<br>Error ${e}`; } + s.onclose = function(e) { info_elem.innerHTML = "Closed"; } + return s; + } function acceptBoard(data) { let vals = new Uint8Array(data); @@ -147,7 +159,7 @@ } last = board[i]; } - board_elem.innerHTML = "<span>" + split_board.join("") + "</span>"; + board_elem.innerHTML = split_board.join(""); } function createCursor(id, name, clr) { @@ -167,30 +179,32 @@ document.getElementById('board-container').append(cursor); document.getElementById('board-container').append(selection_window); if (id == window.id) { - document.addEventListener('mousemove', e => { + document.addEventListener('mousemove', e => { cursor.style.left = (e.pageX + 15) + 'px'; cursor.style.top = (e.pageY + 15) + 'px'; let tpos = tilepos(e.clientX, e.clientY); + socket.send(`pos ${e.pageX} ${e.pageY}`); + }, + false); + board_elem.addEventListener('mousemove', e => { + let tpos = tilepos(e.clientX, e.clientY); selection_window.style.left = ((tpos.x + 0.5) * tile_w) + 'px'; selection_window.style.top = ((tpos.y + 0.5) * tile_h) + 'px'; selection_window.style.width = tile_w + 'px'; selection_window.style.height = tile_h + 'px'; - s.send(`pos ${e.pageX} ${e.pageY}`); - }, - false); + }, false); } cursors.set(id, {name: name, elem: cursor, selwin: selection_window}); return cursor; } function getBoardBounds() { let boardb = board_elem.getBoundingClientRect(); - let textb = board_elem.firstChild.getBoundingClientRect(); - tile_w = textb.width / 75; - tile_h = boardb.height / 35; + tile_w = boardb.width / bwidth; + tile_h = 22; return { ox: boardb.x, oy: boardb.y, - w: textb.width, + w: boardb.width, h: boardb.height }; } @@ -199,13 +213,13 @@ let tpos = tilepos(e.clientX, e.clientY); let cmd = `reveal ${tpos.x} ${tpos.y}`; console.log(cmd); - s.send(cmd); + socket.send(cmd); } board_elem.oncontextmenu = function(e) { let tpos = tilepos(e.clientX, e.clientY); let cmd = `flag ${tpos.x} ${tpos.y}`; console.log(cmd); - s.send(cmd); + socket.send(cmd); return false; } function tilepos(x,y) { @@ -213,8 +227,8 @@ let b = board_bounds; let relx = (x - b.ox); let rely = (y - b.oy); - let tilex = Math.floor(75 * relx/b.w); - let tiley = Math.floor(35 * rely/b.h); + let tilex = Math.floor(bwidth * relx/b.w); + let tiley = Math.floor(bheight * rely/b.h); return { x: tilex, y: tiley }; } function sleep(ms) { diff --git a/src/conn.rs b/src/conn.rs index 5325bf4..01bc1e8 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -26,23 +26,23 @@ pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>) let mut fields = cmd.split(" "); if fields.next() == Some("register") { - let all_fields = fields.collect::<Vec<&str>>(); - let fcount = all_fields.len(); - let mut name = "anon".to_string(); - if fcount >= 2 { - name = all_fields[..fcount-1].join(" "); - } - let mut clr = all_fields[fcount-1].chars().filter(|c| c.is_digit(16) || *c == '#').collect::<String>(); - if clr.is_empty() { - clr = "#f03333".into(); - } - println!("registered {name}"); + let mut all_fields = fields.collect::<Vec<&str>>(); + let clr = all_fields.pop().expect("register without color").chars().filter(|c| c.is_digit(16) || *c == '#').collect::<String>(); + let name = { + let def = "anon".to_string(); + if all_fields.is_empty() { def } + else { + let n = all_fields.join(" "); + if n.is_empty() { def } else { n } + } + }; + println!("registered \"{name}@{addr}\""); let uid = { // new scope cuz paranoid bout deadlocks let conn = Conn { addr, tx: tx.clone() }; - room.write().await.players.insert_conn(conn, name, clr).await + room.write().await.players.insert_conn(conn, name.clone(), clr).await }; - tx.send(Message::text(format!("id {uid}"))).expect("couldn't send register ack"); + tx.send(Message::text(format!("regack {} {uid} {}", name.replace(" ", " "), room.read().await.board_conf))).expect("couldn't send register ack"); if let Err(e) = room.read().await.cmd_stream.send(MetaMove::Dump) { println!("couldn't request game dump in behalf of {addr}: {e}"); } @@ -72,15 +72,13 @@ pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>) let room_lock = room.read().await; let mut players = room_lock.players.write().await; - if players.contains_key(&addr) { - players.remove(&addr); - } - for (paddr, p) in players.iter() { - if let Err(e) = p.conn.tx.send(Message::text("logoff {p.seqid} {p.name}")) { - println!("couldn't deliver logoff info to \"{}\"@{}: {}", p.name, paddr, e); + let disconn_p = players.remove(&addr); + for p in players.values() { + if let Err(e) = p.conn.tx.send(Message::text("logoff {disconn_p.seqid} {disconn_p.name}")) { + println!("couldn't deliver logoff info to {}: {}", p, e); } } - println!("{addr} disconnected"); + println!("{} disconnected", if let Some(p) = disconn_p { p.to_string() } else { addr.to_string() }); } pub async fn handle_room(mut incoming: SplitStream<WebSocket>, addr: SocketAddr, room: Arc<RwLock<Room>>) { |