예제 #1
0
    private async Task OnClientMessageCreated(MessageCreateEventArgs e)
    {
        try
        {
            //Ignore bot messages
            if (e.Author.Id == Client.CurrentUser.Id || string.IsNullOrEmpty(e.Message?.Content ?? ""))
            {
                return;
            }

            if (e.Guild != null)
            {
                using DBContext c = new DBContext();
                DiscordGuildConfig dgc = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)e.Guild.Id);

                if (dgc != null && dgc.AnalyzeChannelId != 0 && dgc.AnalyzeChannelId == (long)e.Channel.Id)
                {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    Task.Run(() => InvokeAnalyzer(e, dgc)).ConfigureAwait(false);
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
                    return;
                }
            }

            await Task.Run(() => CommandHandler.Invoke(e)).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            Logger.Log(ex, LogLevel.Error);
            throw;
        }
    }
예제 #2
0
        private void Set(CommandEventArg args, DBContext c)
        {
            DiscordGuildConfig dgc = args.Config;

            if (dgc == null)
            {
                dgc = c.DiscordGuildConfig.Add(new DiscordGuildConfig()
                {
                    GuildId = (long)args.Guild.Id
                }).Entity;
                c.SaveChanges();
            }

            string val = (args.Parameters.Count == 2 ? args.Parameters[1] : args.ParameterString.Remove(0, args.Parameters[0].Length)).TrimStart(' ').TrimEnd(' ');

            bool result = dgc.TrySetValue(args.Parameters[0], val);

            c.DiscordGuildConfig.Update(dgc);
            c.SaveChanges();

            if (result)
            {
                args.Channel.SendMessageAsync("Set value");
            }
            else
            {
                args.Channel.SendMessageAsync("Failed to set value");
            }
        }
예제 #3
0
        /// <summary>
        /// Synchronizes a user for a specific discord guild
        /// </summary>
        /// <returns>Verification success</returns>
        public static async Task <bool> SynchronizeVerification(ulong discordUserId, ulong discordGuildId, DiscordGuildConfig config = null)
        {
            using DBContext c = new DBContext();
            DiscordGuildConfig dgc;

            if (config == null)
            {
                dgc = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)discordGuildId);
            }
            else
            {
                dgc = config;
            }

            if (dgc == null)
            {
                return(false);
            }

            User u = c.User.FirstOrDefault(u => u.DiscordUserId == (long)discordUserId);

            if (u == null)
            {
                return(false);
            }


            return(await SynchronizeVerification(discordUserId, (int)u.OsuUserId, discordGuildId, (ulong)dgc.VerifiedRoleId, dgc.VerifiedNameAutoSet).ConfigureAwait(false));
        }
예제 #4
0
        private void List(CommandEventArg args)
        {
            StringBuilder response = new StringBuilder();

            foreach (var key in DiscordGuildConfig.GetKeys())
            {
                response.AppendLine(key);
            }

            args.Channel.SendMessageAsync(response.ToString());
        }
예제 #5
0
        private void Get(CommandEventArg args)
        {
            DiscordGuildConfig dgc = args.Config;

            if (dgc == null)
            {
                dgc = new DiscordGuildConfig();
            }

            args.Channel.SendMessageAsync(dgc.TryGetValue(args.Parameters[0]));
        }
예제 #6
0
        private void OnMuteTimerElapsed(object sender, ElapsedEventArgs e)
        {
            try
            {
                using DBContext c = new DBContext();
                List <Mute> mutes = c.Mute.Where(m => m.StartTime.AddMinutes(m.DurationM) <= DateTime.UtcNow && !m.Unmuted).ToList();

                if (mutes.Count == 0)
                {
                    return;
                }

                for (int i = 0; i < mutes.Count; i++)
                {
                    Mute m = mutes[i];

                    try
                    {
                        var guild  = Program.DiscordHandler.GetGuildAsync((ulong)m.DiscordGuildId).ConfigureAwait(false).GetAwaiter().GetResult();
                        var member = guild.GetMemberAsync((ulong)m.DiscordUserId).ConfigureAwait(false).GetAwaiter().GetResult();

                        DiscordGuildConfig dgc = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)guild.Id);
                        if (dgc == null)
                        {
                            continue;
                        }

                        var role = guild.GetRole((ulong)dgc.MutedRoleId);

                        if (member.Roles.Contains(role))
                        {
                            member.RevokeRoleAsync(role, "unmuted");
                        }

                        m.Unmuted = true;
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                    {
                        Logger.Log("Exception at unmuting, " + ex, LogLevel.Error);
                    }
                }

                c.Mute.UpdateRange(mutes);
                c.SaveChanges();
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                Logger.Log(ex, LogLevel.Error);
            }
        }
예제 #7
0
        private static ulong GetTicketRoomId(DiscordGuild guild)
        {
            using DBContext c = new DBContext();
            DiscordGuildConfig dgc = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)guild.Id);

            if (dgc == null)
            {
                return(0);
            }

            return((ulong)dgc.TicketDiscordChannelId);
        }
예제 #8
0
 public CommandEventArg(DiscordGuild guild, DiscordChannel channel, DiscordUser user,
                        DiscordMember member, DiscordMessage message,
                        AccessLevel accessLevel, List <string> parameters, string parameterString,
                        DiscordGuildConfig config)
 {
     Guild           = guild;
     Channel         = channel;
     User            = user;
     Member          = member;
     Message         = message;
     AccessLevel     = accessLevel;
     Parameters      = parameters;
     ParameterString = parameterString;
     Config          = config;
 }
예제 #9
0
    private async Task OnGuildMemberCreated(GuildMemberAddEventArgs args)
    {
        using DBContext c = new DBContext();
        DiscordGuildConfig dgc = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)args.Guild.Id);

        if (dgc == null || string.IsNullOrEmpty(dgc.WelcomeMessage) || dgc.WelcomeChannel == 0)
        {
            return;
        }
        try
        {
            User user  = c.User.FirstOrDefault(u => u.DiscordUserId == (long)args.Member.Id);
            long osuId = user == null ? 0 : user.OsuUserId;

            List <BannedUser> bans = BanManager.GetBansForUser((long)args.Member.Id, osuId, args.Guild == null ? 0 : (long)args.Guild.Id);

            if (bans.Count > 0)
            {
                if (dgc.DebugChannel != 0)
                {
                    await args.Guild.GetChannel((ulong)dgc.DebugChannel).SendMessageAsync($"Banned user detected ({args.Member.Mention} ({args.Member.Id})").ConfigureAwait(false);
                }

                if (dgc.BlacklistRoleId != 0)
                {
                    var drole = args.Guild.GetRole((ulong)dgc.BlacklistRoleId);
                    await args.Member.GrantRoleAsync(drole, "blacklisted").ConfigureAwait(false);
                }

                return;
            }

            string parsedMessage = dgc.WelcomeMessage.Replace("{mention}", args.Member.Mention, StringComparison.CurrentCultureIgnoreCase);
            var    dchannel      = args.Guild.GetChannel((ulong)dgc.WelcomeChannel);

            await dchannel.SendMessageAsync(parsedMessage).ConfigureAwait(false);

            await VerificationManager.SynchronizeVerification(args.Member.Id, args.Guild.Id, dgc).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            Logger.Log(ex, LogLevel.Error);
        }
    }
예제 #10
0
        public static void ShowHelp(DiscordChannel channel, ICommand command, string notice = null)
        {
            if (channel == null)
            {
                throw new ArgumentNullException(nameof(channel));
            }
            else if (command == null)
            {
                throw new ArgumentNullException(nameof(command));
            }

            using DBContext c = new DBContext();
            DiscordGuildConfig dgc = null;

            if (channel.Guild != null)
            {
                dgc = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)channel.Guild.Id);
            }

            char prefix = dgc?.Prefix ?? Program.DiscordHandler.CommandHandler.CommandPrefix;

            ShowHelp(channel, command, prefix, notice);
        }
예제 #11
0
    private static void InvokeAnalyzer(MessageCreateEventArgs e, DiscordGuildConfig dgc)
    {
        try
        {
            using DBContext c = new DBContext();

            string[] lines = e.Message.Content.Split('\n');

            string stageLine = lines.FirstOrDefault(l => l.StartsWith("Stage -", StringComparison.CurrentCultureIgnoreCase));

            if (!string.IsNullOrEmpty(stageLine))
            {
                int stageIndex = stageLine.IndexOf("-", StringComparison.CurrentCultureIgnoreCase);

                string stage  = stageLine.Remove(0, stageIndex + 1).TrimStart(' ').Trim(' ');
                string mpLink = lines.FirstOrDefault(l => l.StartsWith("MP link:", StringComparison.CurrentCultureIgnoreCase)).Split(' ')[2].Trim('>').Trim('<');

                if (!string.IsNullOrEmpty(mpLink))
                {
                    var history = OsuHistoryEndPoint.GetData.FromUrl(mpLink, null);

                    var warmupMaps = c.WarmupBeatmaps.Where(wb => wb.DiscordGuildId == dgc.GuildId);

                    var result = SkyBot.Analyzer.OsuAnalyzer.CreateStatistic(history, e.Guild, (int)(history.CurrentGameId ?? 0), dgc.AnalyzeWarmupMatches, stage, true, beatmapsToIgnore: warmupMaps.Select(wm => wm.BeatmapId).ToArray());
                    var embed  = SkyBot.Analyzer.OsuAnalyzer.GetMatchResultEmbed(result.MatchId);

                    e.Channel.SendMessageAsync(embed: embed);
                }
            }
        }
        catch (Exception ex)
        {
            Logger.Log(ex, LogLevel.Error);
            throw;
        }
    }
예제 #12
0
        /// <summary>
        /// Invokes a <see cref="ICommand"/>
        /// </summary>
        public void Invoke(MessageCreateEventArgs e)
        {
            try
            {
                if (e == null)
                {
                    return;
                }

                DiscordGuildConfig config = null;
                char guildPrefix          = CommandPrefix;
                if (e.Guild != null)
                {
                    using DBContext c = new DBContext();
                    config            = c.DiscordGuildConfig.FirstOrDefault(dgc => dgc.GuildId == (long)e.Guild.Id);
                    User user  = c.User.FirstOrDefault(u => u.DiscordUserId == (long)e.Author.Id);
                    long osuId = user == null ? 0 : user.OsuUserId;

                    List <BannedUser> bans = BanManager.GetBansForUser((long)e.Author.Id, osuId, e.Guild == null ? 0 : (long)e.Guild.Id);

                    if (bans.Count > 0)
                    {
                        OnBannedUserDetected(e, bans);
                        return;
                    }

                    if (config != null && config.Prefix.HasValue)
                    {
                        guildPrefix = config.Prefix.Value;
                    }
                }

                if (!e.Message.Content[0].Equals(guildPrefix))
                {
                    return;
                }

                List <string> parameters = e.Message.Content.Split(' ').Skip(0).ToList();

                if (parameters == null)
                {
                    parameters = new List <string>();
                }

                string command;
                if (parameters.Count == 0)
                {
                    command = e.Message.Content;
                }
                else
                {
                    command = parameters[0];
                }

                command = command.TrimStart(guildPrefix);

                AccessLevel access = GetAccessLevel(e.Author.Id, e.Guild?.Id ?? 0);

                if (!_commandTypes.TryGetValue(command.ToLower(System.Globalization.CultureInfo.CurrentCulture), out ICommand cmd) ||
                    config != null && access <= AccessLevel.VIP && config.CommandChannelId > 0 && config.CommandChannelId != (long)e.Channel.Id)
                {
                    return;
                }
                else if (cmd.IsDisabled)
                {
                    e.Channel.SendMessageAsync("Command is currently disabled");
                    return;
                }

                switch (cmd.CommandType)
                {
                default:
                case CommandType.None:
                    break;

                case CommandType.Private:
                    if (e.Guild != null)
                    {
                        e.Channel.SendMessageAsync("You can only use this command in a private chat!");
                        return;
                    }
                    break;

                case CommandType.Public:
                    if (e.Guild == null)
                    {
                        e.Channel.SendMessageAsync("You can only use this command in a server chat!");
                        return;
                    }
                    break;
                }

                AccessLevel cmdAccess = e.Guild == null ? cmd.AccessLevel : GetCommandAccessLevel(cmd, e.Guild.Id);

                if (access < cmdAccess)
                {
                    OnException(e.Channel, cmd, "You do not have enough permissions to use this command");
                    return;
                }

                if (parameters.Count > 0)
                {
                    parameters.RemoveAt(0);
                }

                if (cmd.MinParameters > 0 && parameters.Count < cmd.MinParameters)
                {
                    OnException(e.Channel, cmd, "Not enough parameters");
                    return;
                }

                string afterCmd = e.Message.Content;

                if (afterCmd.Length > cmd.Command.Length + 1)
                {
                    afterCmd = afterCmd.Remove(0, cmd.Command.Length + 2);
                }
                else
                {
                    afterCmd = string.Empty;
                }

                DiscordMember member = null;
                if (e.Guild != null)
                {
                    try
                    {
                        member = e.Guild.GetMemberAsync(e.Author.Id).ConfigureAwait(false).GetAwaiter().GetResult();
                    }
                    catch (AggregateException ex)
                    {
                        if (!ex.InnerExceptions.Any(e => e is NotFoundException))
                        {
                            throw;
                        }
                    }
                }

                CommandEventArg arg = new CommandEventArg(e.Guild, e.Channel, e.Author, member,
                                                          e.Message, access, parameters, afterCmd,
                                                          config);

                ThreadPool.QueueUserWorkItem(new WaitCallback(o =>
                {
                    try
                    {
                        cmd.Invoke(DiscordHandler, this, arg);
                    }
#pragma warning disable CA1031 // Do not catch general exception types
                    catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                    {
                        if (ex is UnauthorizedException)
                        {
                            OnException?.Invoke(e.Channel, cmd, "Unauthorized, please allow direct messages (if you have direct messages enabled and this keeps happening, please report it)");
                            Logger.Log($"Unauthorized: " + ex, LogLevel.Warning);

                            return;
                        }

                        string debugMsg = $"Something went wrong while invoking command {cmd.Command}, message: {arg.Message.Content} from {arg.User.Username}#{arg.User.Discriminator} ({arg.User.Id}):\n {ex.ToString()}";
                        Logger.Log(debugMsg, LogLevel.Warning);

                        if (arg.Config != null && arg.Config.Debug)
                        {
                            OnException?.Invoke(e.Channel, cmd, GetDebugExceptionMessage(ex));

                            if (arg.Config.DebugChannel != 0)
                            {
                                try
                                {
                                    var dchannel = arg.Guild.GetChannel((ulong)arg.Config.DebugChannel);
                                    dchannel.SendMessageAsync(debugMsg).ConfigureAwait(false);
                                }
#pragma warning disable CA1031 // Do not catch general exception types
                                catch (Exception)
#pragma warning restore CA1031 // Do not catch general exception types
                                {
                                    //If we catch an exception here, there is nothing we can do, so just ignore it
                                }
                            }
                        }
                        else
                        {
                            OnException?.Invoke(e.Channel, cmd, $"Something went wrong executing this command");
                        }
                    }
                }));
            }
#pragma warning disable CA1031 // Do not catch general exception types
            catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
            {
                Logger.Log(ex, LogLevel.Error);
            }

            string GetDebugExceptionMessage(Exception ex)
            {
                return($"Something went wrong executing this command (L: {ex.GetLineNumber()} At: {ex.TargetSite.DeclaringType}.{ex.TargetSite.Name}: {ex.Message})");
            }
        }
예제 #13
0
        public void Invoke(DiscordHandler client, CommandHandler handler, CommandEventArg args)
        {
            using DBContext c = new DBContext();
            DiscordGuildConfig dgc = args.Config;

            if (dgc == null || dgc.MutedRoleId == 0)
            {
                args.Channel.SendMessageAsync("You need to setup your muted role first in the config");
                return;
            }

            args.Parameters[0] = args.Parameters[0].Trim('<', '@', '!', '>');

            DiscordMember member = null;

            if (ulong.TryParse(args.Parameters[0], out ulong uid))
            {
                try
                {
                    member = args.Guild.GetMemberAsync(uid).ConfigureAwait(false).GetAwaiter().GetResult();
                }
                catch (DSharpPlus.Exceptions.NotFoundException)
                {
                }
            }

            if (member == null)
            {
                HelpCommand.ShowHelp(args.Channel, this, "Could not find member or parse id: " + args.Parameters[0]);
                return;
            }

            if (!long.TryParse(args.Parameters[1], out long durationM))
            {
                HelpCommand.ShowHelp(args.Channel, this, "Failed to parse duration: " + args.Parameters[1]);
                return;
            }

            var  drole = args.Guild.GetRole((ulong)dgc.MutedRoleId);
            Mute m;

            if (member.Roles.Contains(drole))
            {
                //Update duration if diffrent
                m = c.Mute.FirstOrDefault(mu => mu.DiscordGuildId == (long)args.Guild.Id && mu.DiscordUserId == (long)uid && !mu.Unmuted);

                if (m != null)
                {
                    if (m.DurationM == durationM)
                    {
                        args.Channel.SendMessageAsync("Not updated, time is the same");
                        return;
                    }

                    m.DurationM = durationM;
                    c.Mute.Update(m);
                    c.SaveChanges();

                    args.Channel.SendMessageAsync("Updated duration");

                    return;
                }
                else
                {
                    member.RevokeRoleAsync(drole, "invalid mute, revoking").ConfigureAwait(false).GetAwaiter().GetResult();
                }
            }

            if (args.Parameters.Count < 3)
            {
                HelpCommand.ShowHelp(args.Channel, this);
                return;
            }

            StringBuilder reasonBuilder = new StringBuilder(args.Parameters[2]);

            for (int i = 3; i < args.Parameters.Count; i++)
            {
                reasonBuilder.Append(" " + args.Parameters[i]);
            }

            m = new Mute((long)uid, (long)args.Guild.Id, DateTime.UtcNow, durationM, args.ParameterString.Remove(0, args.Parameters[0].Length + args.Parameters[1].Length + 2));

            member.GrantRoleAsync(drole, $"muted by {args.User.Username} for {durationM} minutes, reason: {m.Reason}");

            c.Mute.Add(m);
            c.SaveChanges();

            args.Channel.SendMessageAsync($"Muted {member.Username} for {durationM} minutes, reason: {m.Reason}");
        }