diff --git a/ChatSharp/Events/PrivateMessageEventArgs.cs b/ChatSharp/Events/PrivateMessageEventArgs.cs index d7075fc..a5d0aac 100644 --- a/ChatSharp/Events/PrivateMessageEventArgs.cs +++ b/ChatSharp/Events/PrivateMessageEventArgs.cs @@ -7,10 +7,10 @@ namespace ChatSharp.Events public IrcMessage IrcMessage { get; set; } public PrivateMessage PrivateMessage { get; set; } - public PrivateMessageEventArgs(IrcMessage ircMessage, ServerInfo serverInfo) + public PrivateMessageEventArgs(IrcClient client, IrcMessage ircMessage, ServerInfo serverInfo) { IrcMessage = ircMessage; - PrivateMessage = new PrivateMessage(IrcMessage, serverInfo); + PrivateMessage = new PrivateMessage(client, IrcMessage, serverInfo); } } } diff --git a/ChatSharp/Handlers/ChannelHandlers.cs b/ChatSharp/Handlers/ChannelHandlers.cs index 7343091..1f4eb06 100644 --- a/ChatSharp/Handlers/ChannelHandlers.cs +++ b/ChatSharp/Handlers/ChannelHandlers.cs @@ -60,15 +60,19 @@ namespace ChatSharp.Handlers { var user = client.Users.GetOrAdd(nick); user.Channels.Add(channel); + if (!user.ChannelModes.ContainsKey(channel)) + user.ChannelModes.Add(channel, null); + else + user.ChannelModes[channel] = null; } else { var user = client.Users.GetOrAdd(nick.Substring(1)); user.Channels.Add(channel); - // TODO: User modes - /*if (!channel.UsersByMode.ContainsKey(mode.Value)) - channel.UsersByMode.Add(mode.Value, new UserCollection()); - channel.UsersByMode[mode.Value].Add(new IrcUser(nick.Substring(1)));*/ + if (!user.ChannelModes.ContainsKey(channel)) + user.ChannelModes.Add(channel, mode.Value); + else + user.ChannelModes[channel] = mode.Value; } } } @@ -109,13 +113,8 @@ namespace ChatSharp.Handlers { var channel = client.Channels[message.Parameters[0]]; var kicked = channel.Users[message.Parameters[1]]; - if (string.Equals(message.Parameters[1], client.User.Nick, StringComparison.OrdinalIgnoreCase)) // We've been kicked - client.Channels.Remove(client.Channels[message.Parameters[0]]); - else - { - if (kicked.Channels.Contains(channel)) - kicked.Channels.Remove(channel); - } + if (kicked.Channels.Contains(channel)) + kicked.Channels.Remove(channel); client.OnUserKicked(new KickEventArgs(channel, new IrcUser(message.Prefix), kicked, message.Parameters[2])); } diff --git a/ChatSharp/Handlers/ListingHandlers.cs b/ChatSharp/Handlers/ListingHandlers.cs index f5f1fb3..fc1d85c 100644 --- a/ChatSharp/Handlers/ListingHandlers.cs +++ b/ChatSharp/Handlers/ListingHandlers.cs @@ -8,7 +8,8 @@ namespace ChatSharp.Handlers var parameters = parameterString.Substring(parameterString.IndexOf(' ')).Split(' '); var request = client.RequestManager.PeekOperation("GETMODE b " + parameters[1]); var list = (MaskCollection)request.State; - list.Add(new Mask(parameters[2], new IrcUser(parameters[3]), IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); + list.Add(new Mask(parameters[2], client.Users.GetOrAdd(parameters[3]), + IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); } public static void HandleBanListEnd(IrcClient client, IrcMessage message) @@ -24,7 +25,8 @@ namespace ChatSharp.Handlers var parameters = parameterString.Substring(parameterString.IndexOf(' ') + 1).Split(' '); var request = client.RequestManager.PeekOperation("GETMODE e " + parameters[1]); var list = (MaskCollection)request.State; - list.Add(new Mask(parameters[2], new IrcUser(parameters[3]), IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); + list.Add(new Mask(parameters[2], client.Users.GetOrAdd(parameters[3]), + IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); } public static void HandleExceptionListEnd(IrcClient client, IrcMessage message) @@ -40,7 +42,8 @@ namespace ChatSharp.Handlers var parameters = parameterString.Substring(parameterString.IndexOf(' ') + 1).Split(' '); var request = client.RequestManager.PeekOperation("GETMODE I " + parameters[1]); var list = (MaskCollection)request.State; - list.Add(new Mask(parameters[2], new IrcUser(parameters[3]), IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); + list.Add(new Mask(parameters[2], client.Users.GetOrAdd(parameters[3]), + IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); } public static void HandleInviteListEnd(IrcClient client, IrcMessage message) @@ -56,7 +59,8 @@ namespace ChatSharp.Handlers var parameters = parameterString.Substring(parameterString.IndexOf(' ') + 1).Split(' '); var request = client.RequestManager.PeekOperation("GETMODE q " + parameters[1]); var list = (MaskCollection)request.State; - list.Add(new Mask(parameters[2], new IrcUser(parameters[3]), IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); + list.Add(new Mask(parameters[2], client.Users.GetOrAdd(parameters[3]), + IrcClient.DateTimeFromIrcTime(int.Parse(parameters[4])))); } public static void HandleQuietListEnd(IrcClient client, IrcMessage message) diff --git a/ChatSharp/Handlers/MessageHandlers.cs b/ChatSharp/Handlers/MessageHandlers.cs index 3c94287..fd05ad3 100644 --- a/ChatSharp/Handlers/MessageHandlers.cs +++ b/ChatSharp/Handlers/MessageHandlers.cs @@ -97,22 +97,10 @@ namespace ChatSharp.Handlers public static void HandlePrivmsg(IrcClient client, IrcMessage message) { - var eventArgs = new PrivateMessageEventArgs(message, client.ServerInfo); + var eventArgs = new PrivateMessageEventArgs(client, message, client.ServerInfo); client.OnPrivateMessageRecieved(eventArgs); if (eventArgs.PrivateMessage.IsChannelMessage) - { - try - { - // Populate this user's hostname and user from the message - // TODO: Merge all users from all channels into one list and keep references to which channels they're in - var channel = client.Channels[eventArgs.PrivateMessage.Source]; - var u = channel.Users[eventArgs.PrivateMessage.User.Nick]; - u.Hostname = eventArgs.PrivateMessage.User.Hostname; - u.User = eventArgs.PrivateMessage.User.User; - } - catch { /* silently ignored */ } client.OnChannelMessageRecieved(eventArgs); - } else client.OnUserMessageRecieved(eventArgs); } @@ -167,31 +155,38 @@ namespace ChatSharp.Handlers if (client.ServerInfo.SupportedChannelModes.ParameterizedSettings.Contains(c)) { client.OnModeChanged(new ModeChangeEventArgs(channel.Name, new IrcUser(message.Prefix), - (add ? "+" : "-") + c.ToString() + " " + message.Parameters[i++])); + (add ? "+" : "-") + c + " " + message.Parameters[i++])); } else if (client.ServerInfo.SupportedChannelModes.ChannelLists.Contains(c)) { client.OnModeChanged(new ModeChangeEventArgs(channel.Name, new IrcUser(message.Prefix), - (add ? "+" : "-") + c.ToString() + " " + message.Parameters[i++])); + (add ? "+" : "-") + c + " " + message.Parameters[i++])); } else if (client.ServerInfo.SupportedChannelModes.ChannelUserModes.Contains(c)) { - /* - if (!channel.UsersByMode.ContainsKey(c)) channel.UsersByMode.Add(c, new UserCollection()); + if (!channel.UsersByMode.ContainsKey(c)) + { + channel.UsersByMode.Add(c, + new UserPoolView(channel.Users.Where(u => + { + if (!u.ChannelModes.ContainsKey(channel)) + u.ChannelModes.Add(channel, null); + return u.ChannelModes[channel] == c; + }))); + } var user = new IrcUser(message.Parameters[i]); if (add) { if (!channel.UsersByMode[c].Contains(user.Nick)) - channel.UsersByMode[c].Add(user); + user.ChannelModes[channel] = c; } else { if (channel.UsersByMode[c].Contains(user.Nick)) - channel.UsersByMode[c].Remove(user); + user.ChannelModes[channel] = null; } - */ client.OnModeChanged(new ModeChangeEventArgs(channel.Name, new IrcUser(message.Prefix), - (add ? "+" : "-") + c.ToString() + " " + message.Parameters[i++])); + (add ? "+" : "-") + c + " " + message.Parameters[i++])); } if (client.ServerInfo.SupportedChannelModes.Settings.Contains(c)) { @@ -203,7 +198,7 @@ namespace ChatSharp.Handlers else channel.Mode = channel.Mode.Replace(c.ToString(), string.Empty); client.OnModeChanged(new ModeChangeEventArgs(channel.Name, new IrcUser(message.Prefix), - (add ? "+" : "-") + c.ToString())); + (add ? "+" : "-") + c)); } } } diff --git a/ChatSharp/IrcChannel.cs b/ChatSharp/IrcChannel.cs index d0a9c60..ecc74a6 100644 --- a/ChatSharp/IrcChannel.cs +++ b/ChatSharp/IrcChannel.cs @@ -24,6 +24,7 @@ namespace ChatSharp public string Name { get; internal set; } public string Mode { get; internal set; } public UserPoolView Users { get; private set; } + public Dictionary UsersByMode { get; set; } internal IrcChannel(IrcClient client, string name) { diff --git a/ChatSharp/IrcUser.cs b/ChatSharp/IrcUser.cs index 4d999ec..a1fb303 100644 --- a/ChatSharp/IrcUser.cs +++ b/ChatSharp/IrcUser.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Collections.Generic; namespace ChatSharp { @@ -56,6 +57,8 @@ namespace ChatSharp public string Hostname { get; internal set; } public ChannelCollection Channels { get; set; } + internal Dictionary ChannelModes { get; set; } + public string Hostmask { get @@ -128,10 +131,4 @@ namespace ChatSharp return Hostmask; } } - - internal class UserChannel - { - public string Modes { get; set; } - public IrcChannel Channel { get; set; } - } } diff --git a/ChatSharp/PrivateMessage.cs b/ChatSharp/PrivateMessage.cs index 1e28106..a844493 100644 --- a/ChatSharp/PrivateMessage.cs +++ b/ChatSharp/PrivateMessage.cs @@ -4,12 +4,12 @@ namespace ChatSharp { public class PrivateMessage { - public PrivateMessage(IrcMessage message, ServerInfo serverInfo) + public PrivateMessage(IrcClient client, IrcMessage message, ServerInfo serverInfo) { Source = message.Parameters[0]; Message = message.Parameters[1]; - User = new IrcUser(message.Prefix); + User = client.Users.GetOrAdd(message.Prefix); if (serverInfo.ChannelTypes.Any(c => Source.StartsWith(c.ToString()))) IsChannelMessage = true; else diff --git a/ChatSharp/UserPool.cs b/ChatSharp/UserPool.cs index 2989712..aec638e 100644 --- a/ChatSharp/UserPool.cs +++ b/ChatSharp/UserPool.cs @@ -61,7 +61,14 @@ namespace ChatSharp { var user = new IrcUser(prefix); if (Contains(user.Nick)) - return this[user.Nick]; + { + var ret = this[user.Nick]; + if (string.IsNullOrEmpty(ret.User) && !string.IsNullOrEmpty(user.User)) + ret.User = user.User; + if (string.IsNullOrEmpty(ret.Hostname) && !string.IsNullOrEmpty(user.Hostname)) + ret.Hostname = user.Hostname; + return ret; + } Add(user); return user; } diff --git a/ChatSharp/UserPoolView.cs b/ChatSharp/UserPoolView.cs index 7e35e7e..8b93da0 100644 --- a/ChatSharp/UserPoolView.cs +++ b/ChatSharp/UserPoolView.cs @@ -4,7 +4,7 @@ using System.Linq; namespace ChatSharp { - public class UserPoolView + public class UserPoolView : IEnumerable { private UserPool Pool { get; set; } private IEnumerable Users { get; set; } @@ -47,6 +47,16 @@ namespace ChatSharp { return Users.Any(u => u.Hostmask == user.Hostmask); } + + public IEnumerator GetEnumerator() + { + return Users.GetEnumerator(); + } + + System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() + { + return this.GetEnumerator(); + } } }