Files
guardian/crates/dcs-grpc/src/dcs/mod.rs
2023-12-19 19:16:41 +01:00

279 lines
10 KiB
Rust

// Current recommendation as of
// https://github.com/tokio-rs/prost/issues/661#issuecomment-1156606409
#![allow(clippy::derive_partial_eq_without_eq)]
#![allow(clippy::large_enum_variant)]
// use crate::{call::Element, dcs::net::v0::SendChatRequest};
// use std::{cmp::Ordering, collections::HashMap, sync::Arc, time::Duration};
// use tokio::{sync::RwLock, time::sleep};
// use self::{
// common::v0::Coalition,
// mission::v0::{
// mission_service_client::MissionServiceClient, stream_units_response::Update,
// StreamUnitsRequest,
// },
// net::v0::net_service_client::NetServiceClient,
// };
pub mod atmosphere;
pub mod coalition;
pub mod common;
pub mod controller;
pub mod custom;
pub mod group;
pub mod hook;
pub mod mission;
pub mod net;
pub mod srs;
pub mod timer;
pub mod trigger;
pub mod unit;
mod utils;
pub mod world;
// // In the general part of the world DCS is set in, the compass drift is about 5 degrees
// // This should probably be configurable as it depends on the map.
// // (I just remember reading somewhere that the heading drift is about 5°, cant find proof now but in testing it lines up)
// // https://en.wikipedia.org/wiki/Magnetic_declination
// // https://github.com/DCS-gRPC/rust-server/issues/197
// const COMPASS_DRIFT: i32 = -5;
// #[derive(Debug, Clone)]
// pub struct Position {
// pub lat: f64,
// pub long: f64,
// pub altitude: f64,
// }
// impl Position {
// pub fn distance_to_km(&self, other: &Position) -> f64 {
// let radius_of_earth_in_km: f64 = 6371.0;
// let delta_lat = (other.lat - self.lat).to_radians();
// let delta_long = (other.long - self.long).to_radians();
// let a = (delta_lat / 2.0).sin() * (delta_lat / 2.0).sin()
// + self.lat.to_radians().cos()
// * other.lat.to_radians().cos()
// * (delta_long / 2.0).sin()
// * (delta_long / 2.0).sin();
// let c = 2.0 * (a.sqrt().atan2((1.0 - a).sqrt()));
// radius_of_earth_in_km * c
// }
// pub fn distance_to_nmi(&self, other: &Position) -> f64 {
// self.distance_to_km(other) * 0.5399568035
// }
// pub fn get_bearing_to(&self, other: &Position) -> i32 {
// let delta_long = (other.long - self.long).to_radians();
// let y =
// (other.long.to_radians() - self.long.to_radians()).sin() * other.lat.to_radians().cos();
// let x = self.lat.to_radians().cos() * other.lat.to_radians().sin()
// - self.lat.to_radians().sin() * other.lat.to_radians().cos() * delta_long.cos();
// (((y.atan2(x).to_degrees() + 360.0) % 360.0) as i32) + COMPASS_DRIFT
// }
// pub fn feet(&self) -> f64 {
// self.altitude * 3.28084
// }
// pub fn angels(&self) -> i32 {
// (self.feet() / 1000.0).round() as i32
// }
// }
// #[derive(Debug, Clone)]
// pub struct Unit {
// pub id: u32,
// pub name: String,
// pub player: Option<String>,
// pub callsign: String,
// pub group_name: Option<String>,
// pub coalition: i32,
// pub r#type: String,
// pub position: Position,
// pub heading: f64,
// pub speed: f64,
// }
// #[derive(Clone)]
// pub struct RpcClient {
// base_url: String,
// units: Arc<RwLock<HashMap<u32, Unit>>>,
// }
// impl RpcClient {
// pub fn new(base_url: &str) -> Self {
// let units = Arc::new(RwLock::new(HashMap::new()));
// let db = units.clone();
// let url = base_url.to_owned();
// tokio::spawn(async move {
// loop {
// let Ok(mut client) = MissionServiceClient::connect(url.clone()).await else {
// eprintln!("Unable to connect to DCS. Make sure Dcs-gRPC is installed and available, retry in 5 seconds..");
// sleep(Duration::from_secs(5)).await; // retry in 5 seconds
// continue;
// };
// let Ok(mut stream) = client
// .stream_units(StreamUnitsRequest {
// poll_rate: Some(10),
// max_backoff: Some(30),
// category: common::v0::GroupCategory::Airplane as i32,
// })
// .await
// else {
// continue;
// };
// let mut message = stream.get_mut().message().await;
// while let Ok(Some(next)) = &message {
// if let Some(update) = &next.update {
// match update {
// Update::Gone(unit) => {
// db.write().await.remove(&unit.id);
// }
// Update::Unit(unit) => {
// let group_name = unit.group.as_ref().map(|g| g.name.clone());
// let lat = unit.position.as_ref().map_or(0.0, |p| p.lat);
// let long = unit.position.as_ref().map_or(0.0, |p| p.lon);
// let altitude = unit.position.as_ref().map_or(0.0, |p| p.alt);
// let heading = unit.orientation.as_ref().map_or(0.0, |o| o.heading);
// let speed = unit.velocity.as_ref().map_or(0.0, |v| v.speed);
// // println!("updated: {}", &unit.callsign);
// db.write().await.insert(
// unit.id,
// Unit {
// id: unit.id,
// name: unit.name.clone(),
// player: unit.player_name.clone(),
// callsign: unit.callsign.clone(),
// group_name,
// coalition: unit.coalition,
// r#type: unit.r#type.clone(),
// position: Position {
// lat,
// long,
// altitude,
// },
// heading,
// speed,
// },
// );
// }
// }
// }
// message = stream.get_mut().message().await;
// }
// // if we get here, something went wrong, reconnect
// eprintln!("Connection lost");
// }
// });
// Self {
// base_url: base_url.to_string(),
// units,
// }
// }
// // Change to TransmitMessage when it becomes available in gRPC
// // https://github.com/DCS-gRPC/rust-server/blob/main/STATUS.md?plain=1#L519
// pub async fn send_text_message(&self, message: &str) {
// let Ok(mut client) = NetServiceClient::connect(self.base_url.clone()).await else {
// return;
// };
// let request = SendChatRequest {
// message: message.to_string(),
// coalition: Coalition::All as i32,
// // target_player_id: player_id,
// };
// client.send_chat(request).await.ok();
// }
// pub async fn get_unit_by_element(&self, element: &Element) -> Option<Unit> {
// // Return a unit, do the math in the command code
// let units = self.units.read().await;
// units
// .iter()
// .filter(|u| u.1.coalition == Coalition::Blue as i32)
// .map(|u| u.1)
// .find(|e| {
// e.callsign.to_lowercase()
// == format!(
// "{}{}{}",
// element.squadron.to_string(),
// element.group,
// element.unit
// )
// .to_lowercase()
// })
// .cloned()
// }
// pub async fn get_unit_by_pilot(&self, pilot: &str) -> Option<Unit> {
// // Return a unit, do the math in the command code
// let units = self.units.read().await;
// let pilot = pilot.to_string();
// units
// .iter()
// .filter(|u| u.1.coalition == Coalition::Blue as i32)
// .map(|u| u.1)
// .find(|e| {
// let Some(player) = &e.player else {
// return false;
// };
// player == &pilot
// })
// .cloned()
// }
// pub async fn get_nearest_hostile(&self, unit: &Unit) -> Option<Unit> {
// let units = self.units.read().await;
// units
// .iter()
// .filter(|u| u.1.coalition == Coalition::Red as i32) // only reds
// .map(|u| u.1)
// .min_by(|a, b| {
// let a_pos = &a.position; // some hostile A position
// let b_pos = &b.position; // some hostile B position
// let a_dist = a_pos.distance_to_km(&unit.position);
// let b_dist = b_pos.distance_to_km(&unit.position);
// a_dist.partial_cmp(&b_dist).unwrap()
// })
// .cloned()
// }
// pub async fn get_hostiles_in_range_from(&self, unit: &Unit, distance: f64) -> Vec<Unit> {
// let units = self.units.read().await;
// units
// .iter()
// .filter(|u| u.1.coalition == Coalition::Red as i32) // only reds
// .map(|u| u.1)
// .filter(|a| {
// let a_pos = &a.position; // some hostile A position
// let a_dist = a_pos.distance_to_nmi(&unit.position);
// a_dist.partial_cmp(&distance).unwrap() == Ordering::Less
// })
// .cloned()
// .collect::<Vec<_>>()
// }
// }