Logging
This commit is contained in:
3
Cargo.lock
generated
3
Cargo.lock
generated
@@ -2288,6 +2288,8 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -2327,6 +2329,7 @@ dependencies = [
|
|||||||
"tokio-stream",
|
"tokio-stream",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tonic",
|
"tonic",
|
||||||
|
"tracing",
|
||||||
"uuid",
|
"uuid",
|
||||||
"windows 0.52.0",
|
"windows 0.52.0",
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ serde_json = "1.0"
|
|||||||
tokio = { version = "1.34", features = ["macros", "rt-multi-thread", "signal"] }
|
tokio = { version = "1.34", features = ["macros", "rt-multi-thread", "signal"] }
|
||||||
clap = { version = "4.4", features = ["derive"] }
|
clap = { version = "4.4", features = ["derive"] }
|
||||||
shlex = "1.2"
|
shlex = "1.2"
|
||||||
|
tracing = "0.1.40"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bevy.workspace = true
|
bevy.workspace = true
|
||||||
@@ -50,4 +51,6 @@ tokio.workspace = true
|
|||||||
serde.workspace = true
|
serde.workspace = true
|
||||||
guardian_commands.workspace = true
|
guardian_commands.workspace = true
|
||||||
guardian_core.workspace = true
|
guardian_core.workspace = true
|
||||||
|
tracing.workspace = true
|
||||||
toml = "0.8"
|
toml = "0.8"
|
||||||
|
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }
|
||||||
|
|||||||
@@ -2,20 +2,13 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|||||||
std::env::set_var("PROTOC", protoc_bundled::PROTOC);
|
std::env::set_var("PROTOC", protoc_bundled::PROTOC);
|
||||||
std::env::set_var("PROTOC_INCLUDE", protoc_bundled::PROTOC_INCLUDE);
|
std::env::set_var("PROTOC_INCLUDE", protoc_bundled::PROTOC_INCLUDE);
|
||||||
|
|
||||||
println!("cargo:rerun-if-changed=migrations");
|
|
||||||
println!("cargo:rerun-if-changed=protos/dcs");
|
println!("cargo:rerun-if-changed=protos/dcs");
|
||||||
|
|
||||||
build_dcs_grpc_db()?;
|
build_dcs_grpc_db()?;
|
||||||
|
|
||||||
// build_commands()?;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// fn build_commands() -> Result<(), Box<dyn std::error::Error>> {
|
|
||||||
// Ok(())
|
|
||||||
// }
|
|
||||||
|
|
||||||
fn build_dcs_grpc_db() -> Result<(), Box<dyn std::error::Error>> {
|
fn build_dcs_grpc_db() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
tonic_build::configure()
|
tonic_build::configure()
|
||||||
.type_attribute(".", "#[derive(::serde::Serialize, ::serde::Deserialize)]")
|
.type_attribute(".", "#[derive(::serde::Serialize, ::serde::Deserialize)]")
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ serde.workspace = true
|
|||||||
serde_json.workspace = true
|
serde_json.workspace = true
|
||||||
shlex.workspace = true
|
shlex.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
tracing.workspace = true
|
||||||
async-compat = "0.2.1"
|
async-compat = "0.2.1"
|
||||||
serde_repr = "0.1"
|
serde_repr = "0.1"
|
||||||
crossbeam-channel = "0.5.9"
|
crossbeam-channel = "0.5.9"
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use dcs_grpc::dcs::{
|
|||||||
StreamUnitsRequest,
|
StreamUnitsRequest,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
use tracing::{debug, info, warn};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
enum Response {
|
enum Response {
|
||||||
@@ -52,11 +53,11 @@ fn connect_to_grpc(mut commands: Commands, tokio: Res<TokioResource>, url: Res<G
|
|||||||
handle.spawn(async move {
|
handle.spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let Ok(mut client) = MissionServiceClient::connect(url.clone()).await else {
|
let Ok(mut client) = MissionServiceClient::connect(url.clone()).await else {
|
||||||
eprintln!("Connection failed: {}", url);
|
warn!("Connection failed: {}", url); // warn
|
||||||
tokio::time::sleep(Duration::from_secs(5)).await;
|
tokio::time::sleep(Duration::from_secs(5)).await;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
println!("Connected to DCS: {}", url);
|
info!("Connected to DCS: {}", url);
|
||||||
|
|
||||||
let Ok(mut stream) = client
|
let Ok(mut stream) = client
|
||||||
.stream_units(StreamUnitsRequest {
|
.stream_units(StreamUnitsRequest {
|
||||||
@@ -77,17 +78,16 @@ fn connect_to_grpc(mut commands: Commands, tokio: Res<TokioResource>, url: Res<G
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(None) => {
|
Ok(None) => {
|
||||||
// eprintln!("Empty?");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
eprintln!("Error from gRPC: {:?}", e);
|
debug!("Error from gRPC: {:?}", e); // verbose or debug log
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
eprintln!("Disconnected from DCS: {}", url);
|
warn!("Disconnected from DCS: {}", url); // warn
|
||||||
tx.send(Response::Disconnected).ok();
|
tx.send(Response::Disconnected).ok();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use dcs_grpc::dcs::{
|
|||||||
common::v0::Coalition,
|
common::v0::Coalition,
|
||||||
net::v0::{net_service_client::NetServiceClient, SendChatRequest},
|
net::v0::{net_service_client::NetServiceClient, SendChatRequest},
|
||||||
};
|
};
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
use crate::{components::GrpcBaseUrl, TokioResource};
|
use crate::{components::GrpcBaseUrl, TokioResource};
|
||||||
|
|
||||||
@@ -57,7 +58,7 @@ fn send_text_message(
|
|||||||
// target_player_id: player_id,
|
// target_player_id: player_id,
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("> {}", message);
|
info!("> {}", message);
|
||||||
client.send_chat(request).await.ok();
|
client.send_chat(request).await.ok();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ mod voice_command;
|
|||||||
use guardian_commands::{call::parse_call, ConsoleCommandEntered, ConsoleConfiguration};
|
use guardian_commands::{call::parse_call, ConsoleCommandEntered, ConsoleConfiguration};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use simsearch::SimSearch;
|
use simsearch::SimSearch;
|
||||||
|
use tracing::{error, info, warn};
|
||||||
pub use voice_command::VoiceCommand;
|
pub use voice_command::VoiceCommand;
|
||||||
|
|
||||||
use crossbeam_channel::Receiver;
|
use crossbeam_channel::Receiver;
|
||||||
@@ -166,7 +167,7 @@ fn listen_srs(
|
|||||||
radio.handle = Some(tokio.0.spawn(async move {
|
radio.handle = Some(tokio.0.spawn(async move {
|
||||||
loop {
|
loop {
|
||||||
let Ok(tcp) = TcpStream::connect(addr).await else {
|
let Ok(tcp) = TcpStream::connect(addr).await else {
|
||||||
eprintln!("Connection failed: {}", addr);
|
warn!("Connection failed: {}", addr);
|
||||||
sleep(Duration::from_secs(5)).await;
|
sleep(Duration::from_secs(5)).await;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@@ -188,7 +189,7 @@ fn listen_srs(
|
|||||||
client: client.clone(),
|
client: client.clone(),
|
||||||
version: SRS_VERSION.to_string(),
|
version: SRS_VERSION.to_string(),
|
||||||
})).await {
|
})).await {
|
||||||
eprintln!("Srs error: {:?}", e);
|
error!("Srs error: {:?}", e);
|
||||||
sleep(Duration::from_secs(5)).await;
|
sleep(Duration::from_secs(5)).await;
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
@@ -246,7 +247,7 @@ fn listen_srs(
|
|||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
match &data {
|
match &data {
|
||||||
Message::VersionMismatch(VersionMismatchMessage { version, .. }) => {
|
Message::VersionMismatch(VersionMismatchMessage { version, .. }) => {
|
||||||
eprintln!("Version mismatch {} != {}", SRS_VERSION, version);
|
error!("Version mismatch {} != {}", SRS_VERSION, version);
|
||||||
},
|
},
|
||||||
Message::Sync(SyncMessage { clients, .. }) => {
|
Message::Sync(SyncMessage { clients, .. }) => {
|
||||||
for client in clients.iter() {
|
for client in clients.iter() {
|
||||||
@@ -324,7 +325,7 @@ fn listen_srs(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
eprintln!("Disconnected from SRS: {}", addr);
|
warn!("Disconnected from SRS: {}", addr);
|
||||||
}
|
}
|
||||||
#[allow(unreachable_code)]
|
#[allow(unreachable_code)]
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -495,7 +496,10 @@ fn handle_voice_command(
|
|||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
println!("< {}\n\t{}", rawr.clone(), cmd.clone());
|
let raw = rawr.trim().to_string();
|
||||||
|
|
||||||
|
info!("Received: {}", raw);
|
||||||
|
info!("Interpreted as: {}", cmd);
|
||||||
|
|
||||||
let Ok((_, call)) = parse_call(cmd) else {
|
let Ok((_, call)) = parse_call(cmd) else {
|
||||||
// no command, casual conversations?
|
// no command, casual conversations?
|
||||||
@@ -505,9 +509,6 @@ fn handle_voice_command(
|
|||||||
let cmd = call.command;
|
let cmd = call.command;
|
||||||
|
|
||||||
if config.commands.get(&cmd).is_some() {
|
if config.commands.get(&cmd).is_some() {
|
||||||
let raw = rawr.clone();
|
|
||||||
let raw = raw.trim().to_string();
|
|
||||||
|
|
||||||
command_entered.send(ConsoleCommandEntered {
|
command_entered.send(ConsoleCommandEntered {
|
||||||
command_name: cmd.clone(),
|
command_name: cmd.clone(),
|
||||||
raw,
|
raw,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
use tracing::{debug, error, warn};
|
||||||
use windows::core::HSTRING;
|
use windows::core::HSTRING;
|
||||||
use windows::Media::SpeechSynthesis::SpeechSynthesizer;
|
use windows::Media::SpeechSynthesis::SpeechSynthesizer;
|
||||||
use windows::Storage::Streams::DataReader;
|
use windows::Storage::Streams::DataReader;
|
||||||
@@ -58,21 +59,21 @@ pub async fn synthesize(text: &str, voice: &Voice) -> Result<Vec<Vec<u8>>, WinEr
|
|||||||
let lang = v.Language()?.to_string();
|
let lang = v.Language()?.to_string();
|
||||||
if lang.starts_with("en-") {
|
if lang.starts_with("en-") {
|
||||||
let name = v.DisplayName()?.to_string();
|
let name = v.DisplayName()?.to_string();
|
||||||
println!("Using WIN voice: {}", name);
|
debug!("Using WIN voice: {}", name);
|
||||||
voice_info = Some(v);
|
voice_info = Some(v);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if voice_info.is_none() {
|
if voice_info.is_none() {
|
||||||
println!("Could not find any english Windows TTS voice");
|
error!("Could not find any english Windows TTS voice");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if voice_info.is_none() {
|
if voice_info.is_none() {
|
||||||
let all_voices = SpeechSynthesizer::AllVoices()?;
|
let all_voices = SpeechSynthesizer::AllVoices()?;
|
||||||
let len = all_voices.Size()? as usize;
|
let len = all_voices.Size()? as usize;
|
||||||
println!(
|
warn!(
|
||||||
"Available WIN voices are (you don't have to include the `Microsoft` prefix in \
|
"Available WIN voices are (you don't have to include the `Microsoft` prefix in \
|
||||||
the name):"
|
the name):"
|
||||||
);
|
);
|
||||||
@@ -84,7 +85,7 @@ pub async fn synthesize(text: &str, voice: &Voice) -> Result<Vec<Vec<u8>>, WinEr
|
|||||||
}
|
}
|
||||||
|
|
||||||
let name = v.DisplayName()?.to_string();
|
let name = v.DisplayName()?.to_string();
|
||||||
println!("- {} ({})", name, lang);
|
warn!("- {} ({})", name, lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use bevy::ecs::{
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use guardian_commands::{ConsoleCommand, NamedCommand};
|
use guardian_commands::{ConsoleCommand, NamedCommand};
|
||||||
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::braa::Braa;
|
use crate::braa::Braa;
|
||||||
|
|
||||||
@@ -37,12 +38,12 @@ pub fn bogey_dope(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let Ok((p_callsign, p_pos)) = player.get(*pilot) else {
|
let Ok((p_callsign, p_pos)) = player.get(*pilot) else {
|
||||||
eprintln!("no player, died?");
|
debug!("no player, died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(a_callsign) = awacs.get(*operator) else {
|
let Ok(a_callsign) = awacs.get(*operator) else {
|
||||||
eprintln!("no awacs, they died?");
|
debug!("no awacs, they died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use bevy::ecs::system::{Commands, Query, Resource};
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use guardian_commands::{ConsoleCommand, NamedCommand};
|
use guardian_commands::{ConsoleCommand, NamedCommand};
|
||||||
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::tripwire::Tripwire;
|
use crate::tripwire::Tripwire;
|
||||||
|
|
||||||
@@ -25,20 +26,21 @@ pub fn clear_tripwire(
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(pilot) = &cmd.pilot else {
|
let Some(pilot) = &cmd.pilot else {
|
||||||
return; // no pilot
|
debug!("no pilot");
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
let Some(operator) = &cmd.operator else {
|
let Some(operator) = &cmd.operator else {
|
||||||
eprintln!("no operator");
|
debug!("no operator");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(p_callsign) = callsign.get(*pilot) else {
|
let Ok(p_callsign) = callsign.get(*pilot) else {
|
||||||
eprintln!("no player, died?");
|
debug!("no player, died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(a_callsign) = callsign.get(*operator) else {
|
let Ok(a_callsign) = callsign.get(*operator) else {
|
||||||
eprintln!("no awacs, they died?");
|
debug!("no awacs, they died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use bevy::ecs::system::{Commands, Query, Resource};
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use guardian_commands::{ConsoleCommand, NamedCommand};
|
use guardian_commands::{ConsoleCommand, NamedCommand};
|
||||||
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
pub struct RadioCheck;
|
pub struct RadioCheck;
|
||||||
@@ -23,19 +24,21 @@ pub fn radio_check(
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(pilot) = &cmd.pilot else {
|
let Some(pilot) = &cmd.pilot else {
|
||||||
return; // no pilot
|
debug!("no pilot");
|
||||||
|
return;
|
||||||
};
|
};
|
||||||
let Some(operator) = &cmd.operator else {
|
let Some(operator) = &cmd.operator else {
|
||||||
|
debug!("no operator");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(p_callsign) = callsign.get(*pilot) else {
|
let Ok(p_callsign) = callsign.get(*pilot) else {
|
||||||
eprintln!("no player, died?");
|
debug!("no player, died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(a_callsign) = callsign.get(*operator) else {
|
let Ok(a_callsign) = callsign.get(*operator) else {
|
||||||
eprintln!("no awacs, they died?");
|
debug!("no awacs, they died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use bevy::ecs::system::{Commands, Query, Resource};
|
|||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use guardian_commands::{ConsoleCommand, NamedCommand};
|
use guardian_commands::{ConsoleCommand, NamedCommand};
|
||||||
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
use guardian_core::{components::*, dcs::text::TextMessage, srs::voice::VoiceMessage};
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::tripwire::Tripwire;
|
use crate::tripwire::Tripwire;
|
||||||
|
|
||||||
@@ -25,25 +26,25 @@ pub fn set_tripwire(
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(pilot) = &cmd.pilot else {
|
let Some(pilot) = &cmd.pilot else {
|
||||||
return; // no pilot
|
debug!("no pilot");
|
||||||
};
|
|
||||||
let Some(operator) = &cmd.operator else {
|
|
||||||
eprintln!("no operator");
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
let Some(readback) = &cmd.raw else {
|
let Some(operator) = &cmd.operator else {
|
||||||
eprintln!("no readback");
|
debug!("no operator");
|
||||||
// no raw found, wut
|
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(p_callsign) = callsign.get(*pilot) else {
|
let Ok(p_callsign) = callsign.get(*pilot) else {
|
||||||
eprintln!("no player, died?");
|
debug!("no player, died?");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
let Ok(a_callsign) = callsign.get(*operator) else {
|
let Ok(a_callsign) = callsign.get(*operator) else {
|
||||||
eprintln!("no awacs, they died?");
|
debug!("no awacs, they died?");
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
let Some(readback) = &cmd.raw else {
|
||||||
|
debug!("no readback");
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -51,10 +52,8 @@ pub fn set_tripwire(
|
|||||||
|
|
||||||
// check the last part, if it's a number, interpret as miles
|
// check the last part, if it's a number, interpret as miles
|
||||||
let Some(last) = parts.nth_back(0) else {
|
let Some(last) = parts.nth_back(0) else {
|
||||||
eprintln!("no last part?");
|
debug!("no last part");
|
||||||
// there is no last.. dafuq?
|
return;
|
||||||
// there is always a last, otherwise we wouldnt be here
|
|
||||||
return; // readback error
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let distance = match last.parse::<i32>() {
|
let distance = match last.parse::<i32>() {
|
||||||
|
|||||||
14
src/main.rs
14
src/main.rs
@@ -23,6 +23,18 @@ use tripwire::TripwirePlugin;
|
|||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
|
let subscriber = tracing_subscriber::FmtSubscriber::builder()
|
||||||
|
.with_env_filter(
|
||||||
|
"trace,bevy=error,tokio_util=error,h2=error,hyper=error,tower=error,tonic=error",
|
||||||
|
)
|
||||||
|
// .with_span_events(tracing_subscriber::fmt::format::FmtSpan::CLOSE)
|
||||||
|
.with_file(false)
|
||||||
|
.with_line_number(false)
|
||||||
|
.with_target(true)
|
||||||
|
.finish();
|
||||||
|
|
||||||
|
tracing::subscriber::set_global_default(subscriber)?;
|
||||||
|
|
||||||
let config = Config::load("config.toml".into())?;
|
let config = Config::load("config.toml".into())?;
|
||||||
|
|
||||||
App::new()
|
App::new()
|
||||||
@@ -50,6 +62,8 @@ fn give_awacs_radio(
|
|||||||
continue; // not configured for this unit
|
continue; // not configured for this unit
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bevy::log::info!("{} now has a radio", callsign);
|
||||||
|
|
||||||
commands.entity(ent).insert(Radio::new(
|
commands.entity(ent).insert(Radio::new(
|
||||||
channel.frequency,
|
channel.frequency,
|
||||||
channel.modulation,
|
channel.modulation,
|
||||||
|
|||||||
Reference in New Issue
Block a user