diff --git a/CHANGELOG.md b/CHANGELOG.md index be50302b..ca9c67ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Request uses `dcs.common.v0.ObjectCategory[]` and `SearchVolume` (with `InputPosition` for geo points). - Response returns `dcs.common.v0.Target[]` for consistent object union across services. - Lua implementation unwraps grpcui oneof wrapper (`volume.shape`) and supports both wrapped and flattened shapes. +- Added `UnitService.GetAgl` RPC and updated unit stream with same. ## [0.8.1] 2024-11-05 diff --git a/lua/DCS-gRPC/exporters/object.lua b/lua/DCS-gRPC/exporters/object.lua index cc791e45..f3e284ef 100644 --- a/lua/DCS-gRPC/exporters/object.lua +++ b/lua/DCS-gRPC/exporters/object.lua @@ -17,6 +17,10 @@ GRPC.exporters.position = function(pos) end GRPC.exporters.unit = function(unit) + local pos = unit:getPoint() + local alt = pos.y + local land = land.getHeight({x = pos.x, y = pos.z}) or 0 + alt = alt - land return { id = tonumber(unit:getID()), name = unit:getName(), @@ -27,6 +31,7 @@ GRPC.exporters.unit = function(unit) group = GRPC.exporters.group(Unit.getGroup(unit)), numberInGroup = unit:getNumber(), rawTransform = GRPC.exporters.rawTransform(unit), + agl = alt, } end diff --git a/lua/DCS-gRPC/methods/unit.lua b/lua/DCS-gRPC/methods/unit.lua index f0bcb4ed..a6ac93e0 100644 --- a/lua/DCS-gRPC/methods/unit.lua +++ b/lua/DCS-gRPC/methods/unit.lua @@ -149,3 +149,19 @@ GRPC.methods.unitDestroy = function(params) unit:destroy() return GRPC.success({}) end + +GRPC.methods.getUnitAgl = function (params) + local unit = Unit.getByName(params.name) + if unit == nil then + return GRPC.errorNotFound("unit `" .. tostring(params.name) .. "` does not exist") + end + + local pos = unit:getPoint() + local asl = pos.y + local surfaceheight = land.getHeight({x = pos.x, y = pos.z}) or 0 + if surfaceheight < 0 then + surfaceheight = 0 + end + local agl = asl - surfaceheight + return GRPC.success({agl = agl}) +end \ No newline at end of file diff --git a/protos/dcs/common/v0/common.proto b/protos/dcs/common/v0/common.proto index c9e13f79..b4f21dde 100644 --- a/protos/dcs/common/v0/common.proto +++ b/protos/dcs/common/v0/common.proto @@ -236,6 +236,8 @@ message Unit { // The number of this unit in the group. Does not change as units are // destroyed uint32 number_in_group = 11; + // Altitude of unit above ground level + double agl = 12; } /** diff --git a/protos/dcs/unit/v0/unit.proto b/protos/dcs/unit/v0/unit.proto index 75ef9bdc..310521d0 100644 --- a/protos/dcs/unit/v0/unit.proto +++ b/protos/dcs/unit/v0/unit.proto @@ -34,6 +34,8 @@ service UnitService { // https://wiki.hoggitworld.com/view/DCS_func_getDrawArgumentValue rpc GetDrawArgumentValue(GetDrawArgumentValueRequest) returns (GetDrawArgumentValueResponse) {} + + rpc GetAgl(GetAglRequest) returns (GetAglResponse) {} } message GetRadarRequest { @@ -115,4 +117,12 @@ message DestroyRequest { } message DestroyResponse { +} + +message GetAglRequest { + string name = 1; +} + +message GetAglResponse { + double agl = 1; } \ No newline at end of file diff --git a/src/authentication.rs b/src/authentication.rs index 5c37db9d..66299b4b 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -26,11 +26,12 @@ impl RequestInterceptor for AuthInterceptor { } } - if client.is_some() { - log::debug!("Authenticated client: {}", client.unwrap()); - Ok(req) - } else { - Err(Status::unauthenticated("Unauthenticated")) + match client { + Some(client_name) => { + log::debug!("Authenticated client: {}", client_name); + Ok(req) + } + _ => Err(Status::unauthenticated("Unauthenticated")), } } _ => Err(Status::unauthenticated("Unauthenticated")), diff --git a/src/rpc/custom.rs b/src/rpc/custom.rs index 336c3a61..1acfe7a2 100644 --- a/src/rpc/custom.rs +++ b/src/rpc/custom.rs @@ -52,6 +52,7 @@ impl CustomService for MissionRpc { Ok(Response::new(custom::v0::EvalResponse { json })) } + #[allow(clippy::result_large_err)] async fn get_magnetic_declination( &self, request: Request, diff --git a/src/rpc/unit.rs b/src/rpc/unit.rs index 13521f66..cf064d36 100644 --- a/src/rpc/unit.rs +++ b/src/rpc/unit.rs @@ -77,4 +77,12 @@ impl UnitService for MissionRpc { let res = self.request("unitDestroy", request).await?; Ok(Response::new(res)) } + + async fn get_agl( + &self, + request: Request, + ) -> Result, Status> { + let res = self.request("getUnitAgl", request).await?; + Ok(Response::new(res)) + } } diff --git a/src/stream.rs b/src/stream.rs index bb60f0d2..dcc816b9 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -13,7 +13,7 @@ use stubs::mission::v0::stream_events_response::{BirthEvent, DeadEvent, Event}; use stubs::mission::v0::stream_units_response::{UnitGone, Update}; use stubs::mission::v0::{StreamUnitsRequest, StreamUnitsResponse}; use stubs::unit::v0::unit_service_server::UnitService; -use stubs::unit::v0::{GetTransformRequest, GetTransformResponse}; +use stubs::unit::v0::{GetAglRequest, GetAglResponse, GetTransformRequest, GetTransformResponse}; use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::error::SendError; use tokio::time::MissedTickBehavior; @@ -309,6 +309,17 @@ impl UnitState { velocity, } = res.into_inner(); + let res = UnitService::get_agl( + &ctx.rpc, + Request::new(GetAglRequest { + name: self.unit.name.clone(), + }), + ) + .await?; + let GetAglResponse { agl } = res.into_inner(); + + self.unit.agl = agl; + self.update_time = time; if let Some((before, after)) = self.unit.position.as_mut().zip(position) { diff --git a/stubs/src/common.rs b/stubs/src/common.rs index 89577558..49a97a7f 100644 --- a/stubs/src/common.rs +++ b/stubs/src/common.rs @@ -91,6 +91,7 @@ pub mod v0 { group: Option, number_in_group: u32, raw_transform: Option, + agl: f64, } impl From for Unit { @@ -105,6 +106,7 @@ pub mod v0 { group, number_in_group, raw_transform, + agl, } = i; let transform = Transform::from(raw_transform.unwrap_or_default()); Unit { @@ -119,6 +121,7 @@ pub mod v0 { player_name, group, number_in_group, + agl, } } } diff --git a/stubs/src/lib.rs b/stubs/src/lib.rs index 03e65040..fdba881b 100644 --- a/stubs/src/lib.rs +++ b/stubs/src/lib.rs @@ -62,7 +62,8 @@ mod tests { "coalition": 3, "type": "FA-18C_hornet", "playerName": "New callsign", - "numberInGroup": 1 + "numberInGroup": 1, + "agl": 0.0 } } }, @@ -111,6 +112,7 @@ mod tests { speed: Default::default(), velocity: Some(Default::default()) }), + agl: 0.0, })) }), visibility: Some(event::mark_add_event::Visibility::Coalition(