From 799724b122bb46d6e59e56cf0f37bb4e947dd710 Mon Sep 17 00:00:00 2001 From: catvayor Date: Tue, 10 Sep 2024 15:39:59 +0200 Subject: [PATCH] send info when connecting --- src/admin.rs | 2 +- src/coords.rs | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/global.rs | 56 +++------------------------------ src/main.rs | 25 ++------------- src/track.rs | 17 ++++++++++- 5 files changed, 109 insertions(+), 76 deletions(-) create mode 100644 src/coords.rs diff --git a/src/admin.rs b/src/admin.rs index cfdb6a9..7a97069 100644 --- a/src/admin.rs +++ b/src/admin.rs @@ -11,7 +11,7 @@ use rocket::{ }; use rocket_dyn_templates::{context, Template}; -use crate::global::*; +use crate::{coords::admin_view, global::*}; struct AdminAuth(String); diff --git a/src/coords.rs b/src/coords.rs new file mode 100644 index 0000000..44cb3c7 --- /dev/null +++ b/src/coords.rs @@ -0,0 +1,85 @@ +use crate::global::{TrackedState::*, *}; +use rand::Rng; +use rocket::{response::stream::Event, tokio::time::Duration}; + +pub fn base_view(team: &Tracked) -> TrackedInfo { + TrackedInfo { + name: team.name.clone(), + pos: team.pos, + color: team.state.color(), + } +} + +pub fn admin_view(team: &Tracked) -> AdminTrackedInfo { + AdminTrackedInfo { + name: team.name.clone(), + id: team.id.clone(), + pos: team.pos, + color: team.state.admin_color(), + state: team.state.clone(), + } +} + +pub fn apparent_info( + watcher: &Tracked, + team: &Tracked, + blurred_move: (f32, f32), +) -> Option { + if watcher.id == team.id { + None + } else if let Conscrit { captured, .. } = watcher.state { + if captured { + if team.state.invisible() || team.state.npc() { + None + } else if team.state.blurred() { + let mut rng = rand::thread_rng(); + let (lat, lon) = team.pos; + Some(TrackedInfo { + pos: ( + lat + blurred_move.0 * (rng.gen::() * 2.0 - 1.0), + lon + blurred_move.1 * (rng.gen::() * 2.0 - 1.0), + ), + ..base_view(team) + }) + } else { + Some(base_view(team)) + } + } else { + Some(base_view(team)) + } + } else { + Some(admin_view(team).into()) + } +} + +pub fn send_coords_to( + watcher: &Tracked, + evt_queue: &TrackedEventQueue, + tracking: &Tracking, + config: &Config, +) { + if watcher.last_coord.elapsed() > Duration::from_millis(config.fairness_timeout) { + return; + } + let mut infos: Vec = Vec::new(); + for (_, tracked) in tracking.iter() { + if let Some(info) = apparent_info(&watcher, &tracked.read().unwrap(), config.blurred_move) { + infos.push(info); + } + } + evt_queue + .write() + .unwrap() + .push_back(Event::json(&infos).event("coords").into()); +} + +pub fn send_coords(tracking: &Tracking, evt_queue: &TrackingEventQueue, config: &Config) { + for (id, queue) in evt_queue.iter() { + send_coords_to( + &tracking.get(id).unwrap().read().unwrap(), + &queue, + tracking, + config, + ); + } +} diff --git a/src/global.rs b/src/global.rs index 64a8a4f..ac624d3 100644 --- a/src/global.rs +++ b/src/global.rs @@ -1,4 +1,3 @@ -use rand::Rng; use rocket::{ response::stream::Event, serde::{Deserialize, Serialize}, @@ -9,6 +8,8 @@ use std::{ sync::{Arc, RwLock}, }; +use crate::coords::*; + #[derive(Deserialize)] #[serde(crate = "rocket::serde")] pub struct TeamConfig { @@ -168,7 +169,8 @@ impl From for Event { } pub type Tracking = Arc>>; -pub type TrackingEventQueue = Arc>>>; +pub type TrackedEventQueue = RwLock>; +pub type TrackingEventQueue = Arc>; pub type AdminEventQueue = Arc>>; #[derive(Serialize)] @@ -199,56 +201,6 @@ impl From for TrackedInfo { } } -pub fn base_view(team: &Tracked) -> TrackedInfo { - TrackedInfo { - name: team.name.clone(), - pos: team.pos, - color: team.state.color(), - } -} - -pub fn admin_view(team: &Tracked) -> AdminTrackedInfo { - AdminTrackedInfo { - name: team.name.clone(), - id: team.id.clone(), - pos: team.pos, - color: team.state.admin_color(), - state: team.state.clone(), - } -} - -pub fn apparent_info( - watcher: &Tracked, - team: &Tracked, - blurred_move: (f32, f32), -) -> Option { - if watcher.id == team.id { - None - } else if let Conscrit { captured, .. } = watcher.state { - if captured { - if team.state.invisible() || team.state.npc() { - None - } else if team.state.blurred() { - let mut rng = rand::thread_rng(); - let (lat, lon) = team.pos; - Some(TrackedInfo { - pos: ( - lat + blurred_move.0 * (rng.gen::() * 2.0 - 1.0), - lon + blurred_move.1 * (rng.gen::() * 2.0 - 1.0), - ), - ..base_view(team) - }) - } else { - Some(base_view(team)) - } - } else { - Some(base_view(team)) - } - } else { - Some(admin_view(team).into()) - } -} - pub fn evts_to_send(evt_queue: &RwLock>, timeout: Duration) -> Vec { evt_queue .read() diff --git a/src/main.rs b/src/main.rs index 6976aeb..654c74f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,7 +4,7 @@ use rocket::{ fairing::AdHoc, fs::{relative, FileServer}, http::Status, - response::{content, stream::Event}, + response::content, tokio::{ self, select, time::{self, Duration}, @@ -19,8 +19,10 @@ use std::{ }; mod admin; +mod coords; mod global; mod track; +use coords::*; use global::*; #[get("/")] @@ -28,27 +30,6 @@ fn index() -> &'static str { "Hello, world!" } -fn send_coords(tracking: &Tracking, evt_queue: &TrackingEventQueue, config: &Config) { - for (id, queue) in evt_queue.iter() { - let watcher = tracking.get(id).unwrap().read().unwrap(); - if watcher.last_coord.elapsed() > Duration::from_millis(config.fairness_timeout) { - continue - } - let mut infos: Vec = Vec::new(); - for (_, tracked) in tracking.iter() { - if let Some(info) = - apparent_info(&watcher, &tracked.read().unwrap(), config.blurred_move) - { - infos.push(info); - } - } - queue - .write() - .unwrap() - .push_back(Event::json(&infos).event("coords").into()); - } -} - fn clean_expired_evt( evt_queues: &TrackingEventQueue, admin_queue: &AdminEventQueue, diff --git a/src/track.rs b/src/track.rs index 9cc6004..4559c2b 100644 --- a/src/track.rs +++ b/src/track.rs @@ -9,7 +9,10 @@ use rocket::{ }; use rocket_dyn_templates::{context, Template}; -use crate::global::{TrackedState::*, *}; +use crate::{ + coords::*, + global::{TrackedState::*, *}, +}; #[get("/")] fn no_id() -> Status { @@ -44,12 +47,24 @@ fn tracked_view( #[get("//events")] fn tracked_events<'a>( id: &'a str, + tracking: &'a State, evt_queue: &'a State, config: &State, mut shutdown: Shutdown, ) -> Result { if evt_queue.contains_key(&id.to_string()) { let timeout = Duration::from_millis(config.event_timeout); + send_coords_to( + &tracking.get(id).unwrap().read().unwrap(), + &evt_queue.get(id).unwrap(), + tracking, + config, + ); + evt_queue.get(id).unwrap().write().unwrap().push_back( + Event::json(&admin_view(&tracking.get(id).unwrap().read().unwrap())) + .event("self_info") + .into(), + ); Ok(EventStream! { let mut interval = time::interval(timeout); loop {