mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 07:02:56 +00:00
Import TechBot
svn path=/trunk/; revision=13064
This commit is contained in:
parent
568b27baeb
commit
9dab4509fa
94 changed files with 24386 additions and 0 deletions
319
irc/TechBot/TechBot.Library/ApiCommand.cs
Normal file
319
irc/TechBot/TechBot.Library/ApiCommand.cs
Normal file
|
@ -0,0 +1,319 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using System.Data;
|
||||
using System.Text.RegularExpressions;
|
||||
using HtmlHelp;
|
||||
using HtmlHelp.ChmDecoding;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class ApiCommand : BaseCommand, ICommand
|
||||
{
|
||||
private const bool IsVerbose = false;
|
||||
|
||||
private HtmlHelpSystem chm;
|
||||
private IServiceOutput serviceOutput;
|
||||
private string chmPath;
|
||||
private string mainChm;
|
||||
|
||||
public ApiCommand(IServiceOutput serviceOutput,
|
||||
string chmPath,
|
||||
string mainChm)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.chmPath = chmPath;
|
||||
this.mainChm = mainChm;
|
||||
Run();
|
||||
}
|
||||
|
||||
private void WriteIfVerbose(string message)
|
||||
{
|
||||
if (IsVerbose)
|
||||
serviceOutput.WriteLine(message);
|
||||
}
|
||||
|
||||
private void Run()
|
||||
{
|
||||
string CHMFilename = Path.Combine(chmPath, mainChm);
|
||||
chm = new HtmlHelpSystem();
|
||||
chm.OpenFile(CHMFilename, null);
|
||||
|
||||
Console.WriteLine(String.Format("Loaded main CHM: {0}",
|
||||
Path.GetFileName(CHMFilename)));
|
||||
foreach (string filename in Directory.GetFiles(chmPath))
|
||||
{
|
||||
if (!Path.GetExtension(filename).ToLower().Equals(".chm"))
|
||||
continue;
|
||||
if (Path.GetFileName(filename).ToLower().Equals(mainChm))
|
||||
continue;
|
||||
|
||||
Console.WriteLine(String.Format("Loading CHM: {0}",
|
||||
Path.GetFileName(filename)));
|
||||
try
|
||||
{
|
||||
chm.MergeFile(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format("Could not load CHM: {0}. Exception {1}",
|
||||
Path.GetFileName(filename),
|
||||
ex));
|
||||
}
|
||||
}
|
||||
Console.WriteLine(String.Format("Loaded {0} CHMs",
|
||||
chm.FileList.Length));
|
||||
}
|
||||
|
||||
public bool CanHandle(string commandName)
|
||||
{
|
||||
return CanHandle(commandName,
|
||||
new string[] { "api" });
|
||||
}
|
||||
|
||||
public void Handle(string commandName,
|
||||
string parameters)
|
||||
{
|
||||
if (parameters.Trim().Equals(String.Empty))
|
||||
DisplayNoKeyword();
|
||||
else
|
||||
Search(parameters);
|
||||
}
|
||||
|
||||
public string Help()
|
||||
{
|
||||
return "!api <apiname>";
|
||||
}
|
||||
|
||||
private bool SearchIndex(string keyword)
|
||||
{
|
||||
if (chm.HasIndex)
|
||||
{
|
||||
IndexItem item = chm.Index.SearchIndex(keyword,
|
||||
IndexType.KeywordLinks);
|
||||
if (item != null && item.Topics.Count > 0)
|
||||
{
|
||||
WriteIfVerbose(String.Format("Keyword {0} found in index",
|
||||
item.KeyWord));
|
||||
IndexTopic indexTopic = item.Topics[0] as IndexTopic;
|
||||
return DisplayResult(keyword, indexTopic);
|
||||
}
|
||||
else
|
||||
{
|
||||
WriteIfVerbose(String.Format("Keyword {0} not found in index",
|
||||
keyword));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
private void SearchFullText(string keyword)
|
||||
{
|
||||
string sort = "Rating ASC";
|
||||
/*
|
||||
sort = "Location ASC");
|
||||
sort = "Title ASC");
|
||||
*/
|
||||
WriteIfVerbose(String.Format("Searching fulltext database for {0}",
|
||||
keyword));
|
||||
|
||||
bool partialMatches = false;
|
||||
bool titlesOnly = true;
|
||||
int maxResults = 100;
|
||||
DataTable results = chm.PerformSearch(keyword,
|
||||
maxResults,
|
||||
partialMatches,
|
||||
titlesOnly);
|
||||
WriteIfVerbose(String.Format("results.Rows.Count = {0}",
|
||||
results != null ?
|
||||
results.Rows.Count.ToString() : "(none)"));
|
||||
if (results != null && results.Rows.Count > 0)
|
||||
{
|
||||
results.DefaultView.Sort = sort;
|
||||
if (!DisplayResult(keyword, results))
|
||||
{
|
||||
DisplayNoResult(keyword);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DisplayNoResult(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
private void Search(string keyword)
|
||||
{
|
||||
if (!SearchIndex(keyword))
|
||||
{
|
||||
SearchFullText(keyword);
|
||||
}
|
||||
}
|
||||
|
||||
private bool DisplayResult(string keyword,
|
||||
IndexTopic indexTopic)
|
||||
{
|
||||
keyword = keyword.Trim().ToLower();
|
||||
string url = indexTopic.URL;
|
||||
WriteIfVerbose(String.Format("URL from index search {0}",
|
||||
url));
|
||||
string prototype = ExtractPrototype(url);
|
||||
if (prototype == null || prototype.Trim().Equals(String.Empty))
|
||||
return false;
|
||||
string formattedPrototype = FormatPrototype(prototype);
|
||||
serviceOutput.WriteLine(formattedPrototype);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DisplayResult(string keyword,
|
||||
DataTable results)
|
||||
{
|
||||
keyword = keyword.Trim().ToLower();
|
||||
for (int i = 0; i < results.DefaultView.Count; i++)
|
||||
{
|
||||
DataRowView row = results.DefaultView[i];
|
||||
string title = row["Title"].ToString();
|
||||
WriteIfVerbose(String.Format("Examining {0}", title));
|
||||
if (title.Trim().ToLower().Equals(keyword))
|
||||
{
|
||||
string location = row["Location"].ToString();
|
||||
string rating = row["Rating"].ToString();
|
||||
string url = row["Url"].ToString();
|
||||
string prototype = ExtractPrototype(url);
|
||||
if (prototype == null || prototype.Trim().Equals(String.Empty))
|
||||
continue;
|
||||
string formattedPrototype = FormatPrototype(prototype);
|
||||
serviceOutput.WriteLine(formattedPrototype);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DisplayNoResult(string keyword)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("I don't know about keyword {0}", keyword));
|
||||
}
|
||||
|
||||
private void DisplayNoKeyword()
|
||||
{
|
||||
serviceOutput.WriteLine("Please give me a keyword.");
|
||||
}
|
||||
|
||||
private string ReplaceComments(string s)
|
||||
{
|
||||
return Regex.Replace(s, "//(.+)\r\n", "");
|
||||
}
|
||||
|
||||
private string ReplaceLineEndings(string s)
|
||||
{
|
||||
return Regex.Replace(s, "(\r\n)+", " ");
|
||||
}
|
||||
|
||||
private string ReplaceSpaces(string s)
|
||||
{
|
||||
return Regex.Replace(s, @" +", " ");
|
||||
}
|
||||
|
||||
private string ReplaceSpacesBeforeLeftParenthesis(string s)
|
||||
{
|
||||
return Regex.Replace(s, @"\( ", @"(");
|
||||
}
|
||||
|
||||
private string ReplaceSpacesBeforeRightParenthesis(string s)
|
||||
{
|
||||
return Regex.Replace(s, @" \)", @")");
|
||||
}
|
||||
|
||||
private string ReplaceSemicolon(string s)
|
||||
{
|
||||
return Regex.Replace(s, @";", @"");
|
||||
}
|
||||
|
||||
private string FormatPrototype(string prototype)
|
||||
{
|
||||
string s = ReplaceComments(prototype);
|
||||
s = ReplaceLineEndings(s);
|
||||
s = ReplaceSpaces(s);
|
||||
s = ReplaceSpacesBeforeLeftParenthesis(s);
|
||||
s = ReplaceSpacesBeforeRightParenthesis(s);
|
||||
s = ReplaceSemicolon(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
private string ExtractPrototype(string url)
|
||||
{
|
||||
string page = GetPage(url);
|
||||
Match match = Regex.Match(page,
|
||||
"<PRE class=\"?syntax\"?>(.+)</PRE>",
|
||||
RegexOptions.Multiline |
|
||||
RegexOptions.Singleline);
|
||||
if (match.Groups.Count > 1)
|
||||
{
|
||||
string prototype = match.Groups[1].ToString();
|
||||
return StripHtml(StripAfterSlashPre(prototype));
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
private string StripAfterSlashPre(string html)
|
||||
{
|
||||
int index = html.IndexOf("</PRE>");
|
||||
if (index != -1)
|
||||
{
|
||||
return html.Substring(0, index);
|
||||
}
|
||||
else
|
||||
return html;
|
||||
}
|
||||
|
||||
private string StripHtml(string html)
|
||||
{
|
||||
return Regex.Replace(html, @"<(.|\n)*?>", String.Empty);
|
||||
}
|
||||
|
||||
private string GetPage(string url)
|
||||
{
|
||||
string CHMFileName = "";
|
||||
string topicName = "";
|
||||
string anchor = "";
|
||||
CHMStream.CHMStream baseStream;
|
||||
if (!chm.BaseStream.GetCHMParts(url, ref CHMFileName, ref topicName, ref anchor))
|
||||
{
|
||||
baseStream = chm.BaseStream;
|
||||
CHMFileName = baseStream.CHMFileName;
|
||||
topicName = url;
|
||||
anchor = "";
|
||||
}
|
||||
else
|
||||
{
|
||||
baseStream = GetBaseStreamFromCHMFileName(CHMFileName);
|
||||
}
|
||||
|
||||
if ((topicName == "") || (CHMFileName == "") || (baseStream == null))
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
return baseStream.ExtractTextFile(topicName);
|
||||
}
|
||||
|
||||
private CHMStream.CHMStream GetBaseStreamFromCHMFileName(string CHMFileName)
|
||||
{
|
||||
foreach (CHMFile file in chm.FileList)
|
||||
{
|
||||
WriteIfVerbose(String.Format("Compare: {0} <> {1}",
|
||||
file.ChmFilePath,
|
||||
CHMFileName));
|
||||
if (file.ChmFilePath.ToLower().Equals(CHMFileName.ToLower()))
|
||||
{
|
||||
return file.BaseStream;
|
||||
}
|
||||
}
|
||||
WriteIfVerbose(String.Format("Could not find loaded CHM file in list: {0}",
|
||||
CHMFileName));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
32
irc/TechBot/TechBot.Library/AssemblyInfo.cs
Normal file
32
irc/TechBot/TechBot.Library/AssemblyInfo.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
// Information about this assembly is defined by the following
|
||||
// attributes.
|
||||
//
|
||||
// change them to the information which is associated with the assembly
|
||||
// you compile.
|
||||
|
||||
[assembly: AssemblyTitle("")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("")]
|
||||
[assembly: AssemblyCopyright("")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// The assembly version has following format :
|
||||
//
|
||||
// Major.Minor.Build.Revision
|
||||
//
|
||||
// You can specify all values by your own or you can build default build and revision
|
||||
// numbers with the '*' character (the default):
|
||||
|
||||
[assembly: AssemblyVersion("1.0.*")]
|
||||
|
||||
// The following attributes specify the key for the sign of your assembly. See the
|
||||
// .NET Framework documentation for more information about signing.
|
||||
// This is not required, if you don't want signing let these attributes like they're.
|
||||
[assembly: AssemblyDelaySign(false)]
|
||||
[assembly: AssemblyKeyFile("")]
|
24
irc/TechBot/TechBot.Library/Default.build
Normal file
24
irc/TechBot/TechBot.Library/Default.build
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<project name="TechBot.Library" default="build">
|
||||
|
||||
<property name="output.dir" value="..\bin" />
|
||||
|
||||
<target name="build" description="Build component">
|
||||
<mkdir dir="${output.dir}" />
|
||||
<csc target="library"
|
||||
output="${output.dir}\TechBot.Library.dll"
|
||||
optimize="true"
|
||||
debug="true"
|
||||
doc="${output.dir}\TechBot.Library.xml"
|
||||
warninglevel="0">
|
||||
<sources>
|
||||
<include name="*.cs" />
|
||||
</sources>
|
||||
<references>
|
||||
<include name="${output.dir}\CHMLibrary.dll" />
|
||||
<include name="${output.dir}\TechBot.IRCLibrary.dll" />
|
||||
</references>
|
||||
</csc>
|
||||
</target>
|
||||
|
||||
</project>
|
37
irc/TechBot/TechBot.Library/HelpCommand.cs
Normal file
37
irc/TechBot/TechBot.Library/HelpCommand.cs
Normal file
|
@ -0,0 +1,37 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class HelpCommand : BaseCommand, ICommand
|
||||
{
|
||||
private IServiceOutput serviceOutput;
|
||||
private ArrayList commands;
|
||||
|
||||
public HelpCommand(IServiceOutput serviceOutput,
|
||||
ArrayList commands)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.commands = commands;
|
||||
}
|
||||
|
||||
public bool CanHandle(string commandName)
|
||||
{
|
||||
return CanHandle(commandName,
|
||||
new string[] { "help" });
|
||||
}
|
||||
|
||||
public void Handle(string commandName,
|
||||
string parameters)
|
||||
{
|
||||
serviceOutput.WriteLine("I support the following commands:");
|
||||
foreach (ICommand command in commands)
|
||||
serviceOutput.WriteLine(command.Help());
|
||||
}
|
||||
|
||||
public string Help()
|
||||
{
|
||||
return "!help";
|
||||
}
|
||||
}
|
||||
}
|
81
irc/TechBot/TechBot.Library/HresultCommand.cs
Normal file
81
irc/TechBot/TechBot.Library/HresultCommand.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class HresultCommand : BaseCommand, ICommand
|
||||
{
|
||||
private IServiceOutput serviceOutput;
|
||||
private string hresultXml;
|
||||
private XmlDocument hresultXmlDocument;
|
||||
|
||||
public HresultCommand(IServiceOutput serviceOutput,
|
||||
string hresultXml)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.hresultXml = hresultXml;
|
||||
hresultXmlDocument = new XmlDocument();
|
||||
hresultXmlDocument.Load(hresultXml);
|
||||
}
|
||||
|
||||
public bool CanHandle(string commandName)
|
||||
{
|
||||
return CanHandle(commandName,
|
||||
new string[] { "hresult" });
|
||||
}
|
||||
|
||||
public void Handle(string commandName,
|
||||
string parameters)
|
||||
{
|
||||
string hresultText = parameters;
|
||||
if (hresultText.Equals(String.Empty))
|
||||
{
|
||||
serviceOutput.WriteLine("Please provide a valid HRESULT value.");
|
||||
return;
|
||||
}
|
||||
|
||||
NumberParser np = new NumberParser();
|
||||
long hresult = np.Parse(hresultText);
|
||||
if (np.Error)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("{0} is not a valid HRESULT value.",
|
||||
hresultText));
|
||||
return;
|
||||
}
|
||||
|
||||
string description = GetHresultDescription(hresult);
|
||||
if (description != null)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("{0} is {1}.",
|
||||
hresultText,
|
||||
description));
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("I don't know about HRESULT {0}.",
|
||||
hresultText));
|
||||
}
|
||||
}
|
||||
|
||||
public string Help()
|
||||
{
|
||||
return "!hresult <value>";
|
||||
}
|
||||
|
||||
private string GetHresultDescription(long hresult)
|
||||
{
|
||||
XmlElement root = hresultXmlDocument.DocumentElement;
|
||||
XmlNode node = root.SelectSingleNode(String.Format("Hresult[@value='{0}']",
|
||||
hresult.ToString("X8")));
|
||||
if (node != null)
|
||||
{
|
||||
XmlAttribute text = node.Attributes["text"];
|
||||
if (text == null)
|
||||
throw new Exception("Node has no text attribute.");
|
||||
return text.Value;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
28
irc/TechBot/TechBot.Library/ICommand.cs
Normal file
28
irc/TechBot/TechBot.Library/ICommand.cs
Normal file
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public interface ICommand
|
||||
{
|
||||
bool CanHandle(string commandName);
|
||||
void Handle(string commandName,
|
||||
string parameters);
|
||||
string Help();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class BaseCommand
|
||||
{
|
||||
protected bool CanHandle(string commandName,
|
||||
string[] availableCommands)
|
||||
{
|
||||
foreach (string availableCommand in availableCommands)
|
||||
{
|
||||
if (String.Compare(availableCommand, commandName, true) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
142
irc/TechBot/TechBot.Library/IrcService.cs
Normal file
142
irc/TechBot/TechBot.Library/IrcService.cs
Normal file
|
@ -0,0 +1,142 @@
|
|||
using System;
|
||||
using System.Threading;
|
||||
using TechBot.IRCLibrary;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class IrcService : IServiceOutput
|
||||
{
|
||||
private string hostname;
|
||||
private int port;
|
||||
private string channelname;
|
||||
private string botname;
|
||||
private string chmPath;
|
||||
private string mainChm;
|
||||
private string ntstatusXml;
|
||||
private string winerrorXml;
|
||||
private string hresultXml;
|
||||
private string svnCommand;
|
||||
private IrcClient client;
|
||||
private IrcChannel channel1;
|
||||
private TechBotService service;
|
||||
private bool isStopped = false;
|
||||
|
||||
public IrcService(string hostname,
|
||||
int port,
|
||||
string channelname,
|
||||
string botname,
|
||||
string chmPath,
|
||||
string mainChm,
|
||||
string ntstatusXml,
|
||||
string winerrorXml,
|
||||
string hresultXml,
|
||||
string svnCommand)
|
||||
{
|
||||
this.hostname = hostname;
|
||||
this.port = port;
|
||||
this.channelname = channelname;
|
||||
this.botname = botname;
|
||||
this.chmPath = chmPath;
|
||||
this.mainChm = mainChm;
|
||||
this.ntstatusXml = ntstatusXml;
|
||||
this.winerrorXml = winerrorXml;
|
||||
this.hresultXml = hresultXml;
|
||||
this.svnCommand = svnCommand;
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
service = new TechBotService(this,
|
||||
chmPath,
|
||||
mainChm,
|
||||
ntstatusXml,
|
||||
winerrorXml,
|
||||
hresultXml,
|
||||
svnCommand);
|
||||
service.Run();
|
||||
|
||||
client = new IrcClient();
|
||||
client.Encoding = System.Text.Encoding.GetEncoding("iso-8859-1");
|
||||
client.MessageReceived += new MessageReceivedHandler(client_MessageReceived);
|
||||
client.ChannelUserDatabaseChanged += new ChannelUserDatabaseChangedHandler(client_ChannelUserDatabaseChanged);
|
||||
System.Console.WriteLine(String.Format("Connecting to {0} port {1}",
|
||||
hostname, port));
|
||||
client.Connect(hostname, port);
|
||||
System.Console.WriteLine("Connected...");
|
||||
client.Register(botname, null);
|
||||
System.Console.WriteLine(String.Format("Registered as {0}...", botname));
|
||||
channel1 = client.JoinChannel(channelname);
|
||||
System.Console.WriteLine(String.Format("Joined channel {0}...", channelname));
|
||||
|
||||
while (!isStopped)
|
||||
{
|
||||
Thread.Sleep(1000);
|
||||
}
|
||||
|
||||
client.PartChannel(channel1, "Caught in the bitstream...");
|
||||
client.Diconnect();
|
||||
System.Console.WriteLine("Disconnected...");
|
||||
}
|
||||
|
||||
public void Stop()
|
||||
{
|
||||
isStopped = true;
|
||||
}
|
||||
|
||||
public void WriteLine(string message)
|
||||
{
|
||||
Console.WriteLine(String.Format("Sending: {0}", message));
|
||||
channel1.Talk(message);
|
||||
}
|
||||
|
||||
private void ExtractMessage(string parameters,
|
||||
out string message)
|
||||
{
|
||||
int startIndex = parameters.IndexOf(':');
|
||||
if (startIndex != -1)
|
||||
{
|
||||
message = parameters.Substring(startIndex + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
message = parameters;
|
||||
}
|
||||
}
|
||||
|
||||
private void client_MessageReceived(IrcMessage message)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (channel1 != null &&
|
||||
channel1.Name != null &&
|
||||
message.Parameters != null)
|
||||
{
|
||||
string injectMessage;
|
||||
ExtractMessage(message.Parameters, out injectMessage);
|
||||
if ((message.Command.ToUpper().Equals("PRIVMSG")) &&
|
||||
(message.Parameters.ToLower().StartsWith("#" + channel1.Name.ToLower() + " ")))
|
||||
{
|
||||
Console.WriteLine("Injecting: " + injectMessage);
|
||||
service.InjectMessage(injectMessage);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Received: " + message.Line);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Received: " + message.Line);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(String.Format("Exception: {0}", ex));
|
||||
}
|
||||
}
|
||||
|
||||
private void client_ChannelUserDatabaseChanged(IrcChannel channel)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
81
irc/TechBot/TechBot.Library/NtStatusCommand.cs
Normal file
81
irc/TechBot/TechBot.Library/NtStatusCommand.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class NtStatusCommand : BaseCommand, ICommand
|
||||
{
|
||||
private IServiceOutput serviceOutput;
|
||||
private string ntstatusXml;
|
||||
private XmlDocument ntstatusXmlDocument;
|
||||
|
||||
public NtStatusCommand(IServiceOutput serviceOutput,
|
||||
string ntstatusXml)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.ntstatusXml = ntstatusXml;
|
||||
ntstatusXmlDocument = new XmlDocument();
|
||||
ntstatusXmlDocument.Load(ntstatusXml);
|
||||
}
|
||||
|
||||
public bool CanHandle(string commandName)
|
||||
{
|
||||
return CanHandle(commandName,
|
||||
new string[] { "ntstatus" });
|
||||
}
|
||||
|
||||
public void Handle(string commandName,
|
||||
string parameters)
|
||||
{
|
||||
string ntstatusText = parameters;
|
||||
if (ntstatusText.Equals(String.Empty))
|
||||
{
|
||||
serviceOutput.WriteLine("Please provide a valid NTSTATUS value.");
|
||||
return;
|
||||
}
|
||||
|
||||
NumberParser np = new NumberParser();
|
||||
long ntstatus = np.Parse(ntstatusText);
|
||||
if (np.Error)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("{0} is not a valid NTSTATUS value.",
|
||||
ntstatusText));
|
||||
return;
|
||||
}
|
||||
|
||||
string description = GetNtstatusDescription(ntstatus);
|
||||
if (description != null)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("{0} is {1}.",
|
||||
ntstatusText,
|
||||
description));
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("I don't know about NTSTATUS {0}.",
|
||||
ntstatusText));
|
||||
}
|
||||
}
|
||||
|
||||
public string Help()
|
||||
{
|
||||
return "!ntstatus <value>";
|
||||
}
|
||||
|
||||
private string GetNtstatusDescription(long ntstatus)
|
||||
{
|
||||
XmlElement root = ntstatusXmlDocument.DocumentElement;
|
||||
XmlNode node = root.SelectSingleNode(String.Format("Ntstatus[@value='{0}']",
|
||||
ntstatus.ToString("X8")));
|
||||
if (node != null)
|
||||
{
|
||||
XmlAttribute text = node.Attributes["text"];
|
||||
if (text == null)
|
||||
throw new Exception("Node has no text attribute.");
|
||||
return text.Value;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
32
irc/TechBot/TechBot.Library/NumberParser.cs
Normal file
32
irc/TechBot/TechBot.Library/NumberParser.cs
Normal file
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class NumberParser
|
||||
{
|
||||
public bool Error = false;
|
||||
|
||||
public long Parse(string s)
|
||||
{
|
||||
try
|
||||
{
|
||||
Error = false;
|
||||
if (s.StartsWith("0x"))
|
||||
return Int64.Parse(s.Substring(2),
|
||||
NumberStyles.HexNumber);
|
||||
else
|
||||
return Int64.Parse(s);
|
||||
}
|
||||
catch (FormatException)
|
||||
{
|
||||
Error = true;
|
||||
}
|
||||
catch (OverflowException)
|
||||
{
|
||||
Error = true;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
9
irc/TechBot/TechBot.Library/ServiceOutput.cs
Normal file
9
irc/TechBot/TechBot.Library/ServiceOutput.cs
Normal file
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public interface IServiceOutput
|
||||
{
|
||||
void WriteLine(string message);
|
||||
}
|
||||
}
|
34
irc/TechBot/TechBot.Library/SvnCommand.cs
Normal file
34
irc/TechBot/TechBot.Library/SvnCommand.cs
Normal file
|
@ -0,0 +1,34 @@
|
|||
using System;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class SvnCommand : BaseCommand, ICommand
|
||||
{
|
||||
private IServiceOutput serviceOutput;
|
||||
private string svnCommand;
|
||||
|
||||
public SvnCommand(IServiceOutput serviceOutput,
|
||||
string svnCommand)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.svnCommand = svnCommand;
|
||||
}
|
||||
|
||||
public bool CanHandle(string commandName)
|
||||
{
|
||||
return CanHandle(commandName,
|
||||
new string[] { "svn" });
|
||||
}
|
||||
|
||||
public void Handle(string commandName,
|
||||
string parameters)
|
||||
{
|
||||
serviceOutput.WriteLine(svnCommand);
|
||||
}
|
||||
|
||||
public string Help()
|
||||
{
|
||||
return "!svn";
|
||||
}
|
||||
}
|
||||
}
|
16
irc/TechBot/TechBot.Library/TechBot.Library.cmbx
Normal file
16
irc/TechBot/TechBot.Library/TechBot.Library.cmbx
Normal file
|
@ -0,0 +1,16 @@
|
|||
<Combine fileversion="1.0" name="TechBot.Library" description="">
|
||||
<StartMode startupentry="TechBot.Library" single="True">
|
||||
<Execute entry="TechBot.Library" type="None" />
|
||||
</StartMode>
|
||||
<Entries>
|
||||
<Entry filename=".\.\TechBot.Library.prjx" />
|
||||
</Entries>
|
||||
<Configurations active="Debug">
|
||||
<Configuration name="Release">
|
||||
<Entry name="TechBot.Library" configurationname="Debug" build="False" />
|
||||
</Configuration>
|
||||
<Configuration name="Debug">
|
||||
<Entry name="TechBot.Library" configurationname="Debug" build="False" />
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</Combine>
|
39
irc/TechBot/TechBot.Library/TechBot.Library.prjx
Normal file
39
irc/TechBot/TechBot.Library/TechBot.Library.prjx
Normal file
|
@ -0,0 +1,39 @@
|
|||
<Project name="TechBot.Library" standardNamespace="TechBot.Library" description="" newfilesearch="None" enableviewstate="True" version="1.1" projecttype="C#">
|
||||
<Contents>
|
||||
<File name=".\AssemblyInfo.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\Default.build" subtype="Code" buildaction="Nothing" dependson="" data="" />
|
||||
<File name=".\TechBotService.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\ServiceOutput.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\IrcService.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\ApiCommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\ICommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\HelpCommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\NtStatusCommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\NumberParser.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\HresultCommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\WinerrorCommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
<File name=".\SvnCommand.cs" subtype="Code" buildaction="Compile" dependson="" data="" />
|
||||
</Contents>
|
||||
<References>
|
||||
<Reference type="Project" refto="CHMLibrary" localcopy="True" />
|
||||
<Reference type="Project" refto="TechBot.IRCLibrary" localcopy="True" />
|
||||
</References>
|
||||
<DeploymentInformation target="" script="" strategy="File" />
|
||||
<Configuration runwithwarnings="True" name="Debug">
|
||||
<CodeGeneration runtime="MsNet" compiler="Csc" compilerversion="" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" noconfig="False" nostdlib="False" />
|
||||
<Execution commandlineparameters="" consolepause="False" />
|
||||
<Output directory="..\bin\Debug" assembly="TechBot.Library" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||
</Configuration>
|
||||
<Configurations active="Debug">
|
||||
<Configuration runwithwarnings="True" name="Debug">
|
||||
<CodeGeneration runtime="MsNet" compiler="Csc" compilerversion="" warninglevel="4" nowarn="" includedebuginformation="True" optimize="False" unsafecodeallowed="False" generateoverflowchecks="True" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" noconfig="False" nostdlib="False" />
|
||||
<Execution commandlineparameters="" consolepause="False" />
|
||||
<Output directory="..\bin\Debug" assembly="TechBot.Library" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||
</Configuration>
|
||||
<Configuration runwithwarnings="True" name="Release">
|
||||
<CodeGeneration runtime="MsNet" compiler="Csc" compilerversion="" warninglevel="4" nowarn="" includedebuginformation="False" optimize="True" unsafecodeallowed="False" generateoverflowchecks="False" mainclass="" target="Library" definesymbols="" generatexmldocumentation="False" win32Icon="" noconfig="False" nostdlib="False" />
|
||||
<Execution commandlineparameters="" consolepause="False" />
|
||||
<Output directory="..\bin\Release" assembly="TechBot.Library" executeScript="" executeBeforeBuild="" executeAfterBuild="" executeBeforeBuildArguments="" executeAfterBuildArguments="" />
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
</Project>
|
103
irc/TechBot/TechBot.Library/TechBotService.cs
Normal file
103
irc/TechBot/TechBot.Library/TechBotService.cs
Normal file
|
@ -0,0 +1,103 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Data;
|
||||
using System.Threading;
|
||||
using TechBot.IRCLibrary;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class TechBotService
|
||||
{
|
||||
private const bool IsVerbose = false;
|
||||
|
||||
private IServiceOutput serviceOutput;
|
||||
private string chmPath;
|
||||
private string mainChm;
|
||||
private string ntstatusXml;
|
||||
private string winerrorXml;
|
||||
private string hresultXml;
|
||||
private string svnCommand;
|
||||
private ArrayList commands = new ArrayList();
|
||||
|
||||
public TechBotService(IServiceOutput serviceOutput,
|
||||
string chmPath,
|
||||
string mainChm,
|
||||
string ntstatusXml,
|
||||
string winerrorXml,
|
||||
string hresultXml,
|
||||
string svnCommand)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.chmPath = chmPath;
|
||||
this.mainChm = mainChm;
|
||||
this.ntstatusXml = ntstatusXml;
|
||||
this.winerrorXml = winerrorXml;
|
||||
this.hresultXml = hresultXml;
|
||||
this.svnCommand = svnCommand;
|
||||
}
|
||||
|
||||
private void WriteIfVerbose(string message)
|
||||
{
|
||||
if (IsVerbose)
|
||||
serviceOutput.WriteLine(message);
|
||||
}
|
||||
|
||||
public void Run()
|
||||
{
|
||||
commands.Add(new HelpCommand(serviceOutput,
|
||||
commands));
|
||||
commands.Add(new ApiCommand(serviceOutput,
|
||||
chmPath,
|
||||
mainChm));
|
||||
commands.Add(new NtStatusCommand(serviceOutput,
|
||||
ntstatusXml));
|
||||
commands.Add(new WinerrorCommand(serviceOutput,
|
||||
winerrorXml));
|
||||
commands.Add(new HresultCommand(serviceOutput,
|
||||
hresultXml));
|
||||
commands.Add(new SvnCommand(serviceOutput,
|
||||
svnCommand));
|
||||
}
|
||||
|
||||
public void InjectMessage(string message)
|
||||
{
|
||||
if (message.StartsWith("!"))
|
||||
{
|
||||
ParseCommandMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsCommandMessage(string message)
|
||||
{
|
||||
return message.StartsWith("!");
|
||||
}
|
||||
|
||||
public void ParseCommandMessage(string message)
|
||||
{
|
||||
if (!IsCommandMessage(message))
|
||||
return;
|
||||
|
||||
message = message.Substring(1).Trim();
|
||||
int index = message.IndexOf(' ');
|
||||
string commandName;
|
||||
string parameters = "";
|
||||
if (index != -1)
|
||||
{
|
||||
commandName = message.Substring(0, index).Trim();
|
||||
parameters = message.Substring(index).Trim();
|
||||
}
|
||||
else
|
||||
commandName = message.Trim();
|
||||
|
||||
foreach (ICommand command in commands)
|
||||
{
|
||||
if (command.CanHandle(commandName))
|
||||
{
|
||||
command.Handle(commandName, parameters);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
81
irc/TechBot/TechBot.Library/WinerrorCommand.cs
Normal file
81
irc/TechBot/TechBot.Library/WinerrorCommand.cs
Normal file
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Xml;
|
||||
|
||||
namespace TechBot.Library
|
||||
{
|
||||
public class WinerrorCommand : BaseCommand, ICommand
|
||||
{
|
||||
private IServiceOutput serviceOutput;
|
||||
private string winerrorXml;
|
||||
private XmlDocument winerrorXmlDocument;
|
||||
|
||||
public WinerrorCommand(IServiceOutput serviceOutput,
|
||||
string winerrorXml)
|
||||
{
|
||||
this.serviceOutput = serviceOutput;
|
||||
this.winerrorXml = winerrorXml;
|
||||
winerrorXmlDocument = new XmlDocument();
|
||||
winerrorXmlDocument.Load(winerrorXml);
|
||||
}
|
||||
|
||||
public bool CanHandle(string commandName)
|
||||
{
|
||||
return CanHandle(commandName,
|
||||
new string[] { "winerror" });
|
||||
}
|
||||
|
||||
public void Handle(string commandName,
|
||||
string parameters)
|
||||
{
|
||||
string winerrorText = parameters;
|
||||
if (winerrorText.Equals(String.Empty))
|
||||
{
|
||||
serviceOutput.WriteLine("Please provide a valid System Error Code value.");
|
||||
return;
|
||||
}
|
||||
|
||||
NumberParser np = new NumberParser();
|
||||
long winerror = np.Parse(winerrorText);
|
||||
if (np.Error)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("{0} is not a valid System Error Code value.",
|
||||
winerrorText));
|
||||
return;
|
||||
}
|
||||
|
||||
string description = GetWinerrorDescription(winerror);
|
||||
if (description != null)
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("{0} is {1}.",
|
||||
winerrorText,
|
||||
description));
|
||||
}
|
||||
else
|
||||
{
|
||||
serviceOutput.WriteLine(String.Format("I don't know about System Error Code {0}.",
|
||||
winerrorText));
|
||||
}
|
||||
}
|
||||
|
||||
public string Help()
|
||||
{
|
||||
return "!winerror <value>";
|
||||
}
|
||||
|
||||
private string GetWinerrorDescription(long winerror)
|
||||
{
|
||||
XmlElement root = winerrorXmlDocument.DocumentElement;
|
||||
XmlNode node = root.SelectSingleNode(String.Format("Winerror[@value='{0}']",
|
||||
winerror));
|
||||
if (node != null)
|
||||
{
|
||||
XmlAttribute text = node.Attributes["text"];
|
||||
if (text == null)
|
||||
throw new Exception("Node has no text attribute.");
|
||||
return text.Value;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue