/// <summary> /// Creates a tree from the given query /// </summary> /// <param name="query">Query to parse into a tree</param> /// <returns>The tree representation of the query</returns> public static Node CreateTree(string query) { var queryIdentifiers = new[] { "\"", "\\sand\\s", "\\sor\\s", "\\snot\\s", "\\sselect\\s", "\\swhere\\s", }; Node tree; if (string.IsNullOrEmpty(query)) { tree = new ScanNode(); } else if (!queryIdentifiers.Any(i => Regex.IsMatch(query, i)) && !query.TrimStart().StartsWith("*")) { tree = new PhraseNode(query, false, null, null); } else { lock (_fieldTypes) { tree = QueryParser.Parse(query); } } return(tree); }
private ScanNode ProcessElements(JournalScan sc, ISystem sys, SystemNode sn, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster) { SortedList <string, ScanNode> cnodes = sn.starnodes; ScanNode node = null; for (int lvl = 0; lvl < elements.Count; lvl++) { ScanNode sublv; ScanNodeType sublvtype; string ownname = elements[lvl]; if (cnodes == null || !cnodes.TryGetValue(elements[lvl], out sublv)) { if (node != null && node.children == null) { node.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); cnodes = node.children; } if (lvl == 0) { sublvtype = starscannodetype; } else if (isbeltcluster) { sublvtype = lvl == 1 ? ScanNodeType.belt : ScanNodeType.beltcluster; } else { sublvtype = ScanNodeType.body; } sublv = new ScanNode { ownname = ownname, fullname = lvl == 0 ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : node.fullname + " " + ownname, ScanData = null, children = null, type = sublvtype, level = lvl }; cnodes.Add(ownname, sublv); } node = sublv; cnodes = node.children; if (lvl == elements.Count - 1) { node.ScanData = sc; node.customname = customname; } } return(node); }
private bool Process(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 ScanNodeType starscannodetype = ScanNodeType.star; // presuming.. bool isbeltcluster = false; // Extract elements from name List <string> elements = ExtractElements(sc, sys, out isbeltcluster, out starscannodetype); // 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); } // Get custom name if different to designation string customname = GetCustomName(sc, sys); // Process elements ScanNode node = ProcessElements(sc, sys, sn, customname, elements, starscannodetype, isbeltcluster); // 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)) { CachePrimaryStar(sc, sys); // Reprocess if we've encountered the primary (A) star and we already have a "Main Star" if (reprocessPrimary && sn.starnodes.Any(n => n.Key.Length > 1 && n.Value.type == ScanNodeType.star)) { ReProcess(sn); } } } return(true); }
private bool ProcessSAAScan(JournalSAAScanComplete jsaa, ISystem sys, bool reprocessPrimary = false) // background or foreground.. FALSE if you can't process it { SystemNode sn = GetOrCreateSystemNode(sys); ScanNode relatedScan = null; if (sn.NodesByID.ContainsKey((int)jsaa.BodyID)) { relatedScan = sn.NodesByID[(int)jsaa.BodyID]; if (relatedScan.ScanData != null && relatedScan.ScanData.BodyDesignation != null) { jsaa.BodyDesignation = relatedScan.ScanData.BodyDesignation; } } else if (jsaa.BodyDesignation != null && jsaa.BodyDesignation != jsaa.BodyName) { foreach (var body in sn.Bodies) { if (body.fullname == jsaa.BodyDesignation) { relatedScan = body; break; } } } if (relatedScan == null) { foreach (var body in sn.Bodies) { if ((body.fullname == jsaa.BodyName || body.customname == jsaa.BodyName) && (body.fullname != sys.Name || body.level != 0)) { relatedScan = body; break; } } } if (relatedScan != null) { relatedScan.IsMapped = true; // keep data here since we can get scans replaced later.. relatedScan.WasMappedEfficiently = jsaa.ProbesUsed <= jsaa.EfficiencyTarget; //System.Diagnostics.Debug.WriteLine("Setting SAA Scan for " + jsaa.BodyName + " " + sys.Name + " to Mapped: " + relatedScan.WasMappedEfficiently); if (relatedScan.ScanData != null) // if we have a scan, set its values - this keeps the calculation self contained in the class. { relatedScan.ScanData.SetMapped(relatedScan.IsMapped, relatedScan.WasMappedEfficiently); //System.Diagnostics.Debug.WriteLine(".. passing down to scan " + relatedScan.ScanData.ScanType); } return(true); // We already have the scan } return(false); }
public static void DumpTree(ScanNode top, string key, int level) // debug dump out { System.Diagnostics.Debug.WriteLine(" ".Substring(0, level * 3) + key + ":" + top.BodyID + " " + top.fullname + " " + top.type); if (top.children != null) { foreach (var c in top.children) { DumpTree(c.Value, c.Key, level + 1); } } }
private void ProcessBelts(JournalScan sc, ScanNode node) { if (sc.HasRings) { foreach (JournalScan.StarPlanetRing ring in sc.Rings) { ScanNode belt; string beltname = ring.Name; string stardesig = sc.BodyDesignation ?? sc.BodyName; if (beltname.StartsWith(stardesig, StringComparison.InvariantCultureIgnoreCase)) { beltname = beltname.Substring(stardesig.Length).Trim(); } else if (stardesig.ToLowerInvariant() == "lave" && beltname.ToLowerInvariant() == "castellan belt") { beltname = "A Belt"; } if (node.children == null || !node.children.TryGetValue(beltname, out belt)) { if (node.children == null) { node.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); } belt = new ScanNode { ownname = beltname, fullname = node.fullname + " " + beltname, customname = ring.Name, ScanData = null, BeltData = ring, children = null, type = ScanNodeType.belt, level = 1 }; node.children.Add(beltname, belt); } belt.BeltData = ring; } } }
static public ScanNode ReadJSON(JObject jo) { string time = jo["Epoch"].Str(); DateTime epoch = time.HasChars() ? DateTime.Parse(time, CultureInfo.InvariantCulture, DateTimeStyles.AssumeUniversal | DateTimeStyles.AdjustToUniversal) : DateTime.UtcNow; ScanNode n = new ScanNode(); n.OwnName = jo["Name"].Str(); n.FullName = jo["FullName"].Str(n.OwnName); string nt = jo["NodeType"].Str(); n.NodeType = nt.Equals("barycentre") ? ScanNodeType.barycentre : nt.Equals("body") ? ScanNodeType.body : ScanNodeType.star; if (jo.ContainsKey("SemiMajorAxis")) { n.scandata = new JournalScan(n.OwnName, jo["StarClass"].StrNull(), jo["PlanetClass"].StrNull(), jo["Mass"].DoubleNull(), jo["OrbitalPeriod"].DoubleNull(), jo["AxialTilt"].DoubleNull(), jo["Radius"].DoubleNull(), jo["SemiMajorAxis"].DoubleNull(), // km jo["Eccentricity"].DoubleNull(), jo["Inclination"].DoubleNull(), // deg all jo["AscendingNode"].DoubleNull(), jo["Periapis"].DoubleNull(), jo["MeanAnomaly"].DoubleNull(), epoch); if (n.scandata.nRadius.HasValue) { n.scandata.nRadius *= 1000; } } if (jo.ContainsKey("Bodies")) { n.Children = new SortedList <string, ScanNode>(); JArray ja = jo["Bodies"] as JArray; foreach (JObject o in ja) { var cn = ReadJSON(o); n.Children.Add(cn.OwnName, cn); } } return(n); }
static private List <string> ExpandRecurivelyBarynodeTree(ScanNode top, ScanNode pos) // go down tree, moving nodes from the top to their positions { List <string> keystodelete = new List <string>(); foreach (var k in pos.children) // all children of top { string keyid = k.Value.BodyID.ToStringInvariant("00000"); // key from bodyid if (k.Value.type == ScanNodeType.barycentre && top.children.ContainsKey(keyid)) // its a barycentre, and top has that barycentre, move it to here { //System.Diagnostics.Debug.WriteLine(".. barycenter " + keyid); ScanNode tocopy = top.children[keyid]; if (k.Value.children == null) { k.Value.children = new SortedList <string, ScanNode>(); } foreach (var cc in tocopy.children) { string cckey = cc.Key; if (!k.Value.children.ContainsKey(cckey)) // may have been moved already, because we don't remove top keys until finished { // System.Diagnostics.Debug.WriteLine(".. " + cckey + " " + cc.Value.fullname + " onto " + keyid); k.Value.children.Add(cckey, cc.Value); ExpandRecurivelyBarynodeTree(top, k.Value); } else { // System.Diagnostics.Debug.WriteLine(".. Dup move " + cckey + " " + cc.Value.fullname + " onto " + keyid); } } keystodelete.Add(keyid); } } return(keystodelete); }
public void Visit(ScanNode node) => Format(node);
public void Visit(ScanNode node) { Index = _log.Search(); Mode = Query.EvaluationMode.Index; EstimatedCount = _log.Count; }
private ScanNode ProcessElementsBodyAndID(IBodyNameAndID sc, ISystem sys, SystemNode sn, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster) { SortedList <string, ScanNode> currentnodelist = sn.StarNodes; // current operating node list, always made ScanNode previousnode = null; // trails subnode by 1 to point to previous node for (int lvl = 0; lvl < elements.Count; lvl++) { ScanNodeType sublvtype = starscannodetype; if (lvl > 0) { if (isbeltcluster) { sublvtype = lvl == 1 ? ScanNodeType.belt : ScanNodeType.beltcluster; } else { sublvtype = ScanNodeType.body; } } if (currentnodelist == null || !currentnodelist.TryGetValue(elements[lvl], out ScanNode subnode)) { if (currentnodelist == null) // no node list, happens when we are at least 1 level down as systemnode always has a node list, make one { currentnodelist = previousnode.Children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); } string ownname = elements[lvl]; subnode = new ScanNode { OwnName = ownname, FullName = lvl == 0 ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : previousnode.FullName + " " + ownname, ScanData = null, Children = null, NodeType = sublvtype, Level = lvl, }; currentnodelist.Add(ownname, subnode); } if (lvl == elements.Count - 1) { subnode.CustomName = customname; if (sc.BodyID != null) { subnode.BodyID = sc.BodyID; } if (sc.BodyType == "" || sc.BodyType == "Null" || sc.BodyType == "Barycentre") { subnode.NodeType = ScanNodeType.barycentre; } else if (sc.BodyType == "Belt") { subnode.NodeType = ScanNodeType.belt; } } previousnode = subnode; currentnodelist = previousnode.Children; } return(previousnode); }
private ScanNode ProcessElementsJournalScan(JournalScan sc, ISystem sys, SystemNode sn, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster, bool isring = false) { SortedList <string, ScanNode> cnodes = sn.starnodes; ScanNode node = null; List <JournalScan.BodyParent> ancestors = sc.Parents?.AsEnumerable()?.ToList(); List <JournalScan.BodyParent> ancestorbodies = ancestors?.Where(a => a.Type == "Star" || a.Type == "Planet" || a.Type == "Belt")?.Reverse()?.ToList(); ScanNode toplevelnode = null; if ((ancestorbodies != null) && (starscannodetype != ScanNodeType.star)) { ancestorbodies.Insert(0, null); } for (int lvl = 0; lvl < elements.Count; lvl++) { ScanNode sublv; ScanNodeType sublvtype; string ownname = elements[lvl]; if (lvl == 0) { sublvtype = starscannodetype; } else if (isbeltcluster) { if (lvl == 1) { sublvtype = ScanNodeType.belt; // A Belt } else { sublvtype = ScanNodeType.beltcluster; // A Belt Cluster 1 } } else if (isring && lvl == elements.Count - 1) // detailed scans of rings.. placed under planets { sublvtype = ScanNodeType.ring; } else { sublvtype = ScanNodeType.body; } if (cnodes == null || !cnodes.TryGetValue(elements[lvl], out sublv)) { if (node != null && node.children == null) { node.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); cnodes = node.children; } sublv = new ScanNode { ownname = ownname, fullname = lvl == 0 ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : node.fullname + " " + ownname, ScanData = null, children = null, type = sublvtype, level = lvl, IsTopLevelNode = lvl == 0 }; cnodes.Add(ownname, sublv); } if (ancestorbodies != null && lvl < ancestorbodies.Count && ancestorbodies[lvl] != null) { if (sublv.BodyID == null) { sublv.BodyID = ancestorbodies[lvl].BodyID; sn.NodesByID[(int)sublv.BodyID] = sublv; } } node = sublv; cnodes = node.children; if (lvl == elements.Count - 1) { node.ScanData = sc; // only overwrites if scan is better node.ScanData.SetMapped(node.IsMapped, node.WasMappedEfficiently); // pass this data to node, as we may have previously had a SAA Scan node.customname = customname; if (sc.BodyID != null) { node.BodyID = sc.BodyID; } } if (lvl == 0) { toplevelnode = node; } if (node.BodyID != null) { if (lvl == 0 && node.BodyID > sn.MaxTopLevelBodyID) { sn.MaxTopLevelBodyID = (int)node.BodyID; } else if (lvl > 0 && node.BodyID < sn.MinPlanetBodyID) { sn.MinPlanetBodyID = (int)node.BodyID; } } } if (ancestors != null && ancestorbodies != null && ancestorbodies.Count > 0 && ancestorbodies[0] == null && toplevelnode.BodyID == null) { for (int lvl = 1; lvl < ancestors.Count; lvl++) { if (ancestors[lvl - 1].BodyID >= sn.MinPlanetBodyID && ancestors[lvl].BodyID <= sn.MaxTopLevelBodyID) { toplevelnode.BodyID = ancestors[lvl].BodyID; sn.NodesByID[(int)toplevelnode.BodyID] = toplevelnode; } } } return(node); }
public bool Process(JournalScan sc, EliteDangerous.ISystem sys) // FALSE if you can't process it { Tuple <string, long> withedsm = new Tuple <string, long>(sys.name, sys.id_edsm); SystemNode sn = null; if (scandata.ContainsKey(withedsm)) // if with edsm (if id_edsm=0, then thats okay) { sn = scandata[withedsm]; } else if (scandataByName.ContainsKey(sys.name)) // if we now have an edsm id, see if we have one without it { foreach (SystemNode _sn in scandataByName[sys.name]) { if (_sn.system.Equals(sys)) { if (sys.id_edsm != 0) // yep, replace { scandata.Add(new Tuple <string, long>(sys.name, sys.id_edsm), _sn); } sn = _sn; break; } } } if (sn == null) { sn = new SystemNode() { system = sys, starnodes = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()) }; if (!scandataByName.ContainsKey(sys.name)) { scandataByName[sys.name] = new List <SystemNode>(); } scandataByName[sys.name].Add(sn); if (sys.id_edsm != 0) { scandata.Add(new Tuple <string, long>(sys.name, sys.id_edsm), sn); } } // 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 List <string> elements; ScanNodeType starscannodetype = ScanNodeType.star; // presuming.. string rest = sc.IsStarNameRelatedReturnRest(sys.name); if (rest != null) // if we have a relationship.. { if (rest.Length > 0) { elements = rest.Split(' ').ToList(); if (char.IsDigit(elements[0][0])) // if digits, planet number, no star designator { elements.Insert(0, "Main Star"); // no star designator, main star, add MAIN } else if (elements[0].Length > 1) // designator, is it multiple chars.. { starscannodetype = ScanNodeType.barycentre; } } else { elements = new List <string>(); // only 1 item, the star, which is the same as the system name.. elements.Add("Main Star"); // Sol / SN:Sol should come thru here } } else { // so not part of starname elements = sc.BodyName.Split(' ').ToList(); // not related in any way (earth) so assume all bodyparts, and elements.Insert(0, "Main Star"); // insert the MAIN designator as the star designator } string customname = null; if (sc.BodyName.StartsWith(sys.name, StringComparison.InvariantCultureIgnoreCase)) { customname = sc.BodyName.Substring(sys.name.Length).TrimStart(' ', '-'); if (customname == "" && !sc.IsStar) { customname = sc.BodyName; } else if (customname == "" || customname == rest) { customname = null; } } else if (rest == null || !sc.BodyName.EndsWith(rest)) { customname = sc.BodyName; } if (elements.Count >= 1) // okay, we have an element.. first is the star.. { ScanNode sublv0; if (!sn.starnodes.TryGetValue(elements[0], out sublv0)) // not found this node, add.. { sublv0 = new ScanNode() { ownname = elements[0], fullname = sys.name + (elements[0].Contains("Main") ? "" : (" " + elements[0])), ScanData = null, children = null, type = starscannodetype }; sn.starnodes.Add(elements[0], sublv0); //System.Diagnostics.Debug.WriteLine("Added star " + star.fullname + " '" + star.ownname + "'" + " under '" + designator + "' type " + ty); } if (elements.Count >= 2) // we have a sub designator.. { ScanNode sublv1; if (sublv0.children == null || !sublv0.children.TryGetValue(elements[1], out sublv1)) { if (sublv0.children == null) { sublv0.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); } sublv1 = new ScanNode() { ownname = elements[1], fullname = sublv0.fullname + " " + elements[1], ScanData = null, children = null, type = ScanNodeType.body }; sublv0.children.Add(elements[1], sublv1); } if (elements.Count >= 3) { ScanNode sublv2; if (sublv1.children == null || !sublv1.children.TryGetValue(elements[2], out sublv2)) { if (sublv1.children == null) { sublv1.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); } sublv2 = new ScanNode() { ownname = elements[2], fullname = sublv0.fullname + " " + elements[1] + " " + elements[2], ScanData = null, children = null, type = ScanNodeType.body }; sublv1.children.Add(elements[2], sublv2); } if (elements.Count >= 4) { ScanNode sublv3; if (sublv2.children == null || !sublv2.children.TryGetValue(elements[3], out sublv3)) { if (sublv2.children == null) { sublv2.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); } sublv3 = new ScanNode() { ownname = elements[3], fullname = sublv0.fullname + " " + elements[1] + " " + elements[2] + " " + elements[3], ScanData = null, children = null, type = ScanNodeType.body }; sublv2.children.Add(elements[3], sublv3); } if (elements.Count == 4) // okay, need only 4 elements now.. if not, we have not coped.. { sublv3.customname = customname; sublv3.ScanData = sc; } else { System.Diagnostics.Debug.WriteLine("Failed to add system " + sc.BodyName + " too long"); return(false); } } else { sublv2.customname = customname; sublv2.ScanData = sc; } } else { sublv1.customname = customname; sublv1.ScanData = sc; } } else { sublv0.customname = customname; sublv0.ScanData = sc; } return(true); } else { System.Diagnostics.Debug.WriteLine("Failed to add system " + sc.BodyName + " not enough elements"); return(false); } }
public void Visit(ScanNode node) => Visit((MatchNode)node);
// see above for elements private ScanNode ProcessElementsJournalScan(JournalScan sc, ISystem sys, SystemNode systemnode, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster, bool isring) { List <JournalScan.BodyParent> ancestors = sc.Parents?.AsEnumerable()?.ToList(); // this includes Rings, Barycentres(Nulls) that frontier put into the list.. // remove all rings and barycenters first, since thats not in our element list. We just want the bodies and belts List <JournalScan.BodyParent> ancestorbodies = ancestors?.Where(a => a.Type == "Star" || a.Type == "Planet" || a.Type == "Belt")?.Reverse()?.ToList(); // but we need to add back the barycenter at the top, since we do add that that in the element list if (ancestorbodies != null && ancestorbodies.Count > 0 && starscannodetype == ScanNodeType.barycentre) { // this checks out, but disable for safety. System.Diagnostics.Debug.Assert(ancestors[ancestors.Count - 1].Type == "Null"); // double check its a barycentre, it should be ancestorbodies.Insert(0, ancestors[ancestors.Count - 1]); } // for each element we process into the tree SortedList <string, ScanNode> currentnodelist = systemnode.StarNodes; // current operating node list, always made ScanNode previousnode = null; // trails subnode by 1 to point to previous node for (int lvl = 0; lvl < elements.Count; lvl++) { ScanNodeType sublvtype = starscannodetype; // top level, element[0] type is starscannode (star/barycentre) if (lvl > 0) // levels pass 0, we need to determine what it is { if (isbeltcluster) // a belt cluster is in three levels (star, belt, cluster number) { if (lvl == 1) // next level, its a belt { sublvtype = ScanNodeType.belt; } else { sublvtype = ScanNodeType.beltcluster; // third level, cluster } } else if (isring && lvl == elements.Count - 1) // and level, and a ring, mark as a ring { sublvtype = ScanNodeType.ring; } else { sublvtype = ScanNodeType.body; // default is body for levels 1 on } } // if not got a node list (only happens when we have a scannode from another scannode), or we are not in the node list if (currentnodelist == null || !currentnodelist.TryGetValue(elements[lvl], out ScanNode subnode)) // either no nodes, or not found the element name in the node list. { if (currentnodelist == null) // no node list, happens when we are at least 1 level down as systemnode always has a node list, make one { currentnodelist = previousnode.Children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); } string ownname = elements[lvl]; subnode = new ScanNode { OwnName = ownname, FullName = previousnode == null ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : previousnode.FullName + " " + ownname, ScanData = null, Children = null, NodeType = sublvtype, Level = lvl, }; currentnodelist.Add(ownname, subnode); } if (ancestorbodies != null && lvl < ancestorbodies.Count) // if we have the ancestor list, we can fill in the bodyid for each part. { subnode.BodyID = ancestorbodies[lvl].BodyID; systemnode.NodesByID[(int)subnode.BodyID] = subnode; } if (lvl == elements.Count - 1) // if we are at the end node.. { subnode.ScanData = sc; // only overwrites if scan is better subnode.ScanData.SetMapped(subnode.IsMapped, subnode.WasMappedEfficiently); // pass this data to node, as we may have previously had a SAA Scan subnode.CustomName = customname; // and its custom name if (sc.BodyID != null) // if scan has a body ID, pass it to the node { subnode.BodyID = sc.BodyID; } } previousnode = subnode; // move forward 1 step currentnodelist = previousnode.Children; } return(previousnode); }
public override void _Ready() { instance = this; }
private bool Process(IBodyNameAndID sc, ISystem sys, bool reprocessPrimary = false) // background or foreground.. FALSE if you can't process it { SystemNode sn = GetOrCreateSystemNode(sys); ScanNode relatedScan = null; if ((sc.BodyDesignation == null || sc.BodyDesignation == sc.Body) && (sc.Body != sc.StarSystem || sc.BodyType != "Star")) { foreach (var body in sn.Bodies) { if ((body.fullname == sc.Body || body.customname == sc.Body) && (body.fullname != sc.StarSystem || (sc.BodyType == "Star" && body.level == 0) || (sc.BodyType != "Star" && body.level != 0))) { relatedScan = body; sc.BodyDesignation = body.fullname; break; } } } if (relatedScan == null) { foreach (var body in sn.Bodies) { if ((body.fullname == sc.Body || body.customname == sc.Body) && (body.fullname != sc.StarSystem || (sc.BodyType == "Star" && body.level == 0) || (sc.BodyType != "Star" && body.level != 0))) { relatedScan = body; break; } } } if (relatedScan != null && relatedScan.ScanData == null) { relatedScan.BodyLoc = sc; return(true); // We already have the scan } // 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 ScanNodeType starscannodetype = ScanNodeType.star; // presuming.. bool isbeltcluster = false; // Extract elements from name List <string> elements = ExtractElements(sc, sys, out isbeltcluster, out starscannodetype); // Bail out if no elements extracted if (elements.Count == 0) { System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.Body} 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.Body} to system {sys.Name} - too deep"); return(false); } // Get custom name if different to designation string customname = GetCustomName(sc, sys); // Process elements ScanNode node = ProcessElements(sc, sys, sn, customname, elements, starscannodetype, isbeltcluster); if (node.BodyID != null) { sn.NodesByID[(int)node.BodyID] = node; } return(true); }
// given a list of scannodes, construst a tree of barynodes with their scans underneath. // reconstructs the node tree and inserts barynodes into it from the parent info static public ScanNode PopulateBarycentres(List <ScanNode> nodes) { ScanNode top = new ScanNode(); top.children = new SortedList <string, ScanNode>(); foreach (var sn in nodes) { if (sn.ScanData?.Parents != null) { //System.Diagnostics.Debug.WriteLine("Scan " + sn.ScanData.BodyName + ":" + sn.ScanData.BodyID + " " + sn.ScanData.ParentList()); for (int i = 0; i < sn.ScanData.Parents.Count; i++) // go thru all parents of the body { var sd = sn.ScanData; var sp = sd.Parents[i]; if (sp.Type == "Null") // any barycenters, process { ScanNode bodynode = null; if (i > 0) // so its not the last barycentre (remembering its in reverse order- last entry is the deepest (say Star) node { int bodyid = sd.Parents[i - 1].BodyID; // pick up the body ID of the previous entry bodynode = nodes.Find((x) => x.BodyID == bodyid); // see if its in the scan database if (bodynode == null && sd.Parents[i - 1].Type == "Null") // if can't find, and its another barycentre, add a new dummy barycentre node { bodynode = new ScanNode() { BodyID = bodyid, type = ScanNodeType.barycentre, fullname = "Created Barynode " + bodyid, ownname = bodyid.ToString("00000") }; } } else { bodynode = sn; // its directly under the body, so the node is the scan node (Node-barycentre) } if (bodynode != null) { string barykey = sp.BodyID.ToStringInvariant("00000"); // sp is a barycentre, so get its body id ScanNode cur = null; if (top.children.ContainsKey(barykey)) // if top has this barycentre.. { cur = top.children[barykey]; } else { cur = new ScanNode() { BodyID = sp.BodyID, type = ScanNodeType.barycentre, fullname = "Created Barynode " + sp.BodyID }; // make it cur.children = new SortedList <string, ScanNode>(); top.children[barykey] = cur; } //System.Diagnostics.Debug.WriteLine("Scan add " + entry + " to " + barykey); if (!cur.children.ContainsKey(bodynode.ownname)) { cur.children[bodynode.ownname] = bodynode; } } } } } } List <string> keystodelete = new List <string>(); foreach (var n in top.children) { //System.Diagnostics.Debug.WriteLine("Top Node " + n.Value.BodyID); keystodelete.AddRange(ExpandRecurivelyBarynodeTree(top, n.Value)); // move bary-node on the top to their positions in the tree } foreach (var k in keystodelete) // remove any moved keys { top.children.Remove(k); } return(top); }
private bool ProcessSAASignalsFound(JournalSAASignalsFound jsaa, ISystem sys, bool reprocessPrimary = false) // background or foreground.. FALSE if you can't process it { SystemNode sn = GetOrCreateSystemNode(sys); ScanNode relatednode = null; if (sn.NodesByID.ContainsKey((int)jsaa.BodyID)) // find by ID { relatednode = sn.NodesByID[(int)jsaa.BodyID]; if (relatednode.ScanData != null && relatednode.ScanData.BodyDesignation != null) { jsaa.BodyDesignation = relatednode.ScanData.BodyDesignation; } } else if (jsaa.BodyDesignation != null && jsaa.BodyDesignation != jsaa.BodyName) { foreach (var body in sn.Bodies) { if (body.fullname == jsaa.BodyDesignation) { relatednode = body; break; } } } if (relatednode != null && relatednode.type == ScanNodeType.ring && relatednode.ScanData != null && relatednode.ScanData.Parents != null && sn.NodesByID.ContainsKey(relatednode.ScanData.Parents[0].BodyID)) { relatednode = sn.NodesByID[relatednode.ScanData.Parents[0].BodyID]; } if (relatednode == null || relatednode.type == ScanNodeType.ring) { bool ringname = jsaa.BodyName.EndsWith("A Ring") || jsaa.BodyName.EndsWith("B Ring") || jsaa.BodyName.EndsWith("C Ring") || jsaa.BodyName.EndsWith("D Ring"); string ringcutname = ringname ? jsaa.BodyName.Left(jsaa.BodyName.Length - 6).TrimEnd() : null; foreach (var body in sn.Bodies) { if ((body.fullname == jsaa.BodyName || body.customname == jsaa.BodyName) && (body.fullname != sys.Name || body.level != 0)) { relatednode = body; break; } else if (ringcutname != null && body.fullname.Equals(ringcutname)) { relatednode = body; break; } } } if (relatednode != null) { //System.Diagnostics.Debug.WriteLine("Setting SAA Signals Found for " + jsaa.BodyName + " @ " + sys.Name + " body " + jsaa.BodyDesignation); if (relatednode.Signals == null) { relatednode.Signals = new List <JournalSAASignalsFound.SAASignal>(); } relatednode.Signals.AddRange(jsaa.Signals); // add signals to list of signals of this entity return(true); // all ok } return(false); }
private bool ProcessSAASignalsFound(JournalSAASignalsFound jsaa, ISystem sys, bool saveprocessinglater = true) // background or foreground.. FALSE if you can't process it { SystemNode sn = GetOrCreateSystemNode(sys); ScanNode relatednode = null; if (sn.NodesByID.ContainsKey((int)jsaa.BodyID)) // find by ID { relatednode = sn.NodesByID[(int)jsaa.BodyID]; if (relatednode.ScanData != null && relatednode.ScanData.BodyDesignation != null) { jsaa.BodyDesignation = relatednode.ScanData.BodyDesignation; } } else if (jsaa.BodyDesignation != null && jsaa.BodyDesignation != jsaa.BodyName) { foreach (var body in sn.Bodies) { if (body.FullName == jsaa.BodyDesignation) { relatednode = body; break; } } } if (relatednode != null && relatednode.NodeType == ScanNodeType.ring && relatednode.ScanData != null && relatednode.ScanData.Parents != null && sn.NodesByID.ContainsKey(relatednode.ScanData.Parents[0].BodyID)) { relatednode = sn.NodesByID[relatednode.ScanData.Parents[0].BodyID]; } if (relatednode == null || relatednode.NodeType == ScanNodeType.ring) { bool ringname = jsaa.BodyName.EndsWith("A Ring") || jsaa.BodyName.EndsWith("B Ring") || jsaa.BodyName.EndsWith("C Ring") || jsaa.BodyName.EndsWith("D Ring"); string ringcutname = ringname ? jsaa.BodyName.Left(jsaa.BodyName.Length - 6).TrimEnd() : null; foreach (var body in sn.Bodies) { if ((body.FullName == jsaa.BodyName || body.CustomName == jsaa.BodyName) && (body.FullName != sys.Name || body.Level != 0)) { relatednode = body; break; } else if (ringcutname != null && body.FullName.Equals(ringcutname)) { relatednode = body; break; } } } if (relatednode != null) { // System.Diagnostics.Debug.WriteLine("Setting SAA Signals Found for " + jsaa.BodyName + " @ " + sys.Name + " body " + jsaa.BodyDesignation); if (relatednode.Signals == null) { relatednode.Signals = new List <JournalSAASignalsFound.SAASignal>(); } foreach (var x in jsaa.Signals) { if (relatednode.Signals.Find(y => y.Type == x.Type && y.Count == x.Count) == null) { relatednode.Signals.Add(x); } } } else { if (saveprocessinglater) { SaveForProcessing(jsaa, sys); } // System.Diagnostics.Debug.WriteLine("No body to attach data found for " + jsaa.BodyName + " @ " + sys.Name + " body " + jsaa.BodyDesignation); } return(false); }
public void Visit(ScanNode node) { Fields = node.Fields; }
// 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); }
private bool ProcessBodyAndID(IBodyNameAndID sc, ISystem sys) // background or foreground.. { SystemNode sn = GetOrCreateSystemNode(sys); ScanNode relatedScan = null; // try and find the scan related to the body name // no designation, or same designation AND not a star if ((sc.BodyDesignation == null || sc.BodyDesignation == sc.Body) && (sc.Body != sc.StarSystem || sc.BodyType != "Star")) { foreach (var body in sn.Bodies) { if ((body.FullName == sc.Body || body.CustomName == sc.Body) && (body.FullName != sc.StarSystem || (sc.BodyType == "Star" && body.Level == 0) || (sc.BodyType != "Star" && body.Level != 0))) { relatedScan = body; sc.BodyDesignation = body.FullName; break; } } } // else just try and find any matches if (relatedScan == null) { foreach (var body in sn.Bodies) { if ((body.FullName == sc.Body || body.CustomName == sc.Body) && (body.FullName != sc.StarSystem || (sc.BodyType == "Star" && body.Level == 0) || (sc.BodyType != "Star" && body.Level != 0))) { relatedScan = body; break; } } } if (relatedScan != null && relatedScan.ScanData == null) { return(true); // We already have the node, with no scan, so reject } // Extract elements from name List <string> elements = ExtractElementsBodyAndID(sc, sys, out bool isbeltcluster, out ScanNodeType starscannodetype); // Bail out if no elements extracted if (elements.Count == 0) { System.Diagnostics.Trace.WriteLine($"Failed to add body {sc.Body} 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.Body} to system {sys.Name} - too deep"); return(false); } // Get custom name if different to designation string customname = GetCustomNameBodyAndID(sc, sys); // Process elements ScanNode node = ProcessElementsBodyAndID(sc, sys, sn, customname, elements, starscannodetype, isbeltcluster); if (node.BodyID != null) { sn.NodesByID[(int)node.BodyID] = node; } ProcessedSaved(); // any saved JEs due to no scan, add return(true); }
private ScanNode ProcessElements(JournalScan sc, ISystem sys, SystemNode sn, string customname, List <string> elements, ScanNodeType starscannodetype, bool isbeltcluster) { SortedList <string, ScanNode> cnodes = sn.starnodes; ScanNode node = null; List <JournalScan.BodyParent> ancestors = sc.Parents?.AsEnumerable()?.ToList(); List <JournalScan.BodyParent> ancestorbodies = ancestors?.Where(a => a.Type == "Star" || a.Type == "Planet" || a.Type == "Belt")?.Reverse()?.ToList(); ScanNode toplevelnode = null; if ((ancestorbodies != null) && (starscannodetype != ScanNodeType.star)) { ancestorbodies.Insert(0, null); } for (int lvl = 0; lvl < elements.Count; lvl++) { ScanNode sublv; ScanNodeType sublvtype; string ownname = elements[lvl]; if (lvl == 0) { sublvtype = starscannodetype; } else if (isbeltcluster) { sublvtype = lvl == 1 ? ScanNodeType.belt : ScanNodeType.beltcluster; } else { sublvtype = ScanNodeType.body; } if (cnodes == null || !cnodes.TryGetValue(elements[lvl], out sublv)) { if (node != null && node.children == null) { node.children = new SortedList <string, ScanNode>(new DuplicateKeyComparer <string>()); cnodes = node.children; } sublv = new ScanNode { ownname = ownname, fullname = lvl == 0 ? (sys.Name + (ownname.Contains("Main") ? "" : (" " + ownname))) : node.fullname + " " + ownname, ScanData = null, children = null, type = sublvtype, level = lvl, IsTopLevelNode = lvl == 0 }; cnodes.Add(ownname, sublv); } if (ancestorbodies != null && lvl < ancestorbodies.Count && ancestorbodies[lvl] != null) { if (sublv.BodyID == null) { sublv.BodyID = ancestorbodies[lvl].BodyID; sn.NodesByID[(int)sublv.BodyID] = sublv; } } node = sublv; cnodes = node.children; if (lvl == elements.Count - 1) { node.ScanData = sc; node.customname = customname; if (sc.BodyID != null) { node.BodyID = sc.BodyID; } } if (lvl == 0) { toplevelnode = node; } if (node.BodyID != null) { if (lvl == 0 && node.BodyID > sn.MaxTopLevelBodyID) { sn.MaxTopLevelBodyID = (int)node.BodyID; } else if (lvl > 0 && node.BodyID < sn.MinPlanetBodyID) { sn.MinPlanetBodyID = (int)node.BodyID; } } } if (ancestors != null && ancestorbodies != null && ancestorbodies[0] == null && toplevelnode.BodyID == null) { for (int lvl = 1; lvl < ancestors.Count; lvl++) { if (ancestors[lvl - 1].BodyID >= sn.MinPlanetBodyID && ancestors[lvl].BodyID <= sn.MaxTopLevelBodyID) { toplevelnode.BodyID = ancestors[lvl].BodyID; sn.NodesByID[(int)toplevelnode.BodyID] = toplevelnode; } } } return(node); }
public void Visit(ScanNode node) => VisitInternal(node);