diff options
author | stale <redkugelblitzin@gmail.com> | 2022-05-29 20:45:03 -0300 |
---|---|---|
committer | stale <redkugelblitzin@gmail.com> | 2022-05-29 20:45:03 -0300 |
commit | bcd5764aa03e128e06c355272b7b81eac8d4501d (patch) | |
tree | 44e1076c24680325a02317c29d4838c547a6c49d | |
parent | 8e8fb7c45e8088843b71cb55fede723b2f9c7ff2 (diff) |
improved pubs listing, many minor fixes
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | assets/client.js | 4 | ||||
-rw-r--r-- | assets/index.html | 13 | ||||
-rw-r--r-- | assets/room.html | 2 | ||||
-rw-r--r-- | assets/style.css | 10 | ||||
-rw-r--r-- | src/conn.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 40 | ||||
-rw-r--r-- | src/minesweeper.rs | 4 | ||||
-rw-r--r-- | src/types.rs | 15 |
10 files changed, 68 insertions, 24 deletions
@@ -1378,6 +1378,7 @@ dependencies = [ "futures-util", "rand", "serde", + "serde_json", "tokio", "warp", ] @@ -9,6 +9,7 @@ edition = "2018" [dependencies] tokio = { version = "1", features = ["full"] } serde = { version = "1", features = ["derive"] } +serde_json = "1.0" warp = { version = "0.3", features = ["tls", "websocket"] } rand = "0.8" futures-util = "0.3" diff --git a/assets/client.js b/assets/client.js index b23222c..a6a2a73 100644 --- a/assets/client.js +++ b/assets/client.js @@ -163,8 +163,8 @@ function movSelWin(win, x, y) { } else { win.style.display = ""; } - win.style.left = (anch.x + (tpos.x * tile_w)) + 'px'; - win.style.top = (anch.y + ((tpos.y + 0.35) * tile_h)) + 'px'; + win.style.left = (window.scrollX + anch.x + (tpos.x * tile_w)) + 'px'; + win.style.top = (window.scrollY + anch.y + ((tpos.y + 0.35) * tile_h)) + 'px'; win.style.width = tile_w + 'px'; win.style.height = tile_h + 'px'; } diff --git a/assets/index.html b/assets/index.html index 6fc9c46..763b9ef 100644 --- a/assets/index.html +++ b/assets/index.html @@ -11,9 +11,16 @@ <script> let rlist = document.getElementById('rlist'); fetch('rlist').then(r => r.json()).then(rooms => { - rooms.forEach(x => { + Object.keys(rooms).forEach(x => { + let roominfo = JSON.parse(rooms[x]); + let bc = roominfo.board_conf; let a = document.createElement('a'); - a.appendChild(document.createTextNode(x)); + let h1 = document.createElement('h1'); + h1.appendChild(document.createTextNode(`> ${roominfo.name}`)); + let h4 = document.createElement('h4'); + h4.appendChild(document.createTextNode(`${bc.w} by ${bc.h} with ${bc.mine_ratio[0]} in every ${bc.mine_ratio[1]} tiles mined`)); + a.append(h1); + a.append(h4); a.href = 'room/' + x; rlist.append(a); rlist.append(document.createElement('br')); @@ -33,7 +40,7 @@ tiles are mines </label><br> <label>public, ie. shown in the lobby <input name="raccess" type="checkbox" checked></label><br> - <label>always safe first move <input name="ralwayssafe1move" type="checkbox" checked></label><br> + <label>safe first move (if possible)<input name="ralwayssafe1move" type="checkbox" checked></label><br> <label>player limit<input name="rlimit" type="number" value="32"></label><br> <button>create</button> </fieldset> diff --git a/assets/room.html b/assets/room.html index 27f9ae1..e3e6ff9 100644 --- a/assets/room.html +++ b/assets/room.html @@ -7,7 +7,7 @@ <link rel="stylesheet" type="text/css" href="/s.css"> </head> <body> - <div class="cent"> + <div> <div id="board-container"> <span id="board"></span> </div> diff --git a/assets/style.css b/assets/style.css index d217b8d..52a2021 100644 --- a/assets/style.css +++ b/assets/style.css @@ -36,3 +36,13 @@ body { padding: 0.1em 0.1em; } +#rlist a { + text-decoration: none; + line-height: 0.4; + color: #dfdfff; + background-color: #3c3c3c; +} + +a :visited { + color: inherit; +} diff --git a/src/conn.rs b/src/conn.rs index 14777bf..d38b6ef 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -43,7 +43,7 @@ pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>) let conn = Conn { addr, tx: tx.clone() }; room.write().await.players.insert_conn(conn, name.clone(), clr).await }; - tx.send(Message::text(format!("regack {} {uid} {}", name.replace(" ", " "), room.read().await.board_conf))).expect("couldn't send register ack"); + tx.send(Message::text(format!("regack {} {uid} {}", name.replace(" ", " "), room.read().await.conf.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}"); } diff --git a/src/main.rs b/src/main.rs index 2f7d52c..3dd7f39 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use types::*; use tokio::sync::RwLock; const FONT_FILE: &[u8] = include_bytes!("../assets/VT323-Regular.ttf"); +const AREA_LIMIT: usize = 150*150; fn main() -> Result<(), Box<dyn Error>> { let conf = Config { @@ -32,7 +33,7 @@ fn main() -> Result<(), Box<dyn Error>> { #[tokio::main] async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { let rooms: RoomMap = Arc::new(RwLock::new(HashMap::new())); - let public_rooms = Arc::new(RwLock::new(Vec::new())); + let public_rooms = Arc::new(RwLock::new(HashMap::new())); use warp::*; let index = path::end().and(fs::file(conf.index_pg.clone())); @@ -44,8 +45,9 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { path!("rlist").and_then(move || { let pubs = pubs.clone(); async move { - Ok::<_,std::convert::Infallible>( - reply::json(&pubs.read().await.as_slice()) + let map = pubs.read().await; + Ok::<_,std::convert::Infallible>( + reply::json(&*map) ) }}) }; @@ -67,26 +69,36 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { rinfo.get("ralwayssafe1move"), rinfo.get("rlimit").and_then(|l| l.parse::<usize>().ok()), ) { + if w.get()*h.get() > AREA_LIMIT { + return Err(reject::custom(BoardTooBig)) + } let board_conf = minesweeper::BoardConf { w, h, mine_ratio: (num,denom), always_safe_first_move: asfm.is_some() }; - let name = rinfo.get("rname").map(|r| r.to_owned()).unwrap_or(format!("{w}x{h} room")); - let mut rooms = rooms.write().await; let uid = types::RoomId::new_in(&rooms); + let name = { + let n = rinfo.get("rname").map(|r| r.to_owned()).unwrap(); + if n.is_empty() { uid.to_string() } else { n } + }; let players = PlayerMap::default(); let (cmd_tx, cmd_rx) = tokio::sync::mpsc::unbounded_channel(); let handle = tokio::spawn(gameloop(cmd_rx, players.clone(), board_conf)); - rooms.insert(uid.clone(), Arc::new(RwLock::new(Room { + let room_conf = RoomConf { name, - players, - peer_limit: match limit { Some(i) => i, None => usize::MAX }, + player_cap: match limit { Some(i) => i, None => usize::MAX }, public: access.is_some(), + board_conf, + }; + let new_room = Room { + conf: room_conf, + players, driver: handle, cmd_stream: cmd_tx, - board_conf, - }))); + }; if access.is_some() { - pubs.write().await.push(uid.clone()); + pubs.write().await.insert(uid.clone(), serde_json::to_string(&new_room.conf).unwrap()); } + rooms.insert(uid.clone(), Arc::new(RwLock::new(new_room))); + Ok( hyper::Response::builder() .status(hyper::StatusCode::SEE_OTHER) @@ -205,10 +217,16 @@ use warp::{ reject::{ Reject, Rejection }, reply::{ self, Reply }, http::StatusC struct BadFormData; impl Reject for BadFormData {} +#[derive(Debug)] +struct BoardTooBig; +impl Reject for BoardTooBig {} + async fn error_handler(err: Rejection) -> Result<impl Reply, std::convert::Infallible> { if err.is_not_found() { Ok(reply::with_status("No such file", StatusCode::NOT_FOUND)) } else if let Some(_e) = err.find::<BadFormData>() { Ok(reply::with_status("Bad form data", StatusCode::BAD_REQUEST)) + } else if let Some(_e) = err.find::<BoardTooBig>() { + Ok(reply::with_status("Board too big", StatusCode::BAD_REQUEST)) } else { println!("unhandled rejection: {err:?}"); Ok(reply::with_status("Server error", StatusCode::INTERNAL_SERVER_ERROR)) diff --git a/src/minesweeper.rs b/src/minesweeper.rs index c81aa09..a494b94 100644 --- a/src/minesweeper.rs +++ b/src/minesweeper.rs @@ -3,6 +3,8 @@ use std::{ num::NonZeroUsize, }; use rand::{ thread_rng, Rng, distributions::Uniform }; +use serde::Serialize; + const HIDDEN_BIT: u8 = 1 << 7; pub const FLAGGED_BIT: u8 = 1 << 6; const CORRECT_BIT: u8 = 1 << 5; // grading for a rightly flagged mine @@ -29,7 +31,7 @@ pub struct Game { pub board_conf: BoardConf, } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, Serialize)] pub struct BoardConf { pub w: NonZeroUsize, pub h: NonZeroUsize, diff --git a/src/types.rs b/src/types.rs index 84e7d46..d467982 100644 --- a/src/types.rs +++ b/src/types.rs @@ -10,6 +10,7 @@ use std::{ }; use warp::ws::Message; use tokio::sync::RwLock; +use serde::Serialize; use crate::minesweeper; #[derive(Debug, Clone)] @@ -23,15 +24,19 @@ pub struct Config { pub socket_addr: SocketAddr, } -#[derive(Debug)] -pub struct Room { +#[derive(Debug, Serialize)] +pub struct RoomConf { pub name: String, - pub players: PlayerMap, - pub peer_limit: usize, + pub player_cap: usize, pub public: bool, + pub board_conf: minesweeper::BoardConf, +} + +pub struct Room { + pub conf: RoomConf, + pub players: PlayerMap, pub driver: tokio::task::JoinHandle<()>, pub cmd_stream: CmdTx, - pub board_conf: minesweeper::BoardConf, } #[derive(Debug)] |