public string ProcessRadioCall(IRadioCall radioCall) { using (var activity = Constants.ActivitySource.StartActivity("Controller.ProcessRadioCall")) { if (radioCall.Intent == "None") { return(Task.Run(() => None(radioCall)).Result); } if (string.IsNullOrEmpty(radioCall.ReceiverName)) { return(Task.Run(() => None(radioCall)).Result); } if (radioCall.Sender == null) { activity?.AddTag("Response", "Not Recognized"); return(Task.Run(() => NullSender(radioCall)).Result); } if (radioCall.Sender.Id == null) { activity?.AddTag("Response", "Not On Scope"); return(Task.Run(() => UnverifiedSender(radioCall)).Result); } switch (radioCall.Intent) { case "RadioCheck": return(Task.Run(() => RadioCheck(radioCall)).Result); case "BogeyDope": return(Task.Run(() => BogeyDope(radioCall)).Result); case "BearingToAirbase": return(Task.Run(() => BearingToAirbase(radioCall)).Result); case "BearingToFriendlyPlayer": return(Task.Run(() => BearingToFriendlyPlayer(radioCall)).Result); case "SetWarningRadius": return(Task.Run(() => SetWarningRadius(radioCall, Voice, Radio.TransmissionQueue)).Result); case "Picture": return(Task.Run(() => Picture(radioCall)).Result); case "Declare": return(Task.Run(() => Declare(radioCall)).Result); case "ReadyToTaxi": return(Task.Run(() => ReadyToTaxi(radioCall, Voice, Radio.TransmissionQueue)).Result); case "InboundToAirbase": return(Task.Run(() => InboundToAirbase(radioCall)).Result); default: return(Task.Run(() => Unknown(radioCall)).Result); } } }
protected override string UnverifiedSender(IRadioCall radioCall) { if (!IsAddressedToController(radioCall)) { return(null); } return(ResponsePrefix(radioCall) + ", I cannot find you on scope."); }
protected override string InboundToAirbase(IRadioCall radioCall, string voice, ConcurrentQueue <byte[]> responseQueue) { if (!IsAddressedToController(radioCall)) { return(null); } return(ResponsePrefix(radioCall) + "approach, " + Intents.InboundToAirbase.Process(radioCall, voice, responseQueue).Result); }
protected override string BearingToFriendlyPlayer(IRadioCall radioCall) { if (!IsAddressedToController(radioCall) || radioCall.Sender.Coalition == Coalition.Neutral) { return(null); } return(ResponsePrefix(radioCall) + Intents.BearingToFriendlyPlayer.Process(new BearingToFriendlyPlayerRadioCall(radioCall)).Result); }
protected override string RadioCheck(IRadioCall radioCall) { if (!IsAddressedToController(radioCall)) { return(null); } return(ResponsePrefix(radioCall) + "ground, five-by-five"); }
protected override string ReadyToTaxi(IRadioCall radioCall, string voice, ConcurrentQueue <byte[]> responseQueue) { if (!IsAddressedToController(radioCall)) { return(null); } return(ResponsePrefix(radioCall) + "ground, " + ReadytoTaxi.Process(radioCall, voice, responseQueue).Result); }
protected override string Picture(IRadioCall radioCall) { if (!IsAddressedToController(radioCall)) { return(null); } return(ResponsePrefix(radioCall) + "we do not support picture calls."); }
public static async Task <string> Process(IRadioCall radioCall) { var sender = radioCall.Sender; var contact = await GameQuerier.GetBogeyDope(sender.Coalition, sender.Group, sender.Flight, sender.Plane); return(contact != null?BuildResponse(sender, contact) : "Picture is clean."); }
protected override string SetWarningRadius(IRadioCall radioCall, string voice, ConcurrentQueue <byte[]> responseQueue) { if (!IsAddressedToController(radioCall) || radioCall.Sender.Coalition == Coalition.Neutral) { return(null); } return(ResponsePrefix(radioCall) + Intents.SetWarningRadius.Process(new SetWarningRadiusRadioCall(radioCall), voice, responseQueue).Result); }
protected override string Declare(IRadioCall radioCall) { if (!IsAddressedToController(radioCall) || radioCall.Sender.Coalition == Coalition.Neutral) { return(null); } return(ResponsePrefix(radioCall) + "we do not support declare calls."); }
protected override string Unknown(IRadioCall radioCall) { if (!IsAddressedToController(radioCall)) { return(null); } return(ResponsePrefix(radioCall) + ", I could not understand your transmission"); }
protected override string BogeyDope(IRadioCall radioCall) { if (!IsAddressedToController(radioCall) || radioCall.Sender.Coalition == Coalition.Neutral) { return(null); } return(ResponsePrefix(radioCall) + Intents.BogeyDope.Process(radioCall).Result); }
protected override string NullSender(IRadioCall radioCall) { if (!IsAddressedToController(radioCall)) { return(null); } return("Last transmitter, I could not recognize your call-sign"); }
private void LogTransmissionToDiscord(IRadioCall radioCall, string response) { using (Constants.ActivitySource.StartActivity("LogTransmissionToDiscord")) { Logger.Debug($"{_logClientId}| Building Discord Request/Response message"); var transmission = $"Transmission Intent: {radioCall.Intent}\n" + $"Request: {radioCall.Message}\n" + $"Response: {response ?? "**IGNORED**"}"; _ = DiscordClient.LogTransmissionToDiscord(transmission, Controller.Radio, SrsClient).ConfigureAwait(false); } }
public static async Task <string> Process(IRadioCall radioCall) { switch (radioCall.AirbaseName) { case null: return("I could not recognize the airbase name"); case "nearest": return(await NearestAirbase(radioCall)); default: return(await NamedAirbase(radioCall)); } }
public static async Task <string> Process(IRadioCall radioCall, string voice, ConcurrentQueue <byte[]> responseQueue) { return(await Task.Run(() => { try { var airfield = Constants.Airfields.First(x => x.Name == radioCall.ReceiverName); var approachRoute = new ApproachController(airfield).GetApproachRoute(radioCall.Sender.Position); var initialTrueBearing = Geospatial.BearingTo(radioCall.Sender.Position.Coordinate, new Coordinate(approachRoute.First().Latitude, approachRoute.First().Longitude)); var initialMagneticBearing = Regex.Replace( Geospatial.TrueToMagnetic(radioCall.Sender.Position, initialTrueBearing).ToString("000"), "\\d{1}", " $0"); var response = $"fly heading {initialMagneticBearing}, descend and maintain 2,000, reduce speed 2 0 0 knots, for vectors to {approachRoute.Last().Name}, {approachRoute.First().Name}"; var currentPosition = new NavigationPoint { Name = "Current Position", Latitude = radioCall.Sender.Position.Coordinate.Latitude, Longitude = radioCall.Sender.Position.Coordinate.Longitude }; approachRoute = approachRoute.Prepend(currentPosition).ToList(); new AtcProgressChecker(radioCall.Sender, airfield, voice, approachRoute, responseQueue) .CalledInbound(); return response; } catch (InvalidOperationException) { return "There are no ATC services currently available at this airfield."; } catch (NoActiveRunwaysFoundException ex) { Logger.Error(ex, "No Active Runways found"); return "We could not find any active runways."; } })); }
protected override bool IsAddressedToController(IRadioCall radioCall) { Logger.Debug($"Defined Callsign is {Callsign}, Received Callsign is {radioCall.AwacsCallsign}"); if (string.IsNullOrEmpty(radioCall.AwacsCallsign)) { return(false); } if (string.IsNullOrEmpty(Callsign)) { return(true); } var result = string.IsNullOrEmpty(Callsign) != true && (radioCall.ReceiverName.ToLower() == "anyface" || radioCall.ReceiverName.ToLower().Equals(Callsign.ToLower())); return(result); }
public static async Task <string> Process(IRadioCall radioCall, string voice, ConcurrentQueue <byte[]> responseQueue) { return(await Task.Run(() => { var taxiInstructions = DummyInstructions; Airfield airfield; try { airfield = Constants.Airfields.First(x => x.Name == radioCall.ReceiverName); } catch (InvalidOperationException) { return "There are no ATC services currently available at this airfield."; } try { if (airfield.Runways.Count == 0 || airfield.NavigationGraph.EdgeCount == 0) { return "There are no ATC services currently available at this airfield."; } taxiInstructions = new GroundController(airfield).GetTaxiInstructions(radioCall.Sender.Position); Logger.Debug( $"{radioCall.Sender.Id} route is {string.Join(", ", taxiInstructions.TaxiPoints.Select(t => t.Name))}"); var spokenInstructions = ConvertTaxiInstructionsToSsml(taxiInstructions); new AtcProgressChecker(radioCall.Sender, airfield, voice, taxiInstructions.TaxiPoints, responseQueue).CalledTaxi(); return spokenInstructions; } catch (NoActiveRunwaysFoundException ex) { Logger.Error(ex, "No Active Runways found"); return "We could not find any active runways."; } catch (TaxiPathNotFoundException ex) { Logger.Error(ex, "No Path found"); return $"We could not find a path from your position to {taxiInstructions.DestinationName}."; } })); }
private static async Task <string> NearestAirbase(IRadioCall radioCall) { string response; var braData = await GameQuerier.GetBearingToNearestFriendlyAirbase(radioCall.Sender.Position, radioCall.Sender.Group, radioCall.Sender.Flight, radioCall.Sender.Plane, (int)radioCall.Sender.Coalition); if (braData != null) { var bearing = Regex.Replace(Geospatial.TrueToMagnetic(radioCall.Sender.Position, (int)braData["bearing"]).ToString("000"), "\\d{1}", " $0"); var range = braData["range"]; response = $"{AirbasePronouncer.PronounceAirbase((string) braData["name"])} bearing {bearing}, {(int) range} miles"; } else { response = "I Could not find any friendly airbases."; } return(response); }
private static async Task <string> NamedAirbase(IRadioCall radioCall) { string response; var braData = await GameQuerier.GetBearingToNamedAirbase(radioCall.Sender.Position, radioCall.Sender.Group, radioCall.Sender.Flight, radioCall.Sender.Plane, radioCall.AirbaseName); if (braData != null) { var bearing = Regex.Replace(Geospatial.TrueToMagnetic(radioCall.Sender.Position, braData["bearing"]).ToString("000"), "\\d{1}", " $0"); var range = braData["range"]; response = $"{AirbasePronouncer.PronounceAirbase(radioCall.AirbaseName)} bearing {bearing}, {range} miles"; } else { response = $"I Could not find {AirbasePronouncer.PronounceAirbase(radioCall.AirbaseName)}."; } return(response); }
private string ResponsePrefix(IRadioCall radioCall) { string responseCallsign; if (string.IsNullOrEmpty(Callsign) != true) { responseCallsign = Callsign; } else if (radioCall.AwacsCallsign != null && radioCall.AwacsCallsign.ToLower().Equals("anyface")) { responseCallsign = DefaultCallsign; // Overlord is the default callsign; } else if (string.IsNullOrEmpty(Callsign) && string.IsNullOrEmpty(radioCall.AwacsCallsign)) { responseCallsign = DefaultCallsign; // Overlord is the default callsign; } else { responseCallsign = radioCall.AwacsCallsign; } return($"{radioCall.Sender.Callsign}, {responseCallsign}, "); }
protected override string None(IRadioCall radioCall) { return(null); }
private async Task ProcessRecognizedCall(SpeechRecognitionEventArgs e) { using (var activity = Constants.ActivitySource.StartActivity("ProcessRecognizedCall", ActivityKind.Server)) { Logger.Info($"{_logClientId}| Incoming Transmission: {e.Result.Text}"); var luisJson = Task.Run(() => LuisService.ParseIntent(e.Result.Text)).Result; Logger.Debug($"{_logClientId}| LUIS Response: {luisJson}"); IRadioCall radioCall = Controller is AtcController ? new AtcRadioCall(luisJson) : new BaseRadioCall(luisJson); MetricsManager.Instance.RecordRadioCall(radioCall.Intent, $"{_frequency / 1000000} - Bot {_botType}"); activity?.AddTag("Frequency", _frequency); activity?.AddTag("BotType", _botType); activity?.AddTag("Callsign", _callsign); activity?.AddTag("Sender", radioCall.Sender?.Callsign); activity?.AddTag("Intent", radioCall.Intent); activity?.AddTag("Request", radioCall.Message); var response = Controller.ProcessRadioCall(radioCall); activity?.AddTag("Response Text", response); if (!string.IsNullOrEmpty(response)) { Logger.Info($"{_logClientId}| Outgoing Transmission: {response}"); // Try twice to avoid transient C**k-ups resulting in a failure response var audioResponse = await Task.Run(() => Speaker.CreateResponse( $"<speak version=\"1.0\" xmlns=\"https://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name =\"{Controller.Voice}\">{response}</voice></speak>")); if (audioResponse == null) { Logger.Debug($"{_logClientId}| First Synthesis failed, trying again"); audioResponse = await Task.Run(() => Speaker.CreateResponse( $"<speak version=\"1.0\" xmlns=\"https://www.w3.org/2001/10/synthesis\" xml:lang=\"en-US\"><voice name =\"{Controller.Voice}\">{response}</voice></speak>")); } if (audioResponse == null) { activity?.AddTag("Response", "Failure"); activity?.AddEvent(new ActivityEvent("Synthesis Failure")); Logger.Error($"{_logClientId}| Synthesis Failure"); using (Constants.ActivitySource.StartActivity("EnqueueResponseAudio", ActivityKind.Producer)) { Logger.Trace($"{_logClientId}| Sending Failure Message"); Controller.Radio.TransmissionQueue.Enqueue(FailureMessage); } } else { activity?.AddTag("Response", "Success"); using (Constants.ActivitySource.StartActivity("EnqueueResponseAudio", ActivityKind.Producer)) { Controller.Radio.TransmissionQueue.Enqueue(audioResponse); } } } else { activity?.AddTag("Response", "Ignored"); Logger.Info($"{_logClientId}| Radio Call Ignored due to null response for Radio Call Processing"); } if (Controller.Radio.discordTransmissionLogChannelId > 0) { LogTransmissionToDiscord(radioCall, response); } } }
public SetWarningRadiusRadioCall(IRadioCall baseRadioCall) : base(baseRadioCall) { }
protected override bool IsAddressedToController(IRadioCall radioCall) { var atcRadioCall = (AtcRadioCall)radioCall; return(Constants.Airfields.Any(airfield => airfield.Name.Equals(atcRadioCall.AirbaseName) && atcRadioCall.ControlName != "traffic")); }
protected override bool IsAddressedToController(IRadioCall radioCall) { return(false); }
protected override string SetWarningRadius(IRadioCall radioCall, string voice, ConcurrentQueue <byte[]> responseQueue) { return($"{radioCall.Sender.Callsign}, This is an ATC frequency"); }
protected override string Picture(IRadioCall radioCall) { return($"{radioCall.Sender.Callsign}, This is an ATC frequency"); }
protected override string BearingToFriendlyPlayer(IRadioCall radioCall) { return($"{radioCall.Sender.Callsign}, This is an ATC frequency"); }
private static string ResponsePrefix(IRadioCall radioCall) { var name = Constants.Airfields.Any(airfield => airfield.Name.Equals(radioCall.AirbaseName)) ? AirbasePronouncer.PronounceAirbase(radioCall.AirbaseName) : "ATC"; return($"{radioCall.Sender.Callsign}, {name} "); }