public bool Equals(UserAircraftData other)
 {
     return(Latitude == other.Latitude &&
            Longitude == other.Longitude &&
            Heading == other.Heading &&
            Bank == other.Bank &&
            Pitch == other.Pitch &&
            AltitudeMsl == other.AltitudeMsl &&
            PressureAltitude == other.PressureAltitude &&
            GroundSpeed == other.GroundSpeed &&
            OnGround == other.OnGround &&
            FlapsPercentage == other.FlapsPercentage &&
            SpeedBrakeDeployed == other.SpeedBrakeDeployed &&
            GearDown == other.GearDown &&
            StrobeLightsOn == other.StrobeLightsOn &&
            BeaconLightsOn == other.BeaconLightsOn &&
            TaxiLightsOn == other.TaxiLightsOn &&
            LandingLightsOn == other.LandingLightsOn &&
            NavLightsOn == other.NavLightsOn &&
            TransponderCode == other.TransponderCode &&
            TransponderMode == other.TransponderMode &&
            TransponderIdent == other.TransponderIdent &&
            EngineCount == other.EngineCount &&
            Engine1Running == other.Engine1Running &&
            Engine2Running == other.Engine2Running &&
            Engine3Running == other.Engine3Running &&
            Engine4Running == other.Engine4Running &&
            ReplayModeEnabled == other.ReplayModeEnabled);
 }
        public void OnUserAircraftDataUpdated(object sender, UserAircraftDataUpdatedEventArgs e)
        {
            if (UserAircraftData == null || !UserAircraftData.Equals(e.UserAircraftData))
            {
                UserAircraftData = e.UserAircraftData;
            }

            if ((mLastBroadcastConfig == null) || !mFsdManager.IsConnected)
            {
                mLastBroadcastConfig = AircraftConfiguration.FromUserAircraftData(UserAircraftData);
            }
            else if (mAcconfigAvailableTokens > 0)
            {
                AircraftConfiguration newCfg = AircraftConfiguration.FromUserAircraftData(UserAircraftData);
                if (!newCfg.Equals(mLastBroadcastConfig))
                {
                    AircraftConfiguration incremental = mLastBroadcastConfig.CreateIncremental(newCfg);
                    mFsdManager.SendIncrementalAircraftConfigurationUpdate(incremental);
                    mLastBroadcastConfig = newCfg;
                    mAcconfigAvailableTokens--;
                }
            }
            bool wasAirborne = mAirborne;

            mAirborne = !UserAircraftData.OnGround;
            if (mInitialAircraftDataReceived && !wasAirborne && mAirborne && !mConfig.SquawkingModeC && mConfig.AutoSquawkModeC)
            {
                var laminarB738 = new XPlaneConnector.DataRefElement
                {
                    DataRef = "laminar/B738/knob/transpoder_pos"
                };

                var laminarB738_Dn_Cmd = new XPlaneConnector.XPlaneCommand("laminar/B738/knob/transponder_mode_up", "");
                var laminarB738_Up_Cmd = new XPlaneConnector.XPlaneCommand("laminar/B738/knob/transponder_mode_up", "");

                SendXplaneCommand?.Invoke(this, new ClientEventArgs <XPlaneConnector.XPlaneCommand>(laminarB738_Up_Cmd));
                SetXplaneDataRefValue?.Invoke(this, new DataRefEventArgs(laminarB738, 3));
                SendXplaneCommand?.Invoke(this, new ClientEventArgs <XPlaneConnector.XPlaneCommand>(XPlaneConnector.Commands.TransponderTransponderAlt));
            }
            mInitialAircraftDataReceived = true;
        }
        public XplaneConnectionManager(IEventBroker broker, IAppConfig config, IFsdManger fsdManager) : base(broker)
        {
            DealerSocket visualDealerSocket = null;

            mVisualDealerSockets = null;
            mConfig     = config;
            mFsdManager = fsdManager;

            if (mConfig.VisualClientIPs.Count > 0)
            {
                foreach (string mIP in mConfig.VisualClientIPs)
                {
                    visualDealerSocket = new DealerSocket();
                    visualDealerSocket.Options.Identity     = Encoding.UTF8.GetBytes("CLIENT");
                    visualDealerSocket.Options.TcpKeepalive = true;
                    try
                    {
                        visualDealerSocket.Connect("tcp://" + mIP + ":" + mConfig.TcpPort);
                        if (mVisualDealerSockets == null)
                        {
                            mVisualDealerSockets = new List <DealerSocket>();
                        }
                        mVisualDealerSockets.Add(visualDealerSocket);
                    }
                    catch (AddressAlreadyInUseException)
                    {
                        NotificationPosted?.Invoke(this, new NotificationPostedEventArgs(NotificationType.Error, "Plugin port already in use. Please choose a different TCP port."));
                    }
                }
            }

            if (!string.IsNullOrEmpty(mConfig.SimClientIP))
            {
                mSimulatorIP = mConfig.SimClientIP;
            }

            mMessageQueue = new NetMQQueue <string>();
            mDealerSocket = new DealerSocket();
            mDealerSocket.Options.TcpKeepalive = true;
            mDealerSocket.Options.Identity     = Encoding.UTF8.GetBytes("CLIENT");
            mDealerSocket.ReceiveReady        += DealerSocket_ReceiveReady;
            try
            {
                mDealerSocket.Connect("tcp://" + mSimulatorIP + ":" + mConfig.TcpPort);
            }
            catch (AddressAlreadyInUseException)
            {
                NotificationPosted?.Invoke(this, new NotificationPostedEventArgs(NotificationType.Error, "Plugin port already in use. Please choose a different TCP port."));
            }
            mPoller = new NetMQPoller {
                mDealerSocket, mMessageQueue
            };
            if (!mPoller.IsRunning)
            {
                mPoller.RunAsync();
            }

            mMessageQueue.ReceiveReady += (s, e) =>
            {
                if (mMessageQueue.TryDequeue(out string msg, TimeSpan.FromMilliseconds(100)))
                {
                    if (mDealerSocket != null)
                    {
                        mDealerSocket.SendFrame(msg);
                    }
                    if (mVisualDealerSockets != null && mVisualDealerSockets.Count > 0)
                    {
                        foreach (DealerSocket socket in mVisualDealerSockets)
                        {
                            socket.SendFrame(msg);
                        }
                    }
                }
            };

            mXplaneConnector  = new XPlaneConnector.XPlaneConnector(mSimulatorIP);
            mUserAircraftData = new UserAircraftData();
            mRadioStackState  = new UserAircraftRadioStack();

            mGetXplaneDataTimer = new Timer
            {
                Interval = 10
            };
            mGetXplaneDataTimer.Tick += GetXplaneDataTimer_Tick;
            mGetXplaneDataTimer.Start();

            mConnectionTimer = new Timer
            {
                Interval = 50
            };
            mConnectionTimer.Tick += ConnectionTimer_Tick;
            mConnectionTimer.Start();

            mRetryConnectionTimer = new Timer
            {
                Interval = 1000
            };
            mRetryConnectionTimer.Tick += RetryConnectionTimer_Tick;
            mRetryConnectionTimer.Start();

            mWhosOnlineListRefresh = new Timer
            {
                Interval = 5000
            };
            mWhosOnlineListRefresh.Tick += WhosOnlineListRefresh_Tick;

            SetupSubscribers();

            if (!Directory.Exists(Path.Combine(mConfig.AppPath, "PluginLogs")))
            {
                Directory.CreateDirectory(Path.Combine(mConfig.AppPath, "PluginLogs"));
            }

            var directory = new DirectoryInfo(Path.Combine(mConfig.AppPath, "PluginLogs"));
            var query     = directory.GetFiles("*", SearchOption.AllDirectories);

            foreach (var file in query.OrderByDescending(file => file.CreationTime).Skip(10))
            {
                file.Delete();
            }

            mRawDataStream = new StreamWriter(Path.Combine(mConfig.AppPath, string.Format($"PluginLogs/PluginLog-{DateTime.UtcNow:yyyyMMddHHmmss}.log")), false);
        }