// 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; } } }