예제 #1
0
        public async Task <IResult> ExecuteAsync(SocketCommandContext commandContext, int argumentPosition)
        {
            if (commandContext.Channel.Name != GetBotChannel())
            {
                return(ExecuteResult.FromSuccess());
            }

            SearchResult searchResult = innerService.Search(commandContext, argumentPosition);

            if (!searchResult.IsSuccess)
            {
                return(await ExecuteDefaultResponse(commandContext, argumentPosition));
            }

            bool matchIsDevCommand = searchResult.Commands.Any(command =>
                                                               command.Command.Attributes.Any(attribute =>
                                                                                              attribute is DevelopmentAttribute));

            if (!IsDevelopmentEnvironment() && matchIsDevCommand)
            {
                return(ExecuteResult.FromSuccess());
            }

            return(await innerService.ExecuteAsync(commandContext, argumentPosition, services));
        }
예제 #2
0
        public override async Task <IResult> MessageReceived(TyniBot.CommandContext context)
        {
            var message = context.Message;
            var channel = context.Channel;

            KeyValuePair <string, string> addition = ParseMsg(message);
            await message.DeleteAsync();

            var boardMsg = (await channel.GetMessagesAsync(1).FlattenAsync()).FirstOrDefault();

            Dictionary <string, string> board = StringToBoard(boardMsg.Content);

            if (board.ContainsKey(addition.Key))
            {
                board[addition.Key] = addition.Value;
            }
            else
            {
                board.Add(addition.Key, addition.Value);
            }

            await boardMsg.DeleteAsync();

            await channel.SendMessageAsync(BoardToString(board));

            return(ExecuteResult.FromSuccess());
        }
예제 #3
0
        public override async Task <IResult> MessageReceived(CommandContext context)
        {
            if (context.User.IsBot || context.User.IsWebhook)
            {
                return(ExecuteResult.FromSuccess());                                              // ignore bot messages
            }
            var msgCollection = context.Database.GetCollection <PinnedMessage>();
            var pinnedMsg     = msgCollection.Find(m => m.ChannelId == context.Channel.Id).FirstOrDefault();

            if (pinnedMsg == null)                           // no message has been pinned yet
            {
                return(await base.MessageReceived(context)); // proceed as normal
            }
            else // we have a pinned message
            {
                // is this the unpin command?
                var result = await base.MessageReceived(context);

                if (result.IsSuccess) // if we processed a command then return
                {
                    return(result);
                }

                // delete last pinned message
                await context.Channel.DeleteMessageAsync(pinnedMsg.MsgId);

                // write pinned message again
                var newPin = await context.Channel.SendMessageAsync($"**Pinned Message from: {pinnedMsg.Author}\n\n**{pinnedMsg.Content}");

                // update database
                pinnedMsg.MsgId = newPin.Id;
                msgCollection.Update(pinnedMsg);
                return(ExecuteResult.FromSuccess());
            }
        }
예제 #4
0
        public override async Task <IResult> MessageReceived(TyniBot.CommandContext context)
        {
            var message = context.Message;
            var channel = context.Channel;
            //var user = context.User;
            //var role = context.Guild.Roles.FirstOrDefault(x => x.Id == 740316086284845093);

            KeyValuePair <string, string> addition = ParseMsg(message);
            await message.DeleteAsync();

            var boardMsg = (await channel.GetMessagesAsync(1).FlattenAsync()).FirstOrDefault();

            Dictionary <string, string> board = StringToBoard(boardMsg.Content);

            if (board.ContainsKey(addition.Key))
            {
                board[addition.Key] = addition.Value;
            }
            else
            {
                board.Add(addition.Key, addition.Value);
            }

            //await (user as IGuildUser).AddRoleAsync(role);

            await boardMsg.DeleteAsync();

            await channel.SendMessageAsync(BoardToString(board));

            return(ExecuteResult.FromSuccess());
        }
예제 #5
0
        private async Task <ExecuteResult> OpenCategory(string categoryName)
        {
            var getCategoryResult = this.Categories.Select(c => c.ToString()).BestLevenshteinMatch(categoryName, 0.75);

            if (!getCategoryResult.IsSuccess)
            {
                return(ExecuteResult.FromError(getCategoryResult));
            }

            if (!Enum.TryParse <KinkCategory>(getCategoryResult.Entity, true, out var category))
            {
                return(ExecuteResult.FromError(CommandError.ParseFailed, "Could not parse kink category."));
            }

            var getKinkResult = await this.Kinks.GetFirstKinkWithoutPreferenceInCategoryAsync(this.Database, this.Context.User, category);

            if (!getKinkResult.IsSuccess)
            {
                getKinkResult = await this.Kinks.GetFirstKinkInCategoryAsync(this.Database, category);
            }

            if (!getKinkResult.IsSuccess)
            {
                return(ExecuteResult.FromError(getKinkResult));
            }

            var kink = getKinkResult.Entity;

            this.CurrentFListKinkID = (int)kink.FListID;

            this.State = KinkWizardState.KinkPreference;

            return(ExecuteResult.FromSuccess());
        }
예제 #6
0
        public static ExecuteResult AssignPreconditionToChannel(SocketCommandContext context, string preconName, ulong roleID, ulong channelID)
        {
            SQLiteConnection _connect = new SQLiteConnection(Constants.ConnectionString);

            try
            {
                SQLiteCommand command = new SQLiteCommand {
                    Connection = _connect
                };

                command.CommandText = $"INSERT INTO GuildPrecon(GuildID, PreconName, PreconRole, PreconChannel) VALUES ('{context.Guild.Id}', '{preconName}', '{roleID}', '{channelID}')";

                _connect.Open();
                command.ExecuteNonQuery();
                LoggingService.LogAsync(LogSeverity.Info, _className, $"Role {preconName} been assigned to {roleID} to only be used in {channelID} for {context.Guild.Name.ToString()}");
                _result = ExecuteResult.FromSuccess();
            }
            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(SocketMessageComponent arg)
        {
            if (!messages.TryGetValue(arg.Message?.Id ?? 0, out var data))
            {
                return(ExecuteResult.FromError(CommandError.Unsuccessful, "No state data found, unknown callback"));
            }

            var args = new CallbackEventArgs()
            {
                ComponentId = arg.Data.CustomId,
                Message     = arg.Message,
                State       = data.State,
                User        = arg.User,
                Interaction = arg
            };

            try
            {
                var result = await data.Method.Invoke(args).ConfigureAwait(false);

                return(result);
            } catch (Exception ex)
            {
                return(ExecuteResult.FromError(ex));
            }
            return(ExecuteResult.FromSuccess());
        }
예제 #8
0
        public static ExecuteResult RemovePreconditionRole(SocketCommandContext context, string preconName, ulong roleID)
        {
            SQLiteConnection _connect = new SQLiteConnection(Constants.ConnectionString);

            try
            {
                SQLiteCommand command = new SQLiteCommand {
                    Connection = _connect
                };

                command.CommandText = $"DELETE FROM GuildPrecon WHERE (GuildID = '{context.Guild.Id}') AND (PreconName = '{preconName}') AND (PreconRole = '{roleID}')";

                _connect.Open();
                command.ExecuteNonQuery();
                _result = ExecuteResult.FromSuccess();
            }
            catch (Exception ex)
            {
                LoggingService.LogAsync(LogSeverity.Error, _className, ex.Message);
                _result = ExecuteResult.FromError(CommandError.Unsuccessful, ex.Message);
            }
            finally
            {
                _connect.Close();
            }

            return(_result);
        }
예제 #9
0
        /// <summary>
        /// Kicks 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="kickedUser">The user to remove from the roleplay.</param>
        /// <returns>An execution result which may or may not have succeeded.</returns>
        public async Task <ExecuteResult> KickUserFromRoleplayAsync
        (
            [NotNull] GlobalInfoContext db,
            [NotNull] SocketCommandContext context,
            [NotNull] Roleplay roleplay,
            [NotNull] IUser kickedUser
        )
        {
            if (!roleplay.HasJoined(kickedUser) && !roleplay.IsInvited(kickedUser))
            {
                return(ExecuteResult.FromError(CommandError.ObjectNotFound, "That user is neither invited to or a participant of the roleplay."));
            }

            if (!roleplay.HasJoined(kickedUser))
            {
                var removeUserResult = await RemoveUserFromRoleplayAsync(db, context, roleplay, kickedUser);

                if (!removeUserResult.IsSuccess)
                {
                    return(removeUserResult);
                }
            }

            var participantEntry = roleplay.JoinedUsers.First(p => p.User.DiscordID == (long)kickedUser.Id);

            participantEntry.Status = ParticipantStatus.Kicked;

            await db.SaveChangesAsync();

            return(ExecuteResult.FromSuccess());
        }
예제 #10
0
        public static ExecuteResult RemoveGuild(string guildID, string guildName)
        {
            SQLiteConnection _connect = new SQLiteConnection(Constants.ConnectionString);

            try
            {
                SQLiteCommand command = new SQLiteCommand {
                    Connection = _connect
                };

                command.CommandText = $"DELETE FROM Guilds WHERE GuildID = '{guildID}'";

                _connect.Open();
                command.ExecuteNonQuery();

                LoggingService.LogAsync(LogSeverity.Info, _className, $"Guild {guildName} removed from the database.");
                _result = ExecuteResult.FromSuccess();
            }
            catch (Exception ex)
            {
                LoggingService.LogAsync(LogSeverity.Error, _className, ex.Message);
                _result = ExecuteResult.FromError(CommandError.Exception, ex.Message);
            }
            finally
            {
                _connect.Close();
            }

            return(_result);
        }
예제 #11
0
        private async Task <IResult> ExecuteInternalAsync(string commandString, object[] args, IServiceProvider services)
        {
            try
            {
                var task = _action(commandString, args, services, this);
                if (task is Task <IResult> resultTask)
                {
                    var result = await resultTask.ConfigureAwait(false);

                    if (result is RuntimeResult execResult)
                    {
                        return(execResult);
                    }
                }
                else if (task is Task <ExecuteResult> execTask)
                {
                    var result = await execTask.ConfigureAwait(false);

                    return(result);
                }
                else
                {
                    await task.ConfigureAwait(false);

                    var result = ExecuteResult.FromSuccess();
                }

                var executeResult = ExecuteResult.FromSuccess();
                return(executeResult);
            }
            catch (Exception ex)
            {
                var originalEx = ex;
                while (ex is TargetInvocationException) //Happens with void-returning commands
                {
                    ex = ex.InnerException;
                }

                var wrappedEx = new CommandException(this, commandString, ex);

                var result = ExecuteResult.FromError(ex);

                if (Module.Service._throwOnError)
                {
                    if (ex == originalEx)
                    {
                        throw;
                    }
                    else
                    {
                        ExceptionDispatchInfo.Capture(ex).Throw();
                    }
                }

                return(result);
            }
        }
예제 #12
0
        /// <summary>
        /// Adds the given user to 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 add the user to.</param>
        /// <param name="newUser">The user to add to the roleplay.</param>
        /// <returns>An execution result which may or may not have succeeded.</returns>
        public async Task <ExecuteResult> AddUserToRoleplayAsync
        (
            [NotNull] GlobalInfoContext db,
            [NotNull] SocketCommandContext context,
            [NotNull] Roleplay roleplay,
            [NotNull] IUser newUser
        )
        {
            var isCurrentUser = context.Message.Author.Id == newUser.Id;

            if (roleplay.HasJoined(newUser))
            {
                var errorMessage = isCurrentUser
                                        ? "You're already in that roleplay."
                                        : "The user is aleady in that roleplay.";

                return(ExecuteResult.FromError(CommandError.Unsuccessful, errorMessage));
            }

            if (roleplay.IsKicked(newUser))
            {
                var errorMessage = isCurrentUser
                                        ? "You've been kicked from that roleplay, and can't rejoin unless invited."
                                        : "The user has been kicked from that roleplay, and can't rejoin unless invited.";

                return(ExecuteResult.FromError(CommandError.UnmetPrecondition, errorMessage));
            }

            // Check the invite list for nonpublic roleplays.
            if (!roleplay.IsPublic && !roleplay.IsInvited(newUser))
            {
                var errorMessage = isCurrentUser
                                        ? "You haven't been invited to that roleplay."
                                        : "The user hasn't been invited to that roleplay.";

                return(ExecuteResult.FromError(CommandError.UnmetPrecondition, errorMessage));
            }

            var participantEntry = roleplay.ParticipatingUsers.FirstOrDefault(p => p.User.DiscordID == (long)newUser.Id);

            if (participantEntry is null)
            {
                var user = await db.GetOrRegisterUserAsync(newUser);

                participantEntry = new RoleplayParticipant(roleplay, user, ParticipantStatus.Joined);
                roleplay.ParticipatingUsers.Add(participantEntry);
            }
            else
            {
                participantEntry.Status = ParticipantStatus.Joined;
            }

            await db.SaveChangesAsync();

            return(ExecuteResult.FromSuccess());
        }
예제 #13
0
        public async Task <IResult> TryParseCommand(TyniCommandContext context)
        {
            var message = context.Message;

            int cmdPos = 0;

            if (!(message.HasCharPrefix('!', ref cmdPos) || message.HasMentionPrefix(Client.CurrentUser, ref cmdPos)))
            {
                return(ExecuteResult.FromSuccess());
            }

            return(await Commands.ExecuteAsync(context, cmdPos, Services));
        }
예제 #14
0
        /// <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));
        }
예제 #15
0
        public static async Task <IResult> ExecuteAsync(SocketUserMessage message, ICommandContext context)
        {
            StringComparison compare = StringComparison.OrdinalIgnoreCase;;

            foreach (string[] keys in delegates.Keys)
            {
                foreach (string key in keys)
                {
                    int index = message.Content.IndexOf(key, compare);
                    if (index > -1)
                    {
                        return(await delegates[keys].Invoke(message, context, index, key));
                    }
                }
            }
            return(ExecuteResult.FromSuccess());
        }
예제 #16
0
        public async Task <IResult> ExecuteDefaultResponse(SocketCommandContext commandContext, int argumentPosition)
        {
            if (!commandContext.IsPrivate && commandContext.Channel.Name != GetBotChannel())
            {
                return(ExecuteResult.FromSuccess());
            }

            CommandInfo defaultCommand = innerService.Commands.FirstOrDefault(command =>
                                                                              command.Attributes.Any(attribute => attribute is DefaultAttribute));

            if (defaultCommand is default(CommandInfo))
            {
                return(ExecuteResult.FromSuccess());
            }

            return(await defaultCommand.ExecuteAsync(commandContext, Enumerable.Empty <object>(),
                                                     Enumerable.Empty <object>(), services));
        }
예제 #17
0
        /// <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());
        }
        private async Task <IResult> HelpCommandAsync(ICommandContext context, object[] parameters, IServiceProvider services, KeyValuePair <CommandInfo, string>[] aliasedCommands)
        {
            if (parameters?.Length != 0)
            {
                return(ParseResult.FromError(CommandError.BadArgCount, "Help for commands takes no arguments."));
            }

            EmbedBuilder builder = new EmbedBuilder()
            {
                Title = "Help",
                Color = Color.DarkBlue
            };

            foreach (var kvp in aliasedCommands)
            {
                BuildHelpAsField(builder, kvp.Key, kvp.Value);
            }

            await context.Channel.SendMessageAsync(string.Empty, embed : builder.Build()).ConfigureAwait(false);

            return(ExecuteResult.FromSuccess());
        }
예제 #19
0
        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));
            }
        }
예제 #20
0
        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);
        }
예제 #21
0
        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);
        }
예제 #22
0
        /// <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());
        }
        public async Task <IResult> Invoke(CallbackEventArgs args)
        {
            Task task;

            if (_eh != null)
            {
                task = _eh.DynamicInvoke(new object[] { args }) as Task ?? Task.Delay(0);
            }
            else
            {
                task = GetMethod().Invoke(null, new object[] { args }) as Task ?? Task.Delay(0);
            }

            if (task is Task <RuntimeResult> resultTask)
            {
                return(await resultTask.ConfigureAwait(false));
            }
            else
            {
                await task.ConfigureAwait(false);

                return(ExecuteResult.FromSuccess());
            }
        }
예제 #24
0
        /// <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());
        }
        private static void BuildCommand(CommandBuilder builder, TypeInfo typeInfo, MethodInfo method, CommandService service, IServiceProvider serviceprovider)
        {
            var attributes = method.GetCustomAttributes();

            foreach (var attribute in attributes)
            {
                switch (attribute)
                {
                case CommandAttribute command:
                    builder.AddAliases(command.Text);
                    builder.RunMode         = command.RunMode;
                    builder.Name            = builder.Name ?? command.Text;
                    builder.IgnoreExtraArgs = command.IgnoreExtraArgs ?? service._ignoreExtraArgs;
                    break;

                case NameAttribute name:
                    builder.Name = name.Text;
                    break;

                case PriorityAttribute priority:
                    builder.Priority = priority.Priority;
                    break;

                case SummaryAttribute summary:
                    builder.Summary = summary.Text;
                    break;

                case RemarksAttribute remarks:
                    builder.Remarks = remarks.Text;
                    break;

                case AliasAttribute alias:
                    builder.AddAliases(alias.Aliases);
                    break;

                case PreconditionAttribute precondition:
                    builder.AddPrecondition(precondition);
                    break;

                default:
                    builder.AddAttributes(attribute);
                    break;
                }
            }

            if (builder.Name == null)
            {
                builder.Name = method.Name;
            }

            var parameters = method.GetParameters();
            int pos = 0, count = parameters.Length;

            foreach (var paramInfo in parameters)
            {
                builder.AddParameter((parameter) =>
                {
                    BuildParameter(parameter, paramInfo, pos++, count, service, serviceprovider);
                });
            }

            var createInstance = ReflectionUtils.CreateBuilder <IModuleBase>(typeInfo, service);

            async Task <IResult> ExecuteCallback(string commandString, object[] args, IServiceProvider services, CommandInfo cmd)
            {
                var instance = createInstance(services);

                instance.SetContext(commandString);

                try
                {
                    instance.BeforeExecute(cmd);

                    var task = method.Invoke(instance, args) as Task ?? Task.Delay(0);
                    if (task is Task <RuntimeResult> resultTask)
                    {
                        return(await resultTask.ConfigureAwait(false));
                    }
                    else
                    {
                        await task.ConfigureAwait(false);

                        return(ExecuteResult.FromSuccess());
                    }
                }
                finally
                {
                    instance.AfterExecute(cmd);
                    (instance as IDisposable)?.Dispose();
                }
            }

            builder.Callback = ExecuteCallback;
        }
예제 #26
0
        public Task <IResult> ExecuteAsync(SocketCommandContext context)
        {
            var result = ExecuteResult.FromSuccess();

            return(Task.FromResult <IResult>(result));
        }
        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());
        }
예제 #28
0
        private async Task CommandExecutedAsync(Optional <CommandInfo> command, ICommandContext context, IResult result)
        {
            // Null is success, because some modules returns null after success and library always returns ExecuteResult.
            if (result == null)
            {
                result = ExecuteResult.FromSuccess();
            }

            if (!result.IsSuccess && result.Error != null)
            {
                string reply = "";

                string moreInfo = "";
                if (command.IsSpecified)
                {
                    moreInfo = $"\n*Pro vice informací zadej `{Configuration["Prefix"]}help {command.Value.Aliases.First().Split(' ', 2)[0]}`*";
                }

                switch (result.Error.Value)
                {
                case CommandError.Unsuccessful when result is CommandRedirectResult crr && !string.IsNullOrEmpty(crr.NewCommand):
                    await CommandService.ExecuteAsync(context, crr.NewCommand, Provider);

                    break;

                case CommandError.UnmetPrecondition:
                case CommandError.Unsuccessful:
                    reply = result.ErrorReason;
                    break;

                case CommandError.ObjectNotFound when result is ParseResult parseResult && typeof(IUser).IsAssignableFrom(parseResult.ErrorParameter.Type):
                    ParameterInfo param = ((ParseResult)result).ErrorParameter;
                    var           pos   = param.Command.Parameters.ToList().IndexOf(param);

                    reply = $"Nemohl jsem najít uživatele zadaného v {pos + 1}. argumentu.\n> {command.Value.GetCommandFormat(Configuration["Prefix"], param)}{moreInfo}";
                    break;

                case CommandError.ParseFailed:
                    param = ((ParseResult)result).ErrorParameter;
                    pos   = param.Command.Parameters.ToList().IndexOf(param);

                    var typeName = param.Type.Name;

                    if (typeName == "Int32")
                    {
                        typeName = "číslo";
                    }
                    if (typeName == "String")
                    {
                        typeName = "řetězec";
                    }

                    reply = $"V {pos + 1}. argumentu má být **{typeName}**\n> {command.Value.GetCommandFormat(Configuration["Prefix"], param)}{moreInfo}";
                    break;

                case CommandError.BadArgCount:
                    var firstLine = Configuration.GetSection("BadArgumentFirstLine").AsEnumerable().Where(o => o.Value != null).ToArray();

                    reply = $"{firstLine[ThreadSafeRandom.Next(firstLine.Length)].Value}\n> {command.Value.GetCommandFormat(Configuration["Prefix"])}{moreInfo}";
                    break;

                case CommandError.Exception:
                    await context.Message.AddReactionAsync(new Emoji("❌"));

                    break;
                }

                // Reply to command message without mentioning any user
                if (!string.IsNullOrEmpty(reply))
                {
                    await context.Message.ReplyAsync(reply, allowedMentions : new AllowedMentions {
                        MentionRepliedUser = false
                    });
                }
            }
        }
예제 #29
0
        private void BuildCommand(ModuleBuilder builder, TypeInfo moduleType, MethodInfo method,
                                  MetadataPath currentPath)
        {
            var name    = this._metadataProvider.GetCommandValue(c => c.Name);
            var command = this._metadataProvider.GetCommandValue(c => c.Command);

            var isDefault = command == null && !builder.Aliases[0].IsEmpty();

            // This command is not configured properly
            if (!isDefault && command.IsEmpty())
            {
                return;
            }

            async Task <IResult> ExecuteCommand(ICommandContext context, Object[] args, IServiceProvider services,
                                                CommandInfo cmd)
            {
                var instance = (IModule)services.GetRequiredService(moduleType);

                instance.SetContext(context as KuuhakuCommandContext);

                try
                {
                    instance.BeforeExecute(cmd);
                    var task = method.Invoke(instance, args) as Task ?? Task.CompletedTask;
                    if (task is Task <RuntimeResult> resultTask)
                    {
                        return(await resultTask);
                    }
                    await task;
                    return(ExecuteResult.FromSuccess());
                }
                finally
                {
                    instance.AfterExecute(cmd);
                    (instance as IDisposable)?.Dispose();
                    if (instance is IAsyncDisposable disposable)
                    {
                        await disposable.DisposeAsync();
                    }
                }
            }

            void CreateCommand(CommandBuilder builder)
            {
                var attributes = method.GetCustomAttributes()
                                 .ToImmutableArray();

                var preconditions = attributes.Where(a => a is PreconditionAttribute);

                foreach (var precondition in preconditions)
                {
                    builder.AddPrecondition(precondition as PreconditionAttribute);
                }

                builder.AddAttributes(attributes.Where(a => !(a is PreconditionAttribute)).ToArray());

                // TODO: Permissions
                // TODO: Ratelimiting
                // TODO: Generic Precondition Values?

                builder.WithPriority(this._metadataProvider.GetCommandValue(c => c.Priority))
                .WithSummary(this._metadataProvider.GetCommandValue(c => c.Summary))
                .WithRemarks(this._metadataProvider.GetCommandValue(c => c.Remarks))
                .AddAliases(this._metadataProvider.GetCommandValue(c => c.Aliases) ?? new String[0]);

                if (builder.Name.IsEmpty())
                {
                    builder.Name = method.Name.Replace("Async", "");
                }

                var parameters = method.GetParameters();

                for (var i = 0; i < parameters.Length; i++)
                {
                    currentPath.CurrentArgument = i;
                    this._metadataProvider.SetCurrentPath(currentPath);
                    this.BuildArgument(builder, parameters[i], (current: i, total: parameters.Length));
                }
            }

            var primaryAlias = isDefault
                ? ""
                : command.IsEmpty()
                    ? name
                    : command;

            builder.AddCommand(primaryAlias, ExecuteCommand, CreateCommand);
        }