Exemple #1
0
        private void FetcherThreadProc()
        {
            Trace.WriteLine($"EDSM Thread logs start");
            DateTime lastCommentFetch = DateTime.MinValue;

            int waittime = 1000; // initial waittime, will be reestimated later

            DateTime curtime = DateTime.UtcNow;

            KeyName(out string latestdatekeyname, out string oldestdatekeyname);

            while (!ExitRequested.WaitOne(waittime))
            {
                if (ExitRequested.WaitOne(0))
                {
                    return;
                }

                EDSMClass edsm = new EDSMClass(Commander);

                // logic checked 21/12/2018 RJP

                if (edsm.ValidCredentials && Commander.SyncFromEdsm)
                {
                    if (DateTime.UtcNow > lastCommentFetch.AddHours(1))
                    {
                        edsm.GetComments(l => Trace.WriteLine(l));
                        lastCommentFetch = DateTime.UtcNow;
                    }

                    DateTime latestentry = EliteDangerousCore.DB.UserDatabase.Instance.GetSettingDate(latestdatekeyname, GammaStart);      // lastest entry
                    DateTime oldestentry = EliteDangerousCore.DB.UserDatabase.Instance.GetSettingDate(oldestdatekeyname, DateTime.UtcNow); // oldest entry

                    DateTime logstarttime           = DateTime.MinValue;                                                                   // return what we got..
                    DateTime logendtime             = DateTime.MinValue;
                    List <JournalFSDJump>  edsmlogs = null;
                    BaseUtils.ResponseData response = default(BaseUtils.ResponseData);
                    int res = -1;

                    if (DateTime.UtcNow.Subtract(latestentry).TotalMinutes >= EDSMMaxLogAgeMinutes)     // is latest entry old?
                    {
                        DateTime askfor = DateTime.UtcNow;
                        System.Diagnostics.Debug.WriteLine("Fetch latest since Curtime > lastestentry + gap " + askfor.ToStringZulu());
                        res = edsm.GetLogs(null, askfor, out edsmlogs, out logstarttime, out logendtime, out response);
                        //res = 100;  logstarttime = askfor.AddDays(-7); logendtime = askfor; // debug it
                    }
                    else if (oldestentry > GammaStart)      // if oldest entry younger than gamma?
                    {
                        System.Diagnostics.Debug.WriteLine("Go back in time to gamma ");
                        res = edsm.GetLogs(null, oldestentry, out edsmlogs, out logstarttime, out logendtime, out response);
                        //res = 100; logstarttime = oldestentry.AddDays(-7); logendtime = oldestentry; // debug it
                    }

                    if (res == 100)     // hunky dory - note if Anthor faults, we just retry again and again
                    {
                        System.Diagnostics.Debug.WriteLine("Data stored from " + oldestentry.ToStringZulu() + " -> " + latestentry.ToStringZulu());
                        System.Diagnostics.Debug.WriteLine("Process logs from " + logstarttime.ToStringZulu() + " => " + logendtime.ToStringZulu());
                        if (edsmlogs != null && edsmlogs.Count > 0)     // if anything to process..
                        {
                            Process(edsmlogs, logstarttime, logendtime);
                        }

                        if (logendtime > latestentry)
                        {
                            EliteDangerousCore.DB.UserDatabase.Instance.PutSettingDate(latestdatekeyname, logendtime);
                        }

                        if (logstarttime < oldestentry)
                        {
                            EliteDangerousCore.DB.UserDatabase.Instance.PutSettingDate(oldestdatekeyname, logstarttime);
                        }
                    }
                    else if (res != -1)
                    {
                        System.Diagnostics.Debug.WriteLine("EDSM Log request rejected with " + res);
                    }

                    if (response.Headers != null &&
                        response.Headers["X-Rate-Limit-Limit"] != null &&
                        response.Headers["X-Rate-Limit-Remaining"] != null &&
                        response.Headers["X-Rate-Limit-Reset"] != null &&
                        Int32.TryParse(response.Headers["X-Rate-Limit-Limit"], out int ratelimitlimit) &&
                        Int32.TryParse(response.Headers["X-Rate-Limit-Remaining"], out int ratelimitremain) &&
                        Int32.TryParse(response.Headers["X-Rate-Limit-Reset"], out int ratelimitreset))
                    {
                        if (ratelimitremain < ratelimitlimit * 2 / 4)                              // lets keep at least X remaining for other purposes later..
                        {
                            waittime = 1000 * ratelimitreset / (ratelimitlimit - ratelimitremain); // slow down to its pace now.. example 878/(360-272) = 10 seconds per quota
                        }
                        else
                        {
                            waittime = 1000;        // 1 second so we don't thrash
                        }
                        System.Diagnostics.Debug.WriteLine("EDSM Log Delay Parameters {0} {1} {2} => {3}ms", ratelimitlimit, ratelimitremain, ratelimitreset, waittime);
                    }
                }
            }
        }
Exemple #2
0
        private void FetcherThreadProc()
        {
            Trace.WriteLine($"EDSM Thread logs start");
            bool jupdate = false;

            int waittime = 2000; // Max 1 request every 2 seconds, with a backoff if the rate limit is hit

            if (EDSMRequestBackoffTime > DateTime.UtcNow)
            {
                waittime = (int)Math.Min(EDSMMaxLogAgeMinutes * 60000, Math.Min(BackoffInterval.TotalSeconds * 1000, EDSMRequestBackoffTime.Subtract(DateTime.UtcNow).TotalSeconds * 1000));
            }

            // get them as of now.. since we are searching back in time it should be okay. On a refresh we would start again!
            List <HistoryEntry> hlfsdlist = JournalEntry.GetAll(Commander.Nr).OfType <JournalLocOrJump>().OrderBy(je => je.EventTimeUTC).Select(je => HistoryEntry.FromJournalEntry(je, null, false, out jupdate)).ToList();

            while (!ExitRequested.WaitOne(waittime))
            {
                EDSMClass edsm = new EDSMClass {
                    apiKey = Commander.APIKey, commanderName = Commander.EdsmName
                };
                List <HistoryEntry> edsmlogs     = null;
                DateTime            logstarttime = DateTime.MinValue;
                DateTime            logendtime   = DateTime.MinValue;
                int res = -1;

                if (edsm.IsApiKeySet && Commander.SyncFromEdsm && DateTime.UtcNow > EDSMRequestBackoffTime)
                {
                    if (DateTime.UtcNow.Subtract(LastEventTime).TotalMinutes >= EDSMMaxLogAgeMinutes)
                    {
                        //Trace.WriteLine($"Retrieving EDSM logs starting {LastEventTime}");
                        res = edsm.GetLogs(LastEventTime, null, out edsmlogs, out logstarttime, out logendtime);
                    }
                    else if (FirstEventTime > GammaStart)
                    {
                        //Trace.WriteLine($"Retrieving EDSM logs ending {FirstEventTime}");
                        res = edsm.GetLogs(null, FirstEventTime, out edsmlogs, out logstarttime, out logendtime);
                    }
                }

                if (ExitRequested.WaitOne(0))
                {
                    return;
                }

                if (res == 429) // Rate Limit Exceeded
                {
                    Trace.WriteLine($"EDSM Log request rate limit hit - backing off for {BackoffInterval.TotalSeconds}s");
                    EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval;
                    BackoffInterval        = BackoffInterval + TimeSpan.FromSeconds(60);
                }
                else if (logstarttime > LastEventTime && logendtime < FirstEventTime)
                {
                    Trace.WriteLine($"Bad start and/or end times returned by EDSM - backing off for {BackoffInterval.TotalSeconds}s");
                    EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval;
                    BackoffInterval        = BackoffInterval + TimeSpan.FromSeconds(60);
                }
                else if (res == 100 && edsmlogs != null)
                {
                    if (edsmlogs.Count > 0)     // if anything to process..
                    {
                        //Trace.WriteLine($"Retrieving EDSM logs count {edsmlogs.Count}");

                        BackoffInterval = TimeSpan.FromSeconds(60);

                        if (logendtime > DateTime.UtcNow)
                        {
                            logendtime = DateTime.UtcNow;
                        }

                        HistoryList     hl         = new HistoryList(hlfsdlist);
                        List <DateTime> hlfsdtimes = hlfsdlist.Select(he => he.EventTimeUTC).ToList();

                        List <HistoryEntry> toadd = new List <HistoryEntry>();

                        int previdx = -1;
                        foreach (HistoryEntry he in edsmlogs)      // find out list of ones not present
                        {
                            int index = hlfsdlist.FindIndex(x => x.System.name.Equals(he.System.name, StringComparison.InvariantCultureIgnoreCase) && x.EventTimeUTC.Ticks == he.EventTimeUTC.Ticks);

                            if (index < 0)
                            {
                                // Look for any entries where DST may have thrown off the time
                                foreach (var vi in hlfsdlist.Select((v, i) => new { v = v, i = i }).Where(vi => vi.v.System.name.Equals(he.System.name, StringComparison.InvariantCultureIgnoreCase)))
                                {
                                    if (vi.i > previdx)
                                    {
                                        double hdiff = vi.v.EventTimeUTC.Subtract(he.EventTimeUTC).TotalHours;
                                        if (hdiff >= -2 && hdiff <= 2 && hdiff == Math.Floor(hdiff))
                                        {
                                            if (vi.v.System.id_edsm <= 0)
                                            {
                                                vi.v.System.id_edsm = 0;
                                                hl.FillEDSM(vi.v);
                                            }

                                            if (vi.v.System.id_edsm <= 0 || vi.v.System.id_edsm == he.System.id_edsm)
                                            {
                                                index = vi.i;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            if (index < 0)
                            {
                                toadd.Add(he);
                            }
                            else
                            {
                                HistoryEntry lhe = hlfsdlist[index];

                                if (he.IsEDSMFirstDiscover && !lhe.IsEDSMFirstDiscover)
                                {
                                    lhe.SetFirstDiscover();
                                }

                                previdx = index;
                            }
                        }

                        if (toadd.Count > 0)  // if we have any, we can add
                        {
                            Trace.WriteLine($"Adding EDSM logs count {toadd.Count}");

                            TravelLogUnit tlu = new TravelLogUnit(); // need a tlu for it
                            tlu.type        = 2;                     // EDSM
                            tlu.Name        = "EDSM-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                            tlu.Size        = 0;
                            tlu.Path        = "EDSM";
                            tlu.CommanderId = EDCommander.CurrentCmdrID;
                            tlu.Add();  // Add to Database

                            using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true))
                            {
                                foreach (HistoryEntry he in toadd)
                                {
                                    JObject jo = JournalEntry.CreateFSDJournalEntryJson(he.EventTimeUTC,
                                                                                        he.System.name, he.System.x, he.System.y, he.System.z,
                                                                                        EliteConfigInstance.InstanceConfig.DefaultMapColour);
                                    JournalEntry je =
                                        JournalEntry.CreateFSDJournalEntry(tlu.id, tlu.CommanderId.Value,
                                                                           (int)SyncFlags.EDSM, jo);

                                    System.Diagnostics.Trace.WriteLine(string.Format("Add {0} {1}", je.EventTimeUTC, he.System.name));
                                    je.Add(jo, cn);
                                }
                            }

                            LogLine($"Retrieved {toadd.Count} log entries from EDSM, from {logstarttime.ToLocalTime().ToString()} to {logendtime.ToLocalTime().ToString()}");

                            if (logendtime > LastEventTime || logstarttime <= GammaStart)
                            {
                                if (OnDownloadedSystems != null)
                                {
                                    OnDownloadedSystems();
                                }
                            }
                        }
                    }

                    if (logstarttime < FirstEventTime)
                    {
                        FirstEventTime = logstarttime;
                    }

                    if (logendtime > LastEventTime)
                    {
                        LastEventTime = logendtime;
                    }
                }
            }
        }
        private void FetcherThreadProc()
        {
            Trace.WriteLine($"EDSM Thread logs start");
            bool     jupdate          = false;
            DateTime lastCommentFetch = DateTime.MinValue;

            int waittime = 2000; // Max 1 request every 2 seconds, with a backoff if the rate limit is hit

            if (EDSMRequestBackoffTime > DateTime.UtcNow)
            {
                waittime = (int)Math.Min(EDSMMaxLogAgeMinutes * 60000, Math.Min(BackoffInterval.TotalSeconds * 1000, EDSMRequestBackoffTime.Subtract(DateTime.UtcNow).TotalSeconds * 1000));
            }

            while (!ExitRequested.WaitOne(waittime))
            {
                EDSMClass edsm = new EDSMClass(Commander);

                if (edsm.ValidCredentials && DateTime.UtcNow > lastCommentFetch.AddHours(1))
                {
                    edsm.GetComments(l => Trace.WriteLine(l));
                    lastCommentFetch = DateTime.UtcNow;
                }

                DateTime logstarttime          = DateTime.MinValue; // return what we got..
                DateTime logendtime            = DateTime.MinValue;
                List <JournalFSDJump> edsmlogs = null;
                int res = -1;       //return code

                if (edsm.ValidCredentials && Commander.SyncFromEdsm && DateTime.UtcNow > EDSMRequestBackoffTime)
                {
                    if (DateTime.UtcNow.Subtract(LastEventTime).TotalMinutes >= EDSMMaxLogAgeMinutes)
                    {
                        System.Diagnostics.Debug.WriteLine($"Retrieving EDSM logs starting {LastEventTime}");
                        res = edsm.GetLogs(LastEventTime, null, out edsmlogs, out logstarttime, out logendtime);
                    }
                    else if (FirstEventTime > GammaStart)
                    {
                        System.Diagnostics.Debug.WriteLine($"Retrieving EDSM logs ending {FirstEventTime}");
                        res = edsm.GetLogs(null, FirstEventTime, out edsmlogs, out logstarttime, out logendtime);
                    }
                }

                if (ExitRequested.WaitOne(0))
                {
                    return;
                }

                if (res == 429) // Rate Limit Exceeded
                {
                    Trace.WriteLine($"EDSM Log request rate limit hit - backing off for {BackoffInterval.TotalSeconds}s");
                    EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval;
                    BackoffInterval        = BackoffInterval + TimeSpan.FromSeconds(60);
                }
                else if (logstarttime > LastEventTime && logendtime < FirstEventTime)
                {
                    Trace.WriteLine($"Bad start and/or end times returned by EDSM - backing off for {BackoffInterval.TotalSeconds}s");
                    EDSMRequestBackoffTime = DateTime.UtcNow + BackoffInterval;
                    BackoffInterval        = BackoffInterval + TimeSpan.FromSeconds(60);
                }
                else if (res == 100 && edsmlogs != null)
                {
                    if (edsmlogs.Count > 0)     // if anything to process..
                    {
                        //Trace.WriteLine($"Retrieving EDSM logs count {edsmlogs.Count}");

                        BackoffInterval = TimeSpan.FromSeconds(60);

                        if (logendtime > DateTime.UtcNow)
                        {
                            logendtime = DateTime.UtcNow;
                        }
                        if (logstarttime < DateTime.MinValue.AddDays(1))
                        {
                            logstarttime = DateTime.MinValue.AddDays(1);
                        }

                        // Get all of the local entries now that we have the entries from EDSM
                        // Moved here to avoid the race that could have been causing duplicate entries

                        // EDSM only returns FSD entries, so only look for them.  Tested 27/4/2018 after the HE optimisations

                        List <HistoryEntry> hlfsdlist = JournalEntry.GetAll(Commander.Nr, logstarttime.AddDays(-1), logendtime.AddDays(1)).
                                                        OfType <JournalLocOrJump>().OrderBy(je => je.EventTimeUTC).
                                                        Select(je => HistoryEntry.FromJournalEntry(je, null, out jupdate)).ToList(); // using HE just because of the FillEDSM func

                        HistoryList hl = new HistoryList(hlfsdlist);                                                                 // just so we can access the FillEDSM func

                        List <JournalFSDJump> toadd = new List <JournalFSDJump>();

                        int previdx = -1;
                        foreach (JournalFSDJump jfsd in edsmlogs)      // find out list of ones not present
                        {
                            int index = hlfsdlist.FindIndex(x => x.System.Name.Equals(jfsd.StarSystem, StringComparison.InvariantCultureIgnoreCase) && x.EventTimeUTC.Ticks == jfsd.EventTimeUTC.Ticks);

                            if (index < 0)
                            {
                                // Look for any entries where DST may have thrown off the time
                                foreach (var vi in hlfsdlist.Select((v, i) => new { v = v, i = i }).Where(vi => vi.v.System.Name.Equals(jfsd.StarSystem, StringComparison.InvariantCultureIgnoreCase)))
                                {
                                    if (vi.i > previdx)
                                    {
                                        double hdiff = vi.v.EventTimeUTC.Subtract(jfsd.EventTimeUTC).TotalHours;
                                        if (hdiff >= -2 && hdiff <= 2 && hdiff == Math.Floor(hdiff))
                                        {
                                            if (vi.v.System.EDSMID <= 0)        // if we don't have a valid EDMSID..
                                            {
                                                vi.v.System.EDSMID = 0;
                                                hl.FillEDSM(vi.v);
                                            }

                                            if (vi.v.System.EDSMID <= 0 || vi.v.System.EDSMID == jfsd.EdsmID)
                                            {
                                                index = vi.i;
                                                break;
                                            }
                                        }
                                    }
                                }
                            }

                            if (index < 0)      // its not a duplicate, add to db
                            {
                                toadd.Add(jfsd);
                            }
                            else
                            {                   // it is a duplicate, check if the first discovery flag is set right
                                JournalFSDJump existingfsd = hlfsdlist[index].journalEntry as JournalFSDJump;

                                if (existingfsd != null && existingfsd.EDSMFirstDiscover != jfsd.EDSMFirstDiscover)     // if we have a FSD one, and first discover is different
                                {
                                    existingfsd.UpdateFirstDiscover(jfsd.EDSMFirstDiscover);
                                }

                                previdx = index;
                            }
                        }

                        if (toadd.Count > 0)  // if we have any, we can add
                        {
                            Trace.WriteLine($"Adding EDSM logs count {toadd.Count}");

                            TravelLogUnit tlu = new TravelLogUnit(); // need a tlu for it
                            tlu.type        = 2;                     // EDSM
                            tlu.Name        = "EDSM-" + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture);
                            tlu.Size        = 0;
                            tlu.Path        = "EDSM";
                            tlu.CommanderId = EDCommander.CurrentCmdrID;
                            tlu.Add();  // Add to Database

                            using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true))
                            {
                                foreach (JournalFSDJump jfsd in toadd)
                                {
                                    System.Diagnostics.Trace.WriteLine(string.Format("Add {0} {1}", jfsd.EventTimeUTC, jfsd.StarSystem));
                                    jfsd.SetTLUCommander(tlu.id, jfsd.CommanderId);         // update its TLU id to the TLU made above
                                    jfsd.Add(jfsd.CreateFSDJournalEntryJson(), cn);
                                }
                            }

                            LogLine($"Retrieved {toadd.Count} log entries from EDSM, from {logstarttime.ToLocalTime().ToString()} to {logendtime.ToLocalTime().ToString()}");

                            if (logendtime > LastEventTime || logstarttime <= GammaStart)
                            {
                                if (OnDownloadedSystems != null)
                                {
                                    OnDownloadedSystems();
                                }
                            }
                        }
                    }

                    if (logstarttime < FirstEventTime)
                    {
                        FirstEventTime = logstarttime;
                    }

                    if (logendtime > LastEventTime)
                    {
                        LastEventTime = logendtime;
                    }
                }
            }
        }
Exemple #4
0
        private void Sync(EDSMClass edsm, HistoryList hl)
        {
            try
            {
                logout("EDSM sync begin");

                List <HistoryEntry> hlfsdunsyncedlist = hl.FilterByNotEDSMSyncedAndFSD; // first entry is oldest

                if (_syncTo && hlfsdunsyncedlist.Count > 0)                             // send systems to edsm (verified with dates, 29/9/2016, utc throughout)
                {
                    DateTime logstarttime = DateTime.MinValue;
                    DateTime logendtime   = DateTime.MinValue;

                    logout("EDSM: Sending " + hlfsdunsyncedlist.Count.ToString() + " flightlog entries");

                    List <HistoryEntry> edsmsystemlog = null;

                    int edsmsystemssent = 0;

                    foreach (var he in hlfsdunsyncedlist)
                    {
                        if (Exit)
                        {
                            running = false;
                            return;
                        }

                        if (edsmsystemlog == null || he.EventTimeUTC >= logendtime.AddDays(-1))
                        {
                            edsm.GetLogs(he.EventTimeUTC.AddDays(-1), null, out edsmsystemlog, out logstarttime, out logendtime);        // always returns a log, time is in UTC as per HistoryEntry and JournalEntry
                        }

                        if (logendtime < logstarttime)
                        {
                            running = false;
                            return;
                        }

                        if (edsmsystemlog == null)
                        {
                            running = false;
                            return;
                        }

                        HistoryEntry ps2 = (from c in edsmsystemlog where c.System.name == he.System.name && c.EventTimeUTC.Ticks == he.EventTimeUTC.Ticks select c).FirstOrDefault();

                        if (ps2 != null)                // it did, just make sure EDSM sync flag is set..
                        {
                            he.SetEdsmSync();
                        }
                        else
                        {
                            string errmsg;              // (verified with EDSM 29/9/2016)
                            bool   firstdiscover;
                            int    edsmid;

                            if (edsm.SendTravelLog(he.System.name, he.EventTimeUTC, he.System.HasCoordinate && !he.IsStarPosFromEDSM, he.System.x, he.System.y, he.System.z, out errmsg, out firstdiscover, out edsmid))
                            {
                                if (edsmid != 0 && he.System.id_edsm <= 0)
                                {
                                    he.System.id_edsm = edsmid;
                                    JournalEntry.UpdateEDSMIDPosJump(he.Journalid, he.System, false, -1);
                                }

                                if (firstdiscover)
                                {
                                    he.SetFirstDiscover();
                                }

                                he.SetEdsmSync();
                                edsmsystemssent++;
                            }

                            if (errmsg.Length > 0)
                            {
                                logout(errmsg);
                                break;
                            }
                        }
                    }

                    logout(string.Format("EDSM Systems sent {0}", edsmsystemssent));
                }

                // TBD Comments to edsm?

                if (_syncFrom)                                                              // Verified ok with time 29/9/2016
                {
                    var json = edsm.GetComments(new DateTime(2011, 1, 1));

                    if (json != null)
                    {
                        JObject msg   = JObject.Parse(json);
                        int     msgnr = msg["msgnum"].Value <int>();

                        JArray comments = (JArray)msg["comments"];
                        if (comments != null)
                        {
                            int commentsadded = 0;

                            foreach (JObject jo in comments)
                            {
                                string name    = jo["system"].Value <string>();
                                string note    = jo["comment"].Value <string>();
                                string utctime = jo["lastUpdate"].Value <string>();
                                int    edsmid  = 0;

                                if (!Int32.TryParse(jo["systemId"].Str("0"), out edsmid))
                                {
                                    edsmid = 0;
                                }

                                DateTime localtime = DateTime.ParseExact(utctime, "yyyy-MM-dd HH:mm:ss",
                                                                         CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal).ToLocalTime();

                                SystemNoteClass curnote = SystemNoteClass.GetNoteOnSystem(name, edsmid);

                                if (curnote != null)                          // curnote uses local time to store
                                {
                                    if (localtime.Ticks > curnote.Time.Ticks) // if newer, add on (verified with EDSM 29/9/2016)
                                    {
                                        curnote.UpdateNote(curnote.Note + ". EDSM: " + note, true, localtime, edsmid, true);
                                        commentsadded++;
                                    }
                                }
                                else
                                {
                                    SystemNoteClass.MakeSystemNote(note, localtime, name, 0, edsmid, true);   // new one!  its an FSD one as well
                                    commentsadded++;
                                }
                            }

                            logout(string.Format("EDSM Comments downloaded/updated {0}", commentsadded));
                        }
                    }
                }

                logout("EDSM sync Done");
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("Exception ex:" + ex.Message);
                logout("EDSM sync Exception " + ex.Message);
            }
        }