Exemplo n.º 1
0
        private static bool ShouldSendEvent(HistoryEntry he)
        {
            if (lastDiscardFetch < DateTime.UtcNow.AddMinutes(-30))
            {
                EDSMClass edsm = new EDSMClass();
                discardEvents    = new HashSet <string>(edsm.GetJournalEventsToDiscard());
                lastDiscardFetch = DateTime.UtcNow;
            }

            string eventtype = he.EntryType.ToString();

            if (he.EdsmSync ||
                he.MultiPlayer ||
                discardEvents.Contains(eventtype) ||
                alwaysDiscard.Contains(eventtype))
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 2
0
        public static void UpdateDiscardList()
        {
            if (lastDiscardFetch < DateTime.UtcNow.AddMinutes(-120))     // check if we need a new discard list
            {
                try
                {
                    EDSMClass edsm             = new EDSMClass();
                    var       newdiscardEvents = new HashSet <string>(edsm.GetJournalEventsToDiscard());

                    lock (alwaysDiscard)        // use this as a perm proxy to lock discardEvents
                    {
                        discardEvents = newdiscardEvents;
                    }

                    lastDiscardFetch = DateTime.UtcNow;
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine($"Unable to retrieve events to be discarded: {ex.ToString()}");
                }
            }
        }
Exemplo n.º 3
0
        public static void SendTravelLog(HistoryEntry he) // (verified with EDSM 29/9/2016, seen UTC time being sent, and same UTC time on ESDM).
        {
            EDSMClass edsm = new EDSMClass();
            var       cmdr = he.Commander;

            edsm.commanderName = cmdr.EdsmName ?? cmdr.Name;
            edsm.apiKey        = cmdr.APIKey;

            if (!edsm.IsApiKeySet)
            {
                return;
            }

            string errmsg;
            int    errno;
            bool   firstdiscover;
            int    edsmid;
            Task   taskEDSM = Task.Factory.StartNew(() =>
            {                                                   // LOCAL time, there is a UTC converter inside this call
                if (edsm.SendTravelLog(he.System.name, he.EventTimeUTC, he.System.HasCoordinate, he.System.x, he.System.y, he.System.z, out errmsg, out errno, 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();
                }
            });
        }
Exemplo n.º 4
0
        // returns null if EDSM says not there, else if returns list of bodies and a flag indicating if from cache.
        // all this is done in a lock inside a task - the only way to sequence the code and prevent multiple lookups in an await structure
        // so we must pass back all the info we can to tell the caller what happened.
        // optional call back is allowed in lock - may not be used.
        // Verified Nov 20

        public static Tuple <List <JournalScan>, bool> GetBodiesList(ISystem sys, bool edsmweblookup = true, Action <List <JournalScan>, ISystem> onnewbodies = null)
        {
            try
            {
                lock (bodylock) // only one request at a time going, this is to prevent multiple requests for the same body
                {
                    // System.Threading.Thread.Sleep(2000); //debug - delay to show its happening
                    // System.Diagnostics.Debug.WriteLine("EDSM Cache check " + sys.EDSMID + " " + sys.SystemAddress + " " + sys.Name);

                    if (DictEDSMBodies != null && sys.EDSMID > 0 && DictEDSMBodies.ContainsKey(sys.EDSMID))  // Cache EDSM bidies during run of EDD.
                    {
                        System.Diagnostics.Debug.WriteLine("Found sys.EDSMID " + sys.EDSMID);
                        return(new Tuple <List <JournalScan>, bool>(DictEDSMBodies[sys.EDSMID], true));
                    }
                    else if (DictEDSMBodiesByID64 != null && sys.SystemAddress != null && sys.SystemAddress > 0 && DictEDSMBodiesByID64.ContainsKey(sys.SystemAddress.Value))
                    {
                        System.Diagnostics.Debug.WriteLine("Found sys.EDSMID64 " + sys.SystemAddress.Value);
                        return(new Tuple <List <JournalScan>, bool>(DictEDSMBodiesByID64[sys.SystemAddress.Value], true));
                    }

                    if (!edsmweblookup)      // must be set for a web lookup
                    {
                        return(null);
                    }

                    System.Diagnostics.Debug.WriteLine("EDSM Web lookup");
                    List <JournalScan> bodies = new List <JournalScan>();

                    EDSMClass edsm = new EDSMClass();

                    JObject jo = null;

                    if (sys.EDSMID > 0)
                    {
                        jo = edsm.GetBodies(sys.EDSMID);  // Colonia
                    }
                    else if (sys.SystemAddress != null && sys.SystemAddress > 0)
                    {
                        jo = edsm.GetBodiesByID64(sys.SystemAddress.Value);
                    }
                    else if (sys.Name != null)
                    {
                        jo = edsm.GetBodies(sys.Name);
                    }

                    if (jo != null && jo["bodies"] != null)
                    {
                        foreach (JObject edsmbody in jo["bodies"])
                        {
                            try
                            {
                                JObject jbody = EDSMClass.ConvertFromEDSMBodies(edsmbody);

                                JournalScan js = new JournalScan(jbody);//TBD, sys.EDSMID);

                                bodies.Add(js);
                            }
                            catch (Exception ex)
                            {
                                BaseUtils.HttpCom.WriteLog($"Exception Loop: {ex.Message}", "");
                                BaseUtils.HttpCom.WriteLog($"ETrace: {ex.StackTrace}", "");
                                Trace.WriteLine($"Exception Loop: {ex.Message}");
                                Trace.WriteLine($"ETrace: {ex.StackTrace}");
                            }
                        }

                        if (sys.EDSMID > 0)
                        {
                            DictEDSMBodies[sys.EDSMID] = bodies;
                        }

                        if (sys.SystemAddress != null && sys.SystemAddress > 0)
                        {
                            DictEDSMBodiesByID64[sys.SystemAddress.Value] = bodies;
                        }

                        System.Diagnostics.Debug.WriteLine("EDSM Web Lookup complete " + sys.Name + " " + bodies.Count);

                        onnewbodies?.Invoke(bodies, sys);        // inside the lock, with new bodies, allow it to do processsing.

                        return(new Tuple <List <JournalScan>, bool>(bodies, false));
                    }

                    if (sys.EDSMID > 0)
                    {
                        DictEDSMBodies[sys.EDSMID] = null;
                    }

                    if (sys.SystemAddress != null && sys.SystemAddress > 0)
                    {
                        DictEDSMBodiesByID64[sys.SystemAddress.Value] = null;
                    }
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"Exception: {ex.Message}");
                Trace.WriteLine($"ETrace: {ex.StackTrace}");
                return(null);
            }

            return(null);
        }
Exemplo n.º 5
0
        static private bool SendToEDSM(List <HistoryEntry> hl, EDCommander cmdr, out string errmsg)
        {
            EDSMClass edsm = new EDSMClass(cmdr);       // Ensure we use the commanders EDSM credentials.

            errmsg = null;

            List <JObject> entries = new List <JObject>();

            foreach (HistoryEntry he in hl)
            {
                JournalEntry je = he.journalEntry;

                if (je == null)
                {
                    je = JournalEntry.Get(he.Journalid);
                }

                JObject json = je.GetJson();
                RemoveCommonKeys(json);
                if (je.EventTypeID == JournalTypeEnum.FSDJump && json["FuelUsed"].Empty())
                {
                    json["_convertedNetlog"] = true;
                }
                if (json["StarPosFromEDSM"].Bool(false)) // Remove star pos from EDSM
                {
                    json.Remove("StarPos");
                }
                json.Remove("StarPosFromEDSM");
                json["_systemName"]        = he.System.Name;
                json["_systemCoordinates"] = new JArray(he.System.X, he.System.Y, he.System.Z);
                if (he.System.SystemAddress != null)
                {
                    json["_systemAddress"] = he.System.SystemAddress;
                }
                if (he.IsDocked)
                {
                    json["_stationName"] = he.StationName;
                    if (he.MarketID != null)
                    {
                        json["_stationMarketId"] = he.MarketID;
                    }
                }
                json["_shipId"] = he.ShipId;
                entries.Add(json);
            }

            List <JObject> results = edsm.SendJournalEvents(entries, out errmsg);

            if (results == null)
            {
                return(false);
            }
            else
            {
                using (var cn = new SQLiteConnectionUser(utc: true))
                {
                    using (var txn = cn.BeginTransaction())
                    {
                        for (int i = 0; i < hl.Count && i < results.Count; i++)
                        {
                            HistoryEntry he            = hl[i];
                            JObject      result        = results[i];
                            int          msgnr         = result["msgnum"].Int();
                            int          systemId      = result["systemId"].Int();
                            bool         systemCreated = result["systemCreated"].Bool();

                            if ((msgnr >= 100 && msgnr < 200) || msgnr == 500)
                            {
                                if (he.EntryType == JournalTypeEnum.FSDJump || he.EntryType == JournalTypeEnum.Location)
                                {
                                    if (systemId != 0)
                                    {
                                        he.System.EDSMID = systemId;
                                        JournalEntry.UpdateEDSMIDPosJump(he.Journalid, he.System, false, 0, cn, txn);
                                    }

                                    if (systemCreated)
                                    {
                                        he.SetFirstDiscover(true);
                                    }
                                }

                                he.SetEdsmSync(cn, txn);

                                if (msgnr == 500)
                                {
                                    System.Diagnostics.Trace.WriteLine($"Warning submitting event {he.Journalid} \"{he.EventSummary}\": {msgnr} {result["msg"].Str()}");
                                }
                            }
                            else
                            {
                                System.Diagnostics.Trace.WriteLine($"Error submitting event {he.Journalid} \"{he.EventSummary}\": {msgnr} {result["msg"].Str()}");
                            }
                        }

                        txn.Commit();
                    }
                }

                return(true);
            }
        }
Exemplo n.º 6
0
        public static List <JournalScan> GetBodiesList(long edsmid, bool edsmweblookup = true, long?id64 = null, string sysname = null) // get this edsmid,  optionally lookup web protected against bad json
        {
            try
            {
                if (DictEDSMBodies != null && edsmid > 0 && DictEDSMBodies.ContainsKey(edsmid))  // Cache EDSM bidies during run of EDD.
                {
                    // System.Diagnostics.Debug.WriteLine(".. found EDSM Lookup bodies from cache " + edsmid);
                    return(DictEDSMBodies[edsmid]);
                }
                else if (DictEDSMBodiesByID64 != null && id64 != null && id64 > 0 && DictEDSMBodiesByID64.ContainsKey(id64.Value))
                {
                    return(DictEDSMBodiesByID64[id64.Value]);
                }

                if (!edsmweblookup)      // must be set for a web lookup
                {
                    return(null);
                }

                List <JournalScan> bodies = new List <JournalScan>();

                EDSMClass edsm = new EDSMClass();

                //System.Diagnostics.Debug.WriteLine("EDSM Web Lookup bodies " + edsmid);

                JObject jo = null;

                if (edsmid > 0)
                {
                    jo = edsm.GetBodies(edsmid);  // Colonia
                }
                else if (id64 != null && id64 > 0)
                {
                    jo = edsm.GetBodiesByID64(id64.Value);
                }
                else if (sysname != null)
                {
                    jo = edsm.GetBodies(sysname);
                }

                if (jo != null && jo["bodies"] != null)
                {
                    foreach (JObject edsmbody in jo["bodies"])
                    {
                        try
                        {
                            JObject     jbody = EDSMClass.ConvertFromEDSMBodies(edsmbody);
                            JournalScan js    = new JournalScan(jbody, edsmid);

                            bodies.Add(js);
                        }
                        catch (Exception ex)
                        {
                            BaseUtils.HttpCom.WriteLog($"Exception Loop: {ex.Message}", "");
                            BaseUtils.HttpCom.WriteLog($"ETrace: {ex.StackTrace}", "");
                            Trace.WriteLine($"Exception Loop: {ex.Message}");
                            Trace.WriteLine($"ETrace: {ex.StackTrace}");
                        }
                    }

                    if (edsmid > 0)
                    {
                        DictEDSMBodies[edsmid] = bodies;
                    }

                    if (id64 != null && id64 > 0)
                    {
                        DictEDSMBodiesByID64[id64.Value] = bodies;
                    }

                    return(bodies);
                }

                if (edsmid > 0)
                {
                    DictEDSMBodies[edsmid] = null;
                }

                if (id64 != null && id64 > 0)
                {
                    DictEDSMBodiesByID64[id64.Value] = null;
                }
            }
            catch (Exception ex)
            {
                Trace.WriteLine($"Exception: {ex.Message}");
                Trace.WriteLine($"ETrace: {ex.StackTrace}");
                return(null);
            }
            return(null);
        }
Exemplo n.º 7
0
        static private bool SendToEDSM(List <HistoryEntry> hl, EDCommander cmdr, out string errmsg, out string firstdiscovers)
        {
            EDSMClass edsm = new EDSMClass(cmdr);       // Ensure we use the commanders EDSM credentials.

            errmsg         = null;
            firstdiscovers = "";

            List <JObject> entries = new List <JObject>();

            foreach (HistoryEntry he in hl)
            {
                JournalEntry je = he.journalEntry;

                if (je == null)
                {
                    je = JournalEntry.Get(he.Journalid);
                }

                JObject json = je.GetJson();

                if (json == null)
                {
                    continue;
                }

                RemoveCommonKeys(json);
                if (je.EventTypeID == JournalTypeEnum.FSDJump && json["FuelUsed"].Empty())
                {
                    json["_convertedNetlog"] = true;
                }
                if (json["StarPosFromEDSM"].Bool(false)) // Remove star pos from EDSM
                {
                    json.Remove("StarPos");
                }
                json.Remove("StarPosFromEDSM");
                json["_systemName"]        = he.System.Name;
                json["_systemCoordinates"] = new JArray(he.System.X, he.System.Y, he.System.Z);
                if (he.System.SystemAddress != null)
                {
                    json["_systemAddress"] = he.System.SystemAddress;
                }
                if (he.IsDocked)
                {
                    json["_stationName"] = he.WhereAmI;
                    if (he.MarketID != null)
                    {
                        json["_stationMarketId"] = he.MarketID;
                    }
                }
                json["_shipId"] = he.ShipId;
                entries.Add(json);
            }

            List <JObject> results = edsm.SendJournalEvents(entries, out errmsg);

            if (results == null)
            {
                return(false);
            }
            else
            {
                firstdiscovers = UserDatabase.Instance.ExecuteWithDatabase <string>(cn =>
                {
                    string firsts = "";
                    using (var txn = cn.Connection.BeginTransaction())
                    {
                        for (int i = 0; i < hl.Count && i < results.Count; i++)
                        {
                            HistoryEntry he = hl[i];
                            JObject result  = results[i];
                            int msgnr       = result["msgnum"].Int();
                            int systemId    = result["systemId"].Int();

                            if ((msgnr >= 100 && msgnr < 200) || msgnr == 500)
                            {
                                if (he.EntryType == JournalTypeEnum.FSDJump || he.EntryType == JournalTypeEnum.Location)
                                {
                                    if (systemId != 0)
                                    {
                                        he.System.EDSMID = systemId;
                                        JournalEntry.UpdateEDSMIDPosJump(he.Journalid, he.System, false, 0, cn.Connection, txn);
                                    }
                                }

                                if (he.EntryType == JournalTypeEnum.FSDJump)       // only on FSD, confirmed with Anthor.  25/4/2018
                                {
                                    bool systemCreated = result["systemCreated"].Bool();

                                    if (systemCreated)
                                    {
                                        System.Diagnostics.Debug.WriteLine("** EDSM indicates first entry for " + he.System.Name);
                                        (he.journalEntry as JournalFSDJump).UpdateFirstDiscover(true, cn.Connection, txn);
                                        firsts = firsts.AppendPrePad(he.System.Name, ";");
                                    }
                                }

                                he.journalEntry.SetEdsmSync(cn.Connection, txn);

                                if (msgnr == 500)
                                {
                                    System.Diagnostics.Trace.WriteLine($"Warning submitting event {he.Journalid} \"{he.EventSummary}\": {msgnr} {result["msg"].Str()}");
                                }
                            }
                            else
                            {
                                System.Diagnostics.Trace.WriteLine($"Error submitting event {he.Journalid} \"{he.EventSummary}\": {msgnr} {result["msg"].Str()}");
                            }
                        }

                        txn.Commit();
                        return(firsts);
                    }
                });

                return(true);
            }
        }
Exemplo n.º 8
0
        // Called by Perform, by Sync, by above.

        public static bool SendEDSMEvents(Action <string> log, IEnumerable <HistoryEntry> helist, bool manual = false)
        {
            if (lastDiscardFetch < DateTime.UtcNow.AddMinutes(-120))     // check if we need a new discard list
            {
                try
                {
                    EDSMClass edsm = new EDSMClass();
                    discardEvents    = new HashSet <string>(edsm.GetJournalEventsToDiscard());
                    lastDiscardFetch = DateTime.UtcNow;
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.WriteLine($"Unable to retrieve events to be discarded: {ex.ToString()}");
                }
            }

            System.Diagnostics.Debug.WriteLine("Send " + helist.Count());

            int      eventCount = 0;
            bool     hasbeta    = false;
            DateTime betatime   = DateTime.MinValue;

            foreach (HistoryEntry he in helist) // push list of events to historylist queue..
            {
                if (!he.EdsmSync)               // if we have not sent it..
                {
                    string eventtype = he.EntryType.ToString();

                    if (he.Commander.Name.StartsWith("[BETA]", StringComparison.InvariantCultureIgnoreCase) || he.IsBetaMessage)
                    {
                        hasbeta  = true;
                        betatime = he.EventTimeUTC;
                        he.journalEntry.SetEdsmSync();       // crappy slow but unusual, but lets mark them as sent..
                    }
                    else if (!(he.MultiPlayer || discardEvents.Contains(eventtype) || alwaysDiscard.Contains(eventtype)))
                    {
                        historylist.Enqueue(new HistoryQueueEntry {
                            HistoryEntry = he, Logger = log, ManualSync = manual
                        });
                        eventCount++;
                    }
                }
            }

            if (hasbeta && eventCount == 0)
            {
                log?.Invoke($"Cannot send Beta logs to EDSM - most recent timestamp: {betatime.ToString("yyyy-MM-dd'T'HH:mm:ss'Z'")}");
            }

            if (manual)     // if in manual mode, we want to tell the user the end, so push an end marker
            {
                string logline = (eventCount > 0) ? $"Sending {eventCount} journal event(s) to EDSM" : "No new events to send to EDSM";
                log?.Invoke(logline);

                if (eventCount > 0)      // push end of sync event.
                {
                    historylist.Enqueue(new HistoryQueueEntry {
                        HistoryEntry = null, Logger = log, ManualSync = manual
                    });
                }
            }

            if (eventCount > 0)
            {
                historyevent.Set();

                // Start the sync thread if it's not already running
                if (Interlocked.CompareExchange(ref running, 1, 0) == 0)
                {
                    Exit = false;
                    exitevent.Reset();
                    ThreadEDSMSync              = new System.Threading.Thread(new System.Threading.ThreadStart(SyncThread));
                    ThreadEDSMSync.Name         = "EDSM Journal Sync";
                    ThreadEDSMSync.IsBackground = true;
                    ThreadEDSMSync.Start();
                }
            }

            return(true);
        }
Exemplo n.º 9
0
        // Partial update sync, do the 12 hour get and store until we come up to UTC time now approx.

        public static long PerformEDSMUpdateSync(bool[] grididallow, Func <bool> PendingClose, Action <int, string> ReportProgress, Action <string> LogLine, Action <string> LogLineHighlight)
        {
            long     updates        = 0;
            DateTime lastrecordtime = GetLastEDSMRecordTimeUTC();         // this is in UTC, as it comes out of the EDSM records

            if (DateTime.UtcNow.Subtract(lastrecordtime).TotalHours <= 1) // If we have partial synced for 1 hour, don't waste our time
            {
                System.Diagnostics.Debug.WriteLine("EDSM No partial sync, last record less than 1 hour old");
                return(updates);
            }

            // Go For SYNC

            LogLine("Checking for updated EDSM systems (may take a few moments).");

            EDSMClass edsm = new EDSMClass();

            while (lastrecordtime < DateTime.UtcNow.Subtract(new TimeSpan(0, 30, 0)))   // stop at X mins before now, so we don't get in a condition
            {                                                                           // where we do a set, the time moves to just before now,
                                                                                        // and we then do another set with minimum amount of hours
                if (PendingClose())
                {
                    return(updates);
                }

                int hourstofetch = 6;

                if (lastrecordtime < ED21date.AddHours(-48))
                {
                    hourstofetch = 48;
                }
                else if (lastrecordtime < ED23date.AddHours(-12))
                {
                    hourstofetch = 12;
                }

                DateTime enddate = lastrecordtime + TimeSpan.FromHours(hourstofetch);
                if (enddate > DateTime.UtcNow)
                {
                    enddate = DateTime.UtcNow;
                }

                LogLine($"Downloading systems from UTC {lastrecordtime.ToUniversalTime().ToString()} to {enddate.ToUniversalTime().ToString()}");
                ReportProgress(-1, "Requesting systems from EDSM");
                System.Diagnostics.Debug.WriteLine($"Downloading systems from UTC {lastrecordtime.ToUniversalTime().ToString()} to {enddate.ToUniversalTime().ToString()}");

                string json = null;
                BaseUtils.ResponseData response;
                try
                {
                    response = edsm.RequestSystemsData(lastrecordtime, enddate, timeout: 20000);
                }
                catch (WebException ex)
                {
                    ReportProgress(-1, $"EDSM request failed");
                    if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null && ex.Response is HttpWebResponse)
                    {
                        string status = ((HttpWebResponse)ex.Response).StatusDescription;
                        LogLine($"Download of EDSM systems from the server failed ({status}), will try next time program is run");
                    }
                    else
                    {
                        LogLine($"Download of EDSM systems from the server failed ({ex.Status.ToString()}), will try next time program is run");
                    }

                    return(updates);
                }
                catch (Exception ex)
                {
                    ReportProgress(-1, $"EDSM request failed");
                    LogLine($"Download of EDSM systems from the server failed ({ex.Message}), will try next time program is run");
                    return(updates);
                }

                if (response.Error)
                {
                    if ((int)response.StatusCode == 429)
                    {
                        LogLine($"EDSM rate limit hit - waiting 2 minutes");
                        for (int sec = 0; sec < 120; sec++)
                        {
                            if (!PendingClose())
                            {
                                System.Threading.Thread.Sleep(1000);
                            }
                        }
                    }
                    else
                    {
                        LogLine($"Download of EDSM systems from the server failed ({response.StatusCode.ToString()}), will try next time program is run");
                        return(updates);
                    }
                }

                json = response.Body;

                if (json == null)
                {
                    ReportProgress(-1, "EDSM request failed");
                    LogLine("Download of EDSM systems from the server failed (no data returned), will try next time program is run");
                    return(updates);
                }

                // debug File.WriteAllText(@"c:\code\json.txt", json);

                DateTime prevrectime = lastrecordtime;
                System.Diagnostics.Debug.WriteLine("Last record time {0} JSON size {1}", lastrecordtime.ToUniversalTime(), json.Length);

                long updated = 0;

                try
                {
                    updated = ParseEDSMUpdateSystemsString(json, grididallow, ref lastrecordtime, false, PendingClose, ReportProgress, false);
                    System.Diagnostics.Debug.WriteLine($".. Updated {updated} to {lastrecordtime.ToUniversalTime().ToString()}");
                    System.Diagnostics.Debug.WriteLine("Updated to time {0}", lastrecordtime.ToUniversalTime());

                    // if lastrecordtime did not change (=) or worse still, EDSM somehow moved the time back (unlikely)
                    if (lastrecordtime <= prevrectime)
                    {
                        lastrecordtime += TimeSpan.FromHours(12);       // Lets move on manually so we don't get stuck
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine("SysClassEDSM.2 Exception " + e.ToString());
                    ReportProgress(-1, "EDSM request failed");
                    LogLine("Processing EDSM systems download failed, will try next time program is run");
                    return(updates);
                }

                updates += updated;

                SetLastEDSMRecordTimeUTC(lastrecordtime); // keep on storing this in case next time we get an exception

                int delay = 10;                           // Anthor's normal delay
                int ratelimitlimit;
                int ratelimitremain;
                int ratelimitreset;

                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 ratelimitlimit) &&
                    Int32.TryParse(response.Headers["X-Rate-Limit-Remaining"], out ratelimitremain) &&
                    Int32.TryParse(response.Headers["X-Rate-Limit-Reset"], out ratelimitreset))
                {
                    if (ratelimitremain < ratelimitlimit * 3 / 4)                    // lets keep at least X remaining for other purposes later..
                    {
                        delay = ratelimitreset / (ratelimitlimit - ratelimitremain); // slow down to its pace now.. example 878/(360-272) = 10 seconds per quota
                    }
                    else
                    {
                        delay = 0;
                    }

                    System.Diagnostics.Debug.WriteLine("EDSM Delay Parameters {0} {1} {2} => {3}s", ratelimitlimit, ratelimitremain, ratelimitreset, delay);
                }

                for (int sec = 0; sec < delay; sec++)
                {
                    if (!PendingClose())
                    {
                        System.Threading.Thread.Sleep(1000);
                    }
                }
            }

            return(updates);
        }
Exemplo n.º 10
0
        // Partial update sync, do the 12 hour get and store until we come up to UTC time now approx.

        public static long PerformEDSMUpdateSync(bool[] grididallow, Func <bool> PendingClose, Action <int, string> ReportProgress, Action <string> LogLine, Action <string> LogLineHighlight)
        {
            long     updates        = 0;
            DateTime lastrecordtime = GetLastEDSMRecordTimeUTC();         // this is in UTC, as it comes out of the EDSM records

            if (DateTime.UtcNow.Subtract(lastrecordtime).TotalHours <= 1) // If we have partial synced for 1 hour, don't waste our time
            {
                System.Diagnostics.Debug.WriteLine("EDSM No partial sync, last record less than 1 hour old");
                return(updates);
            }

            // Go For SYNC

            LogLine("Checking for updated EDSM systems (may take a few moments).");

            EDSMClass edsm = new EDSMClass();

            while (lastrecordtime < DateTime.UtcNow.Subtract(new TimeSpan(0, 30, 0)))   // stop at X mins before now, so we don't get in a condition
            {                                                                           // where we do a set, the time moves to just before now,
                                                                                        // and we then do another set with minimum amount of hours
                if (PendingClose())
                {
                    return(updates);
                }

                int hourstofetch = 6;

                if (lastrecordtime < ED21date.AddHours(-48))
                {
                    hourstofetch = 48;
                }
                else if (lastrecordtime < ED23date.AddHours(-12))
                {
                    hourstofetch = 12;
                }

                DateTime enddate = lastrecordtime + TimeSpan.FromHours(hourstofetch);
                if (enddate > DateTime.UtcNow)
                {
                    enddate = DateTime.UtcNow;
                }

                LogLine($"Downloading systems from UTC {lastrecordtime.ToUniversalTime().ToString()} to {enddate.ToUniversalTime().ToString()}");
                ReportProgress(-1, "Requesting systems from EDSM");
                System.Diagnostics.Debug.WriteLine($"Downloading systems from UTC {lastrecordtime.ToUniversalTime().ToString()} to {enddate.ToUniversalTime().ToString()}");

                string json = null;
                try
                {
                    json = edsm.RequestSystems(lastrecordtime, enddate, timeout: 20000);
                }
                catch (WebException ex)
                {
                    ReportProgress(-1, $"EDSM request failed");
                    if (ex.Status == WebExceptionStatus.ProtocolError && ex.Response != null && ex.Response is HttpWebResponse)
                    {
                        string status = ((HttpWebResponse)ex.Response).StatusDescription;
                        LogLine($"Download of EDSM systems from the server failed ({status}), will try next time program is run");
                    }
                    else
                    {
                        LogLine($"Download of EDSM systems from the server failed ({ex.Status.ToString()}), will try next time program is run");
                    }

                    return(updates);
                }
                catch (Exception ex)
                {
                    ReportProgress(-1, $"EDSM request failed");
                    LogLine($"Download of EDSM systems from the server failed ({ex.Message}), will try next time program is run");
                    return(updates);
                }

                if (json == null)
                {
                    ReportProgress(-1, "EDSM request failed");
                    LogLine("Download of EDSM systems from the server failed (no data returned), will try next time program is run");
                    return(updates);
                }

                // debug File.WriteAllText(@"c:\code\json.txt", json);

                DateTime prevrectime = lastrecordtime;
                System.Diagnostics.Debug.WriteLine("Last record time {0} JSON size {1}", lastrecordtime.ToUniversalTime(), json.Length);

                long updated = 0;

                try
                {
                    updated = ParseEDSMUpdateSystemsString(json, grididallow, ref lastrecordtime, false, PendingClose, ReportProgress, false);
                    System.Diagnostics.Debug.WriteLine($".. Updated {updated} to {lastrecordtime.ToUniversalTime().ToString()}");
                    System.Diagnostics.Debug.WriteLine("Updated to time {0}", lastrecordtime.ToUniversalTime());

                    // if lastrecordtime did not change (=) or worse still, EDSM somehow moved the time back (unlikely)
                    if (lastrecordtime <= prevrectime)
                    {
                        lastrecordtime += TimeSpan.FromHours(12);       // Lets move on manually so we don't get stuck
                    }
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine("SysClassEDSM.2 Exception " + e.ToString());
                }

                updates += updated;

                SetLastEDSMRecordTimeUTC(lastrecordtime);       // keep on storing this in case next time we get an exception
            }

            return(updates);
        }
Exemplo n.º 11
0
        // Called from EDDiscoveryController, in DoPerform, on back thread, to determine what sync to do..

        public static long PerformEDSMFullSync(bool[] grididallow, Func <bool> PendingClose, Action <int, string> ReportProgress, Action <string> LogLine, Action <string> LogLineHighlight)
        {
            long updates = 0;

            EDSMClass edsm = new EDSMClass();

            LogLine("Get hidden systems from EDSM and remove from database");

            RemoveHiddenSystems();

            if (PendingClose())
            {
                return(updates);
            }

            LogLine("Download systems file from EDSM.");

            string edsmsystems = Path.Combine(EliteConfigInstance.InstanceOptions.AppDataDirectory, "edsmsystems.json");

            LogLine("Resyncing all downloaded EDSM systems with System Database." + Environment.NewLine + "This will take a while.");

            //  string s = edsmsystems; bool success = true; // debug, comment out next two lines

            bool newfile;
            bool success = BaseUtils.DownloadFileHandler.DownloadFile(EDSMClass.ServerAddress + "dump/systemsWithCoordinates.json", edsmsystems, out newfile, (n, s) =>
            {
                SQLiteConnectionSystem.CreateTempSystemsTable();

                DateTime maxdate = new DateTime(2000, 1, 1);

                try
                {
                    using (var reader = new StreamReader(s))
                        updates = ParseEDSMUpdateSystemsStream(reader, grididallow, ref maxdate, true, PendingClose, ReportProgress, useCache: false, useTempSystems: true);
                }
                catch (Exception e)
                {
                    System.Diagnostics.Debug.WriteLine("SysClassEDSM.3 Exception " + e.ToString());
                }

                if (!PendingClose())       // abort, without saving time, to make it do it again
                {
                    LogLine("Replacing old systems table with new systems table and re-indexing - please wait");
                    ReportProgress(-1, "Replacing old systems table with new systems table and re-indexing - please wait");

                    SQLiteConnectionSystem.ReplaceSystemsTable();

                    SetLastEDSMRecordTimeUTC(maxdate);      // record the last record seen in time

                    ReportProgress(-1, "");

                    LogLine("System Database updated with EDSM data, " + updates + " systems updated.");

                    GC.Collect();
                }
                else
                {
                    success = false;
                    throw new OperationCanceledException();
                }
            });

            if (!success)
            {
                LogLine("Failed to download EDSM system file from server, will check next time");
            }

            return(updates);
        }
Exemplo n.º 12
0
        public static void PerformSync(Func <bool> cancelRequested, Action <int, string> reportProgress, Action <string> logLine, Action <string> logError, SystemsSyncState state)           // big check.. done in a thread.
        {
            reportProgress(-1, "");

            state.performhistoryrefresh = false;
            state.syncwasfirstrun       = SystemClassDB.IsSystemsTableEmpty();           // remember if DB is empty

            // Force a full sync if newest data is more than 14 days old

            bool     outoforder = SQLiteConnectionSystem.GetSettingBool("EDSMSystemsOutOfOrder", true);
            DateTime lastmod    = outoforder ? SystemClassDB.GetLastSystemModifiedTime() : SystemClassDB.GetLastSystemModifiedTimeFast();

            if (DateTime.UtcNow.Subtract(lastmod).TotalDays >= 14)
            {
                state.performedsmsync = true;
            }

            bool edsmoreddbsync = state.performedsmsync || state.performeddbsync;           // remember if we are syncing

            state.syncwaseddboredsm = edsmoreddbsync;

            if (state.performedsmsync || state.performeddbsync)
            {
                if (state.performedsmsync && !cancelRequested())
                {
                    // Download new systems
                    try
                    {
                        state.performhistoryrefresh |= PerformEDSMFullSync(cancelRequested, reportProgress, logLine, logError);
                        state.performedsmsync        = false;
                    }
                    catch (Exception ex)
                    {
                        logError("GetAllEDSMSystems exception:" + ex.Message);
                    }
                }

                if (!cancelRequested())
                {
                    logLine("Indexing systems table");
                    SQLiteConnectionSystem.CreateSystemsTableIndexes();

                    try
                    {
                        EliteDangerousCore.EDDB.SystemClassEDDB.PerformEDDBFullSync(cancelRequested, reportProgress, logLine, logError);
                        state.performeddbsync = false;
                    }
                    catch (Exception ex)
                    {
                        logError("GetEDDBUpdate exception: " + ex.Message);
                    }
                    state.performhistoryrefresh = true;
                }
            }

            if (!cancelRequested())
            {
                logLine("Indexing systems table");
                SQLiteConnectionSystem.CreateSystemsTableIndexes();

                lastmod = outoforder ? SystemClassDB.GetLastSystemModifiedTime() : SystemClassDB.GetLastSystemModifiedTimeFast();
                if (DateTime.UtcNow.Subtract(lastmod).TotalHours >= 1)
                {
                    logLine("Checking for new EDSM systems (may take a few moments).");
                    EDSMClass edsm    = new EDSMClass();
                    long      updates = edsm.GetNewSystems(cancelRequested, reportProgress, logLine);
                    logLine($"EDSM updated {updates:N0} systems.");
                    state.performhistoryrefresh |= (updates > 0);
                }
            }

            reportProgress(-1, "");
        }
Exemplo n.º 13
0
        public static bool PerformEDSMFullSync(Func <bool> cancelRequested, Action <int, string> reportProgress, Action <string> logLine, Action <string> logError)
        {
            string   rwsystime = SQLiteConnectionSystem.GetSettingString("EDSMLastSystems", "2000-01-01 00:00:00"); // Latest time from RW file.
            DateTime edsmdate;

            if (!DateTime.TryParse(rwsystime, CultureInfo.InvariantCulture, DateTimeStyles.None, out edsmdate))
            {
                edsmdate = new DateTime(2000, 1, 1);
            }

            long updates = 0;

            // Delete all old systems
            SQLiteConnectionSystem.PutSettingString("EDSMLastSystems", "2010-01-01 00:00:00");
            SQLiteConnectionSystem.PutSettingString("EDDBSystemsTime", "0");

            EDSMClass edsm = new EDSMClass();

            logLine("Get hidden systems from EDSM and remove from database");

            RemoveHiddenSystems();

            if (cancelRequested())
            {
                return(false);
            }

            logLine("Download systems file from EDSM.");

            string edsmsystems = Path.Combine(EliteConfigInstance.InstanceOptions.AppDataDirectory, "edsmsystems.json");

            logLine("Resyncing all downloaded EDSM systems with local database." + Environment.NewLine + "This will take a while.");

            bool newfile;
            bool success = BaseUtils.DownloadFileHandler.DownloadFile(EDSMClass.ServerAddress + "dump/systemsWithCoordinates.json", edsmsystems, out newfile, (n, s) =>
            {
                SQLiteConnectionSystem.CreateTempSystemsTable();

                string rwsysfiletime = "2014-01-01 00:00:00";
                bool outoforder      = false;
                using (var reader = new StreamReader(s))
                    updates = ParseEDSMUpdateSystemsStream(reader, ref rwsysfiletime, ref outoforder, true, cancelRequested, reportProgress, useCache: false, useTempSystems: true);
                if (!cancelRequested())       // abort, without saving time, to make it do it again
                {
                    SQLiteConnectionSystem.PutSettingString("EDSMLastSystems", rwsysfiletime);
                    logLine("Replacing old systems table with new systems table and re-indexing - please wait");
                    reportProgress(-1, "Replacing old systems table with new systems table and re-indexing - please wait");
                    SQLiteConnectionSystem.ReplaceSystemsTable();
                    SQLiteConnectionSystem.PutSettingBool("EDSMSystemsOutOfOrder", outoforder);
                    reportProgress(-1, "");
                }
                else
                {
                    throw new OperationCanceledException();
                }
            });

            if (!success)
            {
                logLine("Failed to download EDSM system file from server, will check next time");
                return(false);
            }

            // Stop if requested
            if (cancelRequested())
            {
                return(false);
            }

            logLine("Local database updated with EDSM data, " + updates + " systems updated.");

            GC.Collect();

            return(updates > 0);
        }
Exemplo n.º 14
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);
            }
        }
Exemplo n.º 15
0
        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;
                    }
                }
            }
        }
Exemplo n.º 16
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);
                    }
                }
            }
        }
Exemplo n.º 17
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;
                    }
                }
            }
        }