/// <summary> /// Navigates this node (and recusively into child nodes) for a match to the path passed as an argument /// whilst processing the referenced request /// </summary> /// <param name="path">The normalized path derived from the user's input</param> /// <param name="query">The query that this search is for</param> /// <param name="request">An encapsulation of the request from the user</param> /// <param name="matchstate">The part of the input path the node represents</param> /// <param name="wildcard">The contents of the user input absorbed by the AIML wildcards "_" and "*"</param> /// <returns>The template to process to generate the output</returns> public string evaluate(string path, SubQuery query, Request request, MatchState matchstate, StringBuilder wildcard) { if (request.StartedOn.AddMilliseconds(request.bot.TimeOut) < DateTime.Now) { request.bot.writeToLog("文件读取超时. 用户ID: " + request.user.UserID + ",输入内容: \"" + request.rawInput + "\""); request.hasTimedOut = true; return(string.Empty); } path = path.Trim(); if (this.children.Count == 0) { if (path.Length > 0) { this.storeWildCard(path, wildcard); } return(this.template); } if (path.Length == 0) { return(this.template); } List <string> splitPath = new List <string>(); string w = ""; foreach (char c in path.ToCharArray()) { if (Regex.IsMatch(c.ToString(), @"[\u4e00-\u9fa5]+")) { if (w != "") { splitPath.Add(w.ToString()); } w = ""; splitPath.Add(c.ToString()); } else if (c.ToString() == "*") { w = ""; splitPath.Add(c.ToString()); } else { if (!Regex.IsMatch(c.ToString(), @"[ \r\n\t]+")) { w += c.ToString(); } else if (w != "") { splitPath.Add(w.ToString()); w = ""; } } } if (w != "") { splitPath.Add(w.ToString()); } string firstWord = Normalize.MakeCaseInsensitive.TransformInput(splitPath[0]); string newPath = path.Substring(firstWord.Length, path.Length - firstWord.Length); if (this.children.ContainsKey("_")) { Node childNode = (Node)this.children["_"]; StringBuilder newWildcard = new StringBuilder(); this.storeWildCard(splitPath[0], newWildcard); string result = childNode.evaluate(newPath, query, request, matchstate, newWildcard); if (result.Length > 0) { if (newWildcard.Length > 0) { switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; case MatchState.That: query.ThatStar.Add(newWildcard.ToString()); break; case MatchState.Topic: query.TopicStar.Add(newWildcard.ToString()); break; } } return(result); } } if (this.children.ContainsKey(firstWord)) { MatchState newMatchstate = matchstate; if (firstWord == "<THAT>") { newMatchstate = MatchState.That; } else if (firstWord == "<TOPIC>") { newMatchstate = MatchState.Topic; } Node childNode = (Node)this.children[firstWord]; StringBuilder newWildcard = new StringBuilder(); string result = childNode.evaluate(newPath, query, request, newMatchstate, newWildcard); if (result.Length > 0) { if (newWildcard.Length > 0) { switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; case MatchState.That: query.ThatStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; case MatchState.Topic: query.TopicStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; } } return(result); } } if (this.children.ContainsKey("*")) { Node childNode = (Node)this.children["*"]; StringBuilder newWildcard = new StringBuilder(); this.storeWildCard(splitPath[0], newWildcard); string result = childNode.evaluate(newPath, query, request, matchstate, newWildcard); if (result.Length > 0) { if (newWildcard.Length > 0) { switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; case MatchState.That: query.ThatStar.Add(newWildcard.ToString()); break; case MatchState.Topic: query.TopicStar.Add(newWildcard.ToString()); break; } } return(result); } } if ((this.word == "_") || (this.word == "*")) { this.storeWildCard(splitPath[0], wildcard); return(this.evaluate(newPath, query, request, matchstate, wildcard)); } wildcard = new StringBuilder(); return(string.Empty); }
/// <summary> /// Navigates this node (and recusively into child nodes) for a match to the path passed as an argument /// whilst processing the referenced request /// </summary> /// <param name="path">The normalized path derived from the user's input</param> /// <param name="query">The query that this search is for</param> /// <param name="request">An encapsulation of the request from the user</param> /// <param name="matchstate">The part of the input path the node represents</param> /// <param name="wildcard">The contents of the user input absorbed by the AIML wildcards "_" and "*"</param> /// <returns>The template to process to generate the output</returns> public string evaluate(string path, SubQuery query, Request request, MatchState matchstate, StringBuilder wildcard) { // check for timeout if (request.StartedOn.AddMilliseconds(request.bot.TimeOut) < DateTime.Now) { request.bot.writeToLog("WARNING! Request timeout. User: "******" raw input: \"" + request.rawInput + "\""); request.hasTimedOut = true; return(string.Empty); } // so we still have time! path = path.Trim(); // check if this is the end of a branch in the GraphMaster // return the cCategory for this node if (children.Count == 0) { if (path.Length > 0) { // if we get here it means that there is a wildcard in the user input part of the // path. storeWildCard(path, wildcard); } return(template); } // if we've matched all the words in the input sentence and this is the end // of the line then return the cCategory for this node if (path.Length == 0) { return(template); } // otherwise split the input into it's component words string[] splitPath = path.Split(" \r\n\t".ToCharArray()); // get the first word of the sentence string firstWord = Normalize.MakeCaseInsensitive.TransformInput(splitPath[0]); // and concatenate the rest of the input into a new path for child nodes string newPath = path.Substring(firstWord.Length, path.Length - firstWord.Length); // first option is to see if this node has a child denoted by the "_" // wildcard. "_" comes first in precedence in the AIML alphabet if (children.ContainsKey("_")) { Node childNode = children["_"]; // add the next word to the wildcard match StringBuilder newWildcard = new StringBuilder(); storeWildCard(splitPath[0], newWildcard); // move down into the identified branch of the GraphMaster structure string result = childNode.evaluate(newPath, query, request, matchstate, newWildcard); // and if we get a result from the branch process the wildcard matches and return // the result if (result.Length > 0) { if (newWildcard.Length > 0) { // capture and push the star content appropriate to the current matchstate switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(newWildcard.ToString()); // added due to this match being the end of the line newWildcard.Remove(0, newWildcard.Length); break; case MatchState.That: query.ThatStar.Add(newWildcard.ToString()); break; case MatchState.Topic: query.TopicStar.Add(newWildcard.ToString()); break; } } return(result); } } // second option - the nodemapper may have contained a "_" child, but led to no match // or it didn't contain a "_" child at all. So get the child nodemapper from this // nodemapper that matches the first word of the input sentence. if (children.ContainsKey(firstWord)) { // process the matchstate - this might not make sense but the matchstate is working // with a "backwards" path: "topic <topic> that <that> user input" // the "classic" path looks like this: "user input <that> that <topic> topic" // but having it backwards is more efficient for searching purposes MatchState newMatchstate = matchstate; if (firstWord == "<THAT>") { newMatchstate = MatchState.That; } else if (firstWord == "<TOPIC>") { newMatchstate = MatchState.Topic; } Node childNode = children[firstWord]; // move down into the identified branch of the GraphMaster structure using the new // matchstate StringBuilder newWildcard = new StringBuilder(); string result = childNode.evaluate(newPath, query, request, newMatchstate, newWildcard); // and if we get a result from the child return it if (result.Length > 0) { if (newWildcard.Length > 0) { // capture and push the star content appropriate to the matchstate if it exists // and then clear it for subsequent wildcards switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; case MatchState.That: query.ThatStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; case MatchState.Topic: query.TopicStar.Add(newWildcard.ToString()); newWildcard.Remove(0, newWildcard.Length); break; } } return(result); } } // third option - the input part of the path might have been matched so far but hasn't // returned a match, so check to see it contains the "*" wildcard. "*" comes last in // precedence in the AIML alphabet. if (children.ContainsKey("*")) { // o.k. look for the path in the child node denoted by "*" Node childNode = children["*"]; // add the next word to the wildcard match StringBuilder newWildcard = new StringBuilder(); storeWildCard(splitPath[0], newWildcard); string result = childNode.evaluate(newPath, query, request, matchstate, newWildcard); // and if we get a result from the branch process and return it if (result.Length > 0) { if (newWildcard.Length > 0) { // capture and push the star content appropriate to the current matchstate switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(newWildcard.ToString()); // added due to this match being the end of the line newWildcard.Remove(0, newWildcard.Length); break; case MatchState.That: query.ThatStar.Add(newWildcard.ToString()); break; case MatchState.Topic: query.TopicStar.Add(newWildcard.ToString()); break; } } return(result); } } // o.k. if the nodemapper has failed to match at all: the input contains neither // a "_", the sFirstWord text, or "*" as a means of denoting a child node. However, // if this node is itself representing a wildcard then the search continues to be // valid if we proceed with the tail. if ((word == "_") || (word == "*")) { storeWildCard(splitPath[0], wildcard); return(evaluate(newPath, query, request, matchstate, wildcard)); } // If we get here then we're at a dead end so return an empty string. Hopefully, if the // AIML files have been set up to include a "* <that> * <topic> *" catch-all this // state won't be reached. Remember to empty the surplus to requirements wildcard matches wildcard = new StringBuilder(); return(string.Empty); }
// Token: 0x0600001D RID: 29 RVA: 0x000028E0 File Offset: 0x000018E0 public string evaluate(string path, SubQuery query, Request request, MatchState matchstate, StringBuilder wildcard) { if (request.StartedOn.AddMilliseconds(request.bot.TimeOut) < DateTime.Now) { request.bot.writeToLog(string.Concat(new string[] { "WARNING! Request timeout. User: "******" raw input: \"", request.rawInput, "\"" })); request.hasTimedOut = true; return(string.Empty); } path = path.Trim(); if (this.children.Count == 0) { if (path.Length > 0) { this.storeWildCard(path, wildcard); } return(this.template); } if (path.Length == 0) { return(this.template); } string[] array = path.Split(" \r\n\t".ToCharArray()); string text = MakeCaseInsensitive.TransformInput(array[0]); string path2 = path.Substring(text.Length, path.Length - text.Length); if (this.children.ContainsKey("_")) { Node node = this.children["_"]; StringBuilder stringBuilder = new StringBuilder(); this.storeWildCard(array[0], stringBuilder); string text2 = node.evaluate(path2, query, request, matchstate, stringBuilder); if (text2.Length > 0) { if (stringBuilder.Length > 0) { switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(stringBuilder.ToString()); stringBuilder.Remove(0, stringBuilder.Length); break; case MatchState.That: query.ThatStar.Add(stringBuilder.ToString()); break; case MatchState.Topic: query.TopicStar.Add(stringBuilder.ToString()); break; } } return(text2); } } if (this.children.ContainsKey(text)) { MatchState matchstate2 = matchstate; if (text == "<THAT>") { matchstate2 = MatchState.That; } else if (text == "<TOPIC>") { matchstate2 = MatchState.Topic; } Node node2 = this.children[text]; StringBuilder stringBuilder2 = new StringBuilder(); string text3 = node2.evaluate(path2, query, request, matchstate2, stringBuilder2); if (text3.Length > 0) { if (stringBuilder2.Length > 0) { switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(stringBuilder2.ToString()); stringBuilder2.Remove(0, stringBuilder2.Length); break; case MatchState.That: query.ThatStar.Add(stringBuilder2.ToString()); stringBuilder2.Remove(0, stringBuilder2.Length); break; case MatchState.Topic: query.TopicStar.Add(stringBuilder2.ToString()); stringBuilder2.Remove(0, stringBuilder2.Length); break; } } return(text3); } } if (this.children.ContainsKey("*")) { Node node3 = this.children["*"]; StringBuilder stringBuilder3 = new StringBuilder(); this.storeWildCard(array[0], stringBuilder3); string text4 = node3.evaluate(path2, query, request, matchstate, stringBuilder3); if (text4.Length > 0) { if (stringBuilder3.Length > 0) { switch (matchstate) { case MatchState.UserInput: query.InputStar.Add(stringBuilder3.ToString()); stringBuilder3.Remove(0, stringBuilder3.Length); break; case MatchState.That: query.ThatStar.Add(stringBuilder3.ToString()); break; case MatchState.Topic: query.TopicStar.Add(stringBuilder3.ToString()); break; } } return(text4); } } if (this.word == "_" || this.word == "*") { this.storeWildCard(array[0], wildcard); return(this.evaluate(path2, query, request, matchstate, wildcard)); } wildcard = new StringBuilder(); return(string.Empty); }