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; + } + } }