summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/conn.rs2
-rw-r--r--src/main.rs52
2 files changed, 49 insertions, 5 deletions
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
+}
+