public void Start()
        {
            //reset last sent
            _clientStateSingleton.LastSent = 0;

            Task.Factory.StartNew(() =>
            {
                while (!_stop)
                {
                    var localEp = new IPEndPoint(IPAddress.Any, _globalSettings.GetNetworkSetting(GlobalSettingsKeys.IL2IncomingUDP));
                    try
                    {
                        _il2UdpListener = new UdpClient(localEp);
                        break;
                    }
                    catch (Exception ex)
                    {
                        Logger.Warn(ex, $"Unable to bind to the IL2 Export Listener Socket Port: {localEp.Port}");
                        Thread.Sleep(500);
                    }
                }

                while (!_stop)
                {
                    try
                    {
                        var groupEp = new IPEndPoint(IPAddress.Any, 0);
                        var bytes   = _il2UdpListener.Receive(ref groupEp);

                        if (bytes.Length > 2)
                        {
                            var messages = IL2UDPMessage.Process(bytes);

                            //IL2 running
                            _clientStateSingleton.IL2ExportLastReceived      = DateTime.Now.Ticks;
                            _clientStateSingleton.PlayerGameState.LastUpdate = DateTime.Now.Ticks;

                            foreach (var msg in messages)
                            {
                                Logger.Debug($"Recevied Message from IL2 {msg.ToString()}");
                                ProcessUDPMessage(msg);
                            }
                        }
                    }
                    catch (SocketException e)
                    {
                        // SocketException is raised when closing app/disconnecting, ignore so we don't log "irrelevant" exceptions
                        if (!_stop)
                        {
                            Logger.Error(e, "SocketException Handling IL2 Message");
                        }
                    }
                    catch (Exception e)
                    {
                        Logger.Error(e, "Exception Handling IL2 Message");
                    }
                }

                try
                {
                    _il2UdpListener.Close();
                }
                catch (Exception e)
                {
                    Logger.Error(e, "Exception stoping IL2 listener ");
                }
            });
        }
        public void ProcessUDPMessage(IL2UDPMessage message)
        {
            bool update = false;

            var playerRadioInfo = _clientStateSingleton.PlayerGameState;

            //copy and compare to look for changes

            /**
             * So ParentID - is an ID of another Client, who owns the vehicle which crew you're participating in now. For instance:
             * Alan is riding his tank on the server. His ClientID is 12345. His ParentID=-1.
             * Now Peter is joining Alan's crew as a gunner. He has his own ClientID=54321. But also he has ParentID=12345.
             * Donald now joined Alan's crew too as radist. Hi has his own ClientID=34251. But also he has ParentID=12345.
             * So if someone on Server has ParentID!=-1 but ParentID=12345 - this means that intercom channel started. And the commander of this intercom is another client with  ClientID=12345.
             */

            if (message is ClientDataMessage dataMessage)
            {   //Just set the Client
                update = playerRadioInfo.unitId != dataMessage.ClientID ||
                         !dataMessage.PlayerName.Equals(_clientStateSingleton.LastSeenName);

                playerRadioInfo.unitId = dataMessage.ClientID;

                Logger.Debug($"ClientID {dataMessage.ClientID}");

                _clientStateSingleton.LastSeenName = dataMessage.PlayerName;
            }
            else if (message is ControlDataMessage controlDataMessage)
            {
                update = playerRadioInfo.vehicleId != controlDataMessage.ParentVehicleClientID || playerRadioInfo.coalition != controlDataMessage.Coalition;

                Logger.Info($"Coalition Update {controlDataMessage.Coalition}");
                Logger.Info($"ParentVehicleClientID {controlDataMessage.ParentVehicleClientID}");

                if (controlDataMessage.Coalition == 0)
                {
                    //WE SOMETIMES RECEIVE AND INCORRECT COALITION MESSAGE - Just kept it for now?>
                    // playerRadioInfo.vehicleId = controlDataMessage.ParentVehicleClientID;
                    // playerRadioInfo.coalition = controlDataMessage.Coalition;
                    Logger.Info($"Ignore Coalition Update for Spectator");
                }
                else
                {
                    playerRadioInfo.vehicleId = controlDataMessage.ParentVehicleClientID;
                    playerRadioInfo.coalition = controlDataMessage.Coalition;
                }
            }
            else if (message is SRSAddressMessage srs)
            {
                if (srs.SRSAddress.Length > 0)
                {
                    //call on main
                    Application.Current.Dispatcher.Invoke(() => { MessageHub.Instance.Publish(srs); });
                }
            }

            var diff = new TimeSpan(DateTime.Now.Ticks - _clientStateSingleton.LastSent);

            if (update ||
                _clientStateSingleton.LastSent < 1 ||
                diff.TotalSeconds > RADIO_UPDATE_PING_INTERVAL)
            {
                Logger.Debug("Sending Radio Info To Server - Update");
                _clientStateSingleton.LastSent = DateTime.Now.Ticks;

                MessageHub.Instance.Publish(new PlayerStateUpdate());
            }
        }