private async Task HandleErrorAsync(LogMessage logMessage) { var commandException = logMessage.Exception as CommandException; if (commandException == null) { return; } await HandleErrorAsync(ExecuteResult.FromError(commandException), (SocketCommandContext)commandException.Context, commandException); }
public virtual async Task <IResult> MessageReceived(CommandContext context) { var message = context.Message; int cmdPos = 0; if (!(message.HasCharPrefix('!', ref cmdPos) || message.HasMentionPrefix(Client.CurrentUser, ref cmdPos))) { return(ExecuteResult.FromError(CommandError.UnknownCommand, "")); } return(await Commands.ExecuteAsync(context, cmdPos, Services)); }
/// <summary> /// Execute the function based on the interaction data we get. /// </summary> /// <param name="data">Interaction data from interaction</param> /// <param name="interaction">SocketInteraction</param> public async Task <IResult> ExecuteAsync(IReadOnlyCollection <SocketInteractionDataOption> data, SocketInteraction interaction) { // Array of arguments to be passed to the Delegate var args = new object[Parameters.Count]; try { // For each parameter to try find its coresponding DataOption based on the name. // !!! names from `data` will always be lowercase regardless if we defined the command with any // number of upercase letters !!! for (var i = 0; i < Parameters.Count; i++) { var parameter = Parameters[i]; if (TryGetInteractionDataOption(data, parameter.Name, out var dataOption)) { args[i] = parameter.Parse(dataOption); } } } catch (Exception e) { return(ExecuteResult.FromError(e)); } var instance = ReflectionUtils.CreateObject <ISlashCommandModule>(Module.ModuleType, Module.Service, Module.ServiceProvider); instance.SetContext(interaction); var delegateMethod = SlashCommandServiceHelper.CreateDelegate(MethodInfo, instance); var callback = new Func <object[], Task <IResult> >(async callbackArgs => { // Try-catch it and see what we get - error or success try { await Task.Run(() => { delegateMethod.DynamicInvoke(callbackArgs); }).ConfigureAwait(false); } catch (Exception e) { return(ExecuteResult.FromError(e)); } return(ExecuteResult.FromSuccess()); }); return(await callback.Invoke(args).ConfigureAwait(false)); }
public async Task HandleMessagesAsync(SocketMessage msg) { if (msg is SocketUserMessage message) { var _ = 0; var prefix = (message.Channel is ITextChannel) ? Configuration.Guilds.GetGuild( (message.Channel as ITextChannel).GuildId).Prefix : Prefix; if (message.HasPrefix(prefix, Socket.CurrentUser, ref _)) { return; } var context = new CWBContext(this, message); foreach (var type in IListeners) { var listener = DependencyInjection.CreateInjected <IListener>(type, Services, context); if (listener.GetRunMode() == RunMode.Async) { await Task.Run(async() => { try { await listener.ExecuteAsync(); } catch (Exception e) { await HandleCommandError(ExecuteResult.FromError(e)); } }); } else { try { await listener.ExecuteAsync(); } catch (Exception e) { await HandleCommandError(ExecuteResult.FromError(e)); } } } } }
protected virtual ExecuteResult OnExecute(IExecuteContext executionContext, TraceInfo traceInfo) { _ = executionContext ?? throw new ArgumentNullException(nameof(executionContext)); _ = traceInfo ?? throw new ArgumentNullException(nameof(traceInfo)); IActionContext actionContext = null; try { //1 resolve action name var actionName = this.OnResolveActionName(executionContext.ActionFullName); traceInfo.ActionName = actionName; //2 get runtime info var runtimeInfo = this.OnGetActionRuntime(actionName); traceInfo.ActionRuntime = runtimeInfo; //3 prepare package this.OnPrepareAction(actionName, runtimeInfo); //4 get meta info var metaInfo = this.OnGetActionMeta(actionName); traceInfo.ActionMeta = metaInfo; //5 resolve action factory var actionFactory = this.OnResolveActionFactory(metaInfo); //6 create action context actionContext = this.OnCreateActionContext(executionContext, actionName, runtimeInfo, metaInfo); //7 check premission this.OnCheckPremission(actionContext); //8 valid inputs this.OnValidInputs(actionContext); //9 create action instance var actionInstance = this.OnCreateActionInstance(actionFactory, actionContext); //10 run action var result = OnRunAction(actionInstance, executionContext, actionContext); //11 valid output this.OnValidOutput(actionContext, result); return(ExecuteResult.FromResult(result, actionContext.Logger.ToString())); } catch (Exception ex) { return(ExecuteResult.FromError(ex, actionContext?.Logger?.ToString())); } }
/// <summary> /// Sends a consent request to the given DM channel. /// </summary> /// <param name="channel">The channel.</param> /// <param name="content">The content service.</param> /// <param name="feedback">The feedback service.</param> /// <returns>An execution result.</returns> public async Task <ExecuteResult> RequestConsentAsync ( [NotNull] IDMChannel channel, [NotNull] ContentService content, [NotNull] UserFeedbackService feedback ) { try { var consentBuilder = feedback.CreateEmbedBase(Color.Orange); consentBuilder.WithDescription ( "Hello there! This appears to be the first time you're using the bot (or you've not granted your " + "consent for it to store potentially sensitive or identifiable data about you).\n" + "\n" + "In order to use Amby and her commands, you need to give her your consent to store various data " + "about you. We need this consent in order to be compliant with data regulations in the European " + "Union (and it'd be rude not to ask!).\n" + "\n" + "In short, if you use the bot, we're going to be storing " + "stuff like your Discord ID, some messages, server IDs, etc. You can - and should! - read the " + "full privacy policy before you agree to anything. It's not very long (3 pages) and shouldn't take " + "more than five minutes to read through.\n" + "\n" + "Once you've read it, you can grant consent by running the `!privacy grant-consent` command over DM. If you " + "don't want to consent to anything, just don't use the bot :smiley:" ); await channel.SendMessageAsync(string.Empty, embed : consentBuilder.Build()); await SendPrivacyPolicyAsync(channel, content, feedback); } catch (HttpException hex) when(hex.HttpCode == HttpStatusCode.Forbidden) { return(ExecuteResult.FromError(CommandError.Exception, "Could not send the privacy message over DM.")); } return(ExecuteResult.FromSuccess()); }
// Commands public static ExecuteResult AddRoleToAutoAssign(SocketCommandContext context, ulong roleID) { SQLiteConnection _connect = new SQLiteConnection(Constants.ConnectionString); try { SQLiteCommand command = new SQLiteCommand { Connection = _connect }; } catch (Exception ex) { LoggingService.LogAsync(LogSeverity.Error, _className, ex.Message); _result = ExecuteResult.FromError(CommandError.Unsuccessful, ex.Message); } finally { _connect.Close(); } return(_result); }
public async Task <IResult> ExecuteAsync(string commandString, IEnumerable <object> argList, IEnumerable <object> paramList, IServiceProvider services) { services = services ?? EmptyServiceProvider.Instance; try { object[] args = GenerateArgs(argList, paramList); for (int position = 0; position < Parameters.Count; position++) { var parameter = Parameters[position]; object argument = args[position]; var result = await parameter.CheckPreconditionsAsync(commandString, argument, services).ConfigureAwait(false); if (!result.IsSuccess) { return(ExecuteResult.FromError(result)); } } switch (RunMode) { case RunMode.Sync: //Always sync return(await ExecuteInternalAsync(commandString, args, services).ConfigureAwait(false)); case RunMode.Async: //Always async var t2 = Task.Run(async() => { await ExecuteInternalAsync(commandString, args, services).ConfigureAwait(false); }); break; } return(ExecuteResult.FromSuccess()); } catch (Exception ex) { return(ExecuteResult.FromError(ex)); } }
public static ExecuteResult ChangeModuleStatus(string moduleName, string guildID, bool moduleStatus) { SQLiteConnection _connect = new SQLiteConnection(Constants.ConnectionString); try { SQLiteCommand command = new SQLiteCommand { Connection = _connect }; if (CheckModuleStatus(moduleName, guildID) == false) { command.CommandText = $"UPDATE Guilds SET [{moduleName}] = '1' WHERE [GuildID] = '{guildID}'"; _result = ExecuteResult.FromSuccess(); } else if (CheckModuleStatus(moduleName, guildID) == true) { command.CommandText = $"UPDATE Guilds SET [{moduleName}] = '0' WHERE [GuildID] = {guildID}"; _result = ExecuteResult.FromSuccess(); } _connect.Open(); command.ExecuteNonQuery(); LoggingService.LogAsync(LogSeverity.Info, _className, $"{moduleName} has been changed for {guildID}."); } catch (Exception ex) { LoggingService.LogAsync(LogSeverity.Error, _className, ex.Message); _result = ExecuteResult.FromError(CommandError.Unsuccessful, ex.Message); } finally { _connect.Close(); } return(_result); }
public static ExecuteResult CheckGuild(string guildID, string guildName) { SQLiteConnection _connect = new SQLiteConnection(Constants.ConnectionString); try { SQLiteCommand command = new SQLiteCommand { Connection = _connect }; command.CommandText = $"SELECT COUNT(*) FROM Guilds WHERE (GuildID = '{guildID}')"; _connect.Open(); if (Convert.ToInt32(command.ExecuteScalar()) == 0) { AddGuild(guildID, guildName); _result = ExecuteResult.FromSuccess(); } else { LoggingService.LogAsync(LogSeverity.Info, _className, $"Guild {guildName} already exists in database."); _result = ExecuteResult.FromError(CommandError.Unsuccessful, $"Guild {guildName} already exists in database."); } } catch (Exception ex) { LoggingService.LogAsync(LogSeverity.Error, _className, ex.Message); _result = ExecuteResult.FromError(CommandError.Exception, ex.Message); } finally { _connect.Close(); } return(_result); }
/// <summary> /// Invites the user to the given roleplay. /// </summary> /// <param name="db">The database where the roleplays are stored.</param> /// <param name="roleplay">The roleplay to invite the user to.</param> /// <param name="invitedUser">The user to invite.</param> /// <returns>An execution result which may or may not have succeeded.</returns> public async Task <ExecuteResult> InviteUserAsync ( [NotNull] GlobalInfoContext db, [NotNull] Roleplay roleplay, [NotNull] IUser invitedUser ) { if (roleplay.IsPublic) { return(ExecuteResult.FromError(CommandError.UnmetPrecondition, "The roleplay is not set to private.")); } if (roleplay.InvitedUsers.Any(p => p.User.DiscordID == (long)invitedUser.Id)) { return(ExecuteResult.FromError(CommandError.Unsuccessful, "The user has already been invited to that roleplay.")); } // Remove the invited user from the kick list, if they're on it var participantEntry = roleplay.ParticipatingUsers.FirstOrDefault(p => p.User.DiscordID == (long)invitedUser.Id); if (participantEntry is null) { var user = await db.GetOrRegisterUserAsync(invitedUser); participantEntry = new RoleplayParticipant(roleplay, user, ParticipantStatus.Invited); roleplay.ParticipatingUsers.Add(participantEntry); } else { participantEntry.Status = ParticipantStatus.Invited; } await db.SaveChangesAsync(); return(ExecuteResult.FromSuccess()); }
/// <summary> /// Removes the given user from the given roleplay. /// </summary> /// <param name="db">The database where the roleplays are stored.</param> /// <param name="context">The context of the user.</param> /// <param name="roleplay">The roleplay to remove the user from.</param> /// <param name="removedUser">The user to remove from the roleplay.</param> /// <returns>An execution result which may or may not have succeeded.</returns> public async Task <ExecuteResult> RemoveUserFromRoleplayAsync ( [NotNull] GlobalInfoContext db, [NotNull] SocketCommandContext context, [NotNull] Roleplay roleplay, [NotNull] IUser removedUser ) { var isCurrentUser = context.Message.Author.Id == removedUser.Id; if (!roleplay.HasJoined(removedUser)) { var errorMessage = isCurrentUser ? "You're not in that roleplay." : "No matching user found in the roleplay."; return(ExecuteResult.FromError(CommandError.Unsuccessful, errorMessage)); } if (roleplay.IsOwner(removedUser)) { var errorMessage = isCurrentUser ? "You can't leave a roleplay you own." : "The owner of a roleplay can't be removed from it."; return(ExecuteResult.FromError(CommandError.Unsuccessful, errorMessage)); } var participantEntry = roleplay.JoinedUsers.First(p => p.User.DiscordID == (long)removedUser.Id); participantEntry.Status = ParticipantStatus.None; await db.SaveChangesAsync(); return(ExecuteResult.FromSuccess()); }
private async Task <ExecuteResult> HelpOverallAsync(ICommandContext context, object[] parameters, IServiceProvider services, CommandInfo invokedHelpCmd) { const int pageSize = 4; // param logic is enforced by the command service int pageNumber = (int)parameters[0]; CommandInfo[] cmds = await _commands.Commands.ToAsyncEnumerable() .WhereAsync(async cmd => { ModuleInfo rootModule = cmd.Module; while (rootModule?.Parent != null) { rootModule = rootModule.Parent; } if (rootModule.Name == "help" && cmd.Aliases.SingleIfOne() != "help") { return(false); } bool preconditionSuccess = false; try { preconditionSuccess = (await cmd.CheckPreconditionsAsync(context, services)).IsSuccess; } catch { } // all commands OK, except: generated help commands and commands where preconditions are not met // only the overall help command should be displayed in help return(preconditionSuccess); }).OrderBy(cmd => cmd.Aliases[0]).ToArray().ConfigureAwait(false); int pageCount = Utilities.CeilingDivision(cmds.Length, pageSize); if (pageNumber < 1 || pageNumber > pageCount) { return(ExecuteResult.FromError(CommandError.Unsuccessful, "The given page number is invalid (too high or too low).")); } EmbedBuilder builder = new EmbedBuilder() { Title = "Help", Description = "Commands applicable in the current context (e.g. DM, guild channel) with your permission level.", Color = Color.DarkBlue }; Models.Guild guildPrefs; if (context.Guild != null && (guildPrefs = await _database.FindOneAsync <Models.Guild>(g => g.Id == context.Guild.Id)) != null && guildPrefs.Prefix != null) { builder.Description += "\n\nThis guild's prefix is: `" + guildPrefs.Prefix + "`"; } foreach (var cmd in cmds.Skip((pageNumber - 1) * pageSize).Take(pageSize)) { BuildHelpAsField(builder, cmd); } builder.WithFooter(footer => footer.WithText($"Page {pageNumber} of {pageCount}")); await context.Channel.SendMessageAsync(string.Empty, embed : builder.Build()).ConfigureAwait(false); return(ExecuteResult.FromSuccess()); }