using System; using System.Collections; using System.Text.RegularExpressions; namespace Icarus.MsnBot { public class Category { private Logger log = Logger.GetLogger("cmd", "Logs"); //Category types public const string TYPE_BEGINS_WITH = "BEGINSWITH"; public const string TYPE_ENDS_WITH = "ENDSWITH"; public const string TYPE_CONTAINS = "CONTAINS"; public const string TYPE_IS_EXACTLY = "ISEXACTLY"; public const string TYPE_REGEX = "REGEX"; public const string TYPE_NONE = "NONE"; public static readonly char[] MATCH_WORD_SPLITTER = new char[] {'|'}; public static readonly char[] REPLY_SPLITTER = new char[] {'$'}; public static readonly char[] SINGLE_REPLY_SPLITTER = new char[] {'&'}; private string title; private string matchType; private string[] matchWords; private Regex[] regexes; private ArrayList replies = new ArrayList(); private ArrayList usedReplies = new ArrayList(); private Random rng = new Random(); public Category(string title, string matchType, string[] matchWords, string[] replies) { log.Info("Created new Category: " + title); this.title = title; this.matchWords = matchWords; foreach (string s in replies) this.replies.Add(s); this.matchType = matchType; if (matchType == TYPE_REGEX) { regexes = new Regex[matchWords.Length]; for (int i = 0; i < matchWords.Length; i++) regexes[i] = new Regex(matchWords[i]); } if (this.matchType != TYPE_NONE && this.matchType != TYPE_REGEX) { //Get the matchwords ready: for (int i = 0; i < this.matchWords.Length; i++) { this.matchWords[i] = this.matchWords[i].ToLower(); if (this.matchType == TYPE_BEGINS_WITH) this.matchWords[i] = this.matchWords[i].TrimStart(); else if (this.matchType == TYPE_ENDS_WITH) this.matchWords[i] = this.matchWords[i].TrimEnd(); else if (this.matchType == TYPE_IS_EXACTLY) this.matchWords[i] = this.matchWords[i].Trim(); else if (this.MatchType != Category.TYPE_CONTAINS) log.Warn("Got non recognized MatchType: " + this.matchType); } } } private Category() { } public string[] MatchWords { get { return matchWords; } } public string MatchType { get { return matchType; } } public string Title { get { return title; } } public string GetRandomReply() { if (replies.Count == 0) { replies = usedReplies; usedReplies = new ArrayList(); } int index = rng.Next() % replies.Count; string reply = (string) replies[index]; replies.RemoveAt(index); usedReplies.Add(reply); return reply; } public string GetMatch(string msg) { try { if (matchType == TYPE_BEGINS_WITH) return GetBeginsWithMatch(msg); else if (matchType == TYPE_ENDS_WITH) return GetEndsWithMatch(msg); else if (matchType == TYPE_CONTAINS) return GetContainsMatch(msg); else if (matchType == TYPE_IS_EXACTLY) return GetIsExactlyMatch(msg); else if (matchType == TYPE_REGEX) return GetRegexMatch(msg); } catch(Exception e) { log.Error("Error in getting match for msg \"" + msg + "\", exception: " + e.Message); } return null; } private string GetBeginsWithMatch(string msg) { msg = msg.TrimStart(); string lmsg = msg.ToLower(); for (int i = 0; i < matchWords.Length; i++) { if (lmsg.StartsWith(matchWords[i])) { return msg.Substring(0, matchWords[i].Length); } } return null; } private string GetEndsWithMatch(string msg) { msg = msg.TrimEnd(); string lmsg = msg.ToLower(); for (int i = 0; i < matchWords.Length; i++) { if (lmsg.EndsWith(matchWords[i])) { return msg.Substring(msg.Length - matchWords[i].Length, matchWords[i].Length); } } return null; } private string GetIsExactlyMatch(string msg) { msg = msg.Trim(); string lmsg = msg.ToLower(); for (int i = 0; i < matchWords.Length; i++) { if (lmsg == matchWords[i]) return msg; } return null; } private string GetContainsMatch(string msg) { msg = msg.Trim(); string lmsg = msg.ToLower(); for (int i = 0; i < matchWords.Length; i++) { int index = lmsg.IndexOf(matchWords[i]); if (index != -1) { return msg.Substring(index, matchWords[i].Length); } } return null; } private string GetRegexMatch(string msg) { msg = msg.Trim(); string lmsg = msg.ToLower(); for (int i = 0; i < regexes.Length; i++) { Regex r = regexes[i]; Match m = r.Match(lmsg); if (m.Success) { string match = m.Value; int index = lmsg.IndexOf(match); return msg.Substring(index, match.Length); } } return null; } public Category Clone() { Category c = new Category(); c.matchType = this.matchType; c.log = this.log; c.matchWords = this.matchWords; c.title = this.title; c.regexes = this.regexes; c.rng = new Random(); c.replies = new ArrayList(); c.usedReplies = new ArrayList(); foreach (string reply in this.replies) c.replies.Add(reply); foreach (string usedReply in this.usedReplies) c.replies.Add(usedReply); return c; } } }