Exemple #1
0
        public Client(ClientConfig config)
        {
            this.Config = config ?? throw new ArgumentNullException(nameof(config));

            this.Session = new IrcSession();

            this.Channels = this.Config.Channels.ToDictionary(x => x.Name, x => new Channel(x.Name, this, x));

            this.commandRegistrationManager = new CommandRegistrationManager(this.Config.CommandPrefixes, this.Config.RequireCommandPrefixInPrivmsg);

            this.Session.RawMessageReceived += (o, e) => Console.WriteLine("<< " + e.Message);
            this.Session.RawMessageSent     += (o, e) => Console.WriteLine(">> " + e.Message);
            this.Session.AddHandler(new IrcCodeHandler(e =>
            {
                Session.Nick(Session.Nickname + "_");
                return(true);
            }, IrcCode.ErrNicknameInUse));
            this.Session.StateChanged += (o, e) =>
            {
                if (Session.State == IrcSessionState.Connected)
                {
                    foreach (var channel in this.Config.Channels)
                    {
                        this.Session.Join(channel.Name);
                    }
                    if (!string.IsNullOrWhiteSpace(this.Config.NickServServicesName) && !string.IsNullOrWhiteSpace(this.Config.NickservPassword))
                    {
                        this.Session.PrivateMessage(new IrcTarget(this.Config.NickServServicesName), $"identify {this.Config.NickservPassword}");
                    }
                }
            };
            this.Session.PrivateMessaged += (o, e) =>
            {
                if (!e.To.IsChannel && e.To.Name == this.Config.Nickname)
                {
                    this.PrivateMessaged?.Invoke(this, new MessagedEventArgs(e.From, e.Text));

                    var response = this.commandRegistrationManager.TryDispatchCommand(e.From, e.Text);
                    if (response != null)
                    {
                        this.Session.PrivateMessage(new IrcTarget(e.From), response);
                    }
                }
            };
            this.Session.AddHandler(new IrcCodeHandler(e =>
            {
                var parts = e.Text.Split(' ');
                foreach (var part in parts)
                {
                    var values = part.Split('=');
                    if (values[0] == "CHANMODES")
                    {
                        this.SupportedChannelModes = values[1];
                    }
                }
                return(false);
            }, IrcCode.RPL_BOUNCE));
        }
Exemple #2
0
        internal Channel(string name, Client client, ChannelConfig channelConfig)
        {
            this.Name          = name ?? throw new ArgumentNullException(nameof(name));
            this.client        = client ?? throw new ArgumentNullException(nameof(client));
            this.permanentlyOp = channelConfig.PermanentlyOp ?? this.client.Config.PermanentlyOp;

            this.commandRegistrationManager = new CommandRegistrationManager(client.Config.CommandPrefixes, requirePrefix: true);

            this.session.SelfJoined += (o, e) =>
            {
                if (e.Channel.IsChannel && e.Channel.Name == this.Name)
                {
                    this.IsJoined = true;
                    this.OnJoined();
                }
            };
            this.session.SelfParted += (o, e) =>
            {
                if (e.Channel.IsChannel && e.Channel.Name == this.Name)
                {
                    this.IsJoined = false;
                }
            };
            this.session.SelfKicked += (o, e) =>
            {
                if (e.Channel.IsChannel && e.Channel.Name == this.Name)
                {
                    this.IsJoined = false;
                }
            };
            this.session.PrivateMessaged += (o, e) =>
            {
                if (e.To.IsChannel && e.To.Name == this.Name)
                {
                    this.Messaged?.Invoke(this, new MessagedEventArgs(e.From, e.Text));

                    var response = this.commandRegistrationManager.TryDispatchCommand(e.From, e.Text);
                    if (response != null)
                    {
                        this.client.Session.PrivateMessage(e.To, response);
                    }
                }
            };
            this.session.ChannelModeChanged += (o, e) =>
            {
                if (e.Channel.IsChannel && e.Channel.Name == this.Name)
                {
                    foreach (var mode in e.Modes)
                    {
                        if (mode.Parameter == this.session.Nickname && mode.Mode == 'o')
                        {
                            this.IsOp = mode.Set;
                        }
                        else if (mode.Mode == 'b' || mode.Mode == 'q')
                        {
                            var    newBanList  = new List <UserBan>(this.BanList);
                            Action eventRaiser = null;
                            if (mode.Set)
                            {
                                var ban = new UserBan(mode.Parameter, e.Who.Prefix, DateTime.UtcNow, mode.Mode);
                                newBanList.Add(ban);
                                eventRaiser = () => this.BanAdded?.Invoke(this, new BanChangedEventArgs(ban));
                            }
                            else
                            {
                                var toRemove = newBanList.FirstOrDefault(x => x.Mask == mode.Parameter && x.Type == mode.Mode);
                                if (toRemove != null)
                                {
                                    newBanList.Remove(toRemove);
                                    eventRaiser = () => this.BanRemoved?.Invoke(this, new BanChangedEventArgs(toRemove));
                                }
                            }
                            this.BanList = newBanList;
                            eventRaiser?.Invoke();
                        }
                    }
                }
            };

            // These 4 form a chain - we always request bans, and when they finish we request mutes (if supported_
            this.session.AddHandler(new IrcCodeHandler(e =>
            {
                var parameters = e.Message.Parameters;
                if (parameters[1] == this.Name)
                {
                    var ban = new UserBan(parameters[2], parameters[3], DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(parameters[4]) * 1000).DateTime, 'b');
                    this.wipBanList.Add(ban);
                }
                return(false);
            }, IrcCode.RPL_BANLIST));
            this.session.AddHandler(new IrcCodeHandler(e =>
            {
                if (e.Message.Parameters[1] == this.Name)
                {
                    if (this.muteSupported)
                    {
                        this.session.Mode(this.Name, "+q");
                    }
                    else
                    {
                        this.BanList    = this.wipBanList;
                        this.wipBanList = new List <UserBan>();
                        this.BanListReloaded?.Invoke(this, new BanListReloadedEventArgs(this.BanList));
                    }
                }
                return(false);
            }, IrcCode.RPL_ENDOFBANLIST));

            if (this.muteSupported)
            {
                this.session.AddHandler(new IrcCodeHandler(e =>
                {
                    var parameters = e.Message.Parameters;
                    if (parameters[1] == this.Name && parameters[2] == "q")
                    {
                        var ban = new UserBan(parameters[3], parameters[4], DateTimeOffset.FromUnixTimeMilliseconds(long.Parse(parameters[5])).DateTime, 'q');
                        this.wipBanList.Add(ban);
                    }
                    return(false);
                }, (IrcCode)728));
                this.session.AddHandler(new IrcCodeHandler(e =>
                {
                    if (e.Message.Parameters[1] == this.Name && e.Message.Parameters[2] == "q")
                    {
                        this.BanList    = this.wipBanList;
                        this.wipBanList = new List <UserBan>();
                        this.BanListReloaded?.Invoke(this, new BanListReloadedEventArgs(this.BanList));
                    }
                    return(false);
                }, (IrcCode)729));
            }
        }