/// <summary> /// Finds the exact tag for the input text. /// Does not perform partial matching or chain parsing. /// </summary> /// <param name="tagText">The input text to search for.</param> /// <returns>The matching tag, or null if not found.</returns> public MetaTag FindTag(string tagText) { string cleaned = MetaTag.CleanTag(tagText); if (Tags.TryGetValue(cleaned, out MetaTag result)) { return(result); } // TODO: Chain searching int dotIndex = cleaned.IndexOf('.'); if (dotIndex > 0) { string tagBase = cleaned.Substring(0, dotIndex); string secondarySearch; if (tagBase == "playertag" || tagBase == "npctag") { // TODO: Object meta, to inform of down-typing like this? secondarySearch = "entitytag" + cleaned.Substring(dotIndex); } else if (!tagBase.EndsWith("tag")) { secondarySearch = tagBase + "tag" + cleaned.Substring(dotIndex); } else { return(null); } return(FindTag(secondarySearch)); } return(null); }
/// <summary> /// Tag meta docs user command. /// </summary> public void CMD_Tag(string[] cmds, SocketMessage message) { List <string> secondarySearches = new List <string>(); if (cmds.Length > 0) { cmds[0] = MetaTag.CleanTag(cmds[0]); int dotIndex = cmds[0].IndexOf('.'); if (dotIndex > 0) { string tagBase = cmds[0].Substring(0, dotIndex); string tagSuffix = cmds[0].Substring(dotIndex); if (!tagBase.EndsWith("tag")) { secondarySearches.Add(tagBase + "tag" + tagSuffix); } string tagBaseLow = tagBase.ToLowerFast(); if (tagBaseLow == "player" || tagBaseLow == "npc" || tagBaseLow == "playertag" || tagBaseLow == "npctag") { secondarySearches.Add("entitytag" + tagSuffix); } secondarySearches.Add("elementtag" + tagSuffix); } } int getDistanceTo(MetaTag tag) { int dist1 = StringConversionHelper.GetLevenshteinDistance(cmds[0], tag.CleanedName); int dist2 = StringConversionHelper.GetLevenshteinDistance(cmds[0], tag.AfterDotCleaned); int dist = Math.Min(dist1, dist2); foreach (string secondSearch in secondarySearches) { int dist3 = StringConversionHelper.GetLevenshteinDistance(secondSearch, tag.CleanedName); dist = Math.Min(dist, dist3); } return(dist); } string findClosestTag() { int lowestDistance = 20; string lowestStr = null; foreach (MetaTag tag in Program.CurrentMeta.Tags.Values) { int currentDistance = getDistanceTo(tag); if (currentDistance < lowestDistance) { lowestDistance = currentDistance; lowestStr = tag.CleanedName; } } return(lowestStr); } AutoMetaCommand(Program.CurrentMeta.Tags, MetaDocs.META_TYPE_TAG, cmds, message, secondarySearches, altFindClosest: findClosestTag, altMatchOrderer: (list) => list.OrderBy(getDistanceTo).ToList()); }