summaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs40
1 files changed, 29 insertions, 11 deletions
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))