// bodyid can be null, bodyname must be set. // scan the history and try and find the best star system this bodyname is associated with private static Tuple <string, ISystem> FindBestSystem(int startindex, List <HistoryEntry> hl, string bodyname, int?bodyid, bool isstar) { System.Diagnostics.Debug.Assert(bodyname != null); for (int j = startindex; j >= 0; j--) { HistoryEntry he = hl[j]; if (he.IsLocOrJump) { JournalLocOrJump jl = (JournalLocOrJump)he.journalEntry; string designation = BodyDesignations.GetBodyDesignation(bodyname, bodyid, isstar, he.System.Name); if (IsStarNameRelated(he.System.Name, designation)) // if its part of the name, use it { return(new Tuple <string, ISystem>(designation, he.System)); } else if (jl != null && IsStarNameRelated(jl.StarSystem, designation)) { // Ignore scans where the system name has changed System.Diagnostics.Trace.WriteLine($"Rejecting body {designation} ({bodyname}) in system {he.System.Name} => {jl.StarSystem} due to system rename"); return(null); } } } return(new Tuple <string, ISystem>(BodyDesignations.GetBodyDesignation(bodyname, bodyid, false, hl[startindex].System.Name), hl[startindex].System)); }
// you must be returning void to use this.. public async System.Threading.Tasks.Task <SystemNode> FindSystemAsync(ISystem sys, bool edsmweblookup) // Find the system. Optionally do a EDSM web lookup { System.Diagnostics.Debug.Assert(System.Windows.Forms.Application.MessageLoop); // foreground only System.Diagnostics.Debug.Assert(sys != null); SystemNode sn = FindSystemNode(sys); //string trace = Environment.StackTrace.StackTrace("FindSystemAsync", 4); //System.Diagnostics.Debug.WriteLine("Scan Lookup " + trace + " " + sys.Name + " found " + (sn != null) + " web? " + edsmweblookup + " edsm lookup " + (sn?.EDSMWebChecked ?? false)); if ((sys.EDSMID > 0 || (sys.SystemAddress != null && sys.SystemAddress > 0) || (sys.Name.HasChars())) && (sn == null || sn.EDSMCacheCheck == false || (edsmweblookup && !sn.EDSMWebChecked))) { var jl = await EliteDangerousCore.EDSM.EDSMClass.GetBodiesListAsync(sys, edsmweblookup); // lookup, with optional web // return bodies and a flag indicating if from cache. // Scenario: Three panels are asking for data, one at a time, since its the foreground thread // each one awaits, sets and runs a task, blocks until tasks completes, foreground continues to next panel where it does the same // we have three tasks, any which could run in any order. // The tasks all go thru GetBodiesListAsync, which locks. Only 1 task gets to do the lookup, the one which got there first, because it did not see // a cached version // once that task completes the lookups, and it unlocks, the other tasks can run, and they will see the cache setup. They won't do an EDSM web access // since the body is in the cache. // for now, i can't guarantee that the task which gives back the bodies first runs on the foreground task. It may be task2 gets the bodies. // so we will just add them in again if (jl != null && jl.Item1 != null) { // removed - can't guarantee if (jl.Item2 == false) // only want them if not previously cached { //System.Diagnostics.Debug.WriteLine("Process bodies from EDSM " + trace + " " + sys.Name + " " + sys.EDSMID + " result " + (jl.Item1?.Count ?? -1)); foreach (JournalScan js in jl.Item1) { js.BodyDesignation = BodyDesignations.GetBodyDesignation(js, sys.Name); ProcessJournalScan(js, sys, true); } } } //System.Diagnostics.Debug.WriteLine("Lookup System node again"); if (sn == null) // refind to make sure SN is set { sn = FindSystemNode(sys); } if (sn != null) // if we found it, set to indicate we did a cache check { sn.EDSMCacheCheck = true; if (edsmweblookup) // and if we did a web check, set it too.. { sn.EDSMWebChecked = true; } } } return(sn); }
public bool AddScanToBestSystem(JournalScan je, int startindex, List <HistoryEntry> hl, out HistoryEntry he, out JournalLocOrJump jl) { he = null; jl = null; if (je?.BodyName == null) { return(false); } // go thru the list of history entries looking for a Loc for (int j = startindex; j >= 0; j--) // same as FindBestSystem { he = hl[j]; if (he.IsLocOrJump) { jl = (JournalLocOrJump)he.journalEntry; // get the body designation, given the je/system name string designation = BodyDesignations.GetBodyDesignation(je, he.System.Name); System.Diagnostics.Debug.Assert(designation != null); // either the name/sys address matches, or the designation matches the star of the system name if (je.IsStarNameRelated(he.System.Name, he.System.SystemAddress, designation)) { je.BodyDesignation = designation; return(ProcessJournalScan(je, he.System, true)); } else if (jl.StarSystem != null && je.IsStarNameRelated(jl.StarSystem, jl.SystemAddress, designation)) // if we have a starsystem name, and its related, its a rename, ignore it { System.Diagnostics.Trace.WriteLine($"Rejecting body {designation} ({je.BodyName}) in system {he.System.Name} => {jl.StarSystem} due to system rename"); return(false); } } } je.BodyDesignation = BodyDesignations.GetBodyDesignation(je, hl[startindex].System.Name); return(ProcessJournalScan(je, hl[startindex].System, true)); // no relationship, add.. }
// ONLY use this if you must because the async await won't work in the call stack. edsmweblookup here with true is strongly discouraged public SystemNode FindSystemSynchronous(ISystem sys, bool edsmweblookup) // Find the system. Optionally do a EDSM web lookup { System.Diagnostics.Debug.Assert(System.Windows.Forms.Application.MessageLoop); // foreground only System.Diagnostics.Debug.Assert(sys != null); SystemNode sn = FindSystemNode(sys); // System.Diagnostics.Debug.WriteLine("Scan Lookup " + sys.Name + " found " + (sn != null) + " web? " + edsmweblookup + " edsm lookup " + (sn?.EDSMAdded ?? false)); if ((sys.EDSMID > 0 || (sys.SystemAddress != null && sys.SystemAddress > 0) || (sys.Name.HasChars())) && (sn == null || sn.EDSMCacheCheck == false || (edsmweblookup && !sn.EDSMWebChecked))) { var jl = EliteDangerousCore.EDSM.EDSMClass.GetBodiesList(sys, edsmweblookup); // lookup, with optional web //if (edsmweblookup) System.Diagnostics.Debug.WriteLine("EDSM WEB Lookup bodies " + sys.Name + " " + sys.EDSMID + " result " + (jl?.Count ?? -1)); if (jl != null && jl.Item2 == false) // found some bodies, not from the cache { foreach (JournalScan js in jl.Item1) { js.BodyDesignation = BodyDesignations.GetBodyDesignation(js, sys.Name); ProcessJournalScan(js, sys, true); } } if (sn == null) // refind to make sure SN is set { sn = FindSystemNode(sys); } if (sn != null) // if we found it, set to indicate we did a cache check { sn.EDSMCacheCheck = true; if (edsmweblookup) // and if we did a web check, set it too.. { sn.EDSMWebChecked = true; } } } return(sn); }
// take the journal scan and add it to the node tree private bool ProcessJournalScan(JournalScan sc, ISystem sys, bool reprocessPrimary = false) // background or foreground.. FALSE if you can't process it { SystemNode sn = GetOrCreateSystemNode(sys); // handle Earth, starname = Sol // handle Eol Prou LW-L c8-306 A 4 a and Eol Prou LW-L c8-306 // handle Colonia 4 , starname = Colonia, planet 4 // handle Aurioum B A BELT // Kyloasly OY-Q d5-906 13 1 // Extract elements from name, and extract if belt, top node type, if ring List <string> elements = ExtractElementsJournalScan(sc, sys, out ScanNodeType starscannodetype, out bool isbeltcluster, out bool isring); // Bail out if no elements extracted if (elements.Count == 0) { System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.BodyName} to system {sys.Name} - not enough elements"); return(false); } // Bail out if more than 5 elements extracted else if (elements.Count > 5) { System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.BodyName} to system {sys.Name} - too deep"); return(false); } //System.Diagnostics.Debug.WriteLine("Made body JS " + sc.BodyName); // Get custom name if different to designation string customname = GetCustomNameJournalScan(sc, sys); // Process elements, ScanNode node = ProcessElementsJournalScan(sc, sys, sn, customname, elements, starscannodetype, isbeltcluster, isring); if (node.BodyID != null) { sn.NodesByID[(int)node.BodyID] = node; } // Process top-level star if (elements.Count == 1) { // Process any belts if present ProcessBelts(sc, node); // Process primary star in multi-star system if (elements[0].Equals("A", StringComparison.InvariantCultureIgnoreCase)) { BodyDesignations.CachePrimaryStar(sc, sys); // Reprocess if we've encountered the primary (A) star and we already have a "Main Star", we reprocess to // allow any updates to PrimaryCache to make a difference if (reprocessPrimary && sn.StarNodes.Any(n => n.Key.Length > 1 && n.Value.NodeType == ScanNodeType.star)) { // get bodies with scans List <JournalScan> bodies = sn.Bodies.Where(b => b.ScanData != null).Select(b => b.ScanData).ToList(); // reset the nodes to zero sn.StarNodes = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); sn.NodesByID = new SortedList <int, ScanNode>(); foreach (JournalScan js in bodies) // replay into process the body scans.. using the newly updated body designation (primary star cache) to correct any errors { js.BodyDesignation = BodyDesignations.GetBodyDesignation(js, sn.System.Name); ProcessJournalScan(js, sn.System); } } } } ProcessedSaved(); // any saved JEs due to no scan, add return(true); }