diff options
author | stale <redkugelblitzin@gmail.com> | 2022-05-18 09:36:43 -0300 |
---|---|---|
committer | stale <redkugelblitzin@gmail.com> | 2022-05-18 09:36:43 -0300 |
commit | d89b9ea43ac65af549279f6e86c68c66243dcdf3 (patch) | |
tree | 39173297e076c4425149c78f6244a2b762786ac8 | |
parent | 127a1059fec4fecb4099cb95ddb7ef3c7cf45077 (diff) |
organizing
-rw-r--r-- | assets/VT323-Regular.ttf (renamed from src/VT323-Regular.ttf) | bin | 149688 -> 149688 bytes | |||
-rw-r--r-- | assets/client.js | 204 | ||||
-rw-r--r-- | assets/room.html | 18 | ||||
-rw-r--r-- | assets/style.css | 33 | ||||
-rw-r--r-- | page.html | 256 | ||||
-rw-r--r-- | src/main.rs | 34 | ||||
-rw-r--r-- | src/types.rs | 9 |
7 files changed, 280 insertions, 274 deletions
diff --git a/src/VT323-Regular.ttf b/assets/VT323-Regular.ttf Binary files differindex 6aec599..6aec599 100644 --- a/src/VT323-Regular.ttf +++ b/assets/VT323-Regular.ttf diff --git a/assets/client.js b/assets/client.js new file mode 100644 index 0000000..0e90d4b --- /dev/null +++ b/assets/client.js @@ -0,0 +1,204 @@ +window.id = NaN; +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="#33c033"></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(); +} + +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") { + d.arrayBuffer().then(acceptBoard); + info_elem.onclick = undefined; + info_elem.innerHTML = `Running, ${mine_ratio} tiles are mines`; + } else if (typeof e.data == "string") { + let fields = d.split(" "); + 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 = cursors.get(oid).elem; + celem.style.left = x + 'px'; + celem.style.top = y + 'px'; + movSelWin(cursors.get(oid).selwin, x, y); + } 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 = Number(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"; } + return s; +} + +function acceptBoard(data) { + let vals = new Uint8Array(data); + board = Array.from(vals).reduce((s,c) => s + String.fromCodePoint(c), ""); + let last = board[0]; + let last_idx = 0; + let split_board = []; + for (let i = 1; i < board.length+1; i++) { + let cur = board[i]; + let gamechars = /^[CFO# 1-8]+$/; + if ((cur != last && gamechars.test(cur)) || cur == undefined) { + let txt = board.substr(last_idx, i-last_idx); + switch(txt[0]) { + case 'O': + txt = `<span style="color:red;">${txt}</span>`; + break; + case 'C': + txt = `<span style="color:green;">${txt}</span>`; + break; + case 'F': + txt = `<span style="color:yellow;">${txt}</span>`; + break; + + case '1': txt = `<span style="color:#0100FB;">${txt}</span>`; break; + case '2': txt = `<span style="color:#027F01;">${txt}</span>`; break; + case '3': txt = `<span style="color:#FD0100;">${txt}</span>`; break; + case '4': txt = `<span style="color:#01017B;">${txt}</span>`; break; + case '5': txt = `<span style="color:#7D0302;">${txt}</span>`; break; + case '6': txt = `<span style="color:#00807F;">${txt}</span>`; break; + + default: txt = `<span style="color:white;">${txt}</span>`; break; + } + split_board.push(txt); + last_idx = i; + } + last = board[i]; + } + board_elem.innerHTML = split_board.join(""); +} + +function createCursor(id, name, clr) { + // shit doesn't line up + let cursor = document.createElement("div"); + cursor.style.position = "absolute"; + let nametag = document.createElement("p"); + nametag.innerHTML = name; + nametag.classList.add('cursor-name'); + let selection_window = document.createElement("div"); + selection_window.style.backgroundColor = clr + "a0"; + selection_window.style.position = "absolute"; + selection_window.classList.add('cursor'); + cursor.appendChild(nametag); + cursor.classList.add('cursor'); + cursor.style.color = clr; + document.getElementById('board-container').append(cursor); + document.getElementById('board-container').append(selection_window); + if (id == window.id) { + document.addEventListener('mousemove', e => { + cursor.style.left = (e.pageX + 15) + 'px'; + cursor.style.top = (e.pageY + 15) + 'px'; + movSelWin(selection_window, e.clientX, e.clientY); + let tpos = tilepos(e.clientX, e.clientY); + socket.send(`pos ${e.pageX} ${e.pageY}`); + }, + false); + } + cursors.set(id, {name: name, elem: cursor, selwin: selection_window}); + return cursor; +} +function movSelWin(win, x, y) { + let tpos = tilepos(x, y); + if (tpos.x > (bwidth - 1) || tpos.x < 0 || tpos.y > (bheight - 1) || tpos.y < 0) { + win.style.display = "none"; + } else { + win.style.display = ""; + } + win.style.left = ((tpos.x + 0.5) * tile_w) + 'px'; + win.style.top = ((tpos.y + 0.5) * tile_h) + 'px'; + win.style.width = tile_w + 'px'; + win.style.height = tile_h + 'px'; +} +function getBoardBounds() { + let boardb = board_elem.getBoundingClientRect(); + tile_w = boardb.width / bwidth; + tile_h = 22; + return { + ox: boardb.x, + oy: boardb.y, + w: boardb.width, + h: boardb.height + }; +} + +board_elem.onclick = function(e) { + let tpos = tilepos(e.clientX, e.clientY); + let cmd = `reveal ${tpos.x} ${tpos.y}`; + console.log(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); + socket.send(cmd); + return false; +} +function tilepos(x,y) { + board_bounds = getBoardBounds(); + let b = board_bounds; + let relx = (x - b.ox); + let rely = (y - b.oy); + let tilex = Math.floor(bwidth * relx/b.w); + let tiley = Math.floor(bheight * rely/b.h); + return { x: tilex, y: tiley }; +} +function sleep(ms) { + return new Promise(resolve => setTimeout(resolve, ms)); +} diff --git a/assets/room.html b/assets/room.html new file mode 100644 index 0000000..f3f130d --- /dev/null +++ b/assets/room.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="UTF-8"> + <title>websweeper</title> + <meta name="viewport" content="width=device-width,initial-scale=1"> + <link rel="stylesheet" type="text/css" href="s.css"> + </head> + <body> + <div class=""> + <div id="board-container"> + <span id="board"></span> + </div> + <p id="miscinfo">Loading...</p> + </div> + </body> + <script src="c.js"></script> +</html> diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..acdd9c0 --- /dev/null +++ b/assets/style.css @@ -0,0 +1,33 @@ +@font-face { + font-family: vt323; + src: url("f.ttf"); +} +#board-container { + font-size: 36px; + line-height: 22px; +} +body { + font-family: vt323, monospace; + background-color: black; + color: white; +} +.unsel { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +.cursor { + font-size: 16pt; + pointer-events: none; +} +.cursor * { + margin: 0 0; +} +.cursor-name { + background-color: #000000c0; + padding: 0.1em 0.1em; +} + diff --git a/page.html b/page.html deleted file mode 100644 index 8656495..0000000 --- a/page.html +++ /dev/null @@ -1,256 +0,0 @@ -<!DOCTYPE html> -<html lang="en"> - <head> - <meta charset="UTF-8"> - <title>websweeper</title> - <meta name="viewport" content="width=device-width,initial-scale=1"> - </head> - <style> -@font-face { - font-family: vt323; - src: url("font.ttf"); -} - #board-container { - font-size: 36px; - line-height: 22px; - } - body { - font-family: vt323, monospace; - background-color: black; - color: white; - } - .unsel { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - } - .cursor { - font-size: 16pt; - pointer-events: none; - } - .cursor * { - margin: 0 0; - } - .cursor-name { - background-color: #000000c0; - padding: 0.1em 0.1em; - } - </style> - <body> - <div class=""> - <div id="board-container"> - <span id="board"></span> - </div> - <p id="miscinfo">Loading...</p> - </div> - </body> - <script> - window.id = NaN; - 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="#33c033"></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(); - } - - 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") { - d.arrayBuffer().then(acceptBoard); - info_elem.onclick = undefined; - info_elem.innerHTML = `Running, ${mine_ratio} tiles are mines`; - } else if (typeof e.data == "string") { - let fields = d.split(" "); - 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 = cursors.get(oid).elem; - celem.style.left = x + 'px'; - celem.style.top = y + 'px'; - movSelWin(cursors.get(oid).selwin, x, y); - } 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 = Number(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"; } - return s; - } - - function acceptBoard(data) { - let vals = new Uint8Array(data); - board = Array.from(vals).reduce((s,c) => s + String.fromCodePoint(c), ""); - let last = board[0]; - let last_idx = 0; - let split_board = []; - for (let i = 1; i < board.length+1; i++) { - let cur = board[i]; - let gamechars = /^[CFO# 1-8]+$/; - if ((cur != last && gamechars.test(cur)) || cur == undefined) { - let txt = board.substr(last_idx, i-last_idx); - switch(txt[0]) { - case 'O': - txt = `<span style="color:red;">${txt}</span>`; - break; - case 'C': - txt = `<span style="color:green;">${txt}</span>`; - break; - case 'F': - txt = `<span style="color:yellow;">${txt}</span>`; - break; - - case '1': txt = `<span style="color:#0100FB;">${txt}</span>`; break; - case '2': txt = `<span style="color:#027F01;">${txt}</span>`; break; - case '3': txt = `<span style="color:#FD0100;">${txt}</span>`; break; - case '4': txt = `<span style="color:#01017B;">${txt}</span>`; break; - case '5': txt = `<span style="color:#7D0302;">${txt}</span>`; break; - case '6': txt = `<span style="color:#00807F;">${txt}</span>`; break; - - default: txt = `<span style="color:white;">${txt}</span>`; break; - } - split_board.push(txt); - last_idx = i; - } - last = board[i]; - } - board_elem.innerHTML = split_board.join(""); - } - - function createCursor(id, name, clr) { - // shit doesn't line up - let cursor = document.createElement("div"); - cursor.style.position = "absolute"; - let nametag = document.createElement("p"); - nametag.innerHTML = name; - nametag.classList.add('cursor-name'); - let selection_window = document.createElement("div"); - selection_window.style.backgroundColor = clr + "a0"; - selection_window.style.position = "absolute"; - selection_window.classList.add('cursor'); - cursor.appendChild(nametag); - cursor.classList.add('cursor'); - cursor.style.color = clr; - document.getElementById('board-container').append(cursor); - document.getElementById('board-container').append(selection_window); - if (id == window.id) { - document.addEventListener('mousemove', e => { - cursor.style.left = (e.pageX + 15) + 'px'; - cursor.style.top = (e.pageY + 15) + 'px'; - movSelWin(selection_window, e.clientX, e.clientY); - let tpos = tilepos(e.clientX, e.clientY); - socket.send(`pos ${e.pageX} ${e.pageY}`); - }, - false); - } - cursors.set(id, {name: name, elem: cursor, selwin: selection_window}); - return cursor; - } - function movSelWin(win, x, y) { - let tpos = tilepos(x, y); - if (tpos.x > (bwidth - 1) || tpos.x < 0 || tpos.y > (bheight - 1) || tpos.y < 0) { - win.style.display = "none"; - } else { - win.style.display = ""; - } - win.style.left = ((tpos.x + 0.5) * tile_w) + 'px'; - win.style.top = ((tpos.y + 0.5) * tile_h) + 'px'; - win.style.width = tile_w + 'px'; - win.style.height = tile_h + 'px'; - } - function getBoardBounds() { - let boardb = board_elem.getBoundingClientRect(); - tile_w = boardb.width / bwidth; - tile_h = 22; - return { - ox: boardb.x, - oy: boardb.y, - w: boardb.width, - h: boardb.height - }; - } - - board_elem.onclick = function(e) { - let tpos = tilepos(e.clientX, e.clientY); - let cmd = `reveal ${tpos.x} ${tpos.y}`; - console.log(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); - socket.send(cmd); - return false; - } - function tilepos(x,y) { - board_bounds = getBoardBounds(); - let b = board_bounds; - let relx = (x - b.ox); - let rely = (y - b.oy); - let tilex = Math.floor(bwidth * relx/b.w); - let tiley = Math.floor(bheight * rely/b.h); - return { x: tilex, y: tiley }; - } - function sleep(ms) { - return new Promise(resolve => setTimeout(resolve, ms)); - } - </script> -</html> diff --git a/src/main.rs b/src/main.rs index 0a17346..e972025 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,6 @@ use std::{ net::SocketAddr, sync::Arc, }; -use warp::Filter; mod types; mod conn; @@ -12,13 +11,16 @@ use types::*; use tokio::sync::RwLock; -const FONT_FILE: &[u8] = include_bytes!("./VT323-Regular.ttf"); +const FONT_FILE: &[u8] = include_bytes!("../assets/VT323-Regular.ttf"); fn main() -> Result<(), Box<dyn Error>> { let conf = Config { - cert_path: "./cert.pem".to_owned(), - pkey_path: "./cert.rsa".to_owned(), - page_path: "./page.html".to_owned(), + cert: "./cert.pem".to_owned(), + pkey: "./cert.rsa".to_owned(), + room_pg: "./assets/room.html".to_owned(), + form_pg: "./assets/form.html".to_owned(), + client_code: "./assets/client.js".to_owned(), + stylesheet: "./assets/style.css".to_owned(), socket_addr: ([0,0,0,0],31235).into(), }; @@ -44,13 +46,14 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { } })); - let page_route = { - use warp::*; - get() - .and(path("font.ttf")) - .map(|| FONT_FILE) - .or(fs::file(conf.page_path.clone())) - }; + use warp::*; + + let style = path("s.css").and(fs::file(conf.stylesheet.clone())); + let code = path("c.js").and(fs::file(conf.client_code.clone())); + let font = path("f.ttf").map(|| FONT_FILE); + let listing = path("rlist").map(|| "placeholder'em"); + let room_form = path("r").map(|| "yeah placeholder mate"); + let index = path::end().and(fs::file(conf.room_pg.clone())); let websocket_route = { let room = room.clone(); @@ -66,12 +69,13 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { }) }) }; - let routes = websocket_route.or(page_route); + let route = any().and(get().and(index).or(style).or(code).or(font).or(listing)).or(post().and(room_form)); + let routes = websocket_route.or(route); let server = warp::serve(routes) .tls() - .cert_path(conf.cert_path) - .key_path(conf.pkey_path) + .cert_path(conf.cert) + .key_path(conf.pkey) .run(conf.socket_addr); println!("Serving on {}", conf.socket_addr); server.await; diff --git a/src/types.rs b/src/types.rs index 86f1e32..fb9f7ae 100644 --- a/src/types.rs +++ b/src/types.rs @@ -14,9 +14,12 @@ use crate::minesweeper; #[derive(Debug, Clone)] pub struct Config { - pub cert_path: String, - pub pkey_path: String, - pub page_path: String, + pub cert: String, + pub pkey: String, + pub room_pg: String, + pub form_pg: String, + pub client_code: String, + pub stylesheet: String, pub socket_addr: SocketAddr, } |