send info when connecting
This commit is contained in:
parent
ebc217ce2a
commit
799724b122
5 changed files with 109 additions and 76 deletions
|
@ -11,7 +11,7 @@ use rocket::{
|
|||
};
|
||||
use rocket_dyn_templates::{context, Template};
|
||||
|
||||
use crate::global::*;
|
||||
use crate::{coords::admin_view, global::*};
|
||||
|
||||
struct AdminAuth(String);
|
||||
|
||||
|
|
85
src/coords.rs
Normal file
85
src/coords.rs
Normal file
|
@ -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<TrackedInfo> {
|
||||
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::<f32>() * 2.0 - 1.0),
|
||||
lon + blurred_move.1 * (rng.gen::<f32>() * 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<TrackedInfo> = 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,
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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<QueuedEvent> for Event {
|
|||
}
|
||||
|
||||
pub type Tracking = Arc<HashMap<String, RwLock<Tracked>>>;
|
||||
pub type TrackingEventQueue = Arc<HashMap<String, RwLock<VecDeque<QueuedEvent>>>>;
|
||||
pub type TrackedEventQueue = RwLock<VecDeque<QueuedEvent>>;
|
||||
pub type TrackingEventQueue = Arc<HashMap<String, TrackedEventQueue>>;
|
||||
pub type AdminEventQueue = Arc<RwLock<VecDeque<QueuedEvent>>>;
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -199,56 +201,6 @@ impl From<AdminTrackedInfo> 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<TrackedInfo> {
|
||||
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::<f32>() * 2.0 - 1.0),
|
||||
lon + blurred_move.1 * (rng.gen::<f32>() * 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<VecDeque<QueuedEvent>>, timeout: Duration) -> Vec<Event> {
|
||||
evt_queue
|
||||
.read()
|
||||
|
|
25
src/main.rs
25
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<TrackedInfo> = 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,
|
||||
|
|
17
src/track.rs
17
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("/<id>/events")]
|
||||
fn tracked_events<'a>(
|
||||
id: &'a str,
|
||||
tracking: &'a State<Tracking>,
|
||||
evt_queue: &'a State<TrackingEventQueue>,
|
||||
config: &State<Config>,
|
||||
mut shutdown: Shutdown,
|
||||
) -> Result<EventStream![Event + 'a], Status> {
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue