/// <summary>
        /// Creates a dedicated channel for the roleplay.
        /// </summary>
        /// <param name="guild">The guild in which the request was made.</param>
        /// <param name="roleplay">The roleplay to create the channel for.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <CreateEntityResult <ITextChannel> > CreateDedicatedChannelAsync
        (
            IGuild guild,
            Roleplay roleplay
        )
        {
            var getServerResult = await _servers.GetOrRegisterServerAsync(guild);

            if (!getServerResult.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError(getServerResult));
            }

            var server = getServerResult.Entity;

            if (!(await guild.GetUserAsync(_client.CurrentUser.Id)).GuildPermissions.ManageChannels)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "I don't have permission to manage channels, so I can't create dedicated RP channels."
                       ));
            }

            var getExistingChannelResult = await GetDedicatedChannelAsync(guild, roleplay);

            if (getExistingChannelResult.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "The roleplay already has a dedicated channel."
                       ));
            }

            var getSettingsResult = await _serverSettings.GetOrCreateServerRoleplaySettingsAsync(server);

            if (!getSettingsResult.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError(getSettingsResult));
            }

            var settings = getSettingsResult.Entity;

            if (!(settings.DedicatedRoleplayChannelsCategory is null))
            {
                var categoryChannelCount = (await guild.GetTextChannelsAsync())
                                           .Count(c => c.CategoryId == (ulong)settings.DedicatedRoleplayChannelsCategory);

                if (categoryChannelCount >= 50)
                {
                    return(CreateEntityResult <ITextChannel> .FromError
                           (
                               "The server's roleplaying category has reached its maximum number of channels. Try " +
                               "contacting the server's owners and either removing some old roleplays or setting up " +
                               "a new category."
                           ));
                }
            }

            Optional <ulong?> categoryId;

            if (settings.DedicatedRoleplayChannelsCategory is null)
            {
                categoryId = null;
            }
            else
            {
                categoryId = (ulong?)settings.DedicatedRoleplayChannelsCategory;
            }

            var dedicatedChannel = await guild.CreateTextChannelAsync
                                   (
                $"{roleplay.Name}-rp",
                properties =>
            {
                properties.CategoryId = categoryId;
                properties.IsNsfw     = roleplay.IsNSFW;
                properties.Topic      = $"Dedicated roleplay channel for {roleplay.Name}. {roleplay.Summary}";
            }
                                   );

            roleplay.DedicatedChannelID = (long)dedicatedChannel.Id;

            var resetPermissions = await ResetChannelPermissionsAsync(dedicatedChannel, roleplay);

            if (!resetPermissions.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError(resetPermissions));
            }

            await _database.SaveChangesAsync();

            return(CreateEntityResult <ITextChannel> .FromSuccess(dedicatedChannel));
        }
Example #2
0
        /// <summary>
        /// Creates a dedicated channel for the roleplay.
        /// </summary>
        /// <param name="guild">The guild in which the request was made.</param>
        /// <param name="roleplay">The roleplay to create the channel for.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <CreateEntityResult <ITextChannel> > CreateDedicatedChannelAsync
        (
            IGuild guild,
            Roleplay roleplay
        )
        {
            var getServerResult = await _servers.GetOrRegisterServerAsync(guild);

            if (!getServerResult.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError(getServerResult));
            }

            var server = getServerResult.Entity;

            if (!(await guild.GetUserAsync(_client.CurrentUser.Id)).GuildPermissions.ManageChannels)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "I don't have permission to manage channels, so I can't create dedicated RP channels."
                       ));
            }

            var getExistingChannelResult = await GetDedicatedChannelAsync(guild, roleplay);

            if (getExistingChannelResult.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "The roleplay already has a dedicated channel."
                       ));
            }

            var getSettingsResult = await _serverSettings.GetOrCreateServerRoleplaySettingsAsync(server);

            if (!getSettingsResult.IsSuccess)
            {
                return(CreateEntityResult <ITextChannel> .FromError(getSettingsResult));
            }

            var settings = getSettingsResult.Entity;

            if (settings.DedicatedRoleplayChannelsCategory is null)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "No dedicated channel category has been configured."
                       ));
            }

            var categoryChannelCount = (await guild.GetTextChannelsAsync())
                                       .Count(c => c.CategoryId == (ulong)settings.DedicatedRoleplayChannelsCategory);

            if (categoryChannelCount >= 50)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "The server's roleplaying category has reached its maximum number of channels. Try " +
                           "contacting the server's owners and either removing some old roleplays or setting up " +
                           "a new category."
                       ));
            }

            Optional <ulong?> categoryId = (ulong?)settings.DedicatedRoleplayChannelsCategory;

            var dedicatedChannel = await guild.CreateTextChannelAsync
                                   (
                $"{roleplay.Name}-rp",
                properties =>
            {
                properties.CategoryId = categoryId;
                properties.IsNsfw     = roleplay.IsNSFW;
                properties.Topic      = $"Dedicated roleplay channel for {roleplay.Name}. {roleplay.Summary}";
            }
                                   );

            roleplay.DedicatedChannelID = (long)dedicatedChannel.Id;

            // This can fail in all manner of ways because of Discord.NET. Try, catch, etc...
            try
            {
                var resetPermissions = await ResetChannelPermissionsAsync(dedicatedChannel, roleplay);

                if (!resetPermissions.IsSuccess)
                {
                    return(CreateEntityResult <ITextChannel> .FromError(resetPermissions));
                }
            }
            catch (HttpException hex) when(hex.HttpCode == HttpStatusCode.Forbidden)
            {
                return(CreateEntityResult <ITextChannel> .FromError
                       (
                           "Failed to update channel permissions. Does the bot have permissions to manage permissions on " +
                           "new channels?"
                       ));
            }
            catch (Exception ex)
            {
                await dedicatedChannel.DeleteAsync();

                return(CreateEntityResult <ITextChannel> .FromError(ex));
            }

            await _database.SaveChangesAsync();

            return(CreateEntityResult <ITextChannel> .FromSuccess(dedicatedChannel));
        }