コード例 #1
0
        private async Task HandleCommandsAsync(SocketMessage m)
        {
            try
            {
                // Stats and stuff.
                MessagesReceived++;

                // Make sure that this object can be a SocketUserMessage before processing anything.
                // Then store the cast in "message" with C# magic.
                // Exit otherwise.
                if (!(m is SocketUserMessage message))
                {
                    return;
                }

                // Only continue if the author is not a bot.
                if (message.Author.IsBot)
                {
                    return;
                }

                // Try to extract and upcast the channel.
                // Same logic as before but without SocketContext overhead.
                if (!(m.Channel is SocketGuildChannel channel))
                {
                    // TODO: Should we mock the D.NET behaviour here?
                    // They seem to assign null if the cast is not possible.
                    // This needs more investigation.

                    // For now we'll just exit here.
                    return;
                }

                // Check if invoker is banend
                if (_banService.IsBanned(message.Author.Id))
                {
                    return;
                }

                // Check the permissions of this channel
                if (await Utility.CheckReadWritePerms(channel.Guild, channel, false) == false)
                {
                    return;
                }

                // Check the ratelimit of this author
                if (await _ratelimitingService.IsRatelimited(message.Author.Id))
                {
                    return;
                }

                // Permissions are present and author is eligible for commands.
                // Get a database instance.
                using (var soraContext = new SoraContext())
                {
                    //Hand it over to the AFK Service to do its thing. Don't await to not block command processing.
                    _afkService.Client_MessageReceived(m, _services);

                    // Look for a prefix but use a hardcoded fallback instead of creating a default guild.
                    // TODO: Move this into the config file
                    var prefix = Utility.GetGuildPrefixFast(soraContext, channel.Guild.Id, "$");

                    // Check if the message starts with the prefix or mention before doing anything else.
                    // Also rely on stdlib stuff for that because #performance.

                    int argPos = prefix.Length - 1;
                    if (!(message.HasStringPrefix(prefix, ref argPos) || message.HasMentionPrefix(_client.CurrentUser, ref argPos)))
                    {
                        return;
                    }

                    // Detection finished.
                    // We know it's *very likely* a command for us.
                    // It's safe to create a context now.
                    var context = new SocketCommandContext(_client, message);

                    // Also allocate a default guild if needed since we skipped that part earlier.
                    Utility.GetOrCreateGuild(channel.Guild.Id, soraContext);
                    // Handoff control to D.NET
                    var result = await _commands.ExecuteAsync(
                        context,
                        argPos,
                        _services
                        );

                    // Handle errors if needed
                    if (result.IsSuccess)
                    {
                        CommandsExecuted++;
                        _ratelimitingService.RateLimitMain(context.User.Id);
                    }
                    else
                    {
                        //await context.Channel.SendMessageAsync($"**FAILED**\n{result.ErrorReason}");
                        await HandleErrorAsync(result, context);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
            }
        }