public async Task <Result <FeedbackMessage> > HideRoleplayAsync
    (
        [AutocompleteProvider("roleplay::any")]
        Roleplay roleplay
    )
    {
        var getDedicatedChannelResult = DedicatedChannelService.GetDedicatedChannel
                                        (
            roleplay
                                        );

        if (!getDedicatedChannelResult.IsSuccess)
        {
            return(Result <FeedbackMessage> .FromError(getDedicatedChannelResult));
        }

        var dedicatedChannel = getDedicatedChannelResult.Entity;
        var setVisibility    = await _dedicatedChannels.SetChannelVisibilityForUserAsync
                               (
            dedicatedChannel,
            _context.User.ID,
            false
                               );

        return(!setVisibility.IsSuccess
            ? Result <FeedbackMessage> .FromError(setVisibility)
            : new FeedbackMessage("Roleplay hidden.", _feedback.Theme.Secondary));
    }
    public async Task <Result <FeedbackMessage> > ViewRoleplayAsync
    (
        [AutocompleteProvider("roleplay::any")] Roleplay roleplay
    )
    {
        var getDedicatedChannelResult = DedicatedChannelService.GetDedicatedChannel(roleplay);

        if (!getDedicatedChannelResult.IsSuccess)
        {
            return(new UserError
                   (
                       "The given roleplay doesn't have a dedicated channel. Try using \"!rp export\" instead."
                   ));
        }

        if (!roleplay.IsPublic && roleplay.ParticipatingUsers.All(p => p.User.DiscordID != _context.User.ID))
        {
            return(new UserError
                   (
                       "You don't have permission to view that roleplay."
                   ));
        }

        var dedicatedChannel = getDedicatedChannelResult.Entity;
        var setVisibility    = await _dedicatedChannels.SetChannelVisibilityForUserAsync
                               (
            dedicatedChannel,
            _context.User.ID,
            true
                               );

        if (!setVisibility.IsSuccess)
        {
            return(Result <FeedbackMessage> .FromError(setVisibility));
        }

        return(new FeedbackMessage
               (
                   $"The roleplay \"{roleplay.Name}\" is now visible in <#{dedicatedChannel}>.",
                   _feedback.Theme.Secondary
               ));
    }
    public async Task <Result> MoveRoleplayIntoChannelAsync(string newName, params IUser[] participants)
    {
        var createRoleplayAsync = await _discordRoleplays.CreateRoleplayAsync
                                  (
            _context.GuildID.Value,
            _context.User.ID,
            newName,
            "No summary set.",
            false,
            true
                                  );

        if (!createRoleplayAsync.IsSuccess)
        {
            return(Result.FromError(createRoleplayAsync));
        }

        var roleplay = createRoleplayAsync.Entity;

        foreach (var participant in participants)
        {
            if (participant.ID == _context.User.ID)
            {
                // Already added
                continue;
            }

            var addParticipantAsync = await _discordRoleplays.AddUserToRoleplayAsync(roleplay, participant.ID);

            if (addParticipantAsync.IsSuccess)
            {
                continue;
            }

            var message =
                $"I couldn't add <@{participant.ID}> to the roleplay ({addParticipantAsync.Error.Message}. " +
                "Please try to invite them manually.";

            var sendWarning = await _feedback.SendContextualWarningAsync
                              (
                message,
                _context.User.ID
                              );

            if (!sendWarning.IsSuccess)
            {
                return(Result.FromError(sendWarning));
            }
        }

        // Copy the last messages from the participants
        var before = _context switch
        {
            MessageContext messageContext => messageContext.MessageID,
            InteractionContext interactionContext => interactionContext.ID,
            _ => throw new ArgumentOutOfRangeException(nameof(_context))
        };

        var getMessageBatch = await _channelAPI.GetChannelMessagesAsync(_context.ChannelID, before : before);

        if (!getMessageBatch.IsSuccess)
        {
            return(Result.FromError(getMessageBatch));
        }

        var messageBatch = getMessageBatch.Entity;

        var participantMessages = participants
                                  .Select(participant => messageBatch.FirstOrDefault(m => m.Author.ID == participant.ID))
                                  .Where(message => message is not null)
                                  .Select(m => m !)
                                  .ToList();

        var getDedicatedChannel = DedicatedChannelService.GetDedicatedChannel(roleplay);

        if (!getDedicatedChannel.IsSuccess)
        {
            return(Result.FromError(getDedicatedChannel));
        }

        var dedicatedChannel = getDedicatedChannel.Entity;

        foreach (var participantMessage in participantMessages.OrderByDescending(m => m.Timestamp))
        {
            var messageLink = "https://discord.com/channels/" +
                              $"{_context.GuildID.Value}/{_context.ChannelID}/{participantMessage.ID}";

            var send = await _channelAPI.CreateMessageAsync(dedicatedChannel, messageLink);

            if (!send.IsSuccess)
            {
                return(Result.FromError(send));
            }
        }

        var start = await StartRoleplayAsync(roleplay);

        return(start.IsSuccess
            ? Result.FromSuccess()
            : Result.FromError(start));
    }
}
    public async Task <Result <FeedbackMessage> > ShowOrCreateDedicatedRoleplayChannel
    (
        [RequireEntityOwner]
        [AutocompleteProvider("roleplay::owned")]
        Roleplay roleplay
    )
    {
        var getDedicatedChannelResult = DedicatedChannelService.GetDedicatedChannel(roleplay);

        if (getDedicatedChannelResult.IsSuccess)
        {
            var existingDedicatedChannel = getDedicatedChannelResult.Entity;
            var message = $"\"{roleplay.Name}\" has a dedicated channel at " +
                          $"<#{existingDedicatedChannel}>";

            return(new FeedbackMessage(message, _feedback.Theme.Secondary));
        }

        var workingMessage = new Embed
        {
            Colour      = _feedback.Theme.Secondary,
            Description = "Setting up dedicated channel..."
        };

        var send = await _feedback.SendContextualEmbedAsync(workingMessage);

        if (!send.IsSuccess)
        {
            return(Result <FeedbackMessage> .FromError(send));
        }

        // The roleplay either doesn't have a channel, or the one it has has been deleted or is otherwise invalid.
        var result = await _dedicatedChannels.CreateDedicatedChannelAsync(roleplay);

        if (!result.IsSuccess)
        {
            return(Result <FeedbackMessage> .FromError(result));
        }

        var dedicatedChannel = result.Entity;

        if (!roleplay.IsActive || roleplay.ActiveChannelID == dedicatedChannel.ID)
        {
            return(new FeedbackMessage
                   (
                       $"All done! Your roleplay now has a dedicated channel at <#{dedicatedChannel}>.",
                       _feedback.Theme.Secondary
                   ));
        }

        var stopResult = await StopRoleplayAsync(roleplay);

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

        var startResult = await StartRoleplayAsync(roleplay);

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

        return(new FeedbackMessage
               (
                   $"All done! Your roleplay now has a dedicated channel at <#{dedicatedChannel}>.",
                   _feedback.Theme.Secondary
               ));
    }
Esempio n. 5
0
    /// <summary>
    /// Starts the given roleplay in the current channel, or the dedicated channel if one exists.
    /// </summary>
    /// <param name="currentChannelID">The current channel.</param>
    /// <param name="roleplay">The roleplay.</param>
    /// <returns>A modification result which may or may not have succeeded.</returns>
    public async Task <Result> StartRoleplayAsync(Snowflake currentChannelID, Roleplay roleplay)
    {
        var getDedicatedChannelResult = DedicatedChannelService.GetDedicatedChannel(roleplay);

        // Identify the channel to start the RP in. Preference is given to the roleplay's dedicated channel.
        var channelID  = getDedicatedChannelResult.IsSuccess ? getDedicatedChannelResult.Entity : currentChannelID;
        var getChannel = await _channelAPI.GetChannelAsync(channelID);

        if (!getChannel.IsSuccess)
        {
            return(Result.FromError(getChannel));
        }

        var channel = getChannel.Entity;

        if (roleplay.IsNSFW && !(channel.IsNsfw.HasValue && channel.IsNsfw.Value))
        {
            return(new UserError
                   (
                       "This channel is not marked as NSFW, while your roleplay is... naughty!"
                   ));
        }

        var getHasActiveRoleplay = await HasActiveRoleplayAsync(channelID);

        if (!getHasActiveRoleplay.IsSuccess)
        {
            return(Result.FromError(getHasActiveRoleplay));
        }

        if (getHasActiveRoleplay.Entity)
        {
            var currentRoleplayResult = await GetActiveRoleplayAsync(channelID);

            if (!currentRoleplayResult.IsSuccess)
            {
                return(Result.FromError(currentRoleplayResult));
            }

            var currentRoleplay   = currentRoleplayResult.Entity;
            var timeOfLastMessage = currentRoleplay.Messages.Last().Timestamp;
            var currentTime       = DateTimeOffset.UtcNow;

            if (timeOfLastMessage < currentTime.AddHours(-4))
            {
                currentRoleplay.IsActive = false;
            }
            else
            {
                return(new UserError("There's already a roleplay active in this channel."));
            }
        }

        var start = await _roleplays.StartRoleplayAsync(roleplay, channelID);

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

        // If the channel in question is the roleplay's dedicated channel, enable it
        if (!roleplay.DedicatedChannelID.HasValue)
        {
            return(Result.FromSuccess());
        }

        var enableChannel = await _dedicatedChannels.UpdateParticipantPermissionsAsync(roleplay);

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

        var joinedUsers = roleplay.JoinedUsers.Select
                          (
            u => $"<@{u.User.DiscordID}>"
                          );

        var participantList = joinedUsers.Humanize();

        var send = await _channelAPI.CreateMessageAsync
                   (
            roleplay.ActiveChannelID !.Value,
            $"Calling {participantList}!"
                   );

        return(!send.IsSuccess
            ? Result.FromError(send)
            : Result.FromSuccess());
    }