summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorstale <redkugelblitzin@gmail.com>2022-05-31 18:06:52 -0300
committerstale <redkugelblitzin@gmail.com>2022-05-31 18:06:52 -0300
commit6c0907a825865956a169d7523b19121ea0e2e700 (patch)
tree572547831fab18925dc558d98a72842abd14bc9d /src
parent47b2b1512484d66cd92ea38b27f94d4dd70cd0b6 (diff)
added config file, room system finished
Diffstat (limited to 'src')
-rw-r--r--src/main.rs43
1 files changed, 38 insertions, 5 deletions
diff --git a/src/main.rs b/src/main.rs
index 9c9e5b1..d8c5122 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -15,8 +15,7 @@ use types::*;
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;
+const CONF_FILE: &str = "./conf.json";
fn main() -> Result<(), Box<dyn Error>> {
let conf = Config {
@@ -34,6 +33,13 @@ fn main() -> Result<(), Box<dyn Error>> {
#[tokio::main]
async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> {
+ let conf_file: serde_json::Value = serde_json::from_str(&tokio::fs::read_to_string(CONF_FILE).await?)?;
+ let area_limit: usize = conf_file.get("area_limit")
+ .expect("no area_limit field in the conf.json file")
+ .as_u64().expect("area_limit not a number") as usize;
+ let room_limit: usize = conf_file.get("room_limit")
+ .expect("no room_limit field in the conf.json file")
+ .as_u64().expect("room_limit not a number") as usize;
let rooms: RoomMap = Arc::new(RwLock::new(HashMap::new()));
let public_rooms = Arc::new(RwLock::new(HashMap::new()));
use warp::*;
@@ -75,7 +81,7 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> {
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;
+ let space = room_limit - r.read().await.len() + empty_len;
Ok::<_,std::convert::Infallible>(
hyper::Response::builder()
.status(hyper::StatusCode::OK)
@@ -94,6 +100,16 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> {
let rooms = rooms.clone();
let pubs = pubs.clone();
async move {
+ let slots_available = room_limit - rooms.read().await.len();
+ let empty = empty_rooms(rooms.clone()).await;
+ if slots_available < 1 {
+ if slots_available + empty.len() > 0 {
+ remove_room(rooms.clone(), pubs.clone(), empty[0].clone()).await;
+ } else {
+ return Err(reject::custom(NoRoomSlots));
+ }
+ }
+
if let (Some(w),Some(h),Some(num),Some(denom),access,asfm,limit) = (
rinfo.get("rwidth").and_then(|wt| wt.parse::<NonZeroUsize>().ok()),
rinfo.get("rheight").and_then(|ht| ht.parse::<NonZeroUsize>().ok()),
@@ -103,14 +119,14 @@ 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 {
+ 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 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();
+ let n = rinfo.get("rname").unwrap().to_owned();
if n.is_empty() { uid.to_string() } else { n }
};
let players = PlayerMap::default();
@@ -261,12 +277,18 @@ impl Reject for BadFormData {}
struct BoardTooBig;
impl Reject for BoardTooBig {}
+#[derive(Debug)]
+struct NoRoomSlots;
+impl Reject for NoRoomSlots {}
+
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 if let Some(_e) = err.find::<NoRoomSlots>() {
+ Ok(reply::with_status("No more rooms slots", StatusCode::BAD_REQUEST))
} else {
println!("unhandled rejection: {err:?}");
Ok(reply::with_status("Server error", StatusCode::INTERNAL_SERVER_ERROR))
@@ -284,3 +306,14 @@ async fn empty_rooms(rooms: RoomMap) -> Vec<RoomId> {
.collect::<Vec<RoomId>>().await
}
+async fn remove_room<T>(rooms: RoomMap, pubs: Arc<RwLock<HashMap<RoomId,T>>>, id: RoomId) {
+ {
+ let mut rwl = rooms.write().await;
+ rwl.remove(&id);
+ }
+ {
+ let mut pwl = pubs.write().await;
+ pwl.remove(&id);
+ }
+}
+