Пример #1
0
 public UIOverallStatus(UIMode.MajorModeType mm, UIMode.ModeType mt, List <UITypeEnum> list, int focus, UIPips.Pips pips, int fg, double fuel, double res, int cargo,
                        UIPosition.Position pos, double heading, double radius, string legalstate, string bodyname,
                        double health, bool lowh, double gravity, double temp, UITemperature.TempState tempstate, double oxygen, bool lowox,
                        string selw, string selwloc,
                        FSDStateType fsd, bool breathableatmosphere,
                        DateTime time, bool refresh) : this(time, refresh)
 {
     MajorMode                = mm;
     Mode                     = mt;
     Flags                    = list;
     Focus                    = (UIGUIFocus.Focus)focus;
     Pips                     = pips;
     Firegroup                = fg;
     Fuel                     = fuel;
     Reserve                  = res;
     Cargo                    = cargo;
     Pos                      = pos;
     Heading                  = heading;
     PlanetRadius             = radius;
     LegalState               = legalstate;
     BodyName                 = bodyname;
     Health                   = health;
     LowHealth                = lowh;
     Gravity                  = gravity;
     Temperature              = temp;
     TemperatureState         = tempstate;
     Oxygen                   = oxygen;
     LowOxygen                = lowox;
     FSDState                 = fsd;
     BreathableAtmosphere     = breathableatmosphere;
     SelectedWeapon           = selw;
     SelectedWeapon_Localised = selwloc;
 }
        private void ScanThreadProc()
        {
            string prev_text    = null;
            int    nextpolltime = ScanRate;

            while (!StopRequested.WaitOne(nextpolltime))
            {
                //System.Diagnostics.Debug.WriteLine(Environment.TickCount % 100000 + "Check " + watchfile);

                if (File.Exists(watchfile))
                {
                    nextpolltime = ScanRate;

                    JObject jo = null;

                    Stream stream = null;
                    try
                    {
                        stream = File.Open(watchfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                        StreamReader reader = new StreamReader(stream);

                        string text = reader.ReadLine();

                        stream.Close();

                        if (text == null || (prev_text != null && text.Equals(prev_text)))        // if text the same, ignore
                        {
                            continue;
                        }

                        //System.Diagnostics.Debug.WriteLine("New status text " + text);

                        jo = (JObject)JObject.Parse(text); // and of course the json could be crap

                        prev_text = text;                  // set after successful parse
                    }
                    catch
                    { }
                    finally
                    {
                        if (stream != null)
                        {
                            stream.Dispose();
                        }
                    }


                    if (jo != null)
                    {
                        DateTime EventTimeUTC = DateTime.Parse(jo.Value <string>("timestamp"), CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal);

                        List <UIEvent> events = new List <UIEvent>();

                        long curflags = (long)jo["Flags"].Long();

                        if (prev_flags == null || curflags != prev_flags.Value)
                        {
                            if (prev_flags == null)
                            {
                                prev_flags = (long)StatusFlagsShipType.ShipMask;      // set an impossible ship type to start the ball rolling
                            }
                            long shiptype     = curflags & (long)StatusFlagsShipType.ShipMask;
                            long prevshiptype = prev_flags.Value & (long)StatusFlagsShipType.ShipMask;

                            if (shiptype != prevshiptype)
                            {
                                UIEvents.UIShipType.Shiptype t = shiptype == 1L << (int)StatusFlagsShipType.InMainShip ? UIEvents.UIShipType.Shiptype.MainShip :
                                                                 shiptype == 1L << (int)StatusFlagsShipType.InSRV ? UIEvents.UIShipType.Shiptype.SRV :
                                                                 shiptype == 1L << (int)StatusFlagsShipType.InFighter ? UIEvents.UIShipType.Shiptype.Fighter :
                                                                 UIEvents.UIShipType.Shiptype.None;

                                events.Add(new UIEvents.UIShipType(t, EventTimeUTC)); // CHANGE of ship
                                prev_flags = ~curflags;                               // force re-reporting
                            }

                            if (shiptype == (long)StatusFlagsShipType.InMainShip)
                            {
                                events.AddRange(ReportFlagState(typeof(StatusFlagsShip), curflags, prev_flags.Value, EventTimeUTC));
                            }
                            else if (shiptype == (long)StatusFlagsShipType.InSRV)
                            {
                                events.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags, prev_flags.Value, EventTimeUTC));
                            }

                            if (shiptype != 0)      // not none
                            {
                                events.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags, prev_flags.Value, EventTimeUTC));
                            }

                            prev_flags = curflags;
                        }

                        int curguifocus = (int)jo["GuiFocus"].Int();
                        if (curguifocus != prev_guifocus)
                        {
                            events.Add(new UIEvents.UIGUIFocus(curguifocus, EventTimeUTC));
                            prev_guifocus = curguifocus;
                        }

                        int[] pips = jo["Pips"]?.ToObjectProtected <int[]>();

                        if (pips != null)
                        {
                            double sys = pips[0] / 2.0;     // convert to normal, instead of half pips
                            double eng = pips[1] / 2.0;
                            double wep = pips[2] / 2.0;
                            if (sys != prev_pips.Systems || wep != prev_pips.Weapons || eng != prev_pips.Engines)
                            {
                                UIEvents.UIPips.Pips newpips = new UIEvents.UIPips.Pips()
                                {
                                    Systems = sys, Engines = eng, Weapons = wep
                                };
                                events.Add(new UIEvents.UIPips(newpips, EventTimeUTC));
                                prev_pips = newpips;
                            }
                        }

                        int?curfiregroup = jo["FireGroup"].IntNull();       // may appear/disappear.

                        if (curfiregroup != null && curfiregroup != prev_firegroup)
                        {
                            events.Add(new UIEvents.UIFireGroup(curfiregroup.Value + 1, EventTimeUTC));
                            prev_firegroup = curfiregroup.Value;
                        }

                        double jlat     = jo["Latitude"].Double(double.MinValue);   // if not there, min value
                        double jlon     = jo["Longitude"].Double(double.MinValue);
                        double jalt     = jo["Altitude"].Double(double.MinValue);
                        double jheading = jo["Heading"].Double(double.MinValue);

                        if (jlat != prev_pos.Latitude || jlon != prev_pos.Longitude || jalt != prev_pos.Altitude || jheading != prev_heading)
                        {
                            UIEvents.UIPosition.Position newpos = new UIEvents.UIPosition.Position()
                            {
                                Latitude = jlat, Longitude = jlon, Altitude = jalt
                            };
                            events.Add(new UIEvents.UIPosition(newpos, jheading, EventTimeUTC));
                            prev_pos     = newpos;
                            prev_heading = jheading;
                        }

                        if (events.Count > 0)
                        {
                            foreach (UIEvent e in events)
                            {
                                Events.Enqueue(e);
                            }

                            UIEventCallBack?.Invoke(Events, WatcherFolder);        // and fire..
                        }
                    }
                }
                else
                {
                    nextpolltime = ScanRate * 40;           // if its not there, we are probably watching a non journal location.. so just do it occasionally
                }
            }
        }
        private void ScanThreadProc()
        {
            string prev_text    = null;
            int    nextpolltime = ScanRate;

            while (!StopRequested.WaitOne(nextpolltime))
            {
                //System.Diagnostics.Debug.WriteLine(Environment.TickCount % 100000 + "Check " + watchfile);

                if (File.Exists(watchfile))
                {
                    nextpolltime = ScanRate;

                    JObject jo = null;

                    Stream stream = null;
                    try
                    {
                        stream = File.Open(watchfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                        StreamReader reader = new StreamReader(stream);

                        string text = reader.ReadLine();

                        stream.Close();

                        if (text == null || (prev_text != null && text.Equals(prev_text)))        // if text the same, ignore
                        {
                            continue;
                        }

                        //System.Diagnostics.Debug.WriteLine("New status text " + text);

                        jo = JObject.ParseThrowCommaEOL(text); // and of course the json could be crap

                        prev_text = text;                      // set after successful parse
                    }
                    catch
                    { }
                    finally
                    {
                        if (stream != null)
                        {
                            stream.Dispose();
                        }
                    }

                    if (jo != null)
                    {
                        DateTime EventTimeUTC = jo["timestamp"].DateTimeUTC();

                        List <UIEvent> events = new List <UIEvent>();

                        long curflags = jo["Flags"].Long();

                        bool fireoverall        = false;
                        bool fireoverallrefresh = prev_guifocus == -1;     //meaning its a refresh

                        if (prev_flags == null || curflags != prev_flags.Value)
                        {
                            if (prev_flags == null)
                            {
                                prev_flags = (long)StatusFlagsShipType.ShipMask;      // set an impossible ship type to start the ball rolling
                            }
                            UIEvents.UIShipType.Shiptype prevshiptype = ShipType(prev_flags.Value);
                            UIEvents.UIShipType.Shiptype curtype      = ShipType(curflags);

                            bool refresh = prevshiptype == UIEvents.UIShipType.Shiptype.None;   // refresh if prev ship was none..

                            if (prevshiptype != curtype)
                            {
                                events.Add(new UIEvents.UIShipType(curtype, EventTimeUTC, refresh)); // CHANGE of ship
                                prev_flags = ~curflags;                                              // force re-reporting
                                refresh    = true;
                            }

                            if (curtype == UIEvents.UIShipType.Shiptype.MainShip)
                            {
                                events.AddRange(ReportFlagState(typeof(StatusFlagsShip), curflags, prev_flags.Value, EventTimeUTC, refresh));
                            }
                            else if (curtype == UIEvents.UIShipType.Shiptype.SRV)
                            {
                                events.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags, prev_flags.Value, EventTimeUTC, refresh));
                            }

                            if (curtype != UIEvents.UIShipType.Shiptype.None)
                            {
                                events.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags, prev_flags.Value, EventTimeUTC, refresh));
                            }

                            prev_flags  = curflags;
                            fireoverall = true;
                        }

                        int curguifocus = jo["GuiFocus"].Int();
                        if (curguifocus != prev_guifocus)
                        {
                            events.Add(new UIEvents.UIGUIFocus(curguifocus, EventTimeUTC, prev_guifocus == -1));
                            prev_guifocus = curguifocus;
                            fireoverall   = true;
                        }

                        int[] pips = jo["Pips"]?.ToObjectQ <int[]>();

                        if (pips != null)
                        {
                            double sys = pips[0] / 2.0;     // convert to normal, instead of half pips
                            double eng = pips[1] / 2.0;
                            double wep = pips[2] / 2.0;
                            if (sys != prev_pips.Systems || wep != prev_pips.Weapons || eng != prev_pips.Engines)
                            {
                                UIEvents.UIPips.Pips newpips = new UIEvents.UIPips.Pips()
                                {
                                    Systems = sys, Engines = eng, Weapons = wep
                                };
                                events.Add(new UIEvents.UIPips(newpips, EventTimeUTC, prev_pips.Engines < 0));
                                prev_pips   = newpips;
                                fireoverall = true;
                            }
                        }
                        else if (prev_pips.Valid)       // missing pips, if we are valid.. need to clear them
                        {
                            UIEvents.UIPips.Pips newpips = new UIEvents.UIPips.Pips();
                            events.Add(new UIEvents.UIPips(newpips, EventTimeUTC, prev_pips.Engines < 0));
                            prev_pips   = newpips;
                            fireoverall = true;
                        }

                        int?curfiregroup = jo["FireGroup"].IntNull();       // may appear/disappear.

                        if (curfiregroup != null && curfiregroup != prev_firegroup)
                        {
                            events.Add(new UIEvents.UIFireGroup(curfiregroup.Value + 1, EventTimeUTC, prev_firegroup == -1));
                            prev_firegroup = curfiregroup.Value;
                            fireoverall    = true;
                        }

                        JToken jfuel = jo["Fuel"];

                        if (jfuel != null && jfuel.IsObject)        // because they changed its type in 3.3.2
                        {
                            double?curfuel = jfuel["FuelMain"].DoubleNull();
                            double?curres  = jfuel["FuelReservoir"].DoubleNull();
                            if (curfuel != null && curres != null)
                            {
                                if (Math.Abs(curfuel.Value - prev_curfuel) >= 0.1 || Math.Abs(curres.Value - prev_curres) >= 0.01)  // don't fire if small changes
                                {
                                    //System.Diagnostics.Debug.WriteLine("UIEvent Fuel " + curfuel.Value + " " + prev_curfuel + " Res " + curres.Value + " " + prev_curres);
                                    events.Add(new UIEvents.UIFuel(curfuel.Value, curres.Value, ShipType(prev_flags.Value), EventTimeUTC, prev_firegroup == -1));
                                    prev_curfuel = curfuel.Value;
                                    prev_curres  = curres.Value;
                                    fireoverall  = true;
                                }
                            }
                        }

                        int?curcargo = jo["Cargo"].IntNull();       // may appear/disappear and only introduced for 3.3
                        if (curcargo != null && curcargo.Value != prev_cargo)
                        {
                            events.Add(new UIEvents.UICargo(curcargo.Value, ShipType(prev_flags.Value), EventTimeUTC, prev_firegroup == -1));
                            prev_cargo  = curcargo.Value;
                            fireoverall = true;
                        }

                        double jlat     = jo["Latitude"].Double(UIEvents.UIPosition.InvalidValue);   // if not there, min value
                        double jlon     = jo["Longitude"].Double(UIEvents.UIPosition.InvalidValue);
                        double jalt     = jo["Altitude"].Double(UIEvents.UIPosition.InvalidValue);
                        double jheading = jo["Heading"].Double(UIEvents.UIPosition.InvalidValue);
                        double jpradius = jo["PlanetRadius"].Double(UIEvents.UIPosition.InvalidValue);       // 3.4

                        if (jlat != prev_pos.Latitude || jlon != prev_pos.Longitude || jalt != prev_pos.Altitude || jheading != prev_heading || jpradius != prev_jpradius)
                        {
                            UIEvents.UIPosition.Position newpos = new UIEvents.UIPosition.Position()
                            {
                                Latitude = jlat, Longitude = jlon,
                                Altitude = jalt, AltitudeFromAverageRadius = (curflags & (1 << (int)StatusFlagsReportedInOtherEvents.AltitudeFromAverageRadius)) != 0
                            };

                            events.Add(new UIEvents.UIPosition(newpos, jheading, jpradius, EventTimeUTC, prev_pos.ValidPosition == false));
                            prev_pos      = newpos;
                            prev_heading  = jheading;
                            prev_jpradius = jpradius;
                            fireoverall   = true;
                        }

                        string cur_legalstatus = jo["LegalState"].StrNull();

                        if (cur_legalstatus != prev_legalstatus)
                        {
                            events.Add(new UIEvents.UILegalStatus(cur_legalstatus, EventTimeUTC, prev_legalstatus == null));
                            prev_legalstatus = cur_legalstatus;
                            fireoverall      = true;
                        }

                        if (fireoverall)
                        {
                            List <UITypeEnum> flagsset = ReportFlagState(typeof(StatusFlagsShip), curflags);
                            flagsset.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags));
                            flagsset.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags));

                            events.Add(new UIEvents.UIOverallStatus(ShipType(curflags), flagsset, prev_guifocus, prev_pips, prev_firegroup,
                                                                    prev_curfuel, prev_curres, prev_cargo, prev_pos, prev_heading, prev_jpradius, prev_legalstatus,
                                                                    EventTimeUTC, fireoverallrefresh));        // overall list of flags set
                        }

                        if (events.Count > 0)
                        {
                            foreach (UIEvent e in events)
                            {
                                Events.Enqueue(e);
                            }

                            UIEventCallBack?.Invoke(Events, WatcherFolder);        // and fire..
                        }
                    }
                }
                else
                {
                    nextpolltime = ScanRate * 40;           // if its not there, we are probably watching a non journal location.. so just do it occasionally
                }
            }
        }
Пример #4
0
        public List <UIEvent> Scan()
        {
            //  System.Diagnostics.Debug.WriteLine(Environment.TickCount % 100000 + "Check " + statusfile);

            if (File.Exists(statusfile))
            {
                JObject jo = null;

                Stream stream = null;
                try
                {
                    stream = File.Open(statusfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                    StreamReader reader = new StreamReader(stream);

                    string text = reader.ReadToEnd();

                    stream.Close();

                    if (text.HasChars() && (prev_text == null || !text.Equals(prev_text))) // if text not null, and prev text is null OR not equal
                    {
                        jo        = JObject.ParseThrowCommaEOL(text);                      // and of course the json could be crap
                        prev_text = text;                                                  // set after successful parse
                    }
                }
                catch
                { }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                }

                if (jo != null)
                {
                    DateTime EventTimeUTC = jo["timestamp"].DateTimeUTC();

                    List <UIEvent> events = new List <UIEvent>();

                    UIMode shiptype = ShipType(prev_flags, prev_flags2);

                    long curflags  = jo["Flags"].Long(0);
                    long curflags2 = jo["Flags2"].Long(0);      // 0 is backwards compat with horizons

                    bool fireoverall      = false;              // fire the overall
                    bool changedmajormode = false;
                    long flagsdelta2      = 0;                  // what changed between prev and current

                    if (curflags != prev_flags || curflags2 != prev_flags2)
                    {
                        UIMode nextshiptype = ShipType(curflags, curflags2);

                        //System.Diagnostics.Debug.WriteLine("UI Flags changed {0} {1} {2} -> {3} {4} {5}", prev_flags.Value, prev_flags2.Value, shiptype, curflags, curflags2, nextshiptype);

                        if (nextshiptype.Mode != shiptype.Mode)                                                                         // changed ship situation..
                        {
                            changedmajormode = nextshiptype.MajorMode != shiptype.MajorMode;                                            // did we change major mode
                            events.Add(new UIEvents.UIMode(nextshiptype.Mode, nextshiptype.MajorMode, EventTimeUTC, changedmajormode)); // Generate an event for it
                        }

                        events.AddRange(ReportFlagState(typeof(StatusFlags2), curflags2, prev_flags2, EventTimeUTC, changedmajormode));
                        events.AddRange(ReportFlagState(typeof(StatusFlagsShip), curflags, prev_flags, EventTimeUTC, changedmajormode));
                        events.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags, prev_flags, EventTimeUTC, changedmajormode));
                        events.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags, prev_flags, EventTimeUTC, changedmajormode));
                        fireoverall = true;

                        flagsdelta2 = curflags2 ^ prev_flags2;        // record the delta here for later processing, some of those flags go into the main reports

                        prev_flags  = curflags;
                        prev_flags2 = curflags2;
                        shiptype    = nextshiptype;
                    }

                    int curguifocus = jo["GuiFocus"].Int(NotPresent);
                    if (curguifocus != prev_guifocus || changedmajormode)
                    {
                        events.Add(new UIEvents.UIGUIFocus(curguifocus, EventTimeUTC, changedmajormode));
                        prev_guifocus = curguifocus;
                        fireoverall   = true;
                    }

                    int[] pips = jo["Pips"]?.ToObjectQ <int[]>();                  // may appear/disappear
                    UIEvents.UIPips.Pips curpips = new UIEvents.UIPips.Pips(pips); // can accept null as input

                    if (!curpips.Equal(prev_pips) || changedmajormode)             // if change in pips, or changed mode
                    {
                        events.Add(new UIEvents.UIPips(curpips, EventTimeUTC, changedmajormode));
                        prev_pips   = curpips;
                        fireoverall = true;
                    }

                    int curfiregroup = jo["FireGroup"].Int(NotPresent);      // may appear/disappear.

                    if (curfiregroup != prev_firegroup || changedmajormode)
                    {
                        events.Add(new UIEvents.UIFireGroup(curfiregroup + 1, EventTimeUTC, changedmajormode));
                        prev_firegroup = curfiregroup;
                        fireoverall    = true;
                    }

                    JToken jfuel   = jo["Fuel"];
                    double curfuel = jfuel != null ? jfuel["FuelMain"].Double(-1) : -1;
                    double curres  = jfuel != null ? jfuel["FuelReservoir"].Double(-1) : -1;

                    if (Math.Abs(curfuel - prev_curfuel) >= 0.1 || Math.Abs(curres - prev_curres) >= 0.01 || changedmajormode)  // don't fire if small changes
                    {
                        events.Add(new UIEvents.UIFuel(curfuel, curres, shiptype.Mode, EventTimeUTC, changedmajormode));
                        prev_curfuel = curfuel;
                        prev_curres  = curres;
                        fireoverall  = true;
                    }

                    int curcargo = jo["Cargo"].Int(NotPresent);      // may appear/disappear and only introduced for 3.3
                    if (curcargo != prev_cargo || changedmajormode)
                    {
                        events.Add(new UIEvents.UICargo(curcargo, shiptype.Mode, EventTimeUTC, changedmajormode));
                        prev_cargo  = curcargo;
                        fireoverall = true;
                    }

                    double jlat     = jo["Latitude"].Double(UIEvents.UIPosition.InvalidValue);   // if not there, min value
                    double jlon     = jo["Longitude"].Double(UIEvents.UIPosition.InvalidValue);
                    double jalt     = jo["Altitude"].Double(UIEvents.UIPosition.InvalidValue);
                    double jheading = jo["Heading"].Double(UIEvents.UIPosition.InvalidValue);
                    double jpradius = jo["PlanetRadius"].Double(UIEvents.UIPosition.InvalidValue);       // 3.4

                    if (jlat != prev_pos.Latitude || jlon != prev_pos.Longitude || jalt != prev_pos.Altitude || jheading != prev_heading || jpradius != prev_jpradius || changedmajormode)
                    {
                        UIEvents.UIPosition.Position newpos = new UIEvents.UIPosition.Position()
                        {
                            Latitude = jlat, Longitude = jlon,
                            Altitude = jalt, AltitudeFromAverageRadius = Flags(curflags, StatusFlagsReportedInOtherEvents.AltitudeFromAverageRadius)
                        };

                        events.Add(new UIEvents.UIPosition(newpos, jheading, jpradius, EventTimeUTC, changedmajormode));
                        prev_pos      = newpos;
                        prev_heading  = jheading;
                        prev_jpradius = jpradius;
                        fireoverall   = true;
                    }

                    string cur_legalstatus = jo["LegalState"].StrNull();

                    if (cur_legalstatus != prev_legalstatus || changedmajormode)
                    {
                        events.Add(new UIEvents.UILegalStatus(cur_legalstatus, EventTimeUTC, changedmajormode));
                        prev_legalstatus = cur_legalstatus;
                        fireoverall      = true;
                    }

                    string cur_bodyname = jo["BodyName"].StrNull();

                    if (cur_bodyname != prev_bodyname || changedmajormode)
                    {
                        events.Add(new UIEvents.UIBodyName(cur_bodyname, EventTimeUTC, changedmajormode));
                        prev_bodyname = cur_bodyname;
                        fireoverall   = true;
                    }

                    string cur_weapon    = jo["SelectedWeapon"].StrNull();              // null if not there
                    string cur_weaponloc = jo["SelectedWeapon_Localised"].Str();        // empty if not there

                    if (cur_weapon != prev_selectedweapon || changedmajormode)
                    {
                        events.Add(new UIEvents.UISelectedWeapon(cur_weapon, cur_weaponloc, EventTimeUTC, changedmajormode));
                        prev_selectedweapon    = cur_weapon;
                        prev_selectedweaponloc = cur_weaponloc;
                        fireoverall            = true;
                    }

                    double oxygen = jo["Oxygen"].Double(NotPresent);                //-1 is not present
                    oxygen = oxygen < 0 ? oxygen : oxygen * 100;                    // correct to 0-100%
                    bool lowoxygen = Flags(curflags2, StatusFlags2OtherFlags.LowOxygen);

                    if (oxygen != prev_oxygen || Flags(flagsdelta2, StatusFlags2OtherFlags.LowOxygen) || changedmajormode)
                    {
                        events.Add(new UIEvents.UIOxygen(oxygen, lowoxygen, EventTimeUTC, changedmajormode));
                        prev_oxygen = oxygen;
                        fireoverall = true;
                    }

                    double health = jo["Health"].Double(NotPresent);                //-1 is not present
                    health = health < 0 ? health : health * 100;                    // correct to 0-100%
                    bool lowhealth = Flags(curflags2, StatusFlags2OtherFlags.LowHealth);

                    if (health != prev_health || Flags(flagsdelta2, StatusFlags2OtherFlags.LowHealth) || changedmajormode)
                    {
                        events.Add(new UIEvents.UIHealth(health, lowhealth, EventTimeUTC, changedmajormode));
                        prev_health = health;
                        fireoverall = true;
                    }

                    double gravity = jo["Gravity"].Double(NotPresent);                //-1 is not present

                    if (gravity != prev_gravity || changedmajormode)
                    {
                        events.Add(new UIEvents.UIGravity(gravity, EventTimeUTC, changedmajormode));
                        prev_gravity = gravity;
                        fireoverall  = true;
                    }

                    double temperature = jo["Temperature"].Double(NotPresent);       //-1 is not present

                    UIEvents.UITemperature.TempState tempstate =
                        Flags(curflags2, StatusFlags2OtherFlags.VeryCold) ? UIEvents.UITemperature.TempState.VeryCold :       // order important, you can get Cold | VeryCold
                        Flags(curflags2, StatusFlags2OtherFlags.VeryHot) ? UIEvents.UITemperature.TempState.VeryHot :
                        Flags(curflags2, StatusFlags2OtherFlags.Cold) ? UIEvents.UITemperature.TempState.Cold :
                        Flags(curflags2, StatusFlags2OtherFlags.Hot) ? UIEvents.UITemperature.TempState.Hot :
                        UIEvents.UITemperature.TempState.Normal;

                    if (temperature != prev_temperature || (flagsdelta2 & (long)StatusFlags2OtherFlags.TempBits) != 0 || changedmajormode)
                    {
                        events.Add(new UIEvents.UITemperature(temperature, tempstate, EventTimeUTC, changedmajormode));
                        prev_temperature = temperature;
                        fireoverall      = true;
                    }

                    if (fireoverall)
                    {
                        List <UITypeEnum> flagsset = ReportFlagState(typeof(StatusFlagsShip), curflags);
                        flagsset.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags));
                        flagsset.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags));
                        flagsset.AddRange(ReportFlagState(typeof(StatusFlags2), curflags2));

                        bool glidemode       = Flags(curflags2, StatusFlags2.GlideMode);
                        bool breathableatmos = Flags(curflags2, StatusFlags2.BreathableAtmosphere);

                        UIEvents.UIOverallStatus.FSDStateType fsdstate = UIEvents.UIOverallStatus.FSDStateType.Normal;
                        if (Flags(curflags, StatusFlagsShip.FsdMassLocked))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.MassLock;
                        }
                        if (Flags(curflags, StatusFlagsShip.FsdJump))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Jumping;
                        }
                        else if (Flags(curflags, StatusFlagsShip.FsdCharging))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Charging;
                        }
                        else if (Flags(curflags2, StatusFlags2.GlideMode))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Gliding;
                        }
                        else if (Flags(curflags, StatusFlagsShip.FsdCooldown))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Cooldown;
                        }

                        events.Add(new UIEvents.UIOverallStatus(shiptype.MajorMode, shiptype.Mode, flagsset, prev_guifocus, prev_pips, prev_firegroup,
                                                                prev_curfuel, prev_curres, prev_cargo, prev_pos, prev_heading, prev_jpradius, prev_legalstatus,
                                                                prev_bodyname,
                                                                prev_health, lowhealth, gravity, prev_temperature, tempstate, prev_oxygen, lowoxygen,
                                                                prev_selectedweapon, prev_selectedweaponloc,
                                                                fsdstate, breathableatmos,
                                                                EventTimeUTC,
                                                                changedmajormode));        // overall list of flags set
                    }

                    //for debugging, keep
#if false
                    foreach (var uient in events)
                    {
                        System.Diagnostics.Trace.WriteLine(string.Format("New UI entry from journal {0} {1} refresh {2}", uient.EventTimeUTC, uient.EventTypeStr, changedmajormode));
                        //BaseUtils.Variables v = new BaseUtils.Variables();
                        //v.AddPropertiesFieldsOfClass(uient, "", null, 2);
                        //foreach (var x in v.NameEnumuerable)
                        //    System.Diagnostics.Trace.WriteLine(string.Format("  {0} = {1}", x, v[x]));
                    }
#endif

                    return(events);
                }
            }

            return(new List <UIEvent>());
        }
Пример #5
0
        public List <UIEvent> Scan()
        {
            //  System.Diagnostics.Debug.WriteLine(Environment.TickCount % 100000 + "Check " + statusfile);

            if (File.Exists(statusfile))
            {
                JObject jo = null;

                Stream stream = null;
                try
                {
                    stream = File.Open(statusfile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

                    StreamReader reader = new StreamReader(stream);

                    string text = reader.ReadToEnd();

                    stream.Close();

                    if (text != null && (prev_text == null || !text.Equals(prev_text))) // if text not null, and prev text is null OR not equal
                    {
                        jo        = JObject.ParseThrowCommaEOL(text);                   // and of course the json could be crap
                        prev_text = text;                                               // set after successful parse
                    }
                }
                catch
                { }
                finally
                {
                    if (stream != null)
                    {
                        stream.Dispose();
                    }
                }

                if (jo != null)
                {
                    DateTime EventTimeUTC = jo["timestamp"].DateTimeUTC();

                    List <UIEvent> events = new List <UIEvent>();

                    if (prev_flags == null)                               // if first run, set prev flags to impossible type.
                    {
                        prev_flags  = (long)StatusFlagsShipType.ShipMask; // set an impossible ship type to start the ball rolling
                        prev_flags2 = 0;
                    }

                    UIEvents.UIShipType.Shiptype shiptype = ShipType(prev_flags.Value, prev_flags2.Value);

                    long curflags  = jo["Flags"].Long();
                    long curflags2 = jo["Flags2"].Long(0);      // 0 is backwards compat with horizons

                    bool fireoverall        = false;
                    bool fireoverallrefresh = prev_guifocus == NotPresent; //meaning its a refresh

                    long flagsdelta2 = 0;                                  // what changed between prev and current

                    if (curflags != prev_flags.Value || curflags2 != prev_flags2.Value)
                    {
                        UIEvents.UIShipType.Shiptype nextshiptype = ShipType(curflags, curflags2);

                        //System.Diagnostics.Debug.WriteLine("UI Flags changed {0} {1} {2} -> {3} {4} {5}", prev_flags.Value, prev_flags2.Value, shiptype, curflags, curflags2, nextshiptype);

                        bool refresh = shiptype == UIEvents.UIShipType.Shiptype.None;   // refresh if prev ship was none..

                        if (shiptype != nextshiptype)
                        {
                            events.Add(new UIEvents.UIShipType(nextshiptype, EventTimeUTC, refresh));        // CHANGE of ship/on foot/taxi etc
                            //prev_flags = ~curflags;       // force re-reporting (don't think its ness)
                            //prev_flags2 = ~curflags2;
                            refresh = true;
                        }

                        if (nextshiptype != UIEvents.UIShipType.Shiptype.None)
                        {
                            events.AddRange(ReportFlagState(typeof(StatusFlags2), curflags2, prev_flags2.Value, EventTimeUTC, refresh));
                            events.AddRange(ReportFlagState(typeof(StatusFlagsShip), curflags, prev_flags.Value, EventTimeUTC, refresh));
                            events.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags, prev_flags.Value, EventTimeUTC, refresh));
                            events.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags, prev_flags.Value, EventTimeUTC, refresh));
                        }

                        flagsdelta2 = curflags2 ^ prev_flags2.Value;        // record the delta here for later processing, some of those flags go into the main reports

                        prev_flags  = curflags;
                        prev_flags2 = curflags2;
                        shiptype    = nextshiptype;
                        fireoverall = true;
                    }

                    int curguifocus = jo["GuiFocus"].Int(NotPresent);
                    if (curguifocus != prev_guifocus)
                    {
                        events.Add(new UIEvents.UIGUIFocus(curguifocus, EventTimeUTC, prev_guifocus == NotPresent));
                        prev_guifocus = curguifocus;
                        fireoverall   = true;
                    }

                    int[] pips = jo["Pips"]?.ToObjectQ <int[]>();

                    if (pips != null)
                    {
                        double sys = pips[0] / 2.0;     // convert to normal, instead of half pips
                        double eng = pips[1] / 2.0;
                        double wep = pips[2] / 2.0;
                        if (sys != prev_pips.Systems || wep != prev_pips.Weapons || eng != prev_pips.Engines)
                        {
                            UIEvents.UIPips.Pips newpips = new UIEvents.UIPips.Pips()
                            {
                                Systems = sys, Engines = eng, Weapons = wep
                            };
                            events.Add(new UIEvents.UIPips(newpips, EventTimeUTC, prev_pips.Engines < 0));
                            prev_pips   = newpips;
                            fireoverall = true;
                        }
                    }
                    else if (prev_pips.Valid)       // missing pips, if we are valid.. need to clear them
                    {
                        UIEvents.UIPips.Pips newpips = new UIEvents.UIPips.Pips();
                        events.Add(new UIEvents.UIPips(newpips, EventTimeUTC, prev_pips.Engines < 0));
                        prev_pips   = newpips;
                        fireoverall = true;
                    }

                    int?curfiregroup = jo["FireGroup"].IntNull();       // may appear/disappear.

                    if (curfiregroup != null && curfiregroup != prev_firegroup)
                    {
                        events.Add(new UIEvents.UIFireGroup(curfiregroup.Value + 1, EventTimeUTC, prev_firegroup == NotPresent));
                        prev_firegroup = curfiregroup.Value;
                        fireoverall    = true;
                    }

                    JToken jfuel = jo["Fuel"];

                    if (jfuel != null && jfuel.IsObject)        // because they changed its type in 3.3.2
                    {
                        double?curfuel = jfuel["FuelMain"].DoubleNull();
                        double?curres  = jfuel["FuelReservoir"].DoubleNull();
                        if (curfuel != null && curres != null)
                        {
                            if (Math.Abs(curfuel.Value - prev_curfuel) >= 0.1 || Math.Abs(curres.Value - prev_curres) >= 0.01)  // don't fire if small changes
                            {
                                //System.Diagnostics.Debug.WriteLine("UIEvent Fuel " + curfuel.Value + " " + prev_curfuel + " Res " + curres.Value + " " + prev_curres);
                                events.Add(new UIEvents.UIFuel(curfuel.Value, curres.Value, shiptype, EventTimeUTC, prev_firegroup == NotPresent));
                                prev_curfuel = curfuel.Value;
                                prev_curres  = curres.Value;
                                fireoverall  = true;
                            }
                        }
                    }

                    int?curcargo = jo["Cargo"].IntNull();       // may appear/disappear and only introduced for 3.3
                    if (curcargo != null && curcargo.Value != prev_cargo)
                    {
                        events.Add(new UIEvents.UICargo(curcargo.Value, shiptype, EventTimeUTC, prev_firegroup == NotPresent));
                        prev_cargo  = curcargo.Value;
                        fireoverall = true;
                    }

                    double jlat     = jo["Latitude"].Double(UIEvents.UIPosition.InvalidValue);   // if not there, min value
                    double jlon     = jo["Longitude"].Double(UIEvents.UIPosition.InvalidValue);
                    double jalt     = jo["Altitude"].Double(UIEvents.UIPosition.InvalidValue);
                    double jheading = jo["Heading"].Double(UIEvents.UIPosition.InvalidValue);
                    double jpradius = jo["PlanetRadius"].Double(UIEvents.UIPosition.InvalidValue);       // 3.4

                    if (jlat != prev_pos.Latitude || jlon != prev_pos.Longitude || jalt != prev_pos.Altitude || jheading != prev_heading || jpradius != prev_jpradius)
                    {
                        UIEvents.UIPosition.Position newpos = new UIEvents.UIPosition.Position()
                        {
                            Latitude = jlat, Longitude = jlon,
                            Altitude = jalt, AltitudeFromAverageRadius = Flags(curflags, StatusFlagsReportedInOtherEvents.AltitudeFromAverageRadius)
                        };

                        events.Add(new UIEvents.UIPosition(newpos, jheading, jpradius, EventTimeUTC, prev_pos.ValidPosition == false));
                        prev_pos      = newpos;
                        prev_heading  = jheading;
                        prev_jpradius = jpradius;
                        fireoverall   = true;
                    }

                    string cur_legalstatus = jo["LegalState"].StrNull();

                    if (cur_legalstatus != prev_legalstatus)
                    {
                        events.Add(new UIEvents.UILegalStatus(cur_legalstatus, EventTimeUTC, prev_legalstatus == null));
                        prev_legalstatus = cur_legalstatus;
                        fireoverall      = true;
                    }

                    string cur_bodyname = jo["BodyName"].StrNull();

                    if (cur_bodyname != prev_bodyname)
                    {
                        events.Add(new UIEvents.UIBodyName(cur_bodyname, EventTimeUTC, prev_bodyname == null));
                        prev_bodyname = cur_bodyname;
                        fireoverall   = true;
                    }

                    string cur_weapon    = jo["SelectedWeapon"].StrNull();              // null if not there
                    string cur_weaponloc = jo["SelectedWeapon_Localised"].Str();        // empty if not there

                    if (cur_weapon != prev_selectedweapon)
                    {
                        events.Add(new UIEvents.UISelectedWeapon(cur_weapon, cur_weaponloc, EventTimeUTC, prev_selectedweapon == null));
                        prev_selectedweapon    = cur_weapon;
                        prev_selectedweaponloc = cur_weaponloc;
                        fireoverall            = true;
                    }

                    double oxygen = jo["Oxygen"].Double(NotPresent);                //-1 is not present
                    oxygen = oxygen < 0 ? oxygen : oxygen * 100;                    // correct to 0-100%
                    bool lowoxygen = Flags(curflags2, StatusFlags2OtherFlags.LowOxygen);

                    if (oxygen != prev_oxygen || Flags(flagsdelta2, StatusFlags2OtherFlags.LowOxygen))
                    {
                        events.Add(new UIEvents.UIOxygen(oxygen, lowoxygen, EventTimeUTC, prev_oxygen < 0));
                        prev_oxygen = oxygen;
                        fireoverall = true;
                    }

                    double health = jo["Health"].Double(NotPresent);                //-1 is not present
                    health = health < 0 ? health : health * 100;                    // correct to 0-100%
                    bool lowhealth = Flags(curflags2, StatusFlags2OtherFlags.LowHealth);

                    if (health != prev_health || Flags(flagsdelta2, StatusFlags2OtherFlags.LowHealth))
                    {
                        events.Add(new UIEvents.UIHealth(health, lowhealth, EventTimeUTC, prev_health < 0));
                        prev_health = health;
                        fireoverall = true;
                    }

                    double gravity = jo["Gravity"].Double(NotPresent);                //-1 is not present

                    if (gravity != prev_gravity)
                    {
                        events.Add(new UIEvents.UIGravity(gravity, EventTimeUTC, prev_gravity < 0));
                        prev_gravity = gravity;
                        fireoverall  = true;
                    }

                    double temperature = jo["Temperature"].Double(NotPresent);       //-1 is not present

                    UIEvents.UITemperature.TempState tempstate =
                        Flags(curflags2, StatusFlags2OtherFlags.VeryCold) ? UIEvents.UITemperature.TempState.VeryCold :       // order important, you can get Cold | VeryCold
                        Flags(curflags2, StatusFlags2OtherFlags.VeryHot) ? UIEvents.UITemperature.TempState.VeryHot :
                        Flags(curflags2, StatusFlags2OtherFlags.Cold) ? UIEvents.UITemperature.TempState.Cold :
                        Flags(curflags2, StatusFlags2OtherFlags.Hot) ? UIEvents.UITemperature.TempState.Hot :
                        UIEvents.UITemperature.TempState.Normal;

                    if (temperature != prev_temperature || (flagsdelta2 & (long)StatusFlags2OtherFlags.TempBits) != 0)
                    {
                        events.Add(new UIEvents.UITemperature(temperature, tempstate, EventTimeUTC, prev_temperature < 0));
                        prev_temperature = temperature;
                        fireoverall      = true;
                    }

                    if (fireoverall)
                    {
                        List <UITypeEnum> flagsset = ReportFlagState(typeof(StatusFlagsShip), curflags);
                        flagsset.AddRange(ReportFlagState(typeof(StatusFlagsSRV), curflags));
                        flagsset.AddRange(ReportFlagState(typeof(StatusFlagsAll), curflags));
                        flagsset.AddRange(ReportFlagState(typeof(StatusFlags2), curflags2));

                        bool glidemode       = Flags(curflags2, StatusFlags2.GlideMode);
                        bool breathableatmos = Flags(curflags2, StatusFlags2.BreathableAtmosphere);

                        UIEvents.UIOverallStatus.FSDStateType fsdstate = UIEvents.UIOverallStatus.FSDStateType.Normal;
                        if (Flags(curflags, StatusFlagsShip.FsdJump))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Jumping;
                        }
                        else if (Flags(curflags, StatusFlagsShip.FsdCharging))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Charging;
                        }
                        else if (Flags(curflags2, StatusFlags2.GlideMode))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Gliding;
                        }
                        else if (Flags(curflags, StatusFlagsShip.FsdCooldown))
                        {
                            fsdstate = UIEvents.UIOverallStatus.FSDStateType.Cooldown;
                        }

                        events.Add(new UIEvents.UIOverallStatus(shiptype, flagsset, prev_guifocus, prev_pips, prev_firegroup,
                                                                prev_curfuel, prev_curres, prev_cargo, prev_pos, prev_heading, prev_jpradius, prev_legalstatus,
                                                                prev_bodyname,
                                                                prev_health, lowhealth, gravity, prev_temperature, tempstate, prev_oxygen, lowoxygen,
                                                                prev_selectedweapon, prev_selectedweaponloc,
                                                                fsdstate, breathableatmos,
                                                                EventTimeUTC, fireoverallrefresh));        // overall list of flags set
                    }

                    //for debugging, keep
#if false
                    foreach (var uient in events)
                    {
                        BaseUtils.Variables v = new BaseUtils.Variables();
                        v.AddPropertiesFieldsOfClass(uient, "", null, 2);
                        System.Diagnostics.Trace.WriteLine(string.Format("New UI entry from journal {0} {1}", uient.EventTimeUTC, uient.EventTypeStr));
                        foreach (var x in v.NameEnumuerable)
                        {
                            System.Diagnostics.Trace.WriteLine(string.Format("  {0} = {1}", x, v[x]));
                        }
                    }
#endif

                    return(events);
                }
            }

            return(new List <UIEvent>());
        }