summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorstale <redkugelblitzin@gmail.com>2022-05-31 04:04:53 -0300
committerstale <redkugelblitzin@gmail.com>2022-05-31 04:04:53 -0300
commitd9eededb736e4ada13ee6e7fe517adcc6a606f88 (patch)
tree726e1e2a335cab290963dbd547e0dd0093de3f99
parent746a810eea15e52f7d1b17778239825daad90e01 (diff)
room limits and player counts
-rw-r--r--Cargo.lock37
-rw-r--r--Cargo.toml2
-rw-r--r--assets/index.html23
-rw-r--r--src/conn.rs2
-rw-r--r--src/main.rs52
5 files changed, 106 insertions, 10 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d57162e..a6a1cd8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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",
diff --git a/Cargo.toml b/Cargo.toml
index 8997bdd..1fb0506 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
+}
+