Ejemplo n.º 1
0
        public async Task LeaveRoleplayAsync([NotNull] Roleplay roleplay)
        {
            var removeUserResult = await _roleplays.RemoveUserFromRoleplayAsync(this.Context, roleplay, this.Context.Message.Author);

            if (!removeUserResult.IsSuccess)
            {
                await _feedback.SendErrorAsync(this.Context, removeUserResult.ErrorReason);

                return;
            }

            // Ensure the user has the correct permissions for the dedicated channel
            var getDedicatedChannelResult = await _roleplays.GetDedicatedRoleplayChannelAsync(this.Context.Guild, roleplay);

            if (getDedicatedChannelResult.IsSuccess)
            {
                var dedicatedChannel = getDedicatedChannelResult.Entity;

                var grantPermissionResult = await _roleplays.RevokeUserDedicatedChannelAccessAsync
                                            (
                    this.Context,
                    dedicatedChannel,
                    this.Context.User
                                            );

                if (!grantPermissionResult.IsSuccess)
                {
                    await _feedback.SendWarningAsync(this.Context, grantPermissionResult.ErrorReason);
                }
            }

            var roleplayOwnerUser = await this.Context.Guild.GetUserAsync((ulong)roleplay.Owner.DiscordID);

            await _feedback.SendConfirmationAsync(this.Context, $"Left {roleplayOwnerUser.Mention}'s roleplay \"{roleplay.Name}\"");
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Determines whether or not the user has consented to data storage and handling under the GDPR, or if the
        /// command that is being executed is exempt from GDPR considerations.
        /// </summary>
        /// <param name="context">The context.</param>
        /// <returns>true if the user has consented or the command does not require consent; otherwise, false.</returns>
        private async Task <bool> HasConsentedOrCommandDoesNotRequireConsentAsync(SocketCommandContext context)
        {
            // Find the argument pos
            if (!FindCommandStartPosition(context.Message, out var argumentPos))
            {
                return(true);
            }

            if (await _privacy.HasUserConsentedAsync(context.User) || IsPrivacyExemptCommand(context, argumentPos))
            {
                return(true);
            }

            // Ask for consent
            var userDMChannel = await context.User.GetOrCreateDMChannelAsync();

            var result = await _privacy.RequestConsentAsync(userDMChannel);

            if (result.IsSuccess)
            {
                return(false);
            }

            const string response = "It seems like you're not accepting DMs from non-friends. Please enable " +
                                    "this, so you can read the bot's privacy policy and consent to data " +
                                    "handling and processing.";

            await _feedback.SendWarningAsync(context, response);

            return(false);
        }
Ejemplo n.º 3
0
        public static async Task <IUserMessage> SendPrivateInteractiveMessageAsync
        (
            this InteractiveService @this,
            [NotNull] SocketCommandContext context,
            [NotNull] UserFeedbackService feedback,
            [NotNull] IInteractiveMessage interactiveMessage
        )
        {
            if (!(await context.User.GetOrCreateDMChannelAsync() is ISocketMessageChannel userChannel))
            {
                throw new InvalidOperationException("Could not create DM channel for target user.");
            }

            try
            {
                await feedback.SendConfirmationAsync(context, "Loading...");
            }
            catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted())
            {
                await feedback.SendWarningAsync(context, "You don't accept DMs from non-friends on this server, so I'm unable to do that.");

                throw new InvalidOperationException("User does not accept DMs from non-friends.");
            }
            finally
            {
                await((IDMChannel)userChannel).CloseAsync();
            }

            if (!context.IsPrivate)
            {
                await feedback.SendConfirmationAsync(context, "Please check your private messages.");
            }

            return(await SendInteractiveMessageAsync(@this, context, interactiveMessage, userChannel));
        }
Ejemplo n.º 4
0
        /// <inheritdoc />
        protected override async Task MessageReceived(SocketMessage arg)
        {
            if (!(arg is SocketUserMessage message))
            {
                return;
            }

            if (arg.Author.IsBot || arg.Author.IsWebhook)
            {
                return;
            }

            var argumentPos = 0;

            if (!(message.HasCharPrefix('!', ref argumentPos) || message.HasMentionPrefix(this.Client.CurrentUser, ref argumentPos)))
            {
                return;
            }

            if (message.Content.Length < 2)
            {
                return;
            }

            if (!message.Content.Any(char.IsLetterOrDigit))
            {
                return;
            }

            var context = new SocketCommandContext(this.Client, message);

            // Perform first-time user checks, making sure the user has their default permissions, has consented, etc
            if (!await _privacy.HasUserConsentedAsync(context.User) && !IsPrivacyExemptCommand(context, argumentPos))
            {
                // Ask for consent
                var userDMChannel = await arg.Author.GetOrCreateDMChannelAsync();

                var result = await _privacy.RequestConsentAsync(userDMChannel);

                if (result.IsSuccess)
                {
                    return;
                }

                const string response = "It seems like you're not accepting DMs from non-friends. Please enable " +
                                        "this, so you can read the bot's privacy policy and consent to data " +
                                        "handling and processing.";

                await _feedback.SendWarningAsync(context, response);

                return;
            }

            // Create a service scope for this command
            using (var scope = _services.CreateScope())
            {
                var result = await _commands.ExecuteAsync(context, argumentPos, scope.ServiceProvider);
                await HandleCommandResultAsync(context, result, argumentPos);
            }
        }
Ejemplo n.º 5
0
        public async Task <RuntimeResult> AddWarningAsync
        (
            IGuildUser user,
            string reason,
            TimeSpan?expiresAfter = null
        )
        {
            DateTime?expiresOn = null;

            if (!(expiresAfter is null))
            {
                expiresOn = DateTime.Now.Add(expiresAfter.Value);
            }

            var addWarning = await _warnings.CreateWarningAsync(this.Context.User, user, reason, expiresOn : expiresOn);

            if (!addWarning.IsSuccess)
            {
                return(addWarning.ToRuntimeResult());
            }

            var warning     = addWarning.Entity;
            var getSettings = await _moderation.GetOrCreateServerSettingsAsync(this.Context.Guild);

            if (!getSettings.IsSuccess)
            {
                return(getSettings.ToRuntimeResult());
            }

            var settings = getSettings.Entity;

            var notifyResult = await _logging.NotifyUserWarningAddedAsync(warning);

            if (!notifyResult.IsSuccess)
            {
                return(notifyResult.ToRuntimeResult());
            }

            var warnings = await _warnings.GetWarningsAsync(user);

            if (warnings.Count >= settings.WarningThreshold)
            {
                await _feedback.SendWarningAsync
                (
                    this.Context, $"The warned user now has {warnings.Count} warnings. Consider further action."
                );
            }

            return(RuntimeCommandResult.FromSuccess($"Warning added (ID {warning.ID})."));
        }
Ejemplo n.º 6
0
        public async Task AddWarningAsync
        (
            [NotNull] IGuildUser user,
            [NotNull] string content,
            TimeSpan?expiresAfter = null
        )
        {
            DateTime?expiresOn = null;

            if (!(expiresAfter is null))
            {
                expiresOn = DateTime.Now.Add(expiresAfter.Value);
            }

            var addWarning = await _warnings.CreateWarningAsync(this.Context.User, user, content, expiresOn : expiresOn);

            if (!addWarning.IsSuccess)
            {
                await _feedback.SendErrorAsync(this.Context, addWarning.ErrorReason);

                return;
            }

            var warning = addWarning.Entity;
            await _feedback.SendConfirmationAsync(this.Context, $"Warning added (ID {warning.ID}).");

            await _logging.NotifyUserWarningAdded(warning);

            var getSettings = await _moderation.GetOrCreateServerSettingsAsync(this.Context.Guild);

            if (!getSettings.IsSuccess)
            {
                return;
            }

            var settings = getSettings.Entity;

            var warningCount = await _warnings.GetWarnings(user).CountAsync();

            if (warningCount >= settings.WarningThreshold)
            {
                await _feedback.SendWarningAsync
                (
                    this.Context, $"The warned user now has {warningCount} warnings. Consider further action."
                );
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Sends a paginated message to the context user's direct messaging channel, alerting them if they are
        /// not already in it, and deletes it after a certain timeout. Defaults to 5 minutes.
        /// </summary>
        /// <param name="this">The interactive service.</param>
        /// <param name="context">The command context.</param>
        /// <param name="feedback">The feedback service to use.</param>
        /// <param name="message">The message to send.</param>
        /// <param name="timeout">The timeout after which the embed will be deleted. Defaults to 5 minutes.</param>
        /// <returns>The message that was sent.</returns>
        public static async Task SendPrivateInteractiveMessageAndDeleteAsync
        (
            [NotNull] this InteractivityService @this,
            [NotNull] ICommandContext context,
            [NotNull] UserFeedbackService feedback,
            [NotNull] InteractiveMessage message,
            [CanBeNull] TimeSpan?timeout = null
        )
        {
            timeout = timeout ?? TimeSpan.FromMinutes(5.0);

            var userChannel = await context.User.GetOrCreateDMChannelAsync();

            try
            {
                var eb = feedback.CreateFeedbackEmbed(context.User, Color.DarkPurple, "Loading...");
                await feedback.SendEmbedAndDeleteAsync(userChannel, eb, TimeSpan.FromSeconds(1));

                if (!(context.Channel is IDMChannel))
                {
                    await feedback.SendConfirmationAsync(context, "Please check your private messages.");
                }

                await @this.SendInteractiveMessageAndDeleteAsync(userChannel, message, timeout);
            }
            catch (HttpException hex)
            {
                if (hex.WasCausedByDMsNotAccepted())
                {
                    await feedback.SendWarningAsync
                    (
                        context,
                        "You don't accept DMs from non-friends on this server, so I'm unable to do that."
                    );
                }

                throw;
            }
        }
Ejemplo n.º 8
0
        public static async Task <IUserMessage> SendPrivatePaginatedMessageAsync <T1, T2>
        (
            this InteractiveService @this,
            [NotNull] SocketCommandContext context,
            [NotNull] UserFeedbackService feedback,
            [NotNull] IPager <T1, T2> pager,
            [CanBeNull] ICriterion <SocketReaction> criterion = null
        )
            where T2 : IPager <T1, T2>
        {
            var userChannel = await context.User.GetOrCreateDMChannelAsync();

            try
            {
                await feedback.SendConfirmationAsync(context, "Loading...");
            }
            catch (HttpException hex)
            {
                if (hex.WasCausedByDMsNotAccepted())
                {
                    await feedback.SendWarningAsync(context, "You don't accept DMs from non-friends on this server, so I'm unable to do that.");

                    throw new InvalidOperationException("User does not accept DMs from non-friends.");
                }
            }
            finally
            {
                await userChannel.CloseAsync();
            }

            if (!context.IsPrivate)
            {
                await feedback.SendConfirmationAsync(context, "Please check your private messages.");
            }

            return(await SendPaginatedMessageAsync(@this, context, feedback, pager, userChannel, criterion));
        }
        public async Task <RuntimeResult> ReplayRoleplayAsync
        (
            [RequireEntityOwnerOrPermission(typeof(ExportRoleplay), PermissionTarget.Other)]
            Roleplay roleplay,
            DateTimeOffset from = default,
            DateTimeOffset to   = default
        )
        {
            if (from == default)
            {
                from = DateTimeOffset.MinValue;
            }

            if (to == default)
            {
                to = DateTimeOffset.Now;
            }

            var userDMChannel = await this.Context.Message.Author.GetOrCreateDMChannelAsync();

            var eb = await CreateRoleplayInfoEmbedAsync(roleplay);

            try
            {
                await userDMChannel.SendMessageAsync(string.Empty, false, eb);

                var messages = roleplay.Messages.Where
                               (
                    m =>
                    m.Timestamp > from && m.Timestamp < to
                               )
                               .OrderBy(msg => msg.Timestamp).ToList();

                var timestampEmbed = _feedback.CreateFeedbackEmbed
                                     (
                    this.Context.User,
                    Color.DarkPurple,
                    $"Roleplay began at {messages.First().Timestamp.ToUniversalTime()}"
                                     );

                await userDMChannel.SendMessageAsync(string.Empty, false, timestampEmbed);

                if (messages.Count <= 0)
                {
                    await userDMChannel.SendMessageAsync("No messages found in the specified timeframe.");

                    return(RuntimeCommandResult.FromSuccess());
                }

                await _feedback.SendConfirmationAsync
                (
                    this.Context,
                    $"Replaying \"{roleplay.Name}\". Please check your private messages."
                );

                const int messageCharacterLimit = 2000;
                var       sb = new StringBuilder(messageCharacterLimit);

                foreach (var message in messages)
                {
                    var newContent = $"**{message.AuthorNickname}** {message.Contents}\n";

                    if (sb.Length + newContent.Length >= messageCharacterLimit)
                    {
                        await userDMChannel.SendMessageAsync(sb.ToString());

                        await Task.Delay(TimeSpan.FromSeconds(2));

                        sb.Clear();
                        sb.AppendLine();
                    }

                    sb.Append(newContent);

                    if (message.ID == messages.Last().ID)
                    {
                        await userDMChannel.SendMessageAsync(sb.ToString());
                    }
                }
            }
            catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted())
            {
                await _feedback.SendWarningAsync
                (
                    this.Context,
                    "I can't do that, since you don't accept DMs from non-friends on this server."
                );
            }
            finally
            {
                await userDMChannel.CloseAsync();
            }

            return(RuntimeCommandResult.FromSuccess());
        }