diff options
author | stale <redkugelblitzin@gmail.com> | 2022-05-31 04:04:53 -0300 |
---|---|---|
committer | stale <redkugelblitzin@gmail.com> | 2022-05-31 04:04:53 -0300 |
commit | d9eededb736e4ada13ee6e7fe517adcc6a606f88 (patch) | |
tree | 726e1e2a335cab290963dbd547e0dd0093de3f99 | |
parent | 746a810eea15e52f7d1b17778239825daad90e01 (diff) |
room limits and player counts
-rw-r--r-- | Cargo.lock | 37 | ||||
-rw-r--r-- | Cargo.toml | 2 | ||||
-rw-r--r-- | assets/index.html | 23 | ||||
-rw-r--r-- | src/conn.rs | 2 | ||||
-rw-r--r-- | src/main.rs | 52 |
5 files changed, 106 insertions, 10 deletions
@@ -190,6 +190,21 @@ dependencies = [ ] [[package]] +name = "futures" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] name = "futures-channel" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -206,6 +221,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" [[package]] +name = "futures-executor" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" + +[[package]] name = "futures-macro" version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -234,10 +266,13 @@ version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" dependencies = [ + "futures-channel", "futures-core", + "futures-io", "futures-macro", "futures-sink", "futures-task", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -1410,7 +1445,7 @@ version = "1.0.0" dependencies = [ "ammonia", "flate2", - "futures-util", + "futures", "rand", "serde", "serde_json", @@ -13,5 +13,5 @@ serde_json = "1.0" flate2 = "1.0" warp = { version = "0.3", features = ["tls", "websocket"] } rand = "0.8" -futures-util = "0.3" +futures = "0.3" ammonia = "3" diff --git a/assets/index.html b/assets/index.html index 9517529..f85b733 100644 --- a/assets/index.html +++ b/assets/index.html @@ -7,16 +7,23 @@ <link rel="stylesheet" type="text/css" href="./s.css"> </head> <body> - <div id="rlist" class="cent"></div> + <div class="cent"> + <div id="rlist"></div> + <span id="rspace"></span> + </div> <script> let rlist = document.getElementById('rlist'); - fetch('rlist').then(r => r.json()).then(rooms => { + fetch('rlist').then(r => r.json()).then(info => { + let rooms = info[0]; + let pcounts = info[1]; Object.keys(rooms).forEach(x => { let roominfo = JSON.parse(rooms[x]); + let pc = Number(pcounts[x]); let bc = roominfo.board_conf; let a = document.createElement('a'); let h1 = document.createElement('h1'); - h1.appendChild(document.createTextNode(`> ${roominfo.name}`)); + let ptxt = (pc > 0)? ((pc > 1)? `${pc} players`: `${pc} player`) : "no players"; + h1.appendChild(document.createTextNode(`> ${roominfo.name} — ${ptxt}`)); 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); @@ -26,6 +33,16 @@ rlist.append(document.createElement('br')); }); }); + fetch("rspace").then(resp => resp.text()).then(roomspace => { + let roomspacenum = Number(roomspace); + let e = document.getElementById('rspace'); + let t = document.createTextNode("room slots filled, if a room empties of active players it can be replaced by a new one"); + if (roomspacenum == 1) { + e.appendChild(document.createTextNode(`there is one available room slot`)); + } else if (roomspacenum > 1) { + e.appendChild(document.createTextNode(`there are ${roomspacenum} available room slots`)); + } + }) </script> <form method="post" action="r" class="cent"> <fieldset> diff --git a/src/conn.rs b/src/conn.rs index af7903f..71beb5d 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -4,7 +4,7 @@ use std::{ net::SocketAddr, }; use tokio::sync::RwLock; -use futures_util::{SinkExt, StreamExt, TryStreamExt, stream::SplitStream}; +use futures::{SinkExt, StreamExt, TryStreamExt, stream::SplitStream}; use warp::ws::{ WebSocket, Message }; use ammonia; diff --git a/src/main.rs b/src/main.rs index 66b2cfd..36ee5ce 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use std::{ collections::HashMap, num::NonZeroUsize, }; +use futures::stream::StreamExt; mod types; mod conn; @@ -15,6 +16,7 @@ use tokio::sync::RwLock; const FONT_FILE: &[u8] = include_bytes!("../assets/VT323-Regular.ttf"); const AREA_LIMIT: usize = 150*150; +const ROOM_LIMIT: usize = 8; fn main() -> Result<(), Box<dyn Error>> { let conf = Config { @@ -41,15 +43,45 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { let code = path!("c.js").and(fs::file(conf.client_code.clone())); let font = path!("f.ttf").map(|| FONT_FILE); let listing = { + let rooms = rooms.clone(); let pubs = public_rooms.clone(); path!("rlist").and_then(move || { + let rooms = rooms.clone(); let pubs = pubs.clone(); async move { - let map = pubs.read().await; + let roomsl = rooms.read().await; + let pubsl = pubs.read().await; + let rooms_pcount = futures::stream::iter(pubsl.iter()) + .then(|(id, _):(&RoomId,_)| { + let roomsl = roomsl.clone(); + async move { + (id.clone(), roomsl.get(id).unwrap().read().await.players.read().await.len()) + } + }) + .collect::<HashMap<RoomId,_>>().await; + let resp = (&*pubsl, rooms_pcount); Ok::<_,std::convert::Infallible>( - reply::json(&*map) - ) - }}) + reply::json(&resp) + ) + } + }) + }; + let roomspace = { + let rooms = rooms.clone(); + + path!("rspace").and_then(move || { + let r = rooms.clone(); + async move { + let empty_len = empty_rooms(r.clone()).await.len(); + let space = ROOM_LIMIT - r.read().await.len() + empty_len; + Ok::<_,std::convert::Infallible>( + hyper::Response::builder() + .status(hyper::StatusCode::OK) + .body(hyper::Body::from(space.to_string())) + .unwrap() + ) + } + }) }; let rform_recv = { let rooms = rooms.clone(); @@ -159,6 +191,7 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> { .or(code) .or(font) .or(listing) + .or(roomspace) .or(rform_recv) .or(room) .recover(error_handler); @@ -238,3 +271,14 @@ async fn error_handler(err: Rejection) -> Result<impl Reply, std::convert::Infal } } +async fn empty_rooms(rooms: RoomMap) -> Vec<RoomId> { + let rl = rooms.read().await; + futures::stream::iter(rl.iter()) + .filter_map(|(id,roomarc)| async move { + let rrl = roomarc.read().await; + let rrrl = rrl.players.read().await; + if rrrl.len() == 0 { Some(id.clone()) } else { None } + }) + .collect::<Vec<RoomId>>().await +} + |