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>>) { | 
