use std::net::SocketAddrV4; use std::sync::Arc; use async_trait::async_trait; use once_cell::sync::Lazy; use rocket::{get, routes, Request, Rocket, State}; use rocket::request::{FromRequest, Outcome}; use rocket::serde::json::Json; use tokio::task::JoinHandle; use serde::Serialize; use tokio::sync::Mutex; use crate::nex::matchmake::MatchmakeManager; use crate::rmc::protocols::HasRmcConnection; use crate::rmc::protocols::notifications::NotificationEvent; struct RnexApiAuth; #[async_trait] impl<'r> FromRequest<'r> for RnexApiAuth{ type Error = (); async fn from_request<'a>(request: &'r Request<'a>) -> Outcome { Outcome::Success(RnexApiAuth) } } #[get("/gatherings")] async fn gatherings(mmm: &State>) -> Json>{ let matches = mmm.sessions.read().await; Json(matches.keys().map(|v| *v).collect()) } #[get("/gathering//players")] async fn players_in_match(mmm: &State>, gid: u32) -> Option>>{ let mmm = mmm.sessions.read().await; let gathering = mmm.get(&gid)?; let gathering = gathering.clone(); drop(mmm); let gathering = gathering.lock().await; Some(Json(gathering.connected_players.iter().filter_map(|p| p.upgrade()).map(|p| p.pid).collect())) } #[get("/player//disconnect")] async fn disconnect_player(_auth: RnexApiAuth, mmm: &State>, pid: u32) -> Option<()>{ // this doesnt work and is broken, there might be some other way to remotely close gatherings... // also if anyone gets this working change it to POST cause the only reason its get is because // that makes testing it easier let mmm = mmm.users.read().await; for player in mmm.values().filter_map(|p| p.upgrade()).filter(|p| p.pid == pid) { player.remote.get_connection().0.close_connection().await; } Some(()) } #[get("/gathering//close")] async fn close_gathering(_auth: RnexApiAuth, mmm: &State>, gid: u32) -> Option<()>{ // this doesnt work and is broken, there might be some other way to remotely close gatherings... // also if anyone gets this working change it to POST cause the only reason its get is because // that makes testing it easier let mmm = mmm.sessions.read().await; let gathering = mmm.get(&gid)?; let gathering = gathering.clone(); drop(mmm); let gathering = gathering.lock().await; gathering.broadcast_notification(&NotificationEvent{ pid_source: gathering.session.gathering.owner_pid, notif_type: 109000, param_1: gathering.session.gathering.self_gid, ..Default::default() }).await; Some(()) } pub async fn start_web(mgr: Arc) -> JoinHandle<()> { tokio::spawn(async move { rocket::build() .mount("/", routes![gatherings, players_in_match, close_gathering, disconnect_player]) .manage(mgr) .launch().await .expect("unable to start webserver"); }) }