Merge pull request #82 from RockyTV/caps

Fully support IRCv3.2 capability negotiation
This commit is contained in:
Drew DeVault 2017-08-25 23:14:23 -05:00 committed by GitHub
commit 838a33e99a
2 changed files with 48 additions and 6 deletions

View File

@ -15,6 +15,7 @@ namespace ChatSharp.Handlers
switch (message.Parameters[1])
{
case "LS":
client.IsNegotiatingCapabilities = true;
// Parse server capabilities
var serverCapsString = (message.Parameters[2] == "*" ? message.Parameters[3] : message.Parameters[2]);
serverCaps.AddRange(serverCapsString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries));
@ -31,7 +32,10 @@ namespace ChatSharp.Handlers
if (requestedCaps.Count > 0)
client.SendRawMessage("CAP REQ :{0}", string.Join(" ", requestedCaps));
else
{
client.SendRawMessage("CAP END");
client.IsNegotiatingCapabilities = false;
}
}
break;
case "ACK":
@ -42,8 +46,11 @@ namespace ChatSharp.Handlers
// Check if the enabled capabilities count is the same as the ones
// acknowledged by the server.
if (client.Capabilities.Enabled.Count() == acceptedCaps.Count())
if (client.IsNegotiatingCapabilities && client.Capabilities.Enabled.Count() == acceptedCaps.Count())
{
client.SendRawMessage("CAP END");
client.IsNegotiatingCapabilities = false;
}
break;
case "NAK":
@ -54,18 +61,46 @@ namespace ChatSharp.Handlers
// Check if the disabled capabilities count is the same as the ones
// rejected by the server.
if (client.Capabilities.Disabled.Count() == rejectedCaps.Count())
if (client.IsNegotiatingCapabilities && client.Capabilities.Disabled.Count() == rejectedCaps.Count())
{
client.SendRawMessage("CAP END");
client.IsNegotiatingCapabilities = false;
}
break;
case "LIST":
// Not implemented yet
var activeCapsString = (message.Parameters[2] == "*" ? message.Parameters[3] : message.Parameters[2]);
var activeCaps = activeCapsString.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
// Check which cap we have that isn't active but the server lists
// as active.
foreach (string cap in activeCaps)
{
if (client.Capabilities.Contains(cap))
if (!client.Capabilities[cap].IsEnabled)
client.Capabilities.Enable(cap);
}
break;
case "NEW":
// Not implemented yet
var newCaps = message.Parameters[2].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
var wantCaps = new List<string>();
// Check which new capabilities we support and send a REQ for them
wantCaps.AddRange(newCaps.Where(cap => client.Capabilities.Contains(cap) && !client.Capabilities[cap].IsEnabled));
client.SendRawMessage(string.Format("CAP REQ :{0}", string.Join(" ", wantCaps)));
break;
case "DEL":
// Not implemented yet
var disabledCaps = message.Parameters[2].Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries).ToList();
// Disable each recently server-disabled capability
disabledCaps.ForEach(
cap => {
if (client.Capabilities.Contains(cap) && client.Capabilities[cap].IsEnabled)
client.Capabilities.Disable(cap);
}
);
break;
default:
break;

View File

@ -131,6 +131,11 @@ namespace ChatSharp
/// after negotiating with the server.
/// </summary>
public CapabilityPool Capabilities { get; set; }
/// <summary>
/// Set to true when the client is negotiating IRC capabilities with the server.
/// If set to False, capability negotiation is finished.
/// </summary>
public bool IsNegotiatingCapabilities { get; internal set; }
/// <summary>
/// Creates a new IRC client, but will not connect until ConnectAsync is called.
@ -158,7 +163,9 @@ namespace ChatSharp
Users = new UserPool();
Users.Add(User); // Add self to user pool
Capabilities = new CapabilityPool();
Capabilities.AddRange(new string[] { "server-time", "multi-prefix" }); // List of supported capabilities
// List of supported capabilities
Capabilities.AddRange(new string[] { "server-time", "multi-prefix", "cap-notify" });
IsNegotiatingCapabilities = false;
}
/// <summary>