summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--page.html162
-rw-r--r--src/conn.rs38
2 files changed, 106 insertions, 94 deletions
diff --git a/page.html b/page.html
index 949989a..d003ee3 100644
--- a/page.html
+++ b/page.html
@@ -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("&nbsp");
- }
- 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(" ", "&nbsp"), 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>>) {