diff --git a/irc/TechBot/TechBot.IRCLibrary/IrcChannel.cs b/irc/TechBot/TechBot.IRCLibrary/IrcChannel.cs
index 2f26abbc607..0c16e59b0bd 100644
--- a/irc/TechBot/TechBot.IRCLibrary/IrcChannel.cs
+++ b/irc/TechBot/TechBot.IRCLibrary/IrcChannel.cs
@@ -128,7 +128,10 @@ namespace TechBot.IRCLibrary
/// Text to send to the channel.
public void Talk(string text)
{
- owner.SendMessage(new IrcMessage(IRC.PRIVMSG, String.Format("#{0} :{1}", name, text)));
+ owner.SendMessage(new IrcMessage(IRC.PRIVMSG,
+ String.Format("#{0} :{1}",
+ name,
+ text)));
}
}
}
diff --git a/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs b/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs
index b5c1d4b207e..3590f57aa35 100644
--- a/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs
+++ b/irc/TechBot/TechBot.IRCLibrary/IrcClient.cs
@@ -391,7 +391,8 @@ namespace TechBot.IRCLibrary
IrcUser user = channel.LocateUser(nickname.Substring(1));
if (user == null)
{
- user = new IrcUser(nickname.Substring(1));
+ user = new IrcUser(this,
+ nickname.Substring(1));
channel.Users.Add(user);
}
for (int i = 4; i < parameters.Length; i++)
@@ -400,7 +401,8 @@ namespace TechBot.IRCLibrary
user = channel.LocateUser(nickname);
if (user == null)
{
- user = new IrcUser(nickname);
+ user = new IrcUser(this,
+ nickname);
channel.Users.Add(user);
}
}
@@ -509,7 +511,7 @@ namespace TechBot.IRCLibrary
{
throw new NotConnectedException();
}
-
+
/* Serialize sending messages */
lock (typeof(IrcClient))
{
@@ -545,16 +547,6 @@ namespace TechBot.IRCLibrary
/// Text to send to the channel.
public void TalkTo(string nickname, string text)
{
- if (nickname == null)
- {
- throw new ArgumentNullException("nickname", "Nickname cannot be null.");
- }
- if (text == null)
- {
- throw new ArgumentNullException("text", "Text cannot be null.");
- }
-
- SendMessage(new IrcMessage(IRC.PRIVMSG, String.Format("{0} :{1}", nickname, text)));
}
///
diff --git a/irc/TechBot/TechBot.IRCLibrary/IrcMessage.cs b/irc/TechBot/TechBot.IRCLibrary/IrcMessage.cs
index bab64de3216..14e62fd8fa4 100644
--- a/irc/TechBot/TechBot.IRCLibrary/IrcMessage.cs
+++ b/irc/TechBot/TechBot.IRCLibrary/IrcMessage.cs
@@ -428,7 +428,7 @@ namespace TechBot.IRCLibrary
}
private const string IrcSpecial = @"-[]\`^{}";
- private const string IrcSpecialNonSpecs = @"_";
+ private const string IrcSpecialNonSpecs = @"_|";
///
/// Returns wether a character is an IRC special character.
diff --git a/irc/TechBot/TechBot.IRCLibrary/IrcUser.cs b/irc/TechBot/TechBot.IRCLibrary/IrcUser.cs
index 901d74c92b7..30f0a94db40 100644
--- a/irc/TechBot/TechBot.IRCLibrary/IrcUser.cs
+++ b/irc/TechBot/TechBot.IRCLibrary/IrcUser.cs
@@ -9,6 +9,7 @@ namespace TechBot.IRCLibrary
{
#region Private fields
+ private IrcClient owner;
private string nickname;
private string decoratedNickname;
@@ -16,6 +17,17 @@ namespace TechBot.IRCLibrary
#region Public properties
+ ///
+ /// Owner of this channel.
+ ///
+ public IrcClient Owner
+ {
+ get
+ {
+ return owner;
+ }
+ }
+
///
/// Nickname of user.
///
@@ -65,13 +77,37 @@ namespace TechBot.IRCLibrary
///
/// Constructor.
///
+ /// Owner of this channel.
/// Nickname (possibly decorated) of user.
- public IrcUser(string nickname)
+ public IrcUser(IrcClient owner,
+ string nickname)
{
+ if (owner == null)
+ {
+ throw new ArgumentNullException("owner", "Owner cannot be null.");
+ }
+ this.owner = owner;
this.decoratedNickname = nickname.Trim();
this.nickname = StripDecoration(decoratedNickname);
}
+ ///
+ /// Talk to the user.
+ ///
+ /// Text to send to the user.
+ public void Talk(string text)
+ {
+ if (text == null)
+ {
+ throw new ArgumentNullException("text", "Text cannot be null.");
+ }
+
+ owner.SendMessage(new IrcMessage(IRC.PRIVMSG,
+ String.Format("{0} :{1}",
+ nickname,
+ text)));
+ }
+
///
/// Strip docoration of nickname.
///
diff --git a/irc/TechBot/TechBot.Library/IrcService.cs b/irc/TechBot/TechBot.Library/IrcService.cs
index efb9d60b01c..374c4754ff0 100644
--- a/irc/TechBot/TechBot.Library/IrcService.cs
+++ b/irc/TechBot/TechBot.Library/IrcService.cs
@@ -104,13 +104,44 @@ namespace TechBot.Library
}
}
+ private string GetMessageSource(MessageContext context)
+ {
+ if (context is ChannelMessageContext)
+ {
+ ChannelMessageContext channelContext = context as ChannelMessageContext;
+ return String.Format("#{0}",
+ channelContext.Channel.Name);
+ }
+ else if (context is UserMessageContext)
+ {
+ UserMessageContext userContext = context as UserMessageContext;
+ return userContext.User.Nickname;
+ }
+ else
+ {
+ throw new InvalidOperationException(String.Format("Unhandled message context '{0}'",
+ context.GetType()));
+ }
+ }
+
public void WriteLine(MessageContext context,
string message)
{
- Console.WriteLine(String.Format("Sending: {0} to #{1}",
- message,
- context.Channel != null ? context.Channel.Name : "(null)"));
- context.Channel.Talk(message);
+ if (context is ChannelMessageContext)
+ {
+ ChannelMessageContext channelContext = context as ChannelMessageContext;
+ channelContext.Channel.Talk(message);
+ }
+ else if (context is UserMessageContext)
+ {
+ UserMessageContext userContext = context as UserMessageContext;
+ userContext.User.Talk(message);
+ }
+ else
+ {
+ throw new InvalidOperationException(String.Format("Unhandled message context '{0}'",
+ context.GetType()));
+ }
}
private void ExtractMessage(string parameters,
@@ -139,7 +170,26 @@ namespace TechBot.Library
int index = message.Parameters.IndexOf(' ');
if (index == -1)
index = message.Parameters.Length;
- channelName = message.Parameters.Substring(1, index - 1);
+ else
+ index = index - 1;
+ channelName = message.Parameters.Substring(1, index);
+ return true;
+ }
+
+ private bool GetTargetNickname(IrcMessage message,
+ out string nickname)
+ {
+ if (message.Parameters == null)
+ {
+ nickname = null;
+ return false;
+ }
+
+ int index = message.Parameters.IndexOf(' ');
+ if (index == -1)
+ index = message.Parameters.Length;
+ nickname = message.Parameters.Substring(0, index);
+ Console.WriteLine("nickname: " + nickname);
return true;
}
@@ -149,6 +199,7 @@ namespace TechBot.Library
if (message.Command.ToUpper().Equals("PRIVMSG"))
{
string channelName;
+ string nickname;
if (GetChannelName(message,
out channelName))
{
@@ -156,11 +207,24 @@ namespace TechBot.Library
{
if (String.Compare(channel.Name, channelName, true) == 0)
{
- context = new MessageContext(channel);
+ context = new ChannelMessageContext(channel);
return true;
}
}
}
+ else if (GetTargetNickname(message,
+ out nickname))
+ {
+ IrcUser targetUser = new IrcUser(client,
+ nickname);
+ if (String.Compare(targetUser.Nickname, botname, true) == 0)
+ {
+ IrcUser sourceUser = new IrcUser(client,
+ message.PrefixNickname);
+ context = new UserMessageContext(sourceUser);
+ return true;
+ }
+ }
}
context = null;
return false;
@@ -180,9 +244,9 @@ namespace TechBot.Library
if (ShouldAcceptMessage(message,
out context))
{
- Console.WriteLine(String.Format("Injecting: {0} from #{1}",
+ Console.WriteLine(String.Format("Injecting: {0} from {1}",
injectMessage,
- context.Channel.Name));
+ GetMessageSource(context)));
service.InjectMessage(context,
injectMessage);
}
diff --git a/irc/TechBot/TechBot.Library/MessageContext.cs b/irc/TechBot/TechBot.Library/MessageContext.cs
index dca3925fdad..8d1728a25c1 100644
--- a/irc/TechBot/TechBot.Library/MessageContext.cs
+++ b/irc/TechBot/TechBot.Library/MessageContext.cs
@@ -3,7 +3,13 @@ using TechBot.IRCLibrary;
namespace TechBot.Library
{
- public class MessageContext
+ public abstract class MessageContext
+ {
+ }
+
+
+
+ public class ChannelMessageContext : MessageContext
{
private IrcChannel channel;
@@ -15,9 +21,29 @@ namespace TechBot.Library
}
}
- public MessageContext(IrcChannel channel)
+ public ChannelMessageContext(IrcChannel channel)
{
this.channel = channel;
}
}
+
+
+
+ public class UserMessageContext : MessageContext
+ {
+ private IrcUser user;
+
+ public IrcUser User
+ {
+ get
+ {
+ return user;
+ }
+ }
+
+ public UserMessageContext(IrcUser user)
+ {
+ this.user = user;
+ }
+ }
}