Support IRCv3.1 multi-prefix capability
- This client capability will make the server send us all prefixes a user may have in NAMES and WHO messages. - http://ircv3.net/specs/extensions/multi-prefix-3.1.html
This commit is contained in:
parent
fac0878e00
commit
879580ccde
|
@ -58,31 +58,25 @@ namespace ChatSharp.Handlers
|
|||
{
|
||||
var channel = client.Channels[message.Parameters[2]];
|
||||
var users = message.Parameters[3].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
foreach (var nick in users)
|
||||
foreach (var rawNick in users)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(nick))
|
||||
if (string.IsNullOrWhiteSpace(rawNick))
|
||||
continue;
|
||||
var mode = client.ServerInfo.GetModeForPrefix(nick[0]);
|
||||
if (mode == null)
|
||||
{
|
||||
var user = client.Users.GetOrAdd(nick);
|
||||
if (!user.Channels.Contains(channel))
|
||||
user.Channels.Add(channel);
|
||||
if (!user.ChannelModes.ContainsKey(channel))
|
||||
user.ChannelModes.Add(channel, null);
|
||||
else
|
||||
user.ChannelModes[channel] = null;
|
||||
}
|
||||
|
||||
var nick = rawNick;
|
||||
var modes = client.ServerInfo.GetModesForNick(nick);
|
||||
|
||||
if (modes.Count > 0)
|
||||
nick = rawNick.Remove(0, modes.Count);
|
||||
|
||||
var user = client.Users.GetOrAdd(nick);
|
||||
|
||||
if (!user.Channels.Contains(channel))
|
||||
user.Channels.Add(channel);
|
||||
if (!user.ChannelModes.ContainsKey(channel))
|
||||
user.ChannelModes.Add(channel, modes);
|
||||
else
|
||||
{
|
||||
var user = client.Users.GetOrAdd(nick.Substring(1));
|
||||
if (!user.Channels.Contains(channel))
|
||||
user.Channels.Add(channel);
|
||||
if (!user.ChannelModes.ContainsKey(channel))
|
||||
user.ChannelModes.Add(channel, mode.Value);
|
||||
else
|
||||
user.ChannelModes[channel] = mode.Value;
|
||||
}
|
||||
user.ChannelModes[channel] = modes;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using ChatSharp.Events;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace ChatSharp.Handlers
|
||||
|
@ -182,15 +183,16 @@ namespace ChatSharp.Handlers
|
|||
new UserPoolView(channel.Users.Where(u =>
|
||||
{
|
||||
if (!u.ChannelModes.ContainsKey(channel))
|
||||
u.ChannelModes.Add(channel, null);
|
||||
return u.ChannelModes[channel] == c;
|
||||
u.ChannelModes.Add(channel, new List<char?>());
|
||||
return u.ChannelModes[channel].Contains(c);
|
||||
})));
|
||||
}
|
||||
var user = new IrcUser(message.Parameters[i]);
|
||||
if (add)
|
||||
{
|
||||
if (!channel.UsersByMode[c].Contains(user.Nick))
|
||||
user.ChannelModes[channel] = c;
|
||||
if (!user.ChannelModes[channel].Contains(c))
|
||||
user.ChannelModes[channel].Add(c);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -158,7 +158,7 @@ namespace ChatSharp
|
|||
Users = new UserPool();
|
||||
Users.Add(User); // Add self to user pool
|
||||
Capabilities = new CapabilityPool();
|
||||
Capabilities.AddRange(new string[] { "server-time" }); // List of supported capabilities
|
||||
Capabilities.AddRange(new string[] { "server-time", "multi-prefix" }); // List of supported capabilities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace ChatSharp
|
|||
internal IrcUser()
|
||||
{
|
||||
Channels = new ChannelCollection();
|
||||
ChannelModes = new Dictionary<IrcChannel, char?>();
|
||||
ChannelModes = new Dictionary<IrcChannel, List<char?>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -98,7 +98,7 @@ namespace ChatSharp
|
|||
/// <value>The channels.</value>
|
||||
public ChannelCollection Channels { get; set; }
|
||||
|
||||
internal Dictionary<IrcChannel, char?> ChannelModes { get; set; }
|
||||
internal Dictionary<IrcChannel, List<char?>> ChannelModes { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// This user's hostmask (nick!user@host).
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace ChatSharp
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -8,7 +11,7 @@ namespace ChatSharp
|
|||
internal ServerInfo()
|
||||
{
|
||||
// Guess for some defaults
|
||||
Prefixes = new[] { "ov", "@+" };
|
||||
Prefixes = new[] { "ovhaq", "@+%&~" };
|
||||
SupportedChannelModes = new ChannelModes();
|
||||
IsGuess = true;
|
||||
}
|
||||
|
@ -23,6 +26,35 @@ namespace ChatSharp
|
|||
return Prefixes[0][Prefixes[1].IndexOf(prefix)];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the channel modes for a given user nick.
|
||||
/// Returns an empty array if user has no modes.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<char?> GetModesForNick(string nick)
|
||||
{
|
||||
var supportedPrefixes = Prefixes[1];
|
||||
List<char?> modeList = new List<char?>();
|
||||
List<char> nickPrefixes = new List<char>();
|
||||
|
||||
foreach (char prefix in supportedPrefixes)
|
||||
{
|
||||
if (nick.Contains(prefix))
|
||||
{
|
||||
nick.Remove(nick.IndexOf(prefix));
|
||||
if (!nickPrefixes.Contains(prefix))
|
||||
{
|
||||
nickPrefixes.Add(prefix);
|
||||
var mode = GetModeForPrefix(prefix);
|
||||
if (!modeList.Contains(mode))
|
||||
modeList.Add(mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return modeList;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// ChatSharp makes some assumptions about what the server supports in order to function properly.
|
||||
/// If it has not recieved a 005 message giving it accurate information, this value will be true.
|
||||
|
@ -97,7 +129,7 @@ namespace ChatSharp
|
|||
ParameterizedSettings = "k";
|
||||
OptionallyParameterizedSettings = "flj";
|
||||
Settings = string.Empty;
|
||||
ChannelUserModes = "vo"; // I have no idea what I'm doing here
|
||||
ChannelUserModes = "vhoaq"; // I have no idea what I'm doing here
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="IrcMessageTests.cs" />
|
||||
<Compile Include="IrcUserTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
using System;
|
||||
using ChatSharp;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace ChatSharp.Tests
|
||||
{
|
||||
[TestClass]
|
||||
public class IrcUserTests
|
||||
{
|
||||
[TestMethod]
|
||||
public void GetUserModes_NotNull_FiveModes()
|
||||
{
|
||||
IrcUser user = new IrcUser("~&@%+aji", "user");
|
||||
IrcClient client = new IrcClient("irc.address", user);
|
||||
|
||||
var userModes = client.ServerInfo.GetModesForNick(user.Nick);
|
||||
|
||||
Assert.IsTrue(userModes.Count == 5);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetUserModes_NotNull_FourModes()
|
||||
{
|
||||
IrcUser user = new IrcUser("&@%+aji", "user");
|
||||
IrcClient client = new IrcClient("irc.address", user);
|
||||
|
||||
var userModes = client.ServerInfo.GetModesForNick(user.Nick);
|
||||
|
||||
Assert.IsTrue(userModes.Count == 4);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetUserModes_NotNull_ThreeModes()
|
||||
{
|
||||
IrcUser user = new IrcUser("@%+aji", "user");
|
||||
IrcClient client = new IrcClient("irc.address", user);
|
||||
|
||||
var userModes = client.ServerInfo.GetModesForNick(user.Nick);
|
||||
|
||||
Assert.IsTrue(userModes.Count == 3);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetUserModes_NotNull_TwoModes()
|
||||
{
|
||||
IrcUser user = new IrcUser("%+aji", "user");
|
||||
IrcClient client = new IrcClient("irc.address", user);
|
||||
|
||||
var userModes = client.ServerInfo.GetModesForNick(user.Nick);
|
||||
|
||||
Assert.IsTrue(userModes.Count == 2);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetUserModes_NotNull_OneMode()
|
||||
{
|
||||
IrcUser user = new IrcUser("+aji", "user");
|
||||
IrcClient client = new IrcClient("irc.address", user);
|
||||
|
||||
var userModes = client.ServerInfo.GetModesForNick(user.Nick);
|
||||
|
||||
Assert.IsTrue(userModes.Count == 1);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetUserModes_IsNull()
|
||||
{
|
||||
IrcUser user = new IrcUser("aji", "user");
|
||||
IrcClient client = new IrcClient("irc.address", user);
|
||||
|
||||
var userModes = client.ServerInfo.GetModesForNick(user.Nick);
|
||||
|
||||
Assert.IsTrue(userModes.Count == 0);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue