private void UpdateNetworkAircraftInSim(NetworkAircraft aircraft, NetworkAircraftState State)
        {
            dynamic data = new ExpandoObject();

            data.Callsign         = aircraft.Callsign;
            data.Latitude         = State.Location.Lat;
            data.Longitude        = State.Location.Lon;
            data.Altitude         = State.Altitude;
            data.Bank             = State.Bank;
            data.Pitch            = State.Pitch;
            data.Heading          = State.Heading;
            data.GroundSpeed      = State.GroundSpeed;
            data.TransponderCode  = State.Transponder.TransponderCode;
            data.TransponderModeC = State.Transponder.TransponderModeC;
            data.TransponderIdent = State.Transponder.TransponderIdent;
            data.Origin           = aircraft.OriginAirport;
            data.Destination      = aircraft.DestinationAirport;

            XplaneConnect xp = new XplaneConnect
            {
                Type      = XplaneConnect.MessageType.PositionUpdate,
                Timestamp = DateTime.Now,
                Data      = data
            };

            XPlaneEventPosted?.Invoke(this, new ClientEventArgs <string>(xp.ToJSON()));
        }
        private void DeleteNetworkAircraft(NetworkAircraft aircraft)
        {
            dynamic data = new ExpandoObject();

            data.Callsign = aircraft.Callsign;

            XplaneConnect xp = new XplaneConnect
            {
                Type      = XplaneConnect.MessageType.RemovePlane,
                Timestamp = DateTime.Now,
                Data      = data
            };

            XPlaneEventPosted?.Invoke(this, new ClientEventArgs <string>(xp.ToJSON()));
            mNetworkAircraft.Remove(aircraft);
        }
        public void OnNetworkAircraftInfoReceived(object sender, NetworkDataReceivedEventArgs e)
        {
            NetworkAircraft aircraft = mNetworkAircraft.FirstOrDefault(o => o.Callsign == e.From);

            if (aircraft == null)
            {
                Console.WriteLine($"Received aircraft info for an unknown aircraft: {e.From}");
            }
            else
            {
                if (!string.IsNullOrEmpty(aircraft.TypeCode))
                {
                    if (aircraft.TypeCode != e.Data)
                    {
                        Console.WriteLine($"Received new aircraft info for {e.From} - changing model");

                        aircraft.TypeCode = e.Data.IndexOf("-") > -1 ? e.Data.Substring(0, e.Data.IndexOf("-")) : e.Data;

                        dynamic data = new ExpandoObject();
                        data.Callsign = aircraft.Callsign;
                        data.TypeCode = aircraft.TypeCode.Substring(0, Math.Min(4, aircraft.TypeCode.Length));
                        data.Airline  = aircraft.AirlineIcao;

                        XplaneConnect xp = new XplaneConnect
                        {
                            Type      = XplaneConnect.MessageType.ChangeModel,
                            Timestamp = DateTime.Now,
                            Data      = data
                        };
                        XPlaneEventPosted?.Invoke(this, new ClientEventArgs <string>(xp.ToJSON()));
                    }
                    else
                    {
                        Console.WriteLine($"Received unchanged aircraft info for {e.From} - already have a model selected");
                    }
                }
                else
                {
                    aircraft.TypeCode = e.Data.IndexOf("-") > -1 ? e.Data.Substring(0, e.Data.IndexOf("-")) : e.Data;
                    AddAircraftToSim(aircraft);
                }
            }
        }
        private void AddAircraftToSim(NetworkAircraft aircraft)
        {
            aircraft.Status = AircraftStatus.Active;

            dynamic data = new ExpandoObject();

            data.Callsign = aircraft.Callsign;
            data.TypeCode = aircraft.TypeCode.Substring(0, Math.Min(4, aircraft.TypeCode.Length));
            if (aircraft.Callsign.Length >= 3)
            {
                data.Airline = aircraft.Callsign.Substring(0, 3);
            }

            XplaneConnect xp = new XplaneConnect
            {
                Type      = XplaneConnect.MessageType.AddPlane,
                Timestamp = DateTime.Now,
                Data      = data
            };

            XPlaneEventPosted?.Invoke(this, new ClientEventArgs <string>(xp.ToJSON()));
        }
        private void ProcessAircraftConfig(NetworkAircraft aircraft, AircraftConfiguration config)
        {
            NetworkAircraftConfig cfgInterop = new NetworkAircraftConfig
            {
                Callsign  = aircraft.Callsign,
                Timestamp = DateTime.Now
            };

            if (config.IsFullData.HasValue && config.IsFullData.Value)
            {
                config.EnsurePopulated();
                aircraft.SupportsConfigurationProtocol = true;
                aircraft.Configuration = config;
            }
            else
            {
                if (!aircraft.SupportsConfigurationProtocol || aircraft.Configuration == null)
                {
                    return;
                }
                aircraft.Configuration.ApplyIncremental(config);
            }

            if (!aircraft.InitialConfigurationSet)
            {
                if (aircraft.Configuration.Lights.StrobesOn.HasValue)
                {
                    cfgInterop.Lights.StrobesOn = aircraft.Configuration.Lights.StrobesOn.Value;
                }
                if (aircraft.Configuration.Lights.LandingOn.HasValue)
                {
                    cfgInterop.Lights.LandingOn = aircraft.Configuration.Lights.LandingOn.Value;
                }
                if (aircraft.Configuration.Lights.TaxiOn.HasValue)
                {
                    cfgInterop.Lights.TaxiOn = aircraft.Configuration.Lights.TaxiOn.Value;
                }
                if (aircraft.Configuration.Lights.BeaconOn.HasValue)
                {
                    cfgInterop.Lights.BeaconOn = aircraft.Configuration.Lights.BeaconOn.Value;
                }
                if (aircraft.Configuration.Lights.NavOn.HasValue)
                {
                    cfgInterop.Lights.NavOn = aircraft.Configuration.Lights.NavOn.Value;
                }
                if (aircraft.Configuration.OnGround.HasValue)
                {
                    cfgInterop.OnGround = aircraft.Configuration.OnGround.Value;
                }
                if (aircraft.Configuration.FlapsPercent.HasValue)
                {
                    cfgInterop.Flaps = aircraft.Configuration.FlapsPercent.Value / 100.0f;
                }
                if (aircraft.Configuration.GearDown.HasValue)
                {
                    cfgInterop.GearDown = aircraft.Configuration.GearDown.Value;
                }
                if (aircraft.Configuration.Engines.IsAnyEngineRunning)
                {
                    cfgInterop.EnginesOn = aircraft.Configuration.Engines.IsAnyEngineRunning;
                }
                if (aircraft.Configuration.SpoilersDeployed.HasValue)
                {
                    cfgInterop.SpoilersDeployed = aircraft.Configuration.SpoilersDeployed.Value;
                }
                aircraft.InitialConfigurationSet = true;
            }
            else
            {
                if (aircraft.LastAppliedConfiguration == null)
                {
                    aircraft.InitialConfigurationSet = false;
                    Console.WriteLine($"LastAppliedConfiguration null; Requesting full ACCONFIG for: {aircraft.Callsign}");
                    mFsdManager.RequestFullAircraftConfiguration(aircraft.Callsign);
                    return;
                }

                if (aircraft.Configuration.Lights.StrobesOn.HasValue && aircraft.Configuration.Lights.StrobesOn.Value != aircraft.LastAppliedConfiguration.Lights.StrobesOn.Value)
                {
                    cfgInterop.Lights.StrobesOn = aircraft.Configuration.Lights.StrobesOn.Value;
                }
                if (aircraft.Configuration.Lights.NavOn.HasValue && aircraft.Configuration.Lights.NavOn.Value != aircraft.LastAppliedConfiguration.Lights.NavOn.Value)
                {
                    cfgInterop.Lights.NavOn = aircraft.Configuration.Lights.NavOn.Value;
                }
                if (aircraft.Configuration.Lights.BeaconOn.HasValue && aircraft.Configuration.Lights.BeaconOn.Value != aircraft.LastAppliedConfiguration.Lights.BeaconOn.Value)
                {
                    cfgInterop.Lights.BeaconOn = aircraft.Configuration.Lights.BeaconOn.Value;
                }
                if (aircraft.Configuration.Lights.LandingOn.HasValue && aircraft.Configuration.Lights.LandingOn.Value != aircraft.LastAppliedConfiguration.Lights.LandingOn.Value)
                {
                    cfgInterop.Lights.LandingOn = aircraft.Configuration.Lights.LandingOn.Value;
                }
                if (aircraft.Configuration.Lights.TaxiOn.HasValue && aircraft.Configuration.Lights.TaxiOn.Value != aircraft.LastAppliedConfiguration.Lights.TaxiOn.Value)
                {
                    cfgInterop.Lights.TaxiOn = aircraft.Configuration.Lights.TaxiOn.Value;
                }
                if (aircraft.Configuration.GearDown.HasValue && aircraft.Configuration.GearDown.Value != aircraft.LastAppliedConfiguration.GearDown.Value)
                {
                    cfgInterop.GearDown = aircraft.Configuration.GearDown.Value;
                }
                if (aircraft.Configuration.OnGround.HasValue && aircraft.Configuration.OnGround.Value != aircraft.LastAppliedConfiguration.OnGround.Value)
                {
                    cfgInterop.OnGround = aircraft.Configuration.OnGround.Value;
                }
                if (aircraft.Configuration.FlapsPercent.HasValue && aircraft.Configuration.FlapsPercent.Value != aircraft.LastAppliedConfiguration.FlapsPercent.Value)
                {
                    cfgInterop.Flaps = aircraft.Configuration.FlapsPercent.Value / 100.0f;
                }
                if (aircraft.Configuration.SpoilersDeployed.HasValue && aircraft.Configuration.SpoilersDeployed.Value != aircraft.LastAppliedConfiguration.SpoilersDeployed.Value)
                {
                    cfgInterop.SpoilersDeployed = aircraft.Configuration.SpoilersDeployed.Value;
                }
                if (aircraft.Configuration.Engines.IsAnyEngineRunning != aircraft.LastAppliedConfiguration.Engines.IsAnyEngineRunning)
                {
                    cfgInterop.EnginesOn = aircraft.Configuration.Engines.IsAnyEngineRunning;
                }
            }
            aircraft.LastAppliedConfiguration = aircraft.Configuration.Clone();

            if (cfgInterop.HasConfig)
            {
                XplaneConnect xp = new XplaneConnect
                {
                    Type      = XplaneConnect.MessageType.SurfaceUpdate,
                    Timestamp = DateTime.Now,
                    Data      = cfgInterop
                };
                XPlaneEventPosted?.Invoke(this, new ClientEventArgs <string>(xp.ToJSON()));
                Console.WriteLine($"Sending ACCONFIG to the sim for: {aircraft.Callsign} - {xp.ToJSON()}");
            }
        }
        private void UpdateLegacyAircraftConfig(NetworkAircraft aircraft, LegacyClientConfigFlags flags)
        {
            NetworkAircraftConfig temp = new NetworkAircraftConfig
            {
                Callsign  = aircraft.Callsign,
                Timestamp = DateTime.Now,
            };

            if (!aircraft.InitialConfigurationSet)
            {
                temp.GearDown                    = flags.GearDown;
                temp.OnGround                    = flags.OnGround;
                temp.Lights.TaxiOn               = flags.TaxiLightsOn;
                temp.Lights.LandingOn            = flags.LandingLightsOn;
                temp.Lights.BeaconOn             = flags.BeaconLightsOn;
                temp.Lights.NavOn                = flags.NavLightsOn;
                temp.Lights.StrobesOn            = flags.StrobeLightsOn;
                temp.EnginesOn                   = flags.EnginesRunning;
                aircraft.InitialConfigurationSet = true;
            }
            else
            {
                if (flags.GearDown != aircraft.LastAppliedConfigFlags.GearDown)
                {
                    temp.GearDown = flags.GearDown;
                }
                if (flags.OnGround != aircraft.LastAppliedConfigFlags.OnGround)
                {
                    temp.OnGround = flags.OnGround;
                }
                if (flags.TaxiLightsOn != aircraft.LastAppliedConfigFlags.TaxiLightsOn)
                {
                    temp.Lights.TaxiOn = flags.TaxiLightsOn;
                }
                if (flags.LandingLightsOn != aircraft.LastAppliedConfigFlags.LandingLightsOn)
                {
                    temp.Lights.LandingOn = flags.LandingLightsOn;
                }
                if (flags.BeaconLightsOn != aircraft.LastAppliedConfigFlags.BeaconLightsOn)
                {
                    temp.Lights.BeaconOn = flags.BeaconLightsOn;
                }
                if (flags.NavLightsOn != aircraft.LastAppliedConfigFlags.NavLightsOn)
                {
                    temp.Lights.NavOn = flags.NavLightsOn;
                }
                if (flags.EnginesRunning != aircraft.LastAppliedConfigFlags.EnginesRunning)
                {
                    temp.EnginesOn = flags.EnginesRunning;
                }
            }
            aircraft.LastAppliedConfigFlags = flags;

            if (temp.HasConfig)
            {
                XplaneConnect msg = new XplaneConnect
                {
                    Type      = XplaneConnect.MessageType.SurfaceUpdate,
                    Timestamp = DateTime.Now,
                    Data      = temp
                };
                XPlaneEventPosted?.Invoke(this, new ClientEventArgs <string>(msg.ToJSON()));
                Console.WriteLine($"Sending Legacy Config to the sim for: {aircraft.Callsign} - {msg.ToJSON()}");
            }
        }