예제 #1
0
        private void FocusDCS()
        {
            if (_globalSettings.GetClientSettingBool(GlobalSettingsKeys.RefocusDCS))
            {
                var overlayWindow = new WindowInteropHelper(this).Handle;

                //focus DCS if needed
                var foreGround = WindowHelper.GetForegroundWindow();

                Process[] localByName = Process.GetProcessesByName("dcs");

                if (localByName != null && localByName.Length > 0)
                {
                    //either DCS is in focus OR Overlay window is not in focus
                    if (foreGround == localByName[0].MainWindowHandle || overlayWindow != foreGround ||
                        this.IsMouseOver)
                    {
                        _lastFocus = DateTime.Now.Ticks;
                    }
                    else if (DateTime.Now.Ticks > _lastFocus + 20000000 && overlayWindow == foreGround)
                    {
                        WindowHelper.BringProcessToFront(localByName[0]);
                    }
                }
            }
        }
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null))
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null)
                                {
                                    var vehicleId = -1;
                                    if (_clients.TryGetValue(udpVoicePacket.Guid, out var transmittingClient))
                                    {
                                        vehicleId = transmittingClient.GameState.vehicleId;
                                    }

                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);


                                        var radio = _clientStateSingleton.PlayerGameState.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.UnitId,
                                            vehicleId,
                                            blockedRadios,
                                            out state);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                globalFrequency ||
                                                (!blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Frequency      = udpVoicePacket.Frequencies[i],
                                                    Modulation     = udpVoicePacket.Modulations[i],
                                                    ReceivingRadio = radio,
                                                    ReceivingState = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,

                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                PacketNumber        = udpVoicePacket.PacketNumber,
                                                OriginalClientGuid  = udpVoicePacket.OriginalClientGuid
                                            };


                                            //handle effects
                                            var radioState = _radioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                          false,
                                                                                          audio.Volume, (RadioInformation.Modulation)audio.Modulation);
                                            }

                                            var transmitterName = "";
                                            if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.SHOW_TRANSMITTER_NAME) &&
                                                _globalSettings.GetClientSettingBool(GlobalSettingsKeys.ShowTransmitterName) &&
                                                transmittingClient != null)

                                            {
                                                transmitterName = transmittingClient.Name;
                                            }

                                            var newRadioReceivingState = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                LastReceivedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn,
                                                SentBy     = transmitterName
                                            };

                                            _radioReceivingState[audio.ReceivedRadio] = newRadioReceivingState;

                                            // Only play actual audio once
                                            if (i == 0)
                                            {
                                                _audioManager.AddClientAudio(audio);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
        private bool UpdateRadio(DCSPlayerRadioInfo message)
        {
            var expansion = _serverSettings.GetSettingAsBool(ServerSettingsKeys.RADIO_EXPANSION);

            var playerRadioInfo = _clientStateSingleton.DcsPlayerRadioInfo;

            //copy and compare to look for changes
            var beforeUpdate = playerRadioInfo.DeepClone();

            //update common parts
            playerRadioInfo.name           = message.name;
            playerRadioInfo.inAircraft     = message.inAircraft;
            playerRadioInfo.intercomHotMic = message.intercomHotMic;
            playerRadioInfo.capabilities   = message.capabilities;

            if (_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys.AlwaysAllowHotasControls))
            {
                message.control         = DCSPlayerRadioInfo.RadioSwitchControls.HOTAS;
                playerRadioInfo.control = DCSPlayerRadioInfo.RadioSwitchControls.HOTAS;
            }
            else
            {
                playerRadioInfo.control = message.control;
            }

            playerRadioInfo.simultaneousTransmissionControl = message.simultaneousTransmissionControl;

            playerRadioInfo.unit = message.unit;

            if (!_clientStateSingleton.ShouldUseLotATCPosition())
            {
                _clientStateSingleton.UpdatePlayerPosition(message.latLng);
            }

            var overrideFreqAndVol = false;

            var newAircraft = playerRadioInfo.unitId != message.unitId || !playerRadioInfo.IsCurrent();

            overrideFreqAndVol = playerRadioInfo.unitId != message.unitId;

            //save unit id
            playerRadioInfo.unitId = message.unitId;


            if (newAircraft)
            {
                if (_globalSettings.GetClientSettingBool(GlobalSettingsKeys.AutoSelectSettingsProfile))
                {
                    _newAircraftCallback(message.unit);
                }

                playerRadioInfo.iff = message.iff;
            }

            if (overrideFreqAndVol)
            {
                playerRadioInfo.selected = message.selected;
            }

            if (playerRadioInfo.control == DCSPlayerRadioInfo.RadioSwitchControls.IN_COCKPIT)
            {
                playerRadioInfo.selected = message.selected;
            }

            bool simul = false;


            //copy over radio names, min + max
            for (var i = 0; i < playerRadioInfo.radios.Length; i++)
            {
                var clientRadio = playerRadioInfo.radios[i];

                //if we have more radios than the message has
                if (i >= message.radios.Length)
                {
                    clientRadio.freq       = 1;
                    clientRadio.freqMin    = 1;
                    clientRadio.freqMax    = 1;
                    clientRadio.secFreq    = 0;
                    clientRadio.retransmit = false;
                    clientRadio.modulation = RadioInformation.Modulation.DISABLED;
                    clientRadio.name       = "No Radio";
                    clientRadio.rtMode     = RadioInformation.RetransmitMode.DISABLED;
                    clientRadio.retransmit = false;

                    clientRadio.freqMode      = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.guardFreqMode = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.encMode       = RadioInformation.EncryptionMode.NO_ENCRYPTION;
                    clientRadio.volMode       = RadioInformation.VolumeMode.COCKPIT;

                    continue;
                }

                var updateRadio = message.radios[i];


                if ((updateRadio.expansion && !expansion) ||
                    (updateRadio.modulation == RadioInformation.Modulation.DISABLED))
                {
                    //expansion radio, not allowed
                    clientRadio.freq       = 1;
                    clientRadio.freqMin    = 1;
                    clientRadio.freqMax    = 1;
                    clientRadio.secFreq    = 0;
                    clientRadio.retransmit = false;
                    clientRadio.modulation = RadioInformation.Modulation.DISABLED;
                    clientRadio.name       = "No Radio";
                    clientRadio.rtMode     = RadioInformation.RetransmitMode.DISABLED;
                    clientRadio.retransmit = false;

                    clientRadio.freqMode      = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.guardFreqMode = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.encMode       = RadioInformation.EncryptionMode.NO_ENCRYPTION;
                    clientRadio.volMode       = RadioInformation.VolumeMode.COCKPIT;
                }
                else
                {
                    //update common parts
                    clientRadio.freqMin = updateRadio.freqMin;
                    clientRadio.freqMax = updateRadio.freqMax;

                    if (playerRadioInfo.simultaneousTransmissionControl == DCSPlayerRadioInfo.SimultaneousTransmissionControl.EXTERNAL_DCS_CONTROL)
                    {
                        clientRadio.simul = updateRadio.simul;
                    }

                    if (updateRadio.simul)
                    {
                        simul = true;
                    }

                    clientRadio.name = updateRadio.name;

                    clientRadio.modulation = updateRadio.modulation;

                    //update modes
                    clientRadio.freqMode      = updateRadio.freqMode;
                    clientRadio.guardFreqMode = updateRadio.guardFreqMode;
                    clientRadio.rtMode        = updateRadio.rtMode;

                    if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.ALLOW_RADIO_ENCRYPTION))
                    {
                        clientRadio.encMode = updateRadio.encMode;
                    }
                    else
                    {
                        clientRadio.encMode = RadioInformation.EncryptionMode.NO_ENCRYPTION;
                    }

                    clientRadio.volMode = updateRadio.volMode;

                    if ((updateRadio.freqMode == RadioInformation.FreqMode.COCKPIT) || overrideFreqAndVol)
                    {
                        clientRadio.freq = updateRadio.freq;

                        if (newAircraft && updateRadio.guardFreqMode == RadioInformation.FreqMode.OVERLAY)
                        {
                            //default guard to off
                            clientRadio.secFreq = 0;
                        }
                        else
                        {
                            if (clientRadio.secFreq != 0 && updateRadio.guardFreqMode == RadioInformation.FreqMode.OVERLAY)
                            {
                                //put back
                                clientRadio.secFreq = updateRadio.secFreq;
                            }
                            else if (clientRadio.secFreq == 0 && updateRadio.guardFreqMode == RadioInformation.FreqMode.OVERLAY)
                            {
                                clientRadio.secFreq = 0;
                            }
                            else
                            {
                                clientRadio.secFreq = updateRadio.secFreq;
                            }
                        }

                        clientRadio.channel = updateRadio.channel;
                    }
                    else
                    {
                        if (clientRadio.secFreq != 0)
                        {
                            //put back
                            clientRadio.secFreq = updateRadio.secFreq;
                        }

                        //check we're not over a limit
                        if (clientRadio.freq > clientRadio.freqMax)
                        {
                            clientRadio.freq = clientRadio.freqMax;
                        }
                        else if (clientRadio.freq < clientRadio.freqMin)
                        {
                            clientRadio.freq = clientRadio.freqMin;
                        }
                    }

                    //reset encryption
                    if (overrideFreqAndVol)
                    {
                        clientRadio.enc    = false;
                        clientRadio.encKey = 0;
                    }

                    //Handle Encryption
                    if (updateRadio.encMode == RadioInformation.EncryptionMode.ENCRYPTION_JUST_OVERLAY)
                    {
                        if (clientRadio.encKey == 0)
                        {
                            clientRadio.encKey = 1;
                        }
                    }
                    else if (clientRadio.encMode ==
                             RadioInformation.EncryptionMode.ENCRYPTION_COCKPIT_TOGGLE_OVERLAY_CODE)
                    {
                        clientRadio.enc = updateRadio.enc;

                        if (clientRadio.encKey == 0)
                        {
                            clientRadio.encKey = 1;
                        }
                    }
                    else if (clientRadio.encMode == RadioInformation.EncryptionMode.ENCRYPTION_FULL)
                    {
                        clientRadio.enc    = updateRadio.enc;
                        clientRadio.encKey = updateRadio.encKey;
                    }
                    else
                    {
                        clientRadio.enc    = false;
                        clientRadio.encKey = 0;
                    }

                    //handle volume
                    if ((updateRadio.volMode == RadioInformation.VolumeMode.COCKPIT) || overrideFreqAndVol)
                    {
                        clientRadio.volume = updateRadio.volume;
                    }

                    //handle Retransmit mode
                    if ((updateRadio.rtMode == RadioInformation.RetransmitMode.COCKPIT))
                    {
                        clientRadio.rtMode     = updateRadio.rtMode;
                        clientRadio.retransmit = updateRadio.retransmit;
                    }
                    else if (updateRadio.rtMode == RadioInformation.RetransmitMode.DISABLED)
                    {
                        clientRadio.rtMode     = updateRadio.rtMode;
                        clientRadio.retransmit = false;
                    }

                    //handle Channels load for radios
                    if (newAircraft && i > 0)
                    {
                        if (clientRadio.freqMode == RadioInformation.FreqMode.OVERLAY)
                        {
                            var channelModel = _clientStateSingleton.FixedChannels[i - 1];
                            channelModel.Max = clientRadio.freqMax;
                            channelModel.Min = clientRadio.freqMin;
                            channelModel.Reload();
                            clientRadio.channel = -1; //reset channel

                            if (_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys.AutoSelectPresetChannel))
                            {
                                RadioHelper.RadioChannelUp(i);
                            }
                        }
                        else
                        {
                            _clientStateSingleton.FixedChannels[i - 1].Clear();
                            //clear
                        }
                    }
                }
            }


            if (playerRadioInfo.simultaneousTransmissionControl ==
                DCSPlayerRadioInfo.SimultaneousTransmissionControl.EXTERNAL_DCS_CONTROL)
            {
                playerRadioInfo.simultaneousTransmission = simul;
            }

            //change PTT last
            if (!_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys.AllowDCSPTT))
            {
                playerRadioInfo.ptt = false;
            }
            else
            {
                playerRadioInfo.ptt = message.ptt;
            }

            //HANDLE IFF/TRANSPONDER UPDATE
            //TODO tidy up the IFF/Transponder handling and this giant function in general as its silly big :(


            if (_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys
                                                                          .AlwaysAllowTransponderOverlay))
            {
                if (message.iff.control != Transponder.IFFControlMode.DISABLED)
                {
                    playerRadioInfo.iff.control = Transponder.IFFControlMode.OVERLAY;
                    message.iff.control         = Transponder.IFFControlMode.OVERLAY;
                }
            }

            if (message.iff.control == Transponder.IFFControlMode.COCKPIT)
            {
                playerRadioInfo.iff = message.iff;
            }


            //HANDLE MIC IDENT
            if (!playerRadioInfo.ptt && playerRadioInfo.iff.mic > 0 && _clientStateSingleton.RadioSendingState.IsSending)
            {
                if (_clientStateSingleton.RadioSendingState.SendingOn == playerRadioInfo.iff.mic)
                {
                    playerRadioInfo.iff.status = Transponder.IFFStatus.IDENT;
                }
            }

            //Handle IDENT only lasting for 40 seconds at most - need to toggle it
            if (playerRadioInfo.iff.status == Transponder.IFFStatus.IDENT)
            {
                if (_identStart == 0)
                {
                    _identStart = DateTime.Now.Ticks;
                }

                if (TimeSpan.FromTicks(DateTime.Now.Ticks - _identStart).TotalSeconds > 40)
                {
                    playerRadioInfo.iff.status = Transponder.IFFStatus.NORMAL;
                }
            }
            else
            {
                _identStart = 0;
            }

            //                }
            //            }

            //update
            playerRadioInfo.LastUpdate = DateTime.Now.Ticks;

            return(!beforeUpdate.Equals(playerRadioInfo));
        }
        public void Start()
        {
            _vaicomUDPListener = new UdpClient();
            _vaicomUDPListener.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress,
                                                      true);
            _vaicomUDPListener.ExclusiveAddressUse = false; // only if you want to send/receive on same machine.

            var localEp = new IPEndPoint(IPAddress.Any,
                                         _globalSettings.GetNetworkSetting(GlobalSettingsKeys.VAICOMIncomingUDP));

            _vaicomUDPListener.Client.Bind(localEp);

            Task.Factory.StartNew(() =>
            {
                using (_vaicomUDPListener)
                {
                    while (!_stop)
                    {
                        try
                        {
                            var groupEp = new IPEndPoint(IPAddress.Any,
                                                         _globalSettings.GetNetworkSetting(GlobalSettingsKeys.VAICOMIncomingUDP));
                            var bytes = _vaicomUDPListener.Receive(ref groupEp);

                            var vaicomMessageWrapper =
                                JsonConvert.DeserializeObject <VAICOMMessageWrapper>(Encoding.UTF8.GetString(
                                                                                         bytes, 0, bytes.Length));

                            if (vaicomMessageWrapper != null)
                            {
                                if (vaicomMessageWrapper.MessageType == 1)
                                {
                                    if (_globalSettings.GetClientSettingBool(GlobalSettingsKeys.VAICOMTXInhibitEnabled))
                                    {
                                        vaicomMessageWrapper.LastReceivedAt = DateTime.Now.Ticks;
                                        _clientStateSingleton.InhibitTX     = vaicomMessageWrapper;
                                    }
                                }
                            }
                        }
                        catch (SocketException e)
                        {
                            if (!_stop)
                            {
                                Logger.Error(e, "SocketException Handling VAICOM UDP Message");
                            }
                        }
                        catch (Exception e)
                        {
                            Logger.Error(e, "Exception Handling VAICOM UDP Message");
                        }
                    }

                    try
                    {
                        _vaicomUDPListener.Close();
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Exception stoping VAICOM UDP listener");
                    }
                }
            });
        }
예제 #5
0
        private void UdpAudioDecode()
        {
            try
            {
                while (!_stop)
                {
                    try
                    {
                        var encodedOpusAudio = new byte[0];
                        _encodedAudio.TryTake(out encodedOpusAudio, 100000, _stopFlag.Token);

                        var time = DateTime.Now.Ticks; //should add at the receive instead?

                        if ((encodedOpusAudio != null) &&
                            (encodedOpusAudio.Length >=
                             (UDPVoicePacket.PacketHeaderLength + UDPVoicePacket.FixedPacketLength +
                              UDPVoicePacket.FrequencySegmentLength)))
                        {
                            //  process
                            // check if we should play audio

                            var myClient = IsClientMetaDataValid(_guid);

                            if ((myClient != null) && _clientStateSingleton.DcsPlayerRadioInfo.IsCurrent())
                            {
                                //Decode bytes
                                var udpVoicePacket = UDPVoicePacket.DecodeVoicePacket(encodedOpusAudio);

                                if (udpVoicePacket != null)
                                {
                                    var globalFrequencies = _serverSettings.GlobalFrequencies;

                                    var frequencyCount = udpVoicePacket.Frequencies.Length;

                                    List <RadioReceivingPriority> radioReceivingPriorities =
                                        new List <RadioReceivingPriority>(frequencyCount);
                                    List <int> blockedRadios = CurrentlyBlockedRadios();

                                    // Parse frequencies into receiving radio priority for selection below
                                    for (var i = 0; i < frequencyCount; i++)
                                    {
                                        RadioReceivingState state = null;
                                        bool decryptable;

                                        //Check if Global
                                        bool globalFrequency = globalFrequencies.Contains(udpVoicePacket.Frequencies[i]);

                                        if (globalFrequency)
                                        {
                                            //remove encryption for global
                                            udpVoicePacket.Encryptions[i] = 0;
                                        }

                                        var radio = _clientStateSingleton.DcsPlayerRadioInfo.CanHearTransmission(
                                            udpVoicePacket.Frequencies[i],
                                            (RadioInformation.Modulation)udpVoicePacket.Modulations[i],
                                            udpVoicePacket.Encryptions[i],
                                            udpVoicePacket.UnitId,
                                            blockedRadios,
                                            out state,
                                            out decryptable);

                                        float  losLoss = 0.0f;
                                        double receivPowerLossPercent = 0.0;

                                        if (radio != null && state != null)
                                        {
                                            if (
                                                radio.modulation == RadioInformation.Modulation.INTERCOM ||
                                                radio.modulation == RadioInformation.Modulation.MIDS || // IGNORE LOS and Distance for MIDS - we assume a Link16 Network is in place
                                                globalFrequency ||
                                                (
                                                    HasLineOfSight(udpVoicePacket, out losLoss) &&
                                                    InRange(udpVoicePacket.Guid, udpVoicePacket.Frequencies[i],
                                                            out receivPowerLossPercent) &&
                                                    !blockedRadios.Contains(state.ReceivedOn)
                                                )
                                                )
                                            {
                                                decryptable =
                                                    (udpVoicePacket.Encryptions[i] == 0) ||
                                                    (udpVoicePacket.Encryptions[i] == radio.encKey && radio.enc);

                                                radioReceivingPriorities.Add(new RadioReceivingPriority()
                                                {
                                                    Decryptable               = decryptable,
                                                    Encryption                = udpVoicePacket.Encryptions[i],
                                                    Frequency                 = udpVoicePacket.Frequencies[i],
                                                    LineOfSightLoss           = losLoss,
                                                    Modulation                = udpVoicePacket.Modulations[i],
                                                    ReceivingPowerLossPercent = receivPowerLossPercent,
                                                    ReceivingRadio            = radio,
                                                    ReceivingState            = state
                                                });
                                            }
                                        }
                                    }

                                    // Sort receiving radios to play audio on correct one
                                    radioReceivingPriorities.Sort(SortRadioReceivingPriorities);

                                    if (radioReceivingPriorities.Count > 0)
                                    {
                                        //ALL GOOD!
                                        //create marker for bytes
                                        for (int i = 0; i < radioReceivingPriorities.Count; i++)
                                        {
                                            var destinationRadio           = radioReceivingPriorities[i];
                                            var isSimultaneousTransmission = radioReceivingPriorities.Count > 1 && i > 0;

                                            var audio = new ClientAudio
                                            {
                                                ClientGuid   = udpVoicePacket.Guid,
                                                EncodedAudio = udpVoicePacket.AudioPart1Bytes,
                                                //Convert to Shorts!
                                                ReceiveTime   = DateTime.Now.Ticks,
                                                Frequency     = destinationRadio.Frequency,
                                                Modulation    = destinationRadio.Modulation,
                                                Volume        = destinationRadio.ReceivingRadio.volume,
                                                ReceivedRadio = destinationRadio.ReceivingState.ReceivedOn,
                                                UnitId        = udpVoicePacket.UnitId,
                                                Encryption    = destinationRadio.Encryption,
                                                Decryptable   = destinationRadio.Decryptable,
                                                // mark if we can decrypt it
                                                RadioReceivingState = destinationRadio.ReceivingState,
                                                RecevingPower       =
                                                    destinationRadio
                                                    .ReceivingPowerLossPercent,     //loss of 1.0 or greater is total loss
                                                LineOfSightLoss =
                                                    destinationRadio
                                                    .LineOfSightLoss,     // Loss of 1.0 or greater is total loss
                                                PacketNumber       = udpVoicePacket.PacketNumber,
                                                OriginalClientGuid = udpVoicePacket.OriginalClientGuid
                                            };


                                            //handle effects
                                            var radioState = _radioReceivingState[audio.ReceivedRadio];

                                            if (!isSimultaneousTransmission &&
                                                (radioState == null || radioState.PlayedEndOfTransmission ||
                                                 !radioState.IsReceiving))
                                            {
                                                var audioDecryptable = audio.Decryptable || (audio.Encryption == 0);

                                                //mark that we have decrypted encrypted audio for sound effects
                                                if (audioDecryptable && (audio.Encryption > 0))
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              true,
                                                                                              audio.Volume, (Modulation)audio.Modulation);
                                                }
                                                else
                                                {
                                                    _audioManager.PlaySoundEffectStartReceive(audio.ReceivedRadio,
                                                                                              false,
                                                                                              audio.Volume, (Modulation)audio.Modulation);
                                                }
                                            }

                                            var transmitterName = "";
                                            if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.SHOW_TRANSMITTER_NAME) &&
                                                _globalSettings.GetClientSettingBool(GlobalSettingsKeys.ShowTransmitterName) &&
                                                _clients.TryGetValue(udpVoicePacket.Guid, out var transmittingClient))

                                            {
                                                transmitterName = transmittingClient.Name;
                                            }

                                            var newRadioReceivingState = new RadioReceivingState
                                            {
                                                IsSecondary             = destinationRadio.ReceivingState.IsSecondary,
                                                IsSimultaneous          = isSimultaneousTransmission,
                                                LastReceviedAt          = DateTime.Now.Ticks,
                                                PlayedEndOfTransmission = false,
                                                ReceivedOn = destinationRadio.ReceivingState.ReceivedOn,
                                                SentBy     = transmitterName
                                            };

                                            _radioReceivingState[audio.ReceivedRadio] = newRadioReceivingState;

                                            // Only play actual audio once
                                            if (i == 0)
                                            {
                                                _audioManager.AddClientAudio(audio);
                                            }
                                        }

                                        //handle retransmission
                                        RetransmitAudio(udpVoicePacket, radioReceivingPriorities);
                                    }
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        if (!_stop)
                        {
                            Logger.Info(ex, "Failed to decode audio from Packet");
                        }
                    }
                }
            }
            catch (OperationCanceledException)
            {
                Logger.Info("Stopped DeJitter Buffer");
            }
        }
예제 #6
0
        public void Start()
        {
            Task.Factory.StartNew(() =>
            {
                while (!_stop)
                {
                    try
                    {
                        var localEp = new IPEndPoint(IPAddress.Any,
                                                     _globalSettings.GetNetworkSetting(GlobalSettingsKeys.VAICOMIncomingUDP));
                        _vaicomUDPListener = new UdpClient(localEp);
                        break;
                    }
                    catch (Exception ex)
                    {
                        Logger.Warn(ex, $"Unable to bind to the VAICOM Listener Socket Port: {_globalSettings.GetNetworkSetting(GlobalSettingsKeys.VAICOMIncomingUDP)}");
                        Thread.Sleep(500);
                    }
                }
                while (!_stop)
                {
                    try
                    {
                        var groupEp = new IPEndPoint(IPAddress.Any, 0);
                        var bytes   = _vaicomUDPListener.Receive(ref groupEp);

                        var vaicomMessageWrapper =
                            JsonConvert.DeserializeObject <VAICOMMessageWrapper>(Encoding.UTF8.GetString(
                                                                                     bytes, 0, bytes.Length));

                        if (vaicomMessageWrapper != null)
                        {
                            if (vaicomMessageWrapper.MessageType == 1)
                            {
                                if (_globalSettings.GetClientSettingBool(GlobalSettingsKeys.VAICOMTXInhibitEnabled))
                                {
                                    vaicomMessageWrapper.LastReceivedAt = DateTime.Now.Ticks;
                                    _clientStateSingleton.InhibitTX     = vaicomMessageWrapper;
                                }
                            }
                        }
                    }
                    catch (SocketException e)
                    {
                        if (!_stop)
                        {
                            Logger.Error(e, "SocketException Handling VAICOM UDP Message");
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Exception Handling VAICOM UDP Message");
                    }
                }

                try
                {
                    _vaicomUDPListener.Close();
                }
                catch (Exception e)
                {
                    Logger.Error(e, "Exception stoping VAICOM UDP listener");
                }
            });
        }
        private bool UpdateRadio(DCSPlayerRadioInfo message)
        {
            var changed = false;

            var expansion = _serverSettings.GetSettingAsBool(ServerSettingsKeys.RADIO_EXPANSION);

            var playerRadioInfo = _clientStateSingleton.DcsPlayerRadioInfo;

            //update common parts
            playerRadioInfo.name           = message.name;
            playerRadioInfo.inAircraft     = message.inAircraft;
            playerRadioInfo.intercomHotMic = message.intercomHotMic;

            if (_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys.AlwaysAllowHotasControls))
            {
                message.control         = DCSPlayerRadioInfo.RadioSwitchControls.HOTAS;
                playerRadioInfo.control = DCSPlayerRadioInfo.RadioSwitchControls.HOTAS;
            }
            else
            {
                playerRadioInfo.control = message.control;
            }

            playerRadioInfo.simultaneousTransmissionControl = message.simultaneousTransmissionControl;

            playerRadioInfo.unit = message.unit;


            if (!_clientStateSingleton.ShouldUseLotATCPosition())
            {
                _clientStateSingleton.UpdatePlayerPosition(message.pos, message.latLng);
            }

            var overrideFreqAndVol = false;

            var newAircraft = playerRadioInfo.unitId != message.unitId || !playerRadioInfo.IsCurrent();

            if (message.unitId >= DCSPlayerRadioInfo.UnitIdOffset &&
                playerRadioInfo.unitId >= DCSPlayerRadioInfo.UnitIdOffset)
            {
                //overriden so leave as is
            }
            else
            {
                overrideFreqAndVol     = playerRadioInfo.unitId != message.unitId;
                playerRadioInfo.unitId = message.unitId;
            }

            if (newAircraft)
            {
                if (_globalSettings.GetClientSettingBool(GlobalSettingsKeys.AutoSelectSettingsProfile))
                {
                    _newAircraftCallback(message.unit);
                }

                playerRadioInfo.iff = message.iff;
            }

            if (overrideFreqAndVol)
            {
                playerRadioInfo.selected = message.selected;
                changed = true;
            }

            if (playerRadioInfo.control == DCSPlayerRadioInfo.RadioSwitchControls.IN_COCKPIT)
            {
                playerRadioInfo.selected = message.selected;
            }

            bool simul = false;


            //copy over radio names, min + max
            for (var i = 0; i < playerRadioInfo.radios.Length; i++)
            {
                var clientRadio = playerRadioInfo.radios[i];

                //if awacs NOT open -  disable radios over 3
                if (i >= message.radios.Length ||
                    (RadioOverlayWindow.AwacsActive == false &&
                     (i > 3 || i == 0)
                     // disable intercom and all radios over 3 if awacs panel isnt open and we're a spectator given by the UnitId
                     && playerRadioInfo.unitId >= DCSPlayerRadioInfo.UnitIdOffset))
                {
                    clientRadio.freq       = 1;
                    clientRadio.freqMin    = 1;
                    clientRadio.freqMax    = 1;
                    clientRadio.secFreq    = 0;
                    clientRadio.modulation = RadioInformation.Modulation.DISABLED;
                    clientRadio.name       = "No Radio";

                    clientRadio.freqMode      = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.guardFreqMode = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.encMode       = RadioInformation.EncryptionMode.NO_ENCRYPTION;
                    clientRadio.volMode       = RadioInformation.VolumeMode.COCKPIT;

                    continue;
                }

                var updateRadio = message.radios[i];


                if ((updateRadio.expansion && !expansion) ||
                    (updateRadio.modulation == RadioInformation.Modulation.DISABLED))
                {
                    //expansion radio, not allowed
                    clientRadio.freq       = 1;
                    clientRadio.freqMin    = 1;
                    clientRadio.freqMax    = 1;
                    clientRadio.secFreq    = 0;
                    clientRadio.modulation = RadioInformation.Modulation.DISABLED;
                    clientRadio.name       = "No Radio";

                    clientRadio.freqMode      = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.guardFreqMode = RadioInformation.FreqMode.COCKPIT;
                    clientRadio.encMode       = RadioInformation.EncryptionMode.NO_ENCRYPTION;
                    clientRadio.volMode       = RadioInformation.VolumeMode.COCKPIT;
                }
                else
                {
                    //update common parts
                    clientRadio.freqMin = updateRadio.freqMin;
                    clientRadio.freqMax = updateRadio.freqMax;

                    if (playerRadioInfo.simultaneousTransmissionControl == DCSPlayerRadioInfo.SimultaneousTransmissionControl.EXTERNAL_DCS_CONTROL)
                    {
                        clientRadio.simul = updateRadio.simul;
                    }

                    if (updateRadio.simul)
                    {
                        simul = true;
                    }

                    clientRadio.name = updateRadio.name;

                    clientRadio.modulation = updateRadio.modulation;

                    //update modes
                    clientRadio.freqMode      = updateRadio.freqMode;
                    clientRadio.guardFreqMode = updateRadio.guardFreqMode;

                    if (_serverSettings.GetSettingAsBool(ServerSettingsKeys.ALLOW_RADIO_ENCRYPTION))
                    {
                        clientRadio.encMode = updateRadio.encMode;
                    }
                    else
                    {
                        clientRadio.encMode = RadioInformation.EncryptionMode.NO_ENCRYPTION;
                    }

                    clientRadio.volMode = updateRadio.volMode;

                    if ((updateRadio.freqMode == RadioInformation.FreqMode.COCKPIT) || overrideFreqAndVol)
                    {
                        if (clientRadio.freq != updateRadio.freq)
                        {
                            changed = true;
                        }

                        if (clientRadio.secFreq != updateRadio.secFreq)
                        {
                            changed = true;
                        }

                        clientRadio.freq = updateRadio.freq;

                        if (newAircraft && updateRadio.guardFreqMode == RadioInformation.FreqMode.OVERLAY)
                        {
                            //default guard to off
                            clientRadio.secFreq = 0;
                        }
                        else
                        {
                            if (clientRadio.secFreq != 0 && updateRadio.guardFreqMode == RadioInformation.FreqMode.OVERLAY)
                            {
                                //put back
                                clientRadio.secFreq = updateRadio.secFreq;
                            }
                            else if (clientRadio.secFreq == 0 && updateRadio.guardFreqMode == RadioInformation.FreqMode.OVERLAY)
                            {
                                clientRadio.secFreq = 0;
                            }
                            else
                            {
                                clientRadio.secFreq = updateRadio.secFreq;
                            }
                        }



                        clientRadio.channel = updateRadio.channel;
                    }
                    else
                    {
                        if (clientRadio.secFreq != 0)
                        {
                            //put back
                            clientRadio.secFreq = updateRadio.secFreq;
                        }

                        //check we're not over a limit
                        if (clientRadio.freq > clientRadio.freqMax)
                        {
                            clientRadio.freq = clientRadio.freqMax;
                        }
                        else if (clientRadio.freq < clientRadio.freqMin)
                        {
                            clientRadio.freq = clientRadio.freqMin;
                        }
                    }

                    //reset encryption
                    if (overrideFreqAndVol)
                    {
                        clientRadio.enc    = false;
                        clientRadio.encKey = 0;
                    }

                    //Handle Encryption
                    if (updateRadio.encMode == RadioInformation.EncryptionMode.ENCRYPTION_JUST_OVERLAY)
                    {
                        if (clientRadio.encKey == 0)
                        {
                            clientRadio.encKey = 1;
                        }
                    }
                    else if (clientRadio.encMode ==
                             RadioInformation.EncryptionMode.ENCRYPTION_COCKPIT_TOGGLE_OVERLAY_CODE)
                    {
                        clientRadio.enc = updateRadio.enc;

                        if (clientRadio.encKey == 0)
                        {
                            clientRadio.encKey = 1;
                        }
                    }
                    else if (clientRadio.encMode == RadioInformation.EncryptionMode.ENCRYPTION_FULL)
                    {
                        clientRadio.enc    = updateRadio.enc;
                        clientRadio.encKey = updateRadio.encKey;
                    }
                    else
                    {
                        clientRadio.enc    = false;
                        clientRadio.encKey = 0;
                    }

                    //handle volume
                    if ((updateRadio.volMode == RadioInformation.VolumeMode.COCKPIT) || overrideFreqAndVol)
                    {
                        clientRadio.volume = updateRadio.volume;
                    }

                    //handle Channels load for radios
                    if (newAircraft && i > 0)
                    {
                        if (clientRadio.freqMode == RadioInformation.FreqMode.OVERLAY)
                        {
                            var channelModel = _clientStateSingleton.FixedChannels[i - 1];
                            channelModel.Max = clientRadio.freqMax;
                            channelModel.Min = clientRadio.freqMin;
                            channelModel.Reload();
                            clientRadio.channel = -1; //reset channel

                            if (_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys.AutoSelectPresetChannel))
                            {
                                RadioHelper.RadioChannelUp(i);
                            }
                        }
                        else
                        {
                            _clientStateSingleton.FixedChannels[i - 1].Clear();
                            //clear
                        }
                    }
                }
            }


            if (playerRadioInfo.simultaneousTransmissionControl ==
                DCSPlayerRadioInfo.SimultaneousTransmissionControl.EXTERNAL_DCS_CONTROL)
            {
                playerRadioInfo.simultaneousTransmission = simul;
            }

            //change PTT last
            if (!_globalSettings.ProfileSettingsStore.GetClientSettingBool(ProfileSettingsKeys.AllowDCSPTT))
            {
                playerRadioInfo.ptt = false;
            }
            else
            {
                playerRadioInfo.ptt = message.ptt;
            }

            //HANDLE IFF/TRANSPONDER UPDATE
            //TODO tidy up the IFF/Transponder handling and this giant function in general as its silly big :(
            if (message.iff.control == Transponder.IFFControlMode.COCKPIT)
            {
                playerRadioInfo.iff = message.iff;
            }

            //HANDLE MIC IDENT
            if (!playerRadioInfo.ptt && playerRadioInfo.iff.mic > 0 && UdpVoiceHandler.RadioSendingState.IsSending)
            {
                if (UdpVoiceHandler.RadioSendingState.SendingOn == playerRadioInfo.iff.mic)
                {
                    playerRadioInfo.iff.status = Transponder.IFFStatus.IDENT;
                }
            }


            //                }
            //            }

            //update
            playerRadioInfo.LastUpdate = DateTime.Now.Ticks;

            return(changed);
        }