Beispiel #1
0
        // this class is where the magic starts, and takes actions upon receiving messages
        public async Task MessageReceivedAsync(SocketMessage rawMessage)
        {
            // ensures we don't process system/other bot messages
            if (!(rawMessage is SocketUserMessage message))
            {
                return;
            }

            if (message.Source != MessageSource.User)
            {
                return;
            }

            // sets the argument position away from the prefix we set
            var argPos = 0;

            // get prefix from the database (if we can)
            string prefix;

            if (message.Channel is IGuildChannel guildChannel)
            {
                var props = _spService.GetProperties(guildChannel.GuildId);
                prefix = props.Prefix ?? _config["Prefix"];
            }
            else
            {
                prefix = _config["Prefix"];
            }

            // determine if the message has a valid prefix, and adjust argPos based on prefix
            if (!(message.HasMentionPrefix(_client.CurrentUser, ref argPos) || message.HasStringPrefix(prefix, ref argPos)))
            {
                return;
            }
            var context = new ShardedCommandContext(_client, message);

            // figure out what module the command is in (if any)
            // command search code based on code from CommandService.ExecuteAsync
            var searchResult = await CommandSearch(context, argPos).ConfigureAwait(false);

            if (searchResult == null)
            {
                return;                       // command not found
            }
            bool enabled = true;

            if (context.Guild != null)
            {
                enabled = _spService.IsModuleEnabled(searchResult.Module, context.Guild.Id);
            }
            // execute command if one is found that matches and it's in an enabled module
            if (enabled)
            {
                await Commands.ExecuteAsync(context, argPos, _services).ConfigureAwait(false);
            }
        }
        /// <summary>
        /// Installs event listeners for type `t`
        /// </summary>
        /// <param name="t">Type to look for events on</param>
        /// <param name="parentModuleName">Module name to use for checking enabled/disabled status</param>
        public void InstallEventListeners(Type t, string parentModuleName = null, string serviceDesc = "No description set")
        {
            if (parentModuleName != null)
            {
                if (SpService == null)
                {
                    throw new Exception("Server properties service wasn't set while module name was set!");
                }
                SpService.DisableableServices.Add(parentModuleName, serviceDesc);
            }
            parentModuleName = "service." + parentModuleName;

            var methods = t.GetMethods().Where(method => method.GetCustomAttributes(typeof(EventListenerAttribute), false).Length > 0);

            foreach (var method in methods)
            {
                var attrib = method.GetCustomAttributes(typeof(EventListenerAttribute), false)[0] as EventListenerAttribute;
                switch (attrib.Event)
                {
                case Event.UserVoiceStateUpdated:
                    Client.UserVoiceStateUpdated += (user, before, after) =>
                    {
                        if (parentModuleName == null)
                        {
                            return(method.Invoke(this, new object[] { user, before, after }) as Task);
                        }
                        // please never copy this code for any purpose. like, really, there's probably a better way to do what you need to do.
                        if (before.VoiceChannel != null && !SpService.IsModuleEnabled(parentModuleName, before.VoiceChannel.Guild.Id))
                        {
                            var field = before.GetType().GetRuntimeFields()
                                        .FirstOrDefault(f => Regex.IsMatch(f.Name, $"\\A<{nameof(before.VoiceChannel)}>k__BackingField\\Z"));
                            field.SetValue(before, null);
                        }
                        if (after.VoiceChannel != null && !SpService.IsModuleEnabled(parentModuleName, after.VoiceChannel.Guild.Id))
                        {
                            var field = after.GetType().GetRuntimeFields()
                                        .FirstOrDefault(f => Regex.IsMatch(f.Name, $"\\A<{nameof(after.VoiceChannel)}>k__BackingField\\Z"));
                            field.SetValue(after, null);
                        }
                        if (before.VoiceChannel == null && after.VoiceChannel == null)
                        {
                            return(Task.CompletedTask);
                        }

                        return(method.Invoke(this, new object[] { user, before, after }) as Task);
                    };
                    break;

                case Event.MessageReceived:
                    Client.MessageReceived += (message) =>
                    {
                        if (parentModuleName == null || !(message.Channel is IGuildChannel))
                        {
                            return(method.Invoke(this, new object[] { message }) as Task);
                        }
                        if (!SpService.IsModuleEnabled(parentModuleName, ((IGuildChannel)message.Channel).GuildId))
                        {
                            return(Task.CompletedTask);
                        }
                        return(method.Invoke(this, new object[] { message }) as Task);
                    };
                    break;

                case Event.MessageUpdated:
                    Client.MessageUpdated += (cachedMessage, message, channel) =>
                    {
                        if (parentModuleName == null || !(channel is IGuildChannel))
                        {
                            return(method.Invoke(this, new object[] { cachedMessage, message, channel }) as Task);
                        }
                        if (!SpService.IsModuleEnabled(parentModuleName, ((IGuildChannel)channel).GuildId))
                        {
                            return(Task.CompletedTask);
                        }
                        return(method.Invoke(this, new object[] { cachedMessage, message, channel }) as Task);
                    };
                    break;
                }
            }
        }