diff options
| -rw-r--r-- | assets/index.html | 16 | ||||
| -rw-r--r-- | assets/style.css | 2 | ||||
| -rw-r--r-- | src/conn.rs | 65 | ||||
| -rw-r--r-- | src/main.rs | 10 | 
4 files changed, 54 insertions, 39 deletions
| diff --git a/assets/index.html b/assets/index.html index f85b733..69f1958 100644 --- a/assets/index.html +++ b/assets/index.html @@ -18,18 +18,20 @@          let pcounts = info[1];          Object.keys(rooms).forEach(x => {            let roominfo = JSON.parse(rooms[x]); -          let pc = Number(pcounts[x]); +          let pc = Number(pcounts[x][0]); +          let pcap = Number(pcounts[x][1]);            let bc = roominfo.board_conf; -          let a = document.createElement('a');            let h1 = document.createElement('h1'); -          let ptxt = (pc > 0)? ((pc > 1)? `${pc} players`: `${pc} player`) : "no players"; +          let full = pc == pcap; +          let ptxt = `${pc}/${pcap} players` + ((full)? " (full)" : "");            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); -          a.append(h4); -          a.href = 'room/' + x; -          rlist.append(a); +          let entry = (full)? document.createElement('span') : document.createElement('a'); +          entry.append(h1); +          entry.append(h4); +          entry.href = 'room/' + x; +          rlist.append(entry);            rlist.append(document.createElement('br'));          });        }); diff --git a/assets/style.css b/assets/style.css index cf9f8a6..66130eb 100644 --- a/assets/style.css +++ b/assets/style.css @@ -36,7 +36,7 @@ body {    padding: 0.1em 0.1em;  } -#rlist a { +#rlist a, span {    text-decoration: none;    line-height: 0.4;    color: #dfdfff; diff --git a/src/conn.rs b/src/conn.rs index 71beb5d..47d0ddc 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -8,13 +8,22 @@ use futures::{SinkExt, StreamExt, TryStreamExt, stream::SplitStream};  use warp::ws::{ WebSocket, Message };  use ammonia; -pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>) { +pub async fn lobby(socket: WebSocket, addr: SocketAddr, rinfo: (RoomId,Arc<RwLock<Room>>)) { +    let (room_id, room) = rinfo;      let (tx, mut rx) = tokio::sync::mpsc::unbounded_channel();      // server <-> client comms      let (mut outgoing, mut incoming) = socket.split(); -    println!("Incoming TCP connection from: {}", addr); +    println!("{room_id} I: Incoming TCP connection from: {}", addr); + +    let full = { +        let rl = room.read().await; +        let pcap = rl.conf.player_cap; +        let pl = rl.players.read().await; +        pl.len() >= pcap +    }; +    if full { return }      let mut registered = false;      while !registered { @@ -37,7 +46,7 @@ pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>)                                  if n.is_empty() { def } else { n }                              }                          }; -                        println!("registered \"{name}@{addr}\""); +                        println!("{room_id} I: registered \"{name}@{addr}\"");                          let uid = {                              // new scope cuz paranoid bout deadlocks                              let conn = Conn { addr, tx: tx.clone() }; @@ -45,30 +54,34 @@ pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>)                          };                          tx.send(Message::text(format!("regack {} {uid} {}", name.replace(" ", " "), room.read().await.conf.board_conf))).expect("couldn't send register ack");                          if let Err(e) = room.read().await.cmd_stream.send(MetaMove::Dump) { -                            println!("couldn't request game dump in behalf of {addr}: {e}"); +                            println!("{room_id} E: couldn't request game dump in behalf of {addr}: {e}");                          }                          registered = true;                      }                  }              },              Err(e) => { -                println!("error reading socket {addr}: {e}"); +                println!("{room_id} E: error reading socket {addr}: {e}");              }          }      } -    let drive_game = handle_room(incoming, addr, room.clone()); -    let send_to_client = async move { -        while let Some(m) = rx.recv().await { -            if let Err(e) = outgoing.send(m).await { -                println!("something went bad lol: {e}"); +    let drive_game = handle_room(incoming, addr, (room_id.clone(),room.clone())); + +    let send_to_client = { +        let room_id = room_id.clone(); +        async move { +            while let Some(m) = rx.recv().await { +                if let Err(e) = outgoing.send(m).await { +                    println!("{room_id} E: something went bad lol: {e}"); +                }              }          }      };      tokio::select! {          _ = drive_game => (), -        _ = send_to_client => { println!("anomalous close for {addr}"); } +        _ = send_to_client => { println!("{room_id} E: anomalous close for {addr}"); }      };      let room_lock = room.read().await; @@ -76,16 +89,17 @@ pub async fn lobby(socket: WebSocket, addr: SocketAddr, room: Arc<RwLock<Room>>)      if let Some(disconn_p) = players.remove(&addr) {          for p in players.values() {              if let Err(e) = p.conn.tx.send(Message::text(format!("logoff {}", disconn_p.uid))) { -                println!("couldn't deliver logoff info to {}: {}", p, e); +                println!("{room_id} E: couldn't deliver logoff info to {}: {}", p, e);              }          } -        println!("{disconn_p} disconnected"); +        println!("{room_id} I: {disconn_p} disconnected");      } else { -        println!("{addr} disconnected"); +        println!("{room_id} I: {addr} disconnected");      }  } -pub async fn handle_room(mut incoming: SplitStream<WebSocket>, addr: SocketAddr, room: Arc<RwLock<Room>>) { +pub async fn handle_room(mut incoming: SplitStream<WebSocket>, addr: SocketAddr, rinfo: (RoomId, Arc<RwLock<Room>>)) { +    let (room_id, room) = rinfo;      let (players, cmd_tx) = {          let room = room.read().await;          (room.players.clone(), room.cmd_stream.clone()) @@ -124,53 +138,50 @@ pub async fn handle_room(mut incoming: SplitStream<WebSocket>, addr: SocketAddr,                                      for peer_tx in players.iter().filter(|(s, _)| **s != addr).map(|(_,p)| &p.conn.tx) {                                          let r = peer_tx.send(Message::text(format!("pos {uid} {sanitized_name} {} {} {}", clr, pos.0, pos.1)));                                          if let Err(e) = r { -                                            println!("error sending pos update: {e}"); +                                            println!("{room_id} E: error sending pos update: {e}");                                          }                                      }                                  }                              },                              None => { -                                println!("bad position update from {}", me); +                                println!("{room_id} E: bad position update from {me}");                              },                          }                      },                      "reveal" => {                          match parse_pos(fields) {                              Some(pos) => { -                                //println!("{cmd} from {me}");                                  if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::Reveal, pos }, addr)) { -                                    println!("couldn't process {me}'s reveal command: {e}"); +                                    println!("{room_id} E: couldn't process {me}'s reveal command: {e}");                                  };                              },                              None => { -                                println!("bad reveal from {me}"); +                                println!("{room_id} E: bad reveal from {me}");                              }                          }                      },                      "flag" => {                          match parse_pos(fields) {                              Some(pos) => { -                                //println!("{cmd} from {me}");                                  if let Err(e) = cmd_tx.send(MetaMove::Move(Move { t: MoveType::ToggleFlag, pos }, addr)) { -                                    println!("couldn't process {me}'s flag command: {e}"); +                                    println!("{room_id} E: couldn't process {me}'s flag command: {e}");                                  };                              },                              None => { -                                println!("bad flag from {me}"); +                                println!("{room_id} E: bad flag from {me}");                              }                          }                      },                      "reset" => { -                        //println!("{cmd} from {me}");                          if let Err(e) = cmd_tx.send(MetaMove::Reset) { -                            println!("couldn't request game dump in behalf of {me}: {e}"); +                            println!("{room_id} E: couldn't request game dump in behalf of {me}: {e}");                          }                      }, -                    e => println!("unknown command {e:?} from {me}, \"{cmd}\""), +                    e => println!("{room_id} E: unknown command {e:?} from {me}: \"{cmd}\""),                  }              }          } else { -            println!("reached end of stream for {addr}"); +            println!("{room_id} E: reached end of stream for {addr}");              break;          }      } diff --git a/src/main.rs b/src/main.rs index 36ee5ce..9c9e5b1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -55,7 +55,9 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> {                      .then(|(id, _):(&RoomId,_)| {                          let roomsl = roomsl.clone();                          async move { -                            (id.clone(), roomsl.get(id).unwrap().read().await.players.read().await.len()) +                            let room = roomsl.get(id).unwrap().read().await; +                            let pcount = room.players.read().await.len(); +                            (id.clone(), (pcount, room.conf.player_cap))                          }                      })                      .collect::<HashMap<RoomId,_>>().await; @@ -157,13 +159,13 @@ async fn tokio_main(conf: Config) -> Result<(), Box<dyn Error>> {                      let id = RoomId {0: id};                      match rooms.read().await.get(&id).map(|x| x.clone()) {                          Some(r) => { -                            println!("conn from {saddr:?} into {id}"); +                            println!("{id} I: conn from {saddr:?}");                              Ok(websocket.on_upgrade(move |socket| { -                                conn::lobby(socket, saddr.expect("socket without address"), r.clone()) +                                conn::lobby(socket, saddr.expect("socket without address"), (id,r.clone()))                              }))                          },                          None => { -                            println!("conn from {saddr:?} into inexistent room {id}"); +                            println!("I: conn from {saddr:?} into inexistent room {id}");                              Err(reject())                          }                      } | 
