<appSettings>\r
<add key="IRCServerHostName" value="irc.eu.freenode.net" />\r
<add key="IRCServerHostPort" value="6667" />\r
- <add key="IRCChannelName" value="channel" />\r
+ <add key="IRCChannelNames" value="channel1;channel2" />\r
<add key="IRCBotName" value="MyBot" />\r
<add key="ChmPath" value="C:\IRC\TechBot\CHM" />\r
<add key="MainChm" value="kmarch.chm" />\r
{\r
public class ConsoleServiceOutput : IServiceOutput\r
{\r
- public void WriteLine(string message)\r
+ public void WriteLine(MessageContext context,\r
+ string message)\r
{\r
System.Console.WriteLine(message);\r
}\r
}\r
}\r
\r
- private static string IRCChannelName\r
+ private static string IRCChannelNames\r
{\r
get\r
{\r
- string optionName = "IRCChannelName";\r
+ string optionName = "IRCChannelNames";\r
string s = ConfigurationSettings.AppSettings[optionName];\r
VerifyRequiredOption(optionName,\r
s);\r
{\r
IrcService ircService = new IrcService(IRCServerHostName,\r
IRCServerHostPort,\r
- IRCChannelName,\r
+ IRCChannelNames,\r
IRCBotName,\r
ChmPath,\r
MainChm,\r
while (true)\r
{\r
string s = System.Console.ReadLine();\r
- service.InjectMessage(s);\r
+ service.InjectMessage(null,\r
+ s);\r
}\r
}\r
}\r
Run();\r
}\r
\r
- private void WriteIfVerbose(string message)\r
+ private void WriteIfVerbose(MessageContext context,\r
+ string message)\r
{\r
if (IsVerbose)\r
- serviceOutput.WriteLine(message);\r
+ serviceOutput.WriteLine(context,\r
+ message);\r
}\r
\r
private void Run()\r
new string[] { "api" });\r
}\r
\r
- public void Handle(string commandName,\r
+ public void Handle(MessageContext context,\r
+ string commandName,\r
string parameters)\r
{\r
if (parameters.Trim().Equals(String.Empty))\r
- DisplayNoKeyword();\r
+ DisplayNoKeyword(context);\r
else\r
- Search(parameters);\r
+ Search(context,\r
+ parameters);\r
}\r
\r
public string Help()\r
return "!api <apiname>";\r
}\r
\r
- private bool SearchIndex(string keyword)\r
+ private bool SearchIndex(MessageContext context,\r
+ string keyword)\r
{\r
if (chm.HasIndex)\r
{\r
IndexType.KeywordLinks);\r
if (item != null && item.Topics.Count > 0)\r
{\r
- WriteIfVerbose(String.Format("Keyword {0} found in index",\r
+ WriteIfVerbose(context,\r
+ String.Format("Keyword {0} found in index",\r
item.KeyWord));\r
IndexTopic indexTopic = item.Topics[0] as IndexTopic;\r
- return DisplayResult(keyword, indexTopic);\r
+ return DisplayResult(context,\r
+ keyword,\r
+ indexTopic);\r
}\r
else\r
{\r
- WriteIfVerbose(String.Format("Keyword {0} not found in index",\r
+ WriteIfVerbose(context,\r
+ String.Format("Keyword {0} not found in index",\r
keyword));\r
return false;\r
}\r
return false;\r
}\r
\r
- private void SearchFullText(string keyword)\r
+ private void SearchFullText(MessageContext context,\r
+ string keyword)\r
{\r
string sort = "Rating ASC";\r
-/*\r
- sort = "Location ASC");\r
- sort = "Title ASC");\r
-*/\r
- WriteIfVerbose(String.Format("Searching fulltext database for {0}",\r
+ WriteIfVerbose(context,\r
+ String.Format("Searching fulltext database for {0}",\r
keyword));\r
\r
bool partialMatches = false;\r
maxResults,\r
partialMatches,\r
titlesOnly);\r
- WriteIfVerbose(String.Format("results.Rows.Count = {0}",\r
+ WriteIfVerbose(context,\r
+ String.Format("results.Rows.Count = {0}",\r
results != null ?\r
results.Rows.Count.ToString() : "(none)"));\r
if (results != null && results.Rows.Count > 0)\r
{\r
results.DefaultView.Sort = sort;\r
- if (!DisplayResult(keyword, results))\r
+ if (!DisplayResult(context,\r
+ keyword,\r
+ results))\r
{\r
- DisplayNoResult(keyword);\r
+ DisplayNoResult(context,\r
+ keyword);\r
}\r
}\r
else\r
{\r
- DisplayNoResult(keyword);\r
+ DisplayNoResult(context,\r
+ keyword);\r
}\r
}\r
\r
- private void Search(string keyword)\r
+ private void Search(MessageContext context,\r
+ string keyword)\r
{\r
- if (!SearchIndex(keyword))\r
- {\r
- SearchFullText(keyword);\r
- }\r
+ if (!SearchIndex(context,\r
+ keyword))\r
+ SearchFullText(context,\r
+ keyword);\r
}\r
\r
- private bool DisplayResult(string keyword,\r
+ private bool DisplayResult(MessageContext context,\r
+ string keyword,\r
IndexTopic indexTopic)\r
{\r
keyword = keyword.Trim().ToLower();\r
string url = indexTopic.URL;\r
- WriteIfVerbose(String.Format("URL from index search {0}",\r
+ WriteIfVerbose(context,\r
+ String.Format("URL from index search {0}",\r
url));\r
- string prototype = ExtractPrototype(url);\r
+ string prototype = ExtractPrototype(context,\r
+ url);\r
if (prototype == null || prototype.Trim().Equals(String.Empty))\r
return false;\r
string formattedPrototype = FormatPrototype(prototype);\r
- serviceOutput.WriteLine(formattedPrototype);\r
+ serviceOutput.WriteLine(context,\r
+ formattedPrototype);\r
return true;\r
}\r
\r
- private bool DisplayResult(string keyword,\r
+ private bool DisplayResult(MessageContext context,\r
+ string keyword,\r
DataTable results)\r
{\r
keyword = keyword.Trim().ToLower();\r
{\r
DataRowView row = results.DefaultView[i];\r
string title = row["Title"].ToString();\r
- WriteIfVerbose(String.Format("Examining {0}", title));\r
+ WriteIfVerbose(context,\r
+ String.Format("Examining {0}", title));\r
if (title.Trim().ToLower().Equals(keyword))\r
{\r
string location = row["Location"].ToString();\r
string rating = row["Rating"].ToString();\r
string url = row["Url"].ToString();\r
- string prototype = ExtractPrototype(url);\r
+ string prototype = ExtractPrototype(context,\r
+ url);\r
if (prototype == null || prototype.Trim().Equals(String.Empty))\r
continue;\r
string formattedPrototype = FormatPrototype(prototype);\r
- serviceOutput.WriteLine(formattedPrototype);\r
+ serviceOutput.WriteLine(context,\r
+ formattedPrototype);\r
return true;\r
}\r
}\r
return false;\r
}\r
\r
- private void DisplayNoResult(string keyword)\r
+ private void DisplayNoResult(MessageContext context,\r
+ string keyword)\r
{\r
- serviceOutput.WriteLine(String.Format("I don't know about keyword {0}", keyword));\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("I don't know about keyword {0}",\r
+ keyword));\r
}\r
\r
- private void DisplayNoKeyword()\r
+ private void DisplayNoKeyword(MessageContext context)\r
{\r
- serviceOutput.WriteLine("Please give me a keyword.");\r
+ serviceOutput.WriteLine(context,\r
+ "Please give me a keyword.");\r
}\r
\r
private string ReplaceComments(string s)\r
return s;\r
}\r
\r
- private string ExtractPrototype(string url)\r
+ private string ExtractPrototype(MessageContext context,\r
+ string url)\r
{\r
- string page = GetPage(url);\r
+ string page = GetPage(context,\r
+ url);\r
Match match = Regex.Match(page,\r
"<PRE class=\"?syntax\"?>(.+)</PRE>",\r
RegexOptions.Multiline |\r
return Regex.Replace(html, @"<(.|\n)*?>", String.Empty);\r
}\r
\r
- private string GetPage(string url)\r
+ private string GetPage(MessageContext context,\r
+ string url)\r
{\r
string CHMFileName = "";\r
string topicName = "";\r
}\r
else\r
{\r
- baseStream = GetBaseStreamFromCHMFileName(CHMFileName);\r
+ baseStream = GetBaseStreamFromCHMFileName(context,\r
+ CHMFileName);\r
}\r
\r
if ((topicName == "") || (CHMFileName == "") || (baseStream == null))\r
return baseStream.ExtractTextFile(topicName);\r
}\r
\r
- private CHMStream.CHMStream GetBaseStreamFromCHMFileName(string CHMFileName)\r
+ private CHMStream.CHMStream GetBaseStreamFromCHMFileName(MessageContext context,\r
+ string CHMFileName)\r
{\r
foreach (CHMFile file in chm.FileList)\r
{\r
- WriteIfVerbose(String.Format("Compare: {0} <> {1}",\r
+ WriteIfVerbose(context,\r
+ String.Format("Compare: {0} <> {1}",\r
file.ChmFilePath,\r
CHMFileName));\r
if (file.ChmFilePath.ToLower().Equals(CHMFileName.ToLower()))\r
return file.BaseStream;\r
}\r
}\r
- WriteIfVerbose(String.Format("Could not find loaded CHM file in list: {0}",\r
+ WriteIfVerbose(context,\r
+ String.Format("Could not find loaded CHM file in list: {0}",\r
CHMFileName));\r
return null;\r
}\r
new string[] { "help" });\r
}\r
\r
- public void Handle(string commandName,\r
+ public void Handle(MessageContext context,\r
+ string commandName,\r
string parameters)\r
{\r
- serviceOutput.WriteLine("I support the following commands:");\r
+ serviceOutput.WriteLine(context,\r
+ "I support the following commands:");\r
foreach (ICommand command in commands)\r
- serviceOutput.WriteLine(command.Help());\r
+ {\r
+ serviceOutput.WriteLine(context,\r
+ command.Help());\r
+ }\r
}\r
\r
public string Help()\r
new string[] { "hresult" });\r
}\r
\r
- public void Handle(string commandName,\r
+ public void Handle(MessageContext context,\r
+ string commandName,\r
string parameters)\r
{\r
string hresultText = parameters;\r
if (hresultText.Equals(String.Empty))\r
{\r
- serviceOutput.WriteLine("Please provide a valid HRESULT value.");\r
+ serviceOutput.WriteLine(context,\r
+ "Please provide a valid HRESULT value.");\r
return;\r
}\r
\r
long hresult = np.Parse(hresultText);\r
if (np.Error)\r
{\r
- serviceOutput.WriteLine(String.Format("{0} is not a valid HRESULT value.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("{0} is not a valid HRESULT value.",\r
hresultText));\r
return;\r
}\r
string description = GetHresultDescription(hresult);\r
if (description != null)\r
{\r
- serviceOutput.WriteLine(String.Format("{0} is {1}.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("{0} is {1}.",\r
hresultText,\r
description));\r
}\r
else\r
{\r
- serviceOutput.WriteLine(String.Format("I don't know about HRESULT {0}.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("I don't know about HRESULT {0}.",\r
hresultText));\r
}\r
}\r
public interface ICommand\r
{\r
bool CanHandle(string commandName);\r
- void Handle(string commandName,\r
+ void Handle(MessageContext context,\r
+ string commandName,\r
string parameters);\r
string Help();\r
}\r
using System;\r
+using System.Collections;\r
using System.Threading;\r
using TechBot.IRCLibrary;\r
\r
{\r
private string hostname;\r
private int port;\r
- private string channelname;\r
+ private string channelnames;\r
private string botname;\r
private string chmPath;\r
private string mainChm;\r
private string hresultXml;\r
private string svnCommand;\r
private IrcClient client;\r
- private IrcChannel channel1;\r
+ private ArrayList channels = new ArrayList(); /* IrcChannel */\r
private TechBotService service;\r
private bool isStopped = false;\r
\r
public IrcService(string hostname,\r
int port,\r
- string channelname,\r
+ string channelnames,\r
string botname,\r
string chmPath,\r
string mainChm,\r
{\r
this.hostname = hostname;\r
this.port = port;\r
- this.channelname = channelname;\r
+ this.channelnames = channelnames;\r
this.botname = botname;\r
this.chmPath = chmPath;\r
this.mainChm = mainChm;\r
System.Console.WriteLine("Connected...");\r
client.Register(botname, null);\r
System.Console.WriteLine(String.Format("Registered as {0}...", botname));\r
- channel1 = client.JoinChannel(channelname);\r
- System.Console.WriteLine(String.Format("Joined channel {0}...", channelname));\r
+ JoinChannels();\r
\r
while (!isStopped)\r
{\r
Thread.Sleep(1000);\r
}\r
\r
- client.PartChannel(channel1, "Caught in the bitstream...");\r
+ PartChannels();\r
client.Diconnect();\r
System.Console.WriteLine("Disconnected...");\r
}\r
- \r
+\r
public void Stop()\r
{\r
isStopped = true;\r
}\r
- \r
- public void WriteLine(string message)\r
+\r
+ private void JoinChannels()\r
{\r
- Console.WriteLine(String.Format("Sending: {0}", message));\r
- channel1.Talk(message);\r
+ foreach (string channelname in channelnames.Split(new char[] { ';' }))\r
+ {\r
+ IrcChannel channel = client.JoinChannel(channelname);\r
+ channels.Add(channel);\r
+ System.Console.WriteLine(String.Format("Joined channel #{0}...",\r
+ channel.Name));\r
+ }\r
+ }\r
+\r
+ private void PartChannels()\r
+ {\r
+ foreach (IrcChannel channel in channels)\r
+ {\r
+ client.PartChannel(channel, "Caught in the bitstream...");\r
+ System.Console.WriteLine(String.Format("Parted channel #{0}...",\r
+ channel.Name));\r
+ }\r
+ }\r
+\r
+ public void WriteLine(MessageContext context,\r
+ string message)\r
+ {\r
+ Console.WriteLine(String.Format("Sending: {0} to #{1}",\r
+ message,\r
+ context.Channel != null ? context.Channel.Name : "(null)"));\r
+ context.Channel.Talk(message);\r
}\r
\r
private void ExtractMessage(string parameters,\r
message = parameters;\r
}\r
}\r
- \r
+\r
+ private bool GetChannelName(IrcMessage message,\r
+ out string channelName)\r
+ {\r
+ if (message.Parameters == null || !message.Parameters.StartsWith("#"))\r
+ {\r
+ channelName = null;\r
+ return false;\r
+ }\r
+\r
+ int index = message.Parameters.IndexOf(' ');\r
+ if (index == -1)\r
+ index = message.Parameters.Length;\r
+ channelName = message.Parameters.Substring(1, index - 1);\r
+ return true;\r
+ }\r
+\r
+ private bool ShouldAcceptMessage(IrcMessage message,\r
+ out MessageContext context)\r
+ {\r
+ if (message.Command.ToUpper().Equals("PRIVMSG"))\r
+ {\r
+ string channelName;\r
+ if (GetChannelName(message,\r
+ out channelName))\r
+ {\r
+ foreach (IrcChannel channel in channels)\r
+ {\r
+ if (String.Compare(channel.Name, channelName, true) == 0)\r
+ {\r
+ context = new MessageContext(channel);\r
+ return true;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ context = null;\r
+ return false;\r
+ }\r
+ \r
private void client_MessageReceived(IrcMessage message)\r
{\r
try\r
{\r
- if (channel1 != null &&\r
- channel1.Name != null &&\r
+ if (message.Command != null &&\r
message.Parameters != null)\r
{\r
string injectMessage;\r
- ExtractMessage(message.Parameters, out injectMessage);\r
- if ((message.Command.ToUpper().Equals("PRIVMSG")) &&\r
- (message.Parameters.ToLower().StartsWith("#" + channel1.Name.ToLower() + " ")))\r
+ ExtractMessage(message.Parameters,\r
+ out injectMessage);\r
+ MessageContext context;\r
+ if (ShouldAcceptMessage(message,\r
+ out context))\r
{\r
- Console.WriteLine("Injecting: " + injectMessage);\r
- service.InjectMessage(injectMessage);\r
+ Console.WriteLine(String.Format("Injecting: {0} from #{1}",\r
+ injectMessage,\r
+ context.Channel.Name));\r
+ service.InjectMessage(context,\r
+ injectMessage);\r
}\r
else\r
{\r
--- /dev/null
+using System;\r
+using TechBot.IRCLibrary;\r
+\r
+namespace TechBot.Library\r
+{\r
+ public class MessageContext\r
+ {\r
+ private IrcChannel channel;\r
+\r
+ public IrcChannel Channel\r
+ {\r
+ get\r
+ {\r
+ return channel;\r
+ }\r
+ }\r
+ \r
+ public MessageContext(IrcChannel channel)\r
+ {\r
+ this.channel = channel;\r
+ }\r
+ }\r
+}\r
new string[] { "ntstatus" });\r
}\r
\r
- public void Handle(string commandName,\r
+ public void Handle(MessageContext context,\r
+ string commandName,\r
string parameters)\r
{\r
string ntstatusText = parameters;\r
if (ntstatusText.Equals(String.Empty))\r
{\r
- serviceOutput.WriteLine("Please provide a valid NTSTATUS value.");\r
+ serviceOutput.WriteLine(context,\r
+ "Please provide a valid NTSTATUS value.");\r
return;\r
}\r
\r
long ntstatus = np.Parse(ntstatusText);\r
if (np.Error)\r
{\r
- serviceOutput.WriteLine(String.Format("{0} is not a valid NTSTATUS value.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("{0} is not a valid NTSTATUS value.",\r
ntstatusText));\r
return;\r
}\r
string description = GetNtstatusDescription(ntstatus);\r
if (description != null)\r
{\r
- serviceOutput.WriteLine(String.Format("{0} is {1}.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("{0} is {1}.",\r
ntstatusText,\r
description));\r
}\r
else\r
{\r
- serviceOutput.WriteLine(String.Format("I don't know about NTSTATUS {0}.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("I don't know about NTSTATUS {0}.",\r
ntstatusText));\r
}\r
}\r
{\r
public interface IServiceOutput\r
{\r
- void WriteLine(string message);\r
+ void WriteLine(MessageContext context,\r
+ string message);\r
}\r
}\r
new string[] { "svn" });\r
}\r
\r
- public void Handle(string commandName,\r
+ public void Handle(MessageContext context,\r
+ string commandName,\r
string parameters)\r
{\r
- serviceOutput.WriteLine(svnCommand);\r
+ serviceOutput.WriteLine(context,\r
+ svnCommand);\r
}\r
\r
public string Help()\r
{\r
public class TechBotService\r
{\r
- private const bool IsVerbose = false;\r
- \r
private IServiceOutput serviceOutput;\r
private string chmPath;\r
private string mainChm;\r
this.svnCommand = svnCommand;\r
}\r
\r
- private void WriteIfVerbose(string message)\r
- {\r
- if (IsVerbose)\r
- serviceOutput.WriteLine(message);\r
- }\r
- \r
public void Run()\r
{\r
commands.Add(new HelpCommand(serviceOutput,\r
svnCommand));\r
}\r
\r
- public void InjectMessage(string message)\r
+ public void InjectMessage(MessageContext context,\r
+ string message)\r
{\r
if (message.StartsWith("!"))\r
- {\r
- ParseCommandMessage(message);\r
- }\r
+ ParseCommandMessage(context,\r
+ message);\r
}\r
\r
private bool IsCommandMessage(string message)\r
return message.StartsWith("!");\r
}\r
\r
- public void ParseCommandMessage(string message)\r
+ public void ParseCommandMessage(MessageContext context,\r
+ string message)\r
{\r
if (!IsCommandMessage(message))\r
return;\r
{\r
if (command.CanHandle(commandName))\r
{\r
- command.Handle(commandName, parameters);\r
+ command.Handle(context,\r
+ commandName, parameters);\r
return;\r
}\r
}\r
new string[] { "winerror" });\r
}\r
\r
- public void Handle(string commandName,\r
+ public void Handle(MessageContext context,\r
+ string commandName,\r
string parameters)\r
{\r
string winerrorText = parameters;\r
if (winerrorText.Equals(String.Empty))\r
{\r
- serviceOutput.WriteLine("Please provide a valid System Error Code value.");\r
+ serviceOutput.WriteLine(context,\r
+ "Please provide a valid System Error Code value.");\r
return;\r
}\r
\r
long winerror = np.Parse(winerrorText);\r
if (np.Error)\r
{\r
- serviceOutput.WriteLine(String.Format("{0} is not a valid System Error Code value.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("{0} is not a valid System Error Code value.",\r
winerrorText));\r
return;\r
}\r
string description = GetWinerrorDescription(winerror);\r
if (description != null)\r
{\r
- serviceOutput.WriteLine(String.Format("{0} is {1}.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("{0} is {1}.",\r
winerrorText,\r
description));\r
}\r
else\r
{\r
- serviceOutput.WriteLine(String.Format("I don't know about System Error Code {0}.",\r
+ serviceOutput.WriteLine(context,\r
+ String.Format("I don't know about System Error Code {0}.",\r
winerrorText));\r
}\r
}\r
<appSettings>\r
<add key="IRCServerHostName" value="irc.eu.freenode.net" />\r
<add key="IRCServerHostPort" value="6667" />\r
- <add key="IRCChannelName" value="channel" />\r
+ <add key="IRCChannelNames" value="channel1;channel2" />\r
<add key="IRCBotName" value="MyBot" />\r
<add key="ChmPath" value="C:\IRC\TechBot\CHM" />\r
<add key="MainChm" value="kmarch.chm" />\r
{\r
private string IRCServerHostName;\r
private int IRCServerHostPort;\r
- private string IRCChannelName;\r
+ private string IRCChannelNames;\r
private string IRCBotName;\r
private string ChmPath;\r
private string MainChm;\r
{\r
IRCServerHostName = ConfigurationSettings.AppSettings["IRCServerHostName"];\r
IRCServerHostPort = Int32.Parse(ConfigurationSettings.AppSettings["IRCServerHostPort"]);\r
- IRCChannelName = ConfigurationSettings.AppSettings["IRCChannelName"];\r
+ IRCChannelNames = ConfigurationSettings.AppSettings["IRCChannelNames"];\r
IRCBotName = ConfigurationSettings.AppSettings["IRCBotName"];\r
ChmPath = ConfigurationSettings.AppSettings["ChmPath"];\r
MainChm = ConfigurationSettings.AppSettings["MainChm"];\r
\r
IrcService ircService = new IrcService(IRCServerHostName,\r
IRCServerHostPort,\r
- IRCChannelName,\r
+ IRCChannelNames,\r
IRCBotName,\r
ChmPath,\r
MainChm,\r