172 lines
6.8 KiB
C#
172 lines
6.8 KiB
C#
using System;
|
|
using System.Linq;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using ChatSharp.Events;
|
|
|
|
namespace ChatSharp.Handlers
|
|
{
|
|
internal static class ChannelHandlers
|
|
{
|
|
public static void HandleJoin(IrcClient client, IrcMessage message)
|
|
{
|
|
var user = client.Users.GetOrAdd(message.Prefix);
|
|
var channel = client.Channels.GetOrAdd(message.Parameters[0]);
|
|
|
|
if (channel != null)
|
|
{
|
|
if (!user.Channels.Contains(channel))
|
|
user.Channels.Add(channel);
|
|
|
|
// account-notify capability
|
|
if (client.Capabilities.IsEnabled("account-notify"))
|
|
client.Who(user.Nick, WhoxFlag.None, WhoxField.Nick | WhoxField.AccountName, whoQuery =>
|
|
{
|
|
if (whoQuery.Count == 1)
|
|
user.Account = whoQuery[0].User.Account;
|
|
});
|
|
|
|
client.OnUserJoinedChannel(new ChannelUserEventArgs(channel, user));
|
|
}
|
|
}
|
|
|
|
public static void HandleGetTopic(IrcClient client, IrcMessage message)
|
|
{
|
|
var channel = client.Channels.GetOrAdd(message.Parameters[1]);
|
|
var old = channel._Topic;
|
|
channel._Topic = message.Parameters[2];
|
|
client.OnChannelTopicReceived(new ChannelTopicEventArgs(channel, old, channel._Topic));
|
|
}
|
|
|
|
public static void HandleGetEmptyTopic(IrcClient client, IrcMessage message)
|
|
{
|
|
var channel = client.Channels.GetOrAdd(message.Parameters[1]);
|
|
var old = channel._Topic;
|
|
channel._Topic = message.Parameters[2];
|
|
client.OnChannelTopicReceived(new ChannelTopicEventArgs(channel, old, channel._Topic));
|
|
}
|
|
|
|
public static void HandlePart(IrcClient client, IrcMessage message)
|
|
{
|
|
if (!client.Channels.Contains(message.Parameters[0]))
|
|
return; // we aren't in this channel, ignore
|
|
|
|
var user = client.Users.Get(message.Prefix);
|
|
var channel = client.Channels[message.Parameters[0]];
|
|
|
|
if (user.Channels.Contains(channel))
|
|
user.Channels.Remove(channel);
|
|
if (user.ChannelModes.ContainsKey(channel))
|
|
user.ChannelModes.Remove(channel);
|
|
|
|
client.OnUserPartedChannel(new ChannelUserEventArgs(channel, user));
|
|
}
|
|
|
|
public static void HandleUserListPart(IrcClient client, IrcMessage message)
|
|
{
|
|
if (client.Capabilities.IsEnabled("userhost-in-names"))
|
|
{
|
|
var channel = client.Channels[message.Parameters[2]];
|
|
var users = message.Parameters[3].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var hostmask in users)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(hostmask))
|
|
continue;
|
|
|
|
// Parse hostmask
|
|
var nick = hostmask.Substring(0, hostmask.IndexOf("!", StringComparison.Ordinal));
|
|
var ident = hostmask[(nick.Length + 1)..hostmask.LastIndexOf("@", StringComparison.Ordinal)];
|
|
var hostname = hostmask[(hostmask.LastIndexOf("@", StringComparison.Ordinal) + 1)..];
|
|
|
|
// Get user modes
|
|
var modes = client.ServerInfo.GetModesForNick(nick);
|
|
if (modes.Count > 0)
|
|
nick = nick.Remove(0, modes.Count);
|
|
|
|
var user = client.Users.GetOrAdd(nick);
|
|
if (user.Hostname != hostname && user.User != ident)
|
|
{
|
|
user.Hostname = hostname;
|
|
user.User = ident;
|
|
}
|
|
|
|
if (!user.Channels.Contains(channel))
|
|
user.Channels.Add(channel);
|
|
if (!user.ChannelModes.ContainsKey(channel))
|
|
user.ChannelModes.Add(channel, modes);
|
|
else
|
|
user.ChannelModes[channel] = modes;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
var channel = client.Channels[message.Parameters[2]];
|
|
var users = message.Parameters[3].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
foreach (var rawNick in users)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(rawNick))
|
|
continue;
|
|
|
|
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
|
|
user.ChannelModes[channel] = modes;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void HandleUserListEnd(IrcClient client, IrcMessage message)
|
|
{
|
|
var channel = client.Channels[message.Parameters[1]];
|
|
client.OnChannelListReceived(new ChannelEventArgs(channel));
|
|
if (client.Settings.ModeOnJoin)
|
|
try
|
|
{
|
|
client.GetMode(channel.Name, _ =>
|
|
{
|
|
/* no-op */
|
|
});
|
|
}
|
|
catch
|
|
{
|
|
/* who cares */
|
|
}
|
|
|
|
if (client.Settings.WhoIsOnJoin) Task.Factory.StartNew(() => WhoIsChannel(channel, client, 0));
|
|
}
|
|
|
|
private static void WhoIsChannel(IrcChannel channel, IrcClient client, int index)
|
|
{
|
|
// Note: joins and parts that happen during this will cause strange behavior here
|
|
Thread.Sleep(client.Settings.JoinWhoIsDelay * 1000);
|
|
var user = channel.Users[index];
|
|
client.WhoIs(user.Nick, whois =>
|
|
{
|
|
user.User = whois.User.User;
|
|
user.Hostname = whois.User.Hostname;
|
|
user.RealName = whois.User.RealName;
|
|
Task.Factory.StartNew(() => WhoIsChannel(channel, client, index + 1));
|
|
});
|
|
}
|
|
|
|
public static void HandleKick(IrcClient client, IrcMessage message)
|
|
{
|
|
var channel = client.Channels[message.Parameters[0]];
|
|
var kicked = channel.Users[message.Parameters[1]];
|
|
if (kicked.Channels.Contains(channel))
|
|
kicked.Channels.Remove(channel);
|
|
client.OnUserKicked(new KickEventArgs(channel, new IrcUser(message.Prefix),
|
|
kicked, message.Parameters[2]));
|
|
}
|
|
}
|
|
} |