public void FSDJump(JournalFSDJump e) { if (HaveCurrentShip) { Ships[currentid] = CurrentShip.SetFuelLevel(e.FuelLevel); } }
public JObject CreateEDDNMessage(JournalFSDJump journal) { if (!journal.HasCoordinate || journal.StarPosFromEDSM) { return(null); } JObject msg = new JObject(); msg["header"] = Header(); msg["$schemaRef"] = GetEDDNJournalSchemaRef(); JObject message = journal.GetJson(); if (message["FuelUsed"].Empty()) // Old ED 2.1 messages has no Fuel used fields { return(null); } message = RemoveCommonKeys(message); message.Remove("BoostUsed"); message.Remove("JumpDist"); message.Remove("FuelUsed"); message.Remove("FuelLevel"); message.Remove("StarPosFromEDSM"); msg["message"] = message; return(msg); }
public JObject CreateEDDNMessage(JournalFSDJump journal) { if (!journal.HasCoordinate || journal.StarPosFromEDSM) { return(null); } JObject msg = new JObject(); msg["header"] = Header(); msg["$schemaRef"] = GetEDDNSchemaRef(); JObject message = (JObject)JObject.Parse(journal.EventDataString); if (JSONHelper.IsNullOrEmptyT(message["FuelUsed"])) // Old ED 2.1 messages has no Fuel used fields { return(null); } message = RemoveCommonKeys(message); message.Remove("BoostUsed"); message.Remove("JumpDist"); message.Remove("FuelUsed"); message.Remove("FuelLevel"); message.Remove("StarPosFromEDSM"); msg["message"] = message; return(msg); }
// Called on a New Entry, by EDDiscoveryController:NewEntry, to add an journal entry in public IEnumerable <HistoryEntry> AddJournalEntry(JournalEntry inje, Action <string> logerror) { if (inje.CommanderId == CommanderId) // we are only interested at this point accepting ones for the display commander { HistoryEntry last = GetLast; foreach (JournalEntry je in ProcessJournalEntry(inje)) { bool journalupdate = false; HistoryEntry he = HistoryEntry.FromJournalEntry(je, last, true, out journalupdate); if (journalupdate) { JournalFSDJump jfsd = je as JournalFSDJump; if (jfsd != null) { JournalEntry.UpdateEDSMIDPosJump(jfsd.Id, he.System, !jfsd.HasCoordinate && he.System.HasCoordinate, jfsd.JumpDist); } } using (SQLiteConnectionUser conn = new SQLiteConnectionUser()) { he.ProcessWithUserDb(je, last, this, conn); // let some processes which need the user db to work cashledger.Process(je, conn); he.Credits = cashledger.CashTotal; Tuple <ShipInformation, ModulesInStore> ret = shipinformationlist.Process(je, conn); he.ShipInformation = ret.Item1; he.StoredModules = ret.Item2; he.MissionList = missionlistaccumulator.Process(je, he.System, he.WhereAmI, conn); } historylist.Add(he); if (je.EventTypeID == JournalTypeEnum.Scan) { JournalScan js = je as JournalScan; JournalLocOrJump jl; HistoryEntry jlhe; if (!starscan.AddScanToBestSystem(js, Count - 1, EntryOrder, out jlhe, out jl)) { // Ignore scans where the system name has been changed // Also ignore belt clusters if (jl == null || (jl.StarSystem.Equals(jlhe.System.name, StringComparison.InvariantCultureIgnoreCase) && !js.BodyDesignation.ToLowerInvariant().Contains(" belt cluster "))) { logerror("Cannot add scan to system - alert the EDDiscovery developers using either discord or Github (see help)" + Environment.NewLine + "Scan object " + js.BodyName + " in " + he.System.name); } } } yield return(he); last = he; } } }
public void FSDJump(JournalFSDJump e) { if (HaveCurrentShip) { Ships[currentid] = CurrentShip.SetFuelLevel(e.FuelLevel).SetSubVehicle(ShipInformation.SubVehicleType.None); } VerifyList(); }
public void UpdateMapColour(int v) { JournalFSDJump fsd = this as JournalFSDJump; // only update if fsd if (fsd != null) { fsd.SetMapColour(v); } }
public void No_filter_does_not_filter_anything() { JournalFSDJump jsd = new JournalFSDJump(DateTime.UtcNow.Subtract(TimeSpan.FromDays(500000)), sol, 0, false, 0); var veryOldData = HistoryEntry.FromJournalEntry(jsd, null, out bool notused); var input = new HistoryList(new List <HistoryEntry> { veryOldData }); Check.That(TravelHistoryFilter.NoFilter.Filter(input)).ContainsExactly(veryOldData); }
override public bool ToCSV(string filename) { try { using (StreamWriter writer = new StreamWriter(filename)) { // Write header writer.Write("Time" + delimiter); writer.Write("Name" + delimiter); writer.Write("X" + delimiter); writer.Write("Y" + delimiter); writer.Write("Z" + delimiter); writer.Write("Distance" + delimiter); writer.Write("Fuel used" + delimiter); writer.Write("Fuel left" + delimiter); writer.Write("Boost" + delimiter); writer.Write("Note" + delimiter); writer.WriteLine(); foreach (var je in scans) { if (je.EventTypeID == JournalTypeEnum.FSDJump) { JournalFSDJump ev = je as JournalFSDJump; writer.Write(MakeValueCsvFriendly(ev.EventTimeLocal)); writer.Write(MakeValueCsvFriendly(ev.StarSystem)); writer.Write(MakeValueCsvFriendly(ev.StarPos.X)); writer.Write(MakeValueCsvFriendly(ev.StarPos.Y)); writer.Write(MakeValueCsvFriendly(ev.StarPos.Z)); writer.Write(MakeValueCsvFriendly(ev.JumpDist)); writer.Write(MakeValueCsvFriendly(ev.FuelUsed)); writer.Write(MakeValueCsvFriendly(ev.FuelLevel)); writer.Write(MakeValueCsvFriendly(ev.BoostUsed, false)); // writer.Write(MakeValueCsvFriendly(je.System.SystemNote)); writer.WriteLine(); } } } return(true); } catch (IOException) { ExtendedControls.MessageBoxTheme.Show(String.Format("Is file {0} open?", filename), "Export Scan", MessageBoxButtons.OK, MessageBoxIcon.Error); return(false); } }
public JObject CreateEDDNMessage(JournalFSDJump journal) { if (!journal.HasCoordinate || journal.StarPosFromEDSM || journal.SystemAddress == null) { return(null); } JObject msg = new JObject(); msg["header"] = Header(); msg["$schemaRef"] = GetEDDNJournalSchemaRef(); JObject message = journal.GetJsonCloned(); if (message == null) { return(null); } if (message["FuelUsed"].IsNull() || message["SystemAddress"] == null) // Old ED 2.1 messages has no Fuel used fields { return(null); } if (message["StarPosFromEDSM"] != null) // Reject systems recently updated with EDSM coords { return(null); } message = RemoveCommonKeys(message); message = RemoveFactionReputation(message); message.Remove("BoostUsed"); message.Remove("MyReputation"); message.Remove("JumpDist"); message.Remove("FuelUsed"); message.Remove("FuelLevel"); message.Remove("StarPosFromEDSM"); message.Remove("ActiveFine"); message = FilterJournalEvent(message, AllowedFieldsFSDJump); message["odyssey"] = journal.IsOdyssey; // new may 21 message["horizons"] = journal.IsHorizons; msg["message"] = message; return(msg); }
override public bool ToCSV(string filename) { using (StreamWriter writer = new StreamWriter(filename)) { // Write header writer.Write("Time" + delimiter); writer.Write("Name" + delimiter); writer.Write("X" + delimiter); writer.Write("Y" + delimiter); writer.Write("Z" + delimiter); writer.Write("Distance" + delimiter); writer.Write("Fuel used" + delimiter); writer.Write("Fuel left" + delimiter); writer.Write("Boost" + delimiter); writer.Write("Note" + delimiter); writer.WriteLine(); foreach (var je in scans) { if (je.EventTypeID == JournalTypeEnum.FSDJump) { JournalFSDJump ev = je as JournalFSDJump; writer.Write(MakeValueCsvFriendly(ev.EventTimeLocal)); writer.Write(MakeValueCsvFriendly(ev.StarSystem)); writer.Write(MakeValueCsvFriendly(ev.StarPos.X)); writer.Write(MakeValueCsvFriendly(ev.StarPos.Y)); writer.Write(MakeValueCsvFriendly(ev.StarPos.Z)); writer.Write(MakeValueCsvFriendly(ev.JumpDist)); writer.Write(MakeValueCsvFriendly(ev.FuelUsed)); writer.Write(MakeValueCsvFriendly(ev.FuelLevel)); writer.Write(MakeValueCsvFriendly(ev.BoostUsed)); // writer.Write(MakeValueCsvFriendly(je.System.SystemNote)); writer.WriteLine(); } } } return(true); }
public JObject CreateEDDNMessage(JournalFSDJump journal) { if (!journal.HasCoordinate || journal.StarPosFromEDSM || journal.SystemAddress == null) { return(null); } JObject msg = new JObject(); msg["header"] = Header(); msg["$schemaRef"] = GetEDDNJournalSchemaRef(); JObject message = journal.GetJson(); if (message == null) { return(null); } if (message["FuelUsed"].Empty() || message["SystemAddress"] == null) // Old ED 2.1 messages has no Fuel used fields { return(null); } message = RemoveCommonKeys(message); message = RemoveFactionReputation(message); message.Remove("BoostUsed"); message.Remove("MyReputation"); message.Remove("JumpDist"); message.Remove("FuelUsed"); message.Remove("FuelLevel"); message.Remove("StarPosFromEDSM"); message.Remove("ActiveFine"); message = FilterJournalEvent(message, AllowedFieldsFSDJump); msg["message"] = message; return(msg); }
void Process(List <JournalFSDJump> edsmlogs, DateTime logstarttime, DateTime logendtime) { // 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 bool 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 { System.Diagnostics.Debug.WriteLine($"Adding EDSM logs count {toadd.Count}"); TravelLogUnit tlu = new TravelLogUnit(); // need a tlu for it tlu.type = TravelLogUnit.EDSMType; // 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 UserDatabase.Instance.ExecuteWithDatabase(cn => { foreach (JournalFSDJump jfsd in toadd) { System.Diagnostics.Trace.WriteLine(string.Format("Add {0} {1}", jfsd.EventTimeUTC, jfsd.StarSystem)); jfsd.SetTLUCommander(tlu.id, tlu.CommanderId.Value); // update its TLU id to the TLU made above jfsd.Add(jfsd.CreateFSDJournalEntryJson(), cn.Connection); // add it to the db with the JSON created } }); LogLine($"Retrieved {toadd.Count} log entries from EDSM, from {logstarttime.ToLocalTime().ToString()} to {logendtime.ToLocalTime().ToString()}"); OnDownloadedSystems?.Invoke(); } }
// Protected against bad JSON public int GetLogs(DateTime?starttimeutc, DateTime?endtimeutc, out List <JournalFSDJump> log, out DateTime logstarttime, out DateTime logendtime) { log = new List <JournalFSDJump>(); logstarttime = DateTime.MaxValue; logendtime = DateTime.MinValue; if (!ValidCredentials) { return(0); } string query = "get-logs?showId=1&apiKey=" + apiKey + "&commanderName=" + HttpUtility.UrlEncode(commanderName); if (starttimeutc != null) { query += "&startDateTime=" + HttpUtility.UrlEncode(starttimeutc.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)); } if (endtimeutc != null) { query += "&endDateTime=" + HttpUtility.UrlEncode(endtimeutc.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)); } var response = RequestGet("api-logs-v1/" + query, handleException: true); if (response.Error) { return(0); } var json = response.Body; if (json == null) { return(0); } try { JObject msg = JObject.Parse(json); int msgnr = msg["msgnum"].Int(0); JArray logs = (JArray)msg["logs"]; if (logs != null) { string startdatestr = msg["startDateTime"].Value <string>(); string enddatestr = msg["endDateTime"].Value <string>(); if (startdatestr == null || !DateTime.TryParseExact(startdatestr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out logstarttime)) { logstarttime = DateTime.MaxValue; } if (enddatestr == null || !DateTime.TryParseExact(enddatestr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out logendtime)) { logendtime = DateTime.MinValue; } using (SQLiteConnectionSystem cn = new SQLiteConnectionSystem()) { foreach (JObject jo in logs) { string name = jo["system"].Value <string>(); string ts = jo["date"].Value <string>(); long id = jo["systemId"].Value <long>(); bool firstdiscover = jo["firstDiscover"].Value <bool>(); DateTime etutc = DateTime.ParseExact(ts, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); // UTC time ISystem sc = SystemClassDB.GetSystem(id, cn, SystemClassDB.SystemIDType.EdsmId, name: name); if (sc == null) { if (DateTime.UtcNow.Subtract(etutc).TotalHours < 6) // Avoid running into the rate limit { sc = GetSystemsByName(name)?.FirstOrDefault(s => s.EDSMID == id); } if (sc == null) { sc = new SystemClass(name) { EDSMID = id }; } } JournalFSDJump fsd = new JournalFSDJump(etutc, sc, EliteConfigInstance.InstanceConfig.DefaultMapColour, firstdiscover, (int)SyncFlags.EDSM); log.Add(fsd); } } } return(msgnr); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Failed due to " + e.ToString()); return(499); // BAD JSON } }
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; } } } }
public static HistoryEntry FromJournalEntry(JournalEntry je, HistoryEntry prev, out bool journalupdate, SQLiteConnectionSystem conn = null) { ISystem isys = prev == null ? new SystemClass("Unknown") : prev.System; int indexno = prev == null ? 1 : prev.Indexno + 1; journalupdate = false; if (je.EventTypeID == JournalTypeEnum.Location || je.EventTypeID == JournalTypeEnum.FSDJump) { JournalLocOrJump jl = je as JournalLocOrJump; ISystem newsys; if (jl != null && jl.HasCoordinate) // LAZY LOAD IF it has a co-ord.. the front end will when it needs it { newsys = new SystemClass(jl.StarSystem, jl.StarPos.X, jl.StarPos.Y, jl.StarPos.Z) { EDSMID = jl.EdsmID < 0 ? 0 : jl.EdsmID, // pass across the EDSMID for the lazy load process. Faction = jl.Faction, Government = jl.EDGovernment, PrimaryEconomy = jl.EDEconomy, Security = jl.EDSecurity, Population = jl.Population ?? 0, State = jl.EDState, Allegiance = jl.EDAllegiance, UpdateDate = jl.EventTimeUTC, status = SystemStatusEnum.EDDiscovery, SystemAddress = jl.SystemAddress, }; // If it was a new system, pass the coords back to the StartJump if (prev != null && prev.journalEntry is JournalStartJump) { prev.System = newsys; // give the previous startjump our system.. } } else { // NOTE Rob: 09-JAN-2018 I've removed the Jumpstart looking up a system by name since they were using up lots of lookup time during history reading. // This is used for pre 2.2 systems without co-ords, which now should be limited. // JumpStart still gets the system when the FSD loc is processed, see above. // Jumpstart was also screwing about with the EDSM ID fill in which was broken. This is now working again. // Default one newsys = new SystemClass(jl.StarSystem); newsys.EDSMID = je.EdsmID; ISystem s = SystemCache.FindSystem(newsys, conn); // has no co-ord, did we find it? if (s != null) // found a system.. { if (jl != null && jl.HasCoordinate) // if journal Loc, and journal has a star position, use that instead of EDSM.. { s.X = Math.Round(jl.StarPos.X * 32.0) / 32.0; s.Y = Math.Round(jl.StarPos.Y * 32.0) / 32.0; s.Z = Math.Round(jl.StarPos.Z * 32.0) / 32.0; } //Debug.WriteLine("HistoryList found system {0} {1}", s.id_edsm, s.name); newsys = s; if (jl != null && je.EdsmID <= 0 && newsys.EDSMID > 0) // only update on a JL.. { journalupdate = true; Debug.WriteLine("HE EDSM ID update requested {0} {1}", newsys.EDSMID, newsys.Name); } } else { newsys.EDSMID = -1; // mark as checked but not found } } JournalFSDJump jfsd = je as JournalFSDJump; if (jfsd != null) { if (jfsd.JumpDist <= 0 && isys.HasCoordinate && newsys.HasCoordinate) // if no JDist, its a really old entry, and if previous has a co-ord { jfsd.JumpDist = isys.Distance(newsys); // fill it out here if (jfsd.JumpDist > 0) { journalupdate = true; Debug.WriteLine("Je Jump distance update(3) requested {0} {1} {2}", newsys.EDSMID, newsys.Name, jfsd.JumpDist); } } } isys = newsys; } HistoryEntry he = new HistoryEntry { Indexno = indexno, journalEntry = je, System = isys, EntryStatus = HistoryEntryStatus.Update(prev?.EntryStatus, je, isys.Name) }; if (prev != null) { if (prev.StopMarker) // if we had a stop marker previously, means the next one needs to clear the counters { he.travelling = false; // still travelling if its a start marker he.travelled_distance = 0; he.travelled_seconds = new TimeSpan(0); he.travelled_missingjump = 0; he.travelled_jumps = 0; } else { he.travelling = prev.travelling; he.travelled_distance = prev.travelled_distance; he.travelled_seconds = prev.travelled_seconds; he.travelled_missingjump = prev.travelled_missingjump; he.travelled_jumps = prev.travelled_jumps; } } if (he.StartMarker) // start marker, start travelling { he.travelling = true; } if (he.travelling) { if (he.IsFSDJump && !he.MultiPlayer) // if jump, and not multiplayer.. { double dist = ((JournalFSDJump)je).JumpDist; if (dist <= 0) { he.travelled_missingjump++; } else { he.travelled_distance += dist; he.travelled_jumps++; } } if (prev != null) { TimeSpan diff = he.EventTimeUTC.Subtract(prev.EventTimeUTC); if (he.EntryType != JournalTypeEnum.LoadGame && diff < new TimeSpan(2, 0, 0)) // time between last entry and load game is not real time { he.travelled_seconds += diff; } } } return(he); }
// Protected against bad JSON Visual Inspection Nov 2020 - using Int() public int GetLogs(DateTime?starttimeutc, DateTime?endtimeutc, out List <JournalFSDJump> log, out DateTime logstarttime, out DateTime logendtime, out BaseUtils.ResponseData response) { log = new List <JournalFSDJump>(); logstarttime = DateTime.MaxValue; logendtime = DateTime.MinValue; response = new BaseUtils.ResponseData { Error = true, StatusCode = HttpStatusCode.Unauthorized }; if (!ValidCredentials) { return(0); } string query = "get-logs?showId=1&apiKey=" + apiKey + "&commanderName=" + HttpUtility.UrlEncode(commanderName); if (starttimeutc != null) { query += "&startDateTime=" + HttpUtility.UrlEncode(starttimeutc.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)); } if (endtimeutc != null) { query += "&endDateTime=" + HttpUtility.UrlEncode(endtimeutc.Value.ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture)); } response = RequestGet("api-logs-v1/" + query, handleException: true); if (response.Error) { if ((int)response.StatusCode == 429) { return(429); } else { return(0); } } var json = response.Body; if (json == null) { return(0); } try { JObject msg = JObject.ParseThrowCommaEOL(json); int msgnr = msg["msgnum"].Int(0); JArray logs = (JArray)msg["logs"]; if (logs != null) { string startdatestr = msg["startDateTime"].Str(); string enddatestr = msg["endDateTime"].Str(); if (startdatestr == null || !DateTime.TryParseExact(startdatestr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out logstarttime)) { logstarttime = DateTime.MaxValue; } if (enddatestr == null || !DateTime.TryParseExact(enddatestr, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal, out logendtime)) { logendtime = DateTime.MinValue; } var tofetch = SystemsDatabase.Instance.ExecuteWithDatabase(db => { var xtofetch = new List <Tuple <JObject, ISystem> >(); foreach (JObject jo in logs) { string name = jo["system"].Str(); string ts = jo["date"].Str(); long id = jo["systemId"].Long(); DateTime etutc = DateTime.ParseExact(ts, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); // UTC time ISystem sc = DB.SystemCache.FindSystem(new SystemClass(name, id), db); // find in our DB only. xtofetch.Add(new Tuple <JObject, ISystem>(jo, sc)); } return(xtofetch); }); var xlog = new List <JournalFSDJump>(); foreach (var js in tofetch) { var jo = js.Item1; var sc = js.Item2; string name = jo["system"].Str(); string ts = jo["date"].Str(); long id = jo["systemId"].Long(); bool firstdiscover = jo["firstDiscover"].Bool(); DateTime etutc = DateTime.ParseExact(ts, "yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal | DateTimeStyles.AssumeUniversal); // UTC time if (sc == null) { if (DateTime.UtcNow.Subtract(etutc).TotalHours < 6) // Avoid running into the rate limit { sc = GetSystem(name)?.FirstOrDefault(s => s.EDSMID == id); } if (sc == null) { sc = new SystemClass(name, id); // make an EDSM system } } JournalFSDJump fsd = new JournalFSDJump(etutc, sc, EDCommander.Current.MapColour, firstdiscover, true); xlog.Add(fsd); } log = xlog; } return(msgnr); } catch (Exception e) { System.Diagnostics.Debug.WriteLine("Failed due to " + e.ToString()); return(499); // BAD JSON } }
// Called on a New Entry, by EDDiscoveryController:NewEntry, to add an journal entry in public HistoryEntry AddJournalEntry(JournalEntry je, Action <string> logerror) // always return he { HistoryEntry prev = GetLast; bool journalupdate = false; HistoryEntry he = HistoryEntry.FromJournalEntry(je, prev, out journalupdate); // we may check edsm for this entry if (journalupdate) { JournalFSDJump jfsd = je as JournalFSDJump; if (jfsd != null) { JournalEntry.UpdateEDSMIDPosJump(jfsd.Id, he.System, !jfsd.HasCoordinate && he.System.HasCoordinate, jfsd.JumpDist); } } using (SQLiteConnectionUser conn = new SQLiteConnectionUser()) { he.ProcessWithUserDb(je, prev, this, conn); // let some processes which need the user db to work cashledger.Process(je, conn); he.Credits = cashledger.CashTotal; shipyards.Process(je, conn); outfitting.Process(je, conn); Tuple <ShipInformation, ModulesInStore> ret = shipinformationlist.Process(je, conn, he.WhereAmI, he.System); he.ShipInformation = ret.Item1; he.StoredModules = ret.Item2; he.MissionList = missionlistaccumulator.Process(je, he.System, he.WhereAmI, conn); } historylist.Add(he); if (je.EventTypeID == JournalTypeEnum.Scan) { JournalScan js = je as JournalScan; JournalLocOrJump jl; HistoryEntry jlhe; if (!starscan.AddScanToBestSystem(js, Count - 1, EntryOrder, out jlhe, out jl)) { // Ignore scans where the system name has been changed // Also ignore belt clusters if (jl == null || (jl.StarSystem.Equals(jlhe.System.Name, StringComparison.InvariantCultureIgnoreCase) && !js.BodyDesignation.ToLowerInvariant().Contains(" belt cluster "))) { logerror("Cannot add scan to system - alert the EDDiscovery developers using either discord or Github (see help)" + Environment.NewLine + "Scan object " + js.BodyName + " in " + he.System.Name); } } } else if (je is IBodyNameAndID) { JournalLocOrJump jl; HistoryEntry jlhe; starscan.AddBodyToBestSystem((IBodyNameAndID)je, Count - 1, EntryOrder, out jlhe, out jl); } return(he); }
public static HistoryEntry FromJournalEntry(JournalEntry je, HistoryEntry prev, out bool journalupdate, SQLiteConnectionSystem conn = null, EDCommander cmdr = null) { ISystem isys = prev == null ? new SystemClass("Unknown") : prev.System; int indexno = prev == null ? 1 : prev.Indexno + 1; int mapcolour = 0; journalupdate = false; bool starposfromedsm = false; bool firstdiscover = false; if (je.EventTypeID == JournalTypeEnum.Location || je.EventTypeID == JournalTypeEnum.FSDJump) { JournalLocOrJump jl = je as JournalLocOrJump; ISystem newsys; if (jl != null && jl.HasCoordinate) // LAZY LOAD IF it has a co-ord.. the front end will when it needs it { newsys = new SystemClass(jl.StarSystem, jl.StarPos.X, jl.StarPos.Y, jl.StarPos.Z) { EDSMID = jl.EdsmID < 0 ? 0 : jl.EdsmID, // pass across the EDSMID for the lazy load process. Faction = jl.Faction, Government = jl.EDGovernment, PrimaryEconomy = jl.EDEconomy, Security = jl.EDSecurity, Population = jl.Population ?? 0, State = jl.EDState, Allegiance = jl.EDAllegiance, UpdateDate = jl.EventTimeUTC, status = SystemStatusEnum.EDDiscovery, SystemAddress = jl.SystemAddress, }; // If it was a new system, pass the coords back to the StartJump if (prev != null && prev.journalEntry is JournalStartJump) { prev.System = newsys; // give the previous startjump our system.. } } else { // NOTE Rob: 09-JAN-2018 I've removed the Jumpstart looking up a system by name since they were using up lots of lookup time during history reading. // This is used for pre 2.2 systems without co-ords, which now should be limited. // JumpStart still gets the system when the FSD loc is processed, see above. // Jumpstart was also screwing about with the EDSM ID fill in which was broken. This is now working again. // Default one newsys = new SystemClass(jl.StarSystem); newsys.EDSMID = je.EdsmID; ISystem s = SystemCache.FindSystem(newsys, conn); // has no co-ord, did we find it? if (s != null) // found a system.. { if (jl != null && jl.HasCoordinate) // if journal Loc, and journal has a star position, use that instead of EDSM.. { s.X = Math.Round(jl.StarPos.X * 32.0) / 32.0; s.Y = Math.Round(jl.StarPos.Y * 32.0) / 32.0; s.Z = Math.Round(jl.StarPos.Z * 32.0) / 32.0; } //Debug.WriteLine("HistoryList found system {0} {1}", s.id_edsm, s.name); newsys = s; if (jl != null && je.EdsmID <= 0 && newsys.EDSMID > 0) // only update on a JL.. { journalupdate = true; Debug.WriteLine("HE EDSM ID update requested {0} {1}", newsys.EDSMID, newsys.Name); } } else { newsys.EDSMID = -1; // mark as checked but not found } } JournalFSDJump jfsd = je as JournalFSDJump; if (jfsd != null) { if (jfsd.JumpDist <= 0 && isys.HasCoordinate && newsys.HasCoordinate) // if no JDist, its a really old entry, and if previous has a co-ord { jfsd.JumpDist = isys.Distance(newsys); // fill it out here if (jfsd.JumpDist > 0) { journalupdate = true; Debug.WriteLine("Je Jump distance update(3) requested {0} {1} {2}", newsys.EDSMID, newsys.Name, jfsd.JumpDist); } } mapcolour = jfsd.MapColor; } isys = newsys; starposfromedsm = (jl != null && jl.HasCoordinate) ? jl.StarPosFromEDSM : newsys.HasCoordinate; firstdiscover = jl == null ? false : jl.EDSMFirstDiscover; } string summary, info, detailed; je.FillInformation(out summary, out info, out detailed); HistoryEntry he = new HistoryEntry { Indexno = indexno, EntryType = je.EventTypeID, Journalid = je.Id, journalEntry = je, System = isys, EventTimeUTC = je.EventTimeUTC, MapColour = mapcolour, EdsmSync = je.SyncedEDSM, EDDNSync = je.SyncedEDDN, EGOSync = je.SyncedEGO, StartMarker = je.StartMarker, StopMarker = je.StopMarker, EventSummary = summary, EventDescription = info, EventDetailedInfo = detailed, IsStarPosFromEDSM = starposfromedsm, IsEDSMFirstDiscover = firstdiscover, Commander = cmdr ?? EDCommander.GetCommander(je.CommanderId) }; // WORK out docked/landed state if (prev != null) { if (prev.docked.HasValue) // copy docked.. { he.docked = prev.docked; } if (prev.landed.HasValue) { he.landed = prev.landed; } if (prev.hyperspace.HasValue) { he.hyperspace = prev.hyperspace; } if (prev.marketId != null) { he.marketId = prev.marketId; } if (prev.wanted.HasValue) { he.wanted = prev.wanted; } he.stationName = prev.stationName; he.shiptype = prev.shiptype; he.shipid = prev.shipid; he.whereami = prev.whereami; he.onCrewWithCaptain = prev.onCrewWithCaptain; he.gamemode = prev.gamemode; he.group = prev.group; } if (je.EventTypeID == JournalTypeEnum.Location) { JournalLocation jl = je as JournalLocation; he.docked = jl.Docked; he.landed = jl.Latitude.HasValue; he.whereami = jl.Docked ? jl.StationName : jl.Body; he.hyperspace = false; he.wanted = jl.Wanted; } else if (je.EventTypeID == JournalTypeEnum.Docked) { JournalDocked jl = je as JournalDocked; he.docked = true; he.whereami = jl.StationName; he.stationName = jl.StationName; he.marketId = jl.MarketID; } else if (je.EventTypeID == JournalTypeEnum.Undocked) { he.docked = false; he.stationName = null; he.marketId = null; } else if (je.EventTypeID == JournalTypeEnum.Touchdown) { he.landed = true; } else if (je.EventTypeID == JournalTypeEnum.Liftoff) { he.landed = !(je as JournalLiftoff).PlayerControlled; } else if (je.EventTypeID == JournalTypeEnum.SupercruiseEntry) { he.whereami = (je as JournalSupercruiseEntry).StarSystem; he.hyperspace = true; } else if (je.EventTypeID == JournalTypeEnum.SupercruiseExit) { he.whereami = (je as JournalSupercruiseExit).Body; he.hyperspace = false; } else if (je.EventTypeID == JournalTypeEnum.FSDJump) { JournalFSDJump ju = (je as JournalFSDJump); he.whereami = ju.StarSystem; he.hyperspace = true; he.wanted = ju.Wanted; } else if (je.EventTypeID == JournalTypeEnum.StartJump) { he.hyperspace = true; // some of these are just to make sure, as FSDJump will also set it } else if (je.EventTypeID == JournalTypeEnum.LoadGame) { JournalLoadGame jl = je as JournalLoadGame; he.onCrewWithCaptain = null; // can't be in a crew at this point he.gamemode = jl.GameMode; // set game mode he.group = jl.Group; // and group, may be empty he.landed = jl.StartLanded; he.hyperspace = false; if (jl.Ship.IndexOf("buggy", StringComparison.InvariantCultureIgnoreCase) == -1) // load game with buggy, can't tell what ship we get back into, so ignore { he.shiptype = (je as JournalLoadGame).Ship; he.shipid = (je as JournalLoadGame).ShipId; } } else if (je.EventTypeID == JournalTypeEnum.ShipyardBuy) // BUY does not have ship id, but the new entry will that is written later - journals 8.34 { he.shiptype = (je as JournalShipyardBuy).ShipType; } else if (je.EventTypeID == JournalTypeEnum.ShipyardNew) { he.shiptype = (je as JournalShipyardNew).ShipType; he.shipid = (je as JournalShipyardNew).ShipId; } else if (je.EventTypeID == JournalTypeEnum.ShipyardSwap) { he.shiptype = (je as JournalShipyardSwap).ShipType; he.shipid = (je as JournalShipyardSwap).ShipId; } else if (je.EventTypeID == JournalTypeEnum.JoinACrew) { he.onCrewWithCaptain = (je as JournalJoinACrew).Captain; } else if (je.EventTypeID == JournalTypeEnum.QuitACrew) { he.onCrewWithCaptain = null; } if (prev != null && prev.travelling) // if we are travelling.. { he.travelled_distance = prev.travelled_distance; he.travelled_missingjump = prev.travelled_missingjump; he.travelled_jumps = prev.travelled_jumps; if (he.IsFSDJump && !he.MultiPlayer) // if jump, and not multiplayer.. { double dist = ((JournalFSDJump)je).JumpDist; if (dist <= 0) { he.travelled_missingjump++; } else { he.travelled_distance += dist; he.travelled_jumps++; } } he.travelled_seconds = prev.travelled_seconds; TimeSpan diff = he.EventTimeUTC.Subtract(prev.EventTimeUTC); if (he.EntryType != JournalTypeEnum.LoadGame && diff < new TimeSpan(2, 0, 0)) // time between last entry and load game is not real time { he.travelled_seconds += diff; } if (he.StopMarker || he.StartMarker) { //Debug.WriteLine("Travelling stop at " + he.Indexno); he.travelling = false; he.EventDetailedInfo += ((he.EventDetailedInfo.Length > 0) ? Environment.NewLine : "") + "Travelled " + he.travelled_distance.ToStringInvariant("0.0") + " LY" + ", " + he.travelled_jumps + " jumps" + ((he.travelled_missingjump > 0) ? ", " + he.travelled_missingjump + " unknown distance jumps" : "") + ", time " + he.travelled_seconds; he.travelled_distance = 0; he.travelled_seconds = new TimeSpan(0); } else { he.travelling = true; if (he.IsFSDJump) { he.EventDetailedInfo += ((he.EventDetailedInfo.Length > 0) ? Environment.NewLine : "") + "Travelling" + " distance " + he.travelled_distance.ToString("0.0") + " LY" + ", " + he.travelled_jumps + " jumps" + ((he.travelled_missingjump > 0) ? ", " + he.travelled_missingjump + " unknown distance jumps" : "") + ", time " + he.travelled_seconds; } } } if (he.StartMarker) { //Debug.WriteLine("Travelling start at " + he.Indexno); he.travelling = true; } return(he); }
public static HistoryEntryStatus Update(HistoryEntryStatus prev, JournalEntry je, string curStarSystem) { if (prev == null) { prev = new HistoryEntryStatus(); } switch (je.EventTypeID) { case JournalTypeEnum.Location: JournalLocation jloc = je as JournalLocation; TravelStateType t = jloc.Docked ? TravelStateType.Docked : (jloc.Latitude.HasValue ? TravelStateType.Landed : TravelStateType.NormalSpace); return(new HistoryEntryStatus(prev) // Bodyapproach copy over we should be in the same state as last.. { TravelState = t, MarketId = jloc.MarketID, BodyID = jloc.BodyID, BodyType = jloc.BodyType, BodyName = jloc.Body, Wanted = jloc.Wanted, StationName = jloc.StationName.Alt(null), // if empty string, set to null StationType = jloc.StationType.Alt(null), }); case JournalTypeEnum.FSDJump: JournalFSDJump jfsd = (je as JournalFSDJump); return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.Hyperspace, MarketId = null, BodyID = -1, BodyType = "Star", BodyName = jfsd.StarSystem, Wanted = jfsd.Wanted, StationName = null, StationType = null, BodyApproached = false, }); case JournalTypeEnum.LoadGame: JournalLoadGame jlg = je as JournalLoadGame; bool isbuggy = ShipModuleData.IsSRV(jlg.ShipFD); string shiptype = isbuggy ? prev.ShipType : jlg.Ship; string shiptypefd = isbuggy ? prev.ShipTypeFD : jlg.ShipFD; int shipid = isbuggy ? prev.ShipID : jlg.ShipId; return(new HistoryEntryStatus(prev) // Bodyapproach copy over we should be in the same state as last.. { OnCrewWithCaptain = null, // can't be in a crew at this point GameMode = jlg.GameMode, // set game mode Group = jlg.Group, // and group, may be empty TravelState = (jlg.StartLanded || isbuggy) ? TravelStateType.Landed : prev.TravelState, ShipType = shiptype, ShipID = shipid, ShipTypeFD = shiptypefd, }); case JournalTypeEnum.Docked: JournalDocked jdocked = (JournalDocked)je; return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.Docked, MarketId = jdocked.MarketID, Wanted = jdocked.Wanted, StationName = jdocked.StationName, StationType = jdocked.StationType, }); case JournalTypeEnum.Undocked: return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.NormalSpace, MarketId = null, StationName = null, StationType = null, }); case JournalTypeEnum.Touchdown: if (((JournalTouchdown)je).PlayerControlled == true) // can get this when not player controlled { return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.Landed, }); } else { return(prev); } case JournalTypeEnum.Liftoff: if (((JournalLiftoff)je).PlayerControlled == true) // can get this when not player controlled { return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.NormalSpace, }); } else { return(prev); } case JournalTypeEnum.SupercruiseExit: JournalSupercruiseExit jsexit = (JournalSupercruiseExit)je; return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.NormalSpace, BodyName = (prev.BodyApproached) ? prev.BodyName : jsexit.Body, BodyType = (prev.BodyApproached) ? prev.BodyType : jsexit.BodyType, BodyID = (prev.BodyApproached) ? prev.BodyID : jsexit.BodyID, }); case JournalTypeEnum.SupercruiseEntry: return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.Hyperspace, BodyName = !prev.BodyApproached ? curStarSystem : prev.BodyName, BodyType = !prev.BodyApproached ? "Star" : prev.BodyType, BodyID = !prev.BodyApproached ? -1 : prev.BodyID, }); case JournalTypeEnum.ApproachBody: JournalApproachBody jappbody = (JournalApproachBody)je; return(new HistoryEntryStatus(prev) { BodyApproached = true, BodyType = jappbody.BodyType, BodyName = jappbody.Body, BodyID = jappbody.BodyID, }); case JournalTypeEnum.LeaveBody: JournalLeaveBody jlbody = (JournalLeaveBody)je; return(new HistoryEntryStatus(prev) { BodyApproached = false, BodyType = "Star", BodyName = curStarSystem, BodyID = -1, }); case JournalTypeEnum.StartJump: if (prev.TravelState != TravelStateType.Hyperspace) // checking we are into hyperspace, we could already be if in a series of jumps { return(new HistoryEntryStatus(prev) { TravelState = TravelStateType.Hyperspace, }); } else { return(prev); } case JournalTypeEnum.ShipyardBuy: return(new HistoryEntryStatus(prev) { ShipID = -1, ShipType = ((JournalShipyardBuy)je).ShipType // BUY does not have ship id, but the new entry will that is written later - journals 8.34 }); case JournalTypeEnum.ShipyardNew: JournalShipyardNew jsnew = (JournalShipyardNew)je; return(new HistoryEntryStatus(prev) { ShipID = jsnew.ShipId, ShipType = jsnew.ShipType, ShipTypeFD = jsnew.ShipFD, }); case JournalTypeEnum.ShipyardSwap: JournalShipyardSwap jsswap = (JournalShipyardSwap)je; return(new HistoryEntryStatus(prev) { ShipID = jsswap.ShipId, ShipType = jsswap.ShipType, ShipTypeFD = jsswap.ShipFD, }); case JournalTypeEnum.JoinACrew: return(new HistoryEntryStatus(prev) { OnCrewWithCaptain = ((JournalJoinACrew)je).Captain }); case JournalTypeEnum.QuitACrew: return(new HistoryEntryStatus(prev) { OnCrewWithCaptain = null }); case JournalTypeEnum.Died: return(new HistoryEntryStatus(prev) { BodyName = "Unknown", BodyID = -1, BodyType = "Unknown", StationName = "Unknown", StationType = "Unknown", MarketId = null, TravelState = TravelStateType.Docked, OnCrewWithCaptain = null, BodyApproached = false, // we have to clear this, we can't tell if we are going back to another place.. }); case JournalTypeEnum.Loadout: var jloadout = (JournalLoadout)je; if (!ShipModuleData.IsSRV(jloadout.ShipFD)) // just double checking! { return(new HistoryEntryStatus(prev) { ShipID = jloadout.ShipId, ShipType = jloadout.Ship, ShipTypeFD = jloadout.ShipFD, }); } else { return(prev); } default: return(prev); } }
public static HistoryEntry FromJournalEntry(JournalEntry je, HistoryEntry prev, bool checkedsm, out bool journalupdate, SQLiteConnectionSystem conn = null, EDCommander cmdr = null) { ISystem isys = prev == null ? new SystemClass("Unknown") : prev.System; int indexno = prev == null ? 1 : prev.Indexno + 1; int mapcolour = 0; journalupdate = false; bool starposfromedsm = false; bool firstdiscover = false; if (je.EventTypeID == JournalTypeEnum.Location || je.EventTypeID == JournalTypeEnum.FSDJump || (je.EventTypeID == JournalTypeEnum.StartJump && (je as JournalStartJump)?.JumpType == "Hyperspace")) { JournalLocOrJump jl = je as JournalLocOrJump; JournalFSDJump jfsd = je as JournalFSDJump; JournalStartJump js = je as JournalStartJump; ISystem newsys; if (jl != null && jl.HasCoordinate) // LAZY LOAD IF it has a co-ord.. the front end will when it needs it { newsys = new SystemClass(jl.StarSystem, jl.StarPos.X, jl.StarPos.Y, jl.StarPos.Z) { id_edsm = jl.EdsmID < 0 ? 0 : jl.EdsmID, // pass across the EDSMID for the lazy load process. faction = jl.Faction, government = jl.EDGovernment, primary_economy = jl.EDEconomy, security = jl.EDSecurity, population = jl.Population ?? 0, state = jl.EDState, allegiance = jl.EDAllegiance, UpdateDate = jl.EventTimeUTC, status = SystemStatusEnum.EDDiscovery, }; if (jfsd != null && jfsd.JumpDist <= 0 && isys.HasCoordinate) // if we don't have a jump distance (pre 2.2) but the last sys does have pos, we can compute distance and update entry { jfsd.JumpDist = SystemClassDB.Distance(isys, newsys); // fill it out here journalupdate = true; } // If it was a new system, pass the coords back to the StartJump if (prev != null && prev.System.name == newsys.name && !prev.System.HasCoordinate) { prev.System.x = newsys.x; prev.System.y = newsys.y; prev.System.z = newsys.z; } } else { // Default one string sysname = jl?.StarSystem ?? js?.StarSystem; newsys = new SystemClass(sysname); newsys.id_edsm = je.EdsmID; if (checkedsm) // see if we can find the right system { ISystem s = SystemCache.FindEDSM(newsys, conn: conn, usedb: true, useedsm: true); // has no co-ord, did we find it? if (s != null) // yes, use, and update the journal with the esdmid, and also the position if we have a co-ord { // so next time we don't have to do this again.. if (jl != null && jl.HasCoordinate) { s.x = Math.Round(jl.StarPos.X * 32.0) / 32.0; s.y = Math.Round(jl.StarPos.Y * 32.0) / 32.0; s.z = Math.Round(jl.StarPos.Z * 32.0) / 32.0; } newsys = s; if (jfsd != null && jfsd.JumpDist <= 0 && newsys.HasCoordinate && isys.HasCoordinate) // if we don't have a jump distance (pre 2.2) but the last sys does, we can compute { jfsd.JumpDist = SystemClassDB.Distance(isys, newsys); // fill it out here. EDSM systems always have co-ords, but we should check anyway journalupdate = true; } if (je.EdsmID <= 0 && newsys.id_edsm > 0) { journalupdate = true; } } } } if (jfsd != null) { if (jfsd.JumpDist <= 0 && isys.HasCoordinate && newsys.HasCoordinate) // if no JDist, its a really old entry, and if previous has a co-ord { jfsd.JumpDist = SystemClassDB.Distance(isys, newsys); // fill it out here journalupdate = true; } mapcolour = jfsd.MapColor; } isys = newsys; starposfromedsm = (jl != null && jl.HasCoordinate) ? jl.StarPosFromEDSM : newsys.HasCoordinate; firstdiscover = jl == null ? false : jl.EDSMFirstDiscover; } string summary, info, detailed; je.FillInformation(out summary, out info, out detailed); HistoryEntry he = new HistoryEntry { Indexno = indexno, EntryType = je.EventTypeID, Journalid = je.Id, journalEntry = je, System = isys, EventTimeUTC = je.EventTimeUTC, MapColour = mapcolour, EdsmSync = je.SyncedEDSM, EDDNSync = je.SyncedEDDN, EGOSync = je.SyncedEGO, StartMarker = je.StartMarker, StopMarker = je.StopMarker, EventSummary = summary, EventDescription = info, EventDetailedInfo = detailed, IsStarPosFromEDSM = starposfromedsm, IsEDSMFirstDiscover = firstdiscover, Commander = cmdr ?? EDCommander.GetCommander(je.CommanderId) }; // WORK out docked/landed state if (prev != null) { if (prev.docked.HasValue) // copy docked.. { he.docked = prev.docked; } if (prev.landed.HasValue) { he.landed = prev.landed; } if (prev.hyperspace.HasValue) { he.hyperspace = prev.hyperspace; } he.shiptype = prev.shiptype; he.shipid = prev.shipid; he.whereami = prev.whereami; he.onCrewWithCaptain = prev.onCrewWithCaptain; he.gamemode = prev.gamemode; he.group = prev.group; } if (je.EventTypeID == JournalTypeEnum.Location) { JournalLocation jl = je as JournalLocation; he.docked = jl.Docked; he.whereami = jl.Docked ? jl.StationName : jl.Body; he.hyperspace = false; } else if (je.EventTypeID == JournalTypeEnum.Docked) { JournalDocked jl = je as JournalDocked; he.docked = true; he.whereami = jl.StationName; } else if (je.EventTypeID == JournalTypeEnum.Undocked) { he.docked = false; } else if (je.EventTypeID == JournalTypeEnum.Touchdown) { he.landed = true; } else if (je.EventTypeID == JournalTypeEnum.Liftoff) { he.landed = false; } else if (je.EventTypeID == JournalTypeEnum.SupercruiseEntry) { he.whereami = (je as JournalSupercruiseEntry).StarSystem; he.hyperspace = true; } else if (je.EventTypeID == JournalTypeEnum.SupercruiseExit) { he.whereami = (je as JournalSupercruiseExit).Body; he.hyperspace = false; } else if (je.EventTypeID == JournalTypeEnum.FSDJump) { he.whereami = (je as JournalFSDJump).StarSystem; he.hyperspace = true; } else if (je.EventTypeID == JournalTypeEnum.StartJump) { he.hyperspace = true; // some of these are just to make sure, as FSDJump will also set it } else if (je.EventTypeID == JournalTypeEnum.LoadGame) { JournalLoadGame jl = je as JournalLoadGame; he.onCrewWithCaptain = null; // can't be in a crew at this point he.gamemode = jl.GameMode; // set game mode he.group = jl.Group; // and group, may be empty he.landed = jl.StartLanded; he.hyperspace = false; if (jl.Ship.IndexOf("buggy", StringComparison.InvariantCultureIgnoreCase) == -1) // load game with buggy, can't tell what ship we get back into, so ignore { he.shiptype = (je as JournalLoadGame).Ship; he.shipid = (je as JournalLoadGame).ShipId; } } else if (je.EventTypeID == JournalTypeEnum.ShipyardBuy) // BUY does not have ship id, but the new entry will that is written later - journals 8.34 { he.shiptype = (je as JournalShipyardBuy).ShipType; } else if (je.EventTypeID == JournalTypeEnum.ShipyardNew) { he.shiptype = (je as JournalShipyardNew).ShipType; he.shipid = (je as JournalShipyardNew).ShipId; } else if (je.EventTypeID == JournalTypeEnum.ShipyardSwap) { he.shiptype = (je as JournalShipyardSwap).ShipType; he.shipid = (je as JournalShipyardSwap).ShipId; } else if (je.EventTypeID == JournalTypeEnum.JoinACrew) { he.onCrewWithCaptain = (je as JournalJoinACrew).Captain; } else if (je.EventTypeID == JournalTypeEnum.QuitACrew) { he.onCrewWithCaptain = null; } if (prev != null && prev.travelling) // if we are travelling.. { he.travelled_distance = prev.travelled_distance; he.travelled_missingjump = prev.travelled_missingjump; he.travelled_jumps = prev.travelled_jumps; if (he.IsFSDJump && !he.MultiPlayer) // if jump, and not multiplayer.. { double dist = ((JournalFSDJump)je).JumpDist; if (dist <= 0) { he.travelled_missingjump++; } else { he.travelled_distance += dist; he.travelled_jumps++; } } he.travelled_seconds = prev.travelled_seconds; TimeSpan diff = he.EventTimeUTC.Subtract(prev.EventTimeUTC); if (he.EntryType != JournalTypeEnum.LoadGame && diff < new TimeSpan(2, 0, 0)) // time between last entry and load game is not real time { he.travelled_seconds += diff; } if (he.StopMarker || he.StartMarker) { //Debug.WriteLine("Travelling stop at " + he.Indexno); he.travelling = false; he.EventDetailedInfo += ((he.EventDetailedInfo.Length > 0) ? Environment.NewLine : "") + "Travelled " + he.travelled_distance.ToStringInvariant("0.0") + " LY" + ", " + he.travelled_jumps + " jumps" + ((he.travelled_missingjump > 0) ? ", " + he.travelled_missingjump + " unknown distance jumps" : "") + ", time " + he.travelled_seconds; he.travelled_distance = 0; he.travelled_seconds = new TimeSpan(0); } else { he.travelling = true; if (he.IsFSDJump) { he.EventDetailedInfo += ((he.EventDetailedInfo.Length > 0) ? Environment.NewLine : "") + "Travelling" + " distance " + he.travelled_distance.ToString("0.0") + " LY" + ", " + he.travelled_jumps + " jumps" + ((he.travelled_missingjump > 0) ? ", " + he.travelled_missingjump + " unknown distance jumps" : "") + ", time " + he.travelled_seconds; } } } if (he.StartMarker) { //Debug.WriteLine("Travelling start at " + he.Indexno); he.travelling = true; } return(he); }
static public void ParseFiles(string datapath, out string error, int defaultMapColour, Func <bool> cancelRequested, Action <int, string> updateProgress, bool forceReload, int currentcmdrid) { error = null; if (datapath == null) { error = "Netlog directory not set!"; return; } if (!Directory.Exists(datapath)) // if logfiles directory is not found { error = "Netlog directory is not present!"; return; } // list of systems in journal, sorted by time List <JournalLocOrJump> vsSystemsEnts = JournalEntry.GetAll(currentcmdrid).OfType <JournalLocOrJump>().OrderBy(j => j.EventTimeUTC).ToList(); // order by file write time so we end up on the last one written FileInfo[] allFiles = Directory.EnumerateFiles(datapath, "netLog.*.log", SearchOption.AllDirectories).Select(f => new FileInfo(f)).OrderBy(p => p.LastWriteTime).ToArray(); List <NetLogFileReader> readersToUpdate = new List <NetLogFileReader>(); List <TravelLogUnit> tlutoadd = new List <TravelLogUnit>(); for (int i = 0; i < allFiles.Length; i++) { FileInfo fi = allFiles[i]; var reader = OpenFileReader(fi.FullName, currentcmdrid); if (reader.ID == 0) // if not present, add to commit add list { tlutoadd.Add(reader.TravelLogUnit); } if (forceReload) // Force a reload of the travel log { reader.Pos = 0; } if (reader.Pos != fi.Length || i == allFiles.Length - 1) // File not already in DB, or is the last one { readersToUpdate.Add(reader); } } if (tlutoadd.Count > 0) // now, on spinning rust, this takes ages for 600+ log files first time, so transaction it { UserDatabase.Instance.ExecuteWithDatabase(cn => { using (DbTransaction txn = cn.Connection.BeginTransaction()) { foreach (var tlu in tlutoadd) { tlu.Add(cn.Connection, txn); } txn.Commit(); } }); } for (int i = 0; i < readersToUpdate.Count; i++) { UserDatabase.Instance.ExecuteWithDatabase(cn => { int ji = 0; NetLogFileReader reader = readersToUpdate[i]; updateProgress(i * 100 / readersToUpdate.Count, reader.TravelLogUnit.FullName); var systems = JournalEntry.GetAllByTLU(reader.ID, cn.Connection).OfType <JournalLocOrJump>().ToList(); var last = systems.LastOrDefault(); // find last system recorded for this TLU, may be null if no systems.. using (DbTransaction tn = cn.Connection.BeginTransaction()) { var ienum = reader.ReadSystems(last, cancelRequested, currentcmdrid); System.Diagnostics.Debug.WriteLine("Scanning TLU " + reader.ID + " " + reader.FullName); foreach (JObject jo in ienum) { jo["EDDMapColor"] = defaultMapColour; JournalLocOrJump je = new JournalFSDJump(jo); je.SetTLUCommander(reader.TravelLogUnit.ID, currentcmdrid); while (ji < vsSystemsEnts.Count && vsSystemsEnts[ji].EventTimeUTC < je.EventTimeUTC) { ji++; // move to next entry which is bigger in time or equal to ours. } JournalLocOrJump prev = (ji > 0 && (ji - 1) < vsSystemsEnts.Count) ? vsSystemsEnts[ji - 1] : null; JournalLocOrJump next = ji < vsSystemsEnts.Count ? vsSystemsEnts[ji] : null; bool previssame = (prev != null && prev.StarSystem.Equals(je.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!prev.HasCoordinate || !je.HasCoordinate || (prev.StarPos - je.StarPos).LengthSquared < 0.01)); bool nextissame = (next != null && next.StarSystem.Equals(je.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!next.HasCoordinate || !je.HasCoordinate || (next.StarPos - je.StarPos).LengthSquared < 0.01)); // System.Diagnostics.Debug.WriteLine("{0} {1} {2}", ji, vsSystemsEnts[ji].EventTimeUTC, je.EventTimeUTC); if (!(previssame || nextissame)) { je.Add(jo, cn.Connection, tn); System.Diagnostics.Debug.WriteLine("Add {0} {1}", je.EventTimeUTC, jo.ToString()); } } reader.TravelLogUnit.Update(cn.Connection, tn); tn.Commit(); } if (updateProgress != null) { updateProgress((i + 1) * 100 / readersToUpdate.Count, reader.TravelLogUnit.FullName); } }); } }
static public void ParseFiles(string datapath, out string error, int defaultMapColour, Func <bool> cancelRequested, Action <int, string> updateProgress, bool forceReload = false, Dictionary <string, NetLogFileReader> netlogreaders = null, int currentcmdrid = -1) { error = null; if (datapath == null) { error = "Netlog directory not set!"; return; } if (!Directory.Exists(datapath)) // if logfiles directory is not found { error = "Netlog directory is not present!"; return; } if (netlogreaders == null) { netlogreaders = new Dictionary <string, NetLogFileReader>(); } if (currentcmdrid < 0) { currentcmdrid = EDDConfig.Instance.CurrentCmdrID; } // TLUs List <TravelLogUnit> tlus = TravelLogUnit.GetAll(); Dictionary <string, TravelLogUnit> netlogtravelogUnits = tlus.Where(t => t.type == 1).GroupBy(t => t.Name).Select(g => g.First()).ToDictionary(t => t.Name); Dictionary <long, string> travellogunitid2name = netlogtravelogUnits.Values.ToDictionary(t => t.id, t => t.Name); Dictionary <string, List <JournalLocOrJump> > vsc_lookup = JournalEntry.GetAll().OfType <JournalLocOrJump>().GroupBy(v => v.TLUId).Where(g => travellogunitid2name.ContainsKey(g.Key)).ToDictionary(g => travellogunitid2name[g.Key], g => g.ToList()); // list of systems in journal, sorted by time List <JournalLocOrJump> vsSystemsEnts = JournalEntry.GetAll(currentcmdrid).OfType <JournalLocOrJump>().OrderBy(j => j.EventTimeUTC).ToList(); // order by file write time so we end up on the last one written FileInfo[] allFiles = Directory.EnumerateFiles(datapath, "netLog.*.log", SearchOption.AllDirectories).Select(f => new FileInfo(f)).OrderBy(p => p.LastWriteTime).ToArray(); List <NetLogFileReader> readersToUpdate = new List <NetLogFileReader>(); for (int i = 0; i < allFiles.Length; i++) { FileInfo fi = allFiles[i]; var reader = OpenFileReader(fi, netlogtravelogUnits, vsc_lookup, netlogreaders); if (!netlogtravelogUnits.ContainsKey(reader.TravelLogUnit.Name)) { netlogtravelogUnits[reader.TravelLogUnit.Name] = reader.TravelLogUnit; reader.TravelLogUnit.Add(); } if (!netlogreaders.ContainsKey(reader.TravelLogUnit.Name)) { netlogreaders[reader.TravelLogUnit.Name] = reader; } if (forceReload) { // Force a reload of the travel log reader.TravelLogUnit.Size = 0; } if (reader.filePos != fi.Length || i == allFiles.Length - 1) // File not already in DB, or is the last one { readersToUpdate.Add(reader); } } for (int i = 0; i < readersToUpdate.Count; i++) { using (SQLiteConnectionUser cn = new SQLiteConnectionUser(utc: true)) { int ji = 0; NetLogFileReader reader = readersToUpdate[i]; updateProgress(i * 100 / readersToUpdate.Count, reader.TravelLogUnit.Name); using (DbTransaction tn = cn.BeginTransaction()) { foreach (JObject jo in reader.ReadSystems(cancelRequested, currentcmdrid)) { jo["EDDMapColor"] = defaultMapColour; JournalLocOrJump je = new JournalFSDJump(jo) { TLUId = (int)reader.TravelLogUnit.id, CommanderId = currentcmdrid, }; while (ji < vsSystemsEnts.Count && vsSystemsEnts[ji].EventTimeUTC < je.EventTimeUTC) { ji++; // move to next entry which is bigger in time or equal to ours. } JournalLocOrJump prev = (ji > 0 && (ji - 1) < vsSystemsEnts.Count) ? vsSystemsEnts[ji - 1] : null; JournalLocOrJump next = ji < vsSystemsEnts.Count ? vsSystemsEnts[ji] : null; bool previssame = (prev != null && prev.StarSystem.Equals(je.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!prev.HasCoordinate || !je.HasCoordinate || (prev.StarPos - je.StarPos).LengthSquared < 0.01)); bool nextissame = (next != null && next.StarSystem.Equals(je.StarSystem, StringComparison.CurrentCultureIgnoreCase) && (!next.HasCoordinate || !je.HasCoordinate || (next.StarPos - je.StarPos).LengthSquared < 0.01)); // System.Diagnostics.Debug.WriteLine("{0} {1} {2}", ji, vsSystemsEnts[ji].EventTimeUTC, je.EventTimeUTC); if (!(previssame || nextissame)) { je.Add(cn, tn); System.Diagnostics.Debug.WriteLine("Add {0} {1}", je.EventTimeUTC, je.EventDataString); } } tn.Commit(); reader.TravelLogUnit.Update(); } if (updateProgress != null) { updateProgress((i + 1) * 100 / readersToUpdate.Count, reader.TravelLogUnit.Name); } } } }
public static HistoryEntry FromJournalEntry(JournalEntry je, HistoryEntry prev, out bool journalupdate, SQLiteConnectionSystem conn = null) { ISystem isys = prev == null ? new SystemClass("Unknown") : prev.System; int indexno = prev == null ? 1 : prev.Indexno + 1; journalupdate = false; if (je.EventTypeID == JournalTypeEnum.Location || je.EventTypeID == JournalTypeEnum.FSDJump) { JournalLocOrJump jl = je as JournalLocOrJump; ISystem newsys; if (jl != null && jl.HasCoordinate) // LAZY LOAD IF it has a co-ord.. the front end will when it needs it { newsys = new SystemClass(jl.StarSystem, jl.StarPos.X, jl.StarPos.Y, jl.StarPos.Z) { EDSMID = jl.EdsmID < 0 ? 0 : jl.EdsmID, // pass across the EDSMID for the lazy load process. SystemAddress = jl.SystemAddress, Population = jl.Population ?? 0, Faction = jl.Faction, Government = jl.EDGovernment, Allegiance = jl.EDAllegiance, State = jl.EDState, Security = jl.EDSecurity, PrimaryEconomy = jl.EDEconomy, Power = jl.PowerList, PowerState = jl.PowerplayState, status = SystemStatusEnum.EDDiscovery, }; // If it was a new system, pass the coords back to the StartJump if (prev != null && prev.journalEntry is JournalStartJump) { prev.System = newsys; // give the previous startjump our system.. } } else { // NOTE Rob: 09-JAN-2018 I've removed the Jumpstart looking up a system by name since they were using up lots of lookup time during history reading. // This is used for pre 2.2 systems without co-ords, which now should be limited. // JumpStart still gets the system when the FSD loc is processed, see above. // Jumpstart was also screwing about with the EDSM ID fill in which was broken. This is now working again. // Default one newsys = new SystemClass(jl.StarSystem); newsys.EDSMID = je.EdsmID; ISystem s = SystemCache.FindSystem(newsys, conn); // has no co-ord, did we find it? if (s != null) // found a system.. { if (jl != null && jl.HasCoordinate) // if journal Loc, and journal has a star position, use that instead of EDSM.. { s.X = Math.Round(jl.StarPos.X * 32.0) / 32.0; s.Y = Math.Round(jl.StarPos.Y * 32.0) / 32.0; s.Z = Math.Round(jl.StarPos.Z * 32.0) / 32.0; } //Debug.WriteLine("HistoryList found system {0} {1}", s.id_edsm, s.name); newsys = s; if (jl != null && je.EdsmID <= 0 && newsys.EDSMID > 0) // only update on a JL.. { journalupdate = true; Debug.WriteLine("HE EDSM ID update requested {0} {1}", newsys.EDSMID, newsys.Name); } } else { newsys.EDSMID = -1; // mark as checked but not found } } JournalFSDJump jfsd = je as JournalFSDJump; if (jfsd != null) { if (jfsd.JumpDist <= 0 && isys.HasCoordinate && newsys.HasCoordinate) // if no JDist, its a really old entry, and if previous has a co-ord { jfsd.JumpDist = isys.Distance(newsys); // fill it out here if (jfsd.JumpDist > 0) { journalupdate = true; Debug.WriteLine("Je Jump distance update(3) requested {0} {1} {2}", newsys.EDSMID, newsys.Name, jfsd.JumpDist); } } } isys = newsys; } HistoryEntry he = new HistoryEntry { Indexno = indexno, journalEntry = je, System = isys, EntryStatus = HistoryEntryStatus.Update(prev?.EntryStatus, je, isys.Name) }; he.TravelStatus = HistoryTravelStatus.Update(prev?.TravelStatus, prev, he); // need a real he so can't do that as part of the constructor. return(he); }
protected bool ParseVisitedSystem(DateTime time, TimeSpan tzoffset, string line, out JObject jo, out JournalLocOrJump je) { jo = new JObject(); jo["timestamp"] = time.ToString("yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"); jo["event"] = "FSDJump"; je = null; try { Regex pattern; /* MKW: Use regular expressions to parse the log; much more readable and robust. * Example log entry: * * From ED 2.1 /1.6 * {19:21:15} System:"Ooscs Fraae JR-L d8-112" StarPos:(-11609.469,639.594,20141.875)ly NormalFlight * string rgexpstr = "{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; * * new from beta3? * {18:15:14} System:"Pleiades Sector HR-W d1-41" StarPos:(-83.969,-146.156,-334.219)ly Body:0 RelPos:(-1.19887e+07,-9.95573e+06,2.55124e+06)km Supercruise * string rgexpstr = "{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly Body:(?<Body>\d+) StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; * * From ED 2.3 * {12:55:06GMT 96.066s} System:"Stuemeae KM-W c1-342" StarPos:(26.344,-20.563,25899.250)ly Body:9 RelPos:(244.784,1133.47,732.025)km NormalFlight * string rgexpstr = "{{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)GMT \\d+\\.\\d+s} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly Body:(?<Body>\d+) StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; * * Pre ED 2.1/1.6 * {09:36:16} System:0(Thuechea JE-O b11-0) Body:1 Pos:(-6.67432e+009,7.3151e+009,-1.19125e+010) Supercruise * * Also, please note that due to E:D bugs, these entries can be at the end of a line as well, not just on a line of their own. * The RegExp below actually just finds the pattern somewhere in the line, so it caters for rubbish at the end too. */ if (line.Contains("StarPos:")) // new ED 2.1 format { //{(?<Hour>\d+):(?<Minute>\d+):(?<Second>\d+)} System:"(?<SystemName>[^"]+)" StarPos:\((?<Pos>.*?)\)ly( +(?<TravelMode>\w+))? //{(?<Hour>\d+):(?<Minute>\d+):(?<Second>\d+)} System:"(?<SystemName>[^"]+)" StarPos:\((?<Pos>.*?)\)ly( +(?<TravelMode>\w+))? //string rgexpstr = "{(?<Hour>\\d+):(?<Minute>\\d+):(?<Second>\\d+)} System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; string rgexpstr; if (line.Contains("Body:")) { rgexpstr = "System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly Body:(?<Body>\\d+) RelPos:\\((?<RelPos>.*?)\\)km( +(?<TravelMode>\\w+))?"; } else { rgexpstr = "System:\"(?<SystemName>[^\"]+)\" StarPos:\\((?<Pos>.*?)\\)ly( +(?<TravelMode>\\w+))?"; } pattern = new Regex(rgexpstr); Match match = pattern.Match(line); if (match != null && match.Success) { //sp.Nr = int.Parse(match.Groups["Body"].Value); jo["StarSystem"] = match.Groups["SystemName"].Value; string pos = match.Groups["Pos"].Value; try { string[] xyzpos = pos.Split(','); jo["StarPos"] = new JArray( double.Parse(xyzpos[0], CultureInfo.InvariantCulture), double.Parse(xyzpos[1], CultureInfo.InvariantCulture), double.Parse(xyzpos[2], CultureInfo.InvariantCulture) ); } catch { System.Diagnostics.Trace.WriteLine("System parse error 1:" + line); return(false); } } else { System.Diagnostics.Trace.WriteLine("System parse error 1:" + line); return(false); } } else { pattern = new Regex(@"System:\d+\((?<SystemName>.*?)\) Body:(?<Body>\d+) Pos:\(.*?\)( (?<TravelMode>\w+))?"); Match match = pattern.Match(line); if (match != null && match.Success) { //sp.Nr = int.Parse(match.Groups["Body"].Value); jo["StarSystem"] = match.Groups["SystemName"].Value; } else { System.Diagnostics.Trace.WriteLine("System parse error 2:" + line); return(false); } } je = new JournalFSDJump(jo); return(true); } catch { // MKW TODO: should we log bad lines? return(false); } }
public static HistoryList LoadHistory(EDJournalClass journalmonitor, Func <bool> cancelRequested, Action <int, string> reportProgress, string NetLogPath = null, bool ForceNetLogReload = false, bool ForceJournalReload = false, bool CheckEdsm = false, int CurrentCommander = Int32.MinValue) { HistoryList hist = new HistoryList(); EDCommander cmdr = null; if (CurrentCommander >= 0) { cmdr = EDCommander.GetCommander(CurrentCommander); journalmonitor.ParseJournalFiles(() => cancelRequested(), (p, s) => reportProgress(p, s), forceReload: ForceJournalReload); // Parse files stop monitor.. if (NetLogPath != null) { string errstr = null; NetLogClass.ParseFiles(NetLogPath, out errstr, EliteConfigInstance.InstanceConfig.DefaultMapColour, () => cancelRequested(), (p, s) => reportProgress(p, s), ForceNetLogReload, currentcmdrid: CurrentCommander); } } reportProgress(-1, "Resolving systems"); List <JournalEntry> jlist = JournalEntry.GetAll(CurrentCommander).OrderBy(x => x.EventTimeUTC).ThenBy(x => x.Id).ToList(); List <Tuple <JournalEntry, HistoryEntry> > jlistUpdated = new List <Tuple <JournalEntry, HistoryEntry> >(); using (SQLiteConnectionSystem conn = new SQLiteConnectionSystem()) { HistoryEntry prev = null; foreach (JournalEntry inje in jlist) { foreach (JournalEntry je in hist.ProcessJournalEntry(inje)) { bool journalupdate = false; HistoryEntry he = HistoryEntry.FromJournalEntry(je, prev, CheckEdsm, out journalupdate, conn, cmdr); prev = he; hist.historylist.Add(he); if (journalupdate) { jlistUpdated.Add(new Tuple <JournalEntry, HistoryEntry>(je, he)); } } } } if (jlistUpdated.Count > 0) { reportProgress(-1, "Updating journal entries"); using (SQLiteConnectionUser conn = new SQLiteConnectionUser(utc: true)) { using (DbTransaction txn = conn.BeginTransaction()) { foreach (Tuple <JournalEntry, HistoryEntry> jehe in jlistUpdated) { JournalEntry je = jehe.Item1; HistoryEntry he = jehe.Item2; JournalFSDJump jfsd = je as JournalFSDJump; if (jfsd != null) { JournalEntry.UpdateEDSMIDPosJump(jfsd.Id, he.System, !jfsd.HasCoordinate && he.System.HasCoordinate, jfsd.JumpDist, conn, txn); } } txn.Commit(); } } } // now database has been updated due to initial fill, now fill in stuff which needs the user database hist.CommanderId = CurrentCommander; hist.ProcessUserHistoryListEntries(h => h.ToList()); // here, we update the DBs in HistoryEntry and any global DBs in historylist hist.SendEDSMStatusInfo(hist.GetLast, true); return(hist); }