示例#1
0
        public BaseClient()
        {
            var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "config", "settings.json");

            if (File.Exists(path))
            {
                var data = File.ReadAllText(path);

                try
                {
                    Settings = JsonConvert.DeserializeObject <Settings>(data, new JsonSerializerSettings {
                        MissingMemberHandling = MissingMemberHandling.Error
                    });

                    if (!IrcValidation.IsNickname(Settings.Nickname))
                    {
                        throw new JsonException("Nickname is not valid.");
                    }

                    if (!IrcValidation.IsChannelName(Settings.RedirectChannel))
                    {
                        throw new JsonException("Redirect channel is not valid.");
                    }

                    foreach (var channel in Settings.Channels)
                    {
                        if (!IrcValidation.IsChannelName(channel))
                        {
                            throw new JsonException($"Channel '{channel}' is not valid.");
                        }
                    }
                }
                catch (JsonException e)
                {
                    Log.WriteError("IRC", "Failed to parse settings.json file: {0}", e.Message);

                    Environment.Exit(1);
                }
            }
            else
            {
                Log.WriteWarn("IRC", "File config/settings.json doesn't exist");

                Environment.Exit(1);
            }

            Client = new IrcClient
            {
                ClientVersion = "Wendy# -- https://github.com/xPaw/WendySharp"
            };

            Client.Connected += OnConnected;
            Client.Closed    += OnDisconnected;

            Permissions  = new Permissions();
            Commands     = new Commands(Client);
            LinkExpander = new LinkExpander(Client);
            ChannelList  = new Channels(Client);
            Whois        = new Whois(Client);
        }
示例#2
0
文件: Spam.cs 项目: crannk/WendySharp
        private void ProcessQuit(IrcIdentity ident, string channelName, SpamConfig channel)
        {
            var nickname = ident.Nickname;

            Whois.NormalizeIdentity(ident);

            var quits = channel.AddUserPart(ident.ToString(), channel.QuitsThresholdSeconds);

            if (quits < channel.QuitsThreshold)
            {
                return;
            }

            channel.ResetUserPart(ident.ToString());

            Log.WriteInfo("Spam", "'{1}' ({0}) is spamming joins/quits in {2}. Redirecting for {3} minutes.", nickname, ident, channelName, channel.QuitsBanMinutes);

            Bootstrap.Client.Client.Mode(channelName, "+b", ident + "$" + Bootstrap.Client.Settings.RedirectChannel);

            // In case they manage to come back before ban takes place
            Bootstrap.Client.Client.Kick(nickname, channelName, string.Format("Fix your connection. Banned for {0} minutes", channel.QuitsBanMinutes));

            Bootstrap.Client.Client.Notice(nickname, string.Format("You have been banned from {0} for {1} minutes for rapidly rejoining the channel.", channelName, channel.QuitsBanMinutes));

            Bootstrap.Client.ModeList.AddLateModeRequest(
                new LateModeRequest
            {
                Channel   = channelName,
                Recipient = ident.ToString(),
                Mode      = "-b",
                Time      = DateTime.UtcNow.AddMinutes(channel.QuitsBanMinutes),
                Reason    = "Quit/leave flood"
            }
                );
        }
示例#3
0
        public override void OnCommand(CommandArguments command)
        {
            var nick = command.Arguments.Groups["nick"].Value;

            if (!IrcIdentity.TryParse(nick, out var ident))
            {
                command.Reply("Invalid identity.");

                return;
            }

            var channel = Bootstrap.Client.ChannelList.GetChannel(command.Event.Recipient);

            if (!channel.WeAreOpped)
            {
                if (channel.HasChanServ)
                {
                    Bootstrap.Client.Client.Message("ChanServ", string.Format("op {0}", channel.Name));
                }
                else
                {
                    command.Reply("I'm not opped, send help.");

                    return;
                }
            }

            var isQuiet = command.MatchedCommand != "unban";

            Bootstrap.Client.Whois.Query(ident,
                                         whoisData =>
            {
                if (whoisData.Identity.Nickname != null)
                {
                    ident = whoisData.Identity;

                    Whois.NormalizeIdentity(ident);
                }
                else
                {
                    if (ident.Username == null)
                    {
                        ident.Username = "******";
                    }

                    if (ident.Hostname == null)
                    {
                        ident.Hostname = "*";
                    }
                }

                Log.WriteInfo("Unban", "'{0}' unbanned '{1}' in {2}", command.Event.Sender, ident, command.Event.Recipient);

                Bootstrap.Client.Client.Mode(command.Event.Recipient, isQuiet ? "-q" : "-b", ident);

                command.ReplyAsNotice("{0} {1}", isQuiet ? "Unmuted" : "Unbanned", ident);
            }
                                         );
        }
示例#4
0
        private void ProcessQuit(IrcIdentity ident, string channelName, SpamConfig channel)
        {
            var nickname = ident.Nickname;

            ident = Whois.NormalizeIdentity(ident);

            var quits = channel.AddUserPart(ident.ToString(), channel.QuitsThresholdSeconds);

            if (quits < channel.QuitsThreshold)
            {
                return;
            }

            var banMinutes = channel.AddUserBan(ident.ToString()) * channel.QuitsBanMinutes;

            Log.WriteInfo("Spam", "'{1}' ({0}) is spamming joins/quits in {2}. Redirecting for {3} minutes.", nickname, ident, channelName, banMinutes);

            Bootstrap.Client.Client.Mode(channelName, "+b", ident + "$" + Bootstrap.Client.Settings.RedirectChannel);

            // In case they manage to come back before ban takes place
            Bootstrap.Client.Client.Kick(nickname, channelName, $"Fix your connection. Banned for {banMinutes} minutes");

            Bootstrap.Client.Client.Notice(nickname, $"Please fix your connection. You have been banned from {channelName} for {banMinutes} minutes for rapidly rejoining the channel.");

            if (Bootstrap.Client.ModeList.Find(channelName, ident.ToString(), "-b") != null)
            {
                Log.WriteInfo("Spam", "There's already a latemode set for '{0}' in {1}", ident, channelName);

                return;
            }

            Bootstrap.Client.ModeList.AddLateModeRequest(
                new LateModeRequest
            {
                Channel   = channelName,
                Recipient = ident.ToString(),
                Mode      = "-b",
                Time      = DateTime.UtcNow.AddMinutes(banMinutes),
                Reason    = "Quit/leave flood"
            }
                );
        }
示例#5
0
        public override void OnCommand(CommandArguments command)
        {
            var nick = command.Arguments.Groups["nick"].Value;

            if (!IrcIdentity.TryParse(nick, out var ident))
            {
                command.Reply("Invalid identity.");

                return;
            }

            var channel = Bootstrap.Client.ChannelList.GetChannel(command.Event.Recipient);

            if (!channel.WeAreOpped)
            {
                if (channel.HasChanServ)
                {
                    Bootstrap.Client.Client.Message("ChanServ", string.Format("op {0}", channel.Name));
                }
                else
                {
                    command.Reply("I'm not opped, send help.");

                    return;
                }
            }

            Bootstrap.Client.Whois.Query(ident,
                                         whoisData =>
            {
                if (whoisData.Identity.Nickname != null)
                {
                    ident = whoisData.Identity;
                }

                var nickname = ident.Nickname;

                if (nickname.ToString().ToLowerInvariant() == Bootstrap.Client.TrueNickname.ToLowerInvariant())
                {
                    command.Reply("Don't you even dare.");

                    return;
                }

                if (whoisData.Identity.Nickname != null)
                {
                    Whois.NormalizeIdentity(ident);
                }
                else
                {
                    if (ident.Username == null)
                    {
                        ident.Username = "******";
                    }

                    if (ident.Hostname == null)
                    {
                        ident.Hostname = "*";
                    }
                }

                var targetChannel = command.Arguments.Groups["channel"].Value.Trim();

                if (targetChannel.Length == 0)
                {
                    targetChannel = Bootstrap.Client.Settings.RedirectChannel;
                }
                else if (!IrcValidation.IsChannelName(targetChannel))
                {
                    command.Reply("Invalid target channel.");

                    return;
                }

                if (Bootstrap.Client.ModeList.Find(command.Event.Recipient, ident.ToString(), "-b") != null)
                {
                    command.Reply("{0} is already banned in this channel.", ident);

                    return;
                }

                Log.WriteInfo("Redirect", "'{0}' redirected '{1}' from {2} to {3}", command.Event.Sender, ident, command.Event.Recipient, targetChannel);

                var reason = string.Format("Redirected to {0} by {1} for 2 hours", targetChannel, command.Event.Sender.Nickname);

                Bootstrap.Client.Client.Mode(command.Event.Recipient, "+b", ident + "$" + targetChannel);

                if (channel.HasUser(nickname))
                {
                    Bootstrap.Client.Client.Kick(nickname, command.Event.Recipient, reason);
                }

                command.ReplyAsNotice("Redirected {0} to {1} for 2 hours", ident, targetChannel);

                Bootstrap.Client.ModeList.AddLateModeRequest(
                    new LateModeRequest
                {
                    Channel   = command.Event.Recipient,
                    Recipient = ident.ToString(),
                    Sender    = command.Event.Sender.ToString(),
                    Mode      = "-b",
                    Time      = DateTime.UtcNow.AddHours(2),
                    Reason    = reason
                }
                    );
            }
                                         );
        }
示例#6
0
        public void OnMessage(ChatMessageEventArgs e, string message, User user)
        {
            if (e.Sender == null || !Channels.ContainsKey(e.Recipient) || (user?.HasPermission(e.Recipient, "spam.whitelist") == true))
            {
                return;
            }

            var sender  = e.Sender;
            var channel = Channels[e.Recipient];

            channel.AddAction(sender, message);

            var actualChannel = Bootstrap.Client.ChannelList.GetChannel(e.Recipient);
            var mentions      = message.Split(' ').Count(word => word.Length > 2 && actualChannel.HasUser(word));

            if (mentions >= channel.UserMentionsInOneMessage)
            {
                Bootstrap.Client.Client.Notice(sender.Nickname, "Don't mention too many users at once.");
            }
            else
            {
                var saidLines   = 0;
                var repeatLines = 0;

                foreach (var action in channel.LastActions)
                {
                    if (action.Identity != sender)
                    {
                        continue;
                    }

                    if (action.Time.AddSeconds(channel.LinesThresholdSeconds) >= DateTime.UtcNow)
                    {
                        saidLines++;
                    }

                    if (action.Time.AddSeconds(channel.RepeatThresholdSeconds) >= DateTime.UtcNow && action.Message == message)
                    {
                        repeatLines++;
                    }
                }

                if (saidLines < channel.LinesThreshold && repeatLines < channel.RepeatThreshold)
                {
                    return;
                }

                channel.LastActions.Clear(); // TODO: FIX

                Bootstrap.Client.Client.Notice(sender.Nickname, channel.Message);
            }

            Log.WriteInfo("Spam", "A line by '{0}' in {1} was detected as spam. Quieting for {2} seconds.", sender, e.Recipient, channel.Duration);

            sender = Whois.NormalizeIdentity(sender);

            Bootstrap.Client.Client.Mode(e.Recipient, "+q", sender);

            if (Bootstrap.Client.ModeList.Find(e.Recipient, sender.ToString(), "-q") != null)
            {
                Log.WriteInfo("Spam", "There's already a latemode set for '{0}' in {1}", sender, e.Recipient);

                return;
            }

            Bootstrap.Client.ModeList.AddLateModeRequest(
                new LateModeRequest
            {
                Channel   = e.Recipient,
                Recipient = sender.ToString(),
                Mode      = "-q",
                Time      = DateTime.UtcNow.AddSeconds(channel.Duration),
                Reason    = "Spam"
            }
                );
        }
示例#7
0
        public override void OnCommand(CommandArguments command)
        {
            var nick = command.Arguments.Groups["nick"].Value;

            if (!IrcIdentity.TryParse(nick, out var ident))
            {
                command.Reply("Invalid identity.");

                return;
            }

            var duration     = command.Arguments.Groups["duration"].Value;
            var durationTime = default(DateTime);

            if (duration.Length > 0)
            {
                try
                {
                    durationTime = DateTimeParser.Parse(duration, command.Arguments.Groups["durationUnit"].Value);
                }
                catch (ArgumentException e)
                {
                    command.Reply("{0}", e.Message);

                    return;
                }
            }

            var channel = Bootstrap.Client.ChannelList.GetChannel(command.Event.Recipient);

            if (!channel.WeAreOpped)
            {
                if (channel.HasChanServ)
                {
                    Bootstrap.Client.Client.IrcCommand("CHANSERV", "op", channel.Name);
                }
                else
                {
                    command.Reply("I'm not opped, send help.");

                    return;
                }
            }

            var isQuiet = command.MatchedCommand == "quiet" || command.MatchedCommand == "mute";

            Bootstrap.Client.Whois.Query(ident,
                                         whoisData =>
            {
                if (whoisData.Identity.Nickname == null)
                {
                    command.Reply("There is no user by that nick on the network. Try {0}!*@* to {1} anyone with that nick, or specify a full hostmask.", ident.Nickname, isQuiet ? "quiet" : "ban");

                    return;
                }

                ident = whoisData.Identity;

                var nickname = ident.Nickname;

                if (string.Equals(nickname.ToString(), Bootstrap.Client.TrueNickname, StringComparison.InvariantCultureIgnoreCase))
                {
                    command.Reply("Don't you even dare.");

                    return;
                }

                ident = Whois.NormalizeIdentity(ident);

                if (Bootstrap.Client.ModeList.Find(command.Event.Recipient, ident.ToString(), isQuiet ? "-q" : "-b") != null)
                {
                    command.Reply("{0} is already {1} in this channel.", ident, isQuiet ? "muted" : "banned");

                    return;
                }

                Log.WriteInfo("Ban", "'{0}' {1} '{2}' from {3}", command.Event.Sender, isQuiet ? "quieted" : "banned", ident, command.Event.Recipient);

                var reason = command.Arguments.Groups["reason"].Value.Trim();

                if (reason.Length == 0)
                {
                    reason = $"Banned by {command.Event.Sender.Nickname}";
                }

                Bootstrap.Client.Client.Mode(command.Event.Recipient, isQuiet ? "+q" : "+b", ident);

                if (!isQuiet && channel.HasUser(nickname))
                {
                    Bootstrap.Client.Client.Kick(nickname, command.Event.Recipient, reason);
                }

                if (duration.Length > 0)
                {
                    command.ReplyAsNotice("Will {0} {1} {2}", isQuiet ? "unmute" : "unban", ident, durationTime.ToRelativeString());

                    Bootstrap.Client.ModeList.AddLateModeRequest(
                        new LateModeRequest
                    {
                        Channel   = command.Event.Recipient,
                        Recipient = ident.ToString(),
                        Sender    = command.Event.Sender.ToString(),
                        Mode      = isQuiet ? "-q" : "-b",
                        Time      = durationTime,
                        Reason    = reason
                    }
                        );
                }
                else
                {
                    command.ReplyAsNotice("{0} {1}", isQuiet ? "Muted" : "Banned", ident);
                }
            }
                                         );
        }
示例#8
0
文件: Spam.cs 项目: crannk/WendySharp
        private void OnMessage(object obj, ChatMessageEventArgs e)
        {
            if (e.Sender == null || !Channels.ContainsKey(e.Recipient) || IsWhitelisted(e.Sender, e.Recipient))
            {
                return;
            }

            var sender  = e.Sender;
            var channel = Channels[e.Recipient];

            channel.AddAction(sender, e.Message);

            var actualChannel = Bootstrap.Client.ChannelList.GetChannel(e.Recipient);
            var mentions      = e.Message.Split((byte)' ').Count(word => word.Length > 2 && actualChannel.HasUser(word));

            if (mentions >= channel.UserMentionsInOneMessage)
            {
                Bootstrap.Client.Client.Notice(sender.Nickname, "Don't mention too many users at once.");
            }
            else if (mentions > 0 && e.Message.ToString().Contains('▄'))
            {
                // Stupid tactic to deal with spambots
            }
            else
            {
                var saidLines   = 0;
                var repeatLines = 0;

                foreach (var message in channel.LastActions)
                {
                    if (message.Identity != sender)
                    {
                        continue;
                    }

                    if (message.Time.AddSeconds(channel.LinesThresholdSeconds) >= DateTime.UtcNow)
                    {
                        saidLines++;
                    }

                    if (message.Time.AddSeconds(channel.RepeatThresholdSeconds) >= DateTime.UtcNow && message.Message == e.Message)
                    {
                        repeatLines++;
                    }
                }

                if (saidLines < channel.LinesThreshold && repeatLines < channel.RepeatThreshold)
                {
                    return;
                }

                channel.LastActions.Clear(); // TODO: FIX

                Bootstrap.Client.Client.Notice(sender.Nickname, channel.Message);
            }

            Log.WriteInfo("Spam", "A line by '{0}' in {1} was detected as spam. Quieting for {2} seconds.", sender, e.Recipient, channel.Duration);

            Whois.NormalizeIdentity(sender);

            Bootstrap.Client.Client.Mode(e.Recipient, "+q", sender);

            Bootstrap.Client.ModeList.AddLateModeRequest(
                new LateModeRequest
            {
                Channel   = e.Recipient,
                Recipient = sender.ToString(),
                Mode      = "-q",
                Time      = DateTime.UtcNow.AddSeconds(channel.Duration),
                Reason    = "Spam"
            }
                );
        }