using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; using Model = Discord.API.Channel; namespace Discord.Rest { /// /// Represents a private REST-based group channel. /// public class RestGuildChannel : RestChannel, IGuildChannel { #region RestGuildChannel private ImmutableArray _overwrites; /// public virtual IReadOnlyCollection PermissionOverwrites => _overwrites; internal IGuild Guild { get; } /// public string Name { get; private set; } /// public int Position { get; private set; } /// public ulong GuildId { get; } /// public ChannelFlags Flags { get; private set; } internal RestGuildChannel(BaseDiscordClient discord, IGuild guild, ulong id, ulong guildId) : base(discord, id) { Guild = guild; GuildId = guildId; } internal static RestGuildChannel Create(BaseDiscordClient discord, IGuild guild, Model model) { return model.Type switch { ChannelType.News => RestNewsChannel.Create(discord, guild, model), ChannelType.Text => RestTextChannel.Create(discord, guild, model), ChannelType.Voice => RestVoiceChannel.Create(discord, guild, model), ChannelType.Stage => RestStageChannel.Create(discord, guild, model), ChannelType.Media => RestMediaChannel.Create(discord, guild, model), ChannelType.Forum => RestForumChannel.Create(discord, guild, model), ChannelType.Category => RestCategoryChannel.Create(discord, guild, model), ChannelType.PublicThread or ChannelType.PrivateThread or ChannelType.NewsThread => RestThreadChannel.Create(discord, guild, model), _ => new RestGuildChannel(discord, guild, model.Id, guild?.Id ?? model.GuildId.Value), }; } internal override void Update(Model model) { Name = model.Name.Value; if (model.Position.IsSpecified) { Position = model.Position.Value; } if (model.PermissionOverwrites.IsSpecified) { var overwrites = model.PermissionOverwrites.Value; var newOverwrites = ImmutableArray.CreateBuilder(overwrites.Length); for (int i = 0; i < overwrites.Length; i++) newOverwrites.Add(overwrites[i].ToEntity()); _overwrites = newOverwrites.ToImmutable(); } Flags = model.Flags.GetValueOrDefault(ChannelFlags.None); } /// public override async Task UpdateAsync(RequestOptions options = null) { var model = await Discord.ApiClient.GetChannelAsync(GuildId, Id, options).ConfigureAwait(false); Update(model); } /// public async Task ModifyAsync(Action func, RequestOptions options = null) { var model = await ChannelHelper.ModifyAsync(this, Discord, func, options).ConfigureAwait(false); Update(model); } /// public Task DeleteAsync(RequestOptions options = null) => ChannelHelper.DeleteAsync(this, Discord, options); /// /// Gets the permission overwrite for a specific user. /// /// The user to get the overwrite from. /// /// An overwrite object for the targeted user; if none is set. /// public virtual OverwritePermissions? GetPermissionOverwrite(IUser user) { for (int i = 0; i < _overwrites.Length; i++) { if (_overwrites[i].TargetId == user.Id) return _overwrites[i].Permissions; } return null; } /// /// Gets the permission overwrite for a specific role. /// /// The role to get the overwrite from. /// /// An overwrite object for the targeted role; if none is set. /// public virtual OverwritePermissions? GetPermissionOverwrite(IRole role) { for (int i = 0; i < _overwrites.Length; i++) { if (_overwrites[i].TargetId == role.Id) return _overwrites[i].Permissions; } return null; } /// /// Adds or updates the permission overwrite for the given user. /// /// The user to add the overwrite to. /// The overwrite to add to the user. /// The options to be used when sending the request. /// /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. /// public virtual async Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, user, permissions, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(user.Id, PermissionTarget.User, new OverwritePermissions(permissions.AllowValue, permissions.DenyValue))); } /// /// Adds or updates the permission overwrite for the given role. /// /// The role to add the overwrite to. /// The overwrite to add to the role. /// The options to be used when sending the request. /// /// A task representing the asynchronous permission operation for adding the specified permissions to the channel. /// public virtual async Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, role, permissions, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(role.Id, PermissionTarget.Role, new OverwritePermissions(permissions.AllowValue, permissions.DenyValue))); } /// /// Removes the permission overwrite for the given user, if one exists. /// /// The user to remove the overwrite from. /// The options to be used when sending the request. /// /// A task representing the asynchronous operation for removing the specified permissions from the channel. /// public virtual async Task RemovePermissionOverwriteAsync(IUser user, RequestOptions options = null) { await ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, user, options).ConfigureAwait(false); for (int i = 0; i < _overwrites.Length; i++) { if (_overwrites[i].TargetId == user.Id) { _overwrites = _overwrites.RemoveAt(i); return; } } } /// /// Removes the permission overwrite for the given role, if one exists. /// /// The role to remove the overwrite from. /// The options to be used when sending the request. /// /// A task representing the asynchronous operation for removing the specified permissions from the channel. /// public virtual async Task RemovePermissionOverwriteAsync(IRole role, RequestOptions options = null) { await ChannelHelper.RemovePermissionOverwriteAsync(this, Discord, role, options).ConfigureAwait(false); for (int i = 0; i < _overwrites.Length; i++) { if (_overwrites[i].TargetId == role.Id) { _overwrites = _overwrites.RemoveAt(i); return; } } } /// /// Gets the name of this channel. /// /// /// A string that is the name of this channel. /// public override string ToString() => Name; #endregion #region IGuildChannel /// IGuild IGuildChannel.Guild { get { if (Guild != null) return Guild; throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); } } /// OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IRole role) => GetPermissionOverwrite(role); /// OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IUser user) => GetPermissionOverwrite(user); /// Task IGuildChannel.AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options) => AddPermissionOverwriteAsync(role, permissions, options); /// Task IGuildChannel.AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options) => AddPermissionOverwriteAsync(user, permissions, options); /// Task IGuildChannel.RemovePermissionOverwriteAsync(IRole role, RequestOptions options) => RemovePermissionOverwriteAsync(role, options); /// Task IGuildChannel.RemovePermissionOverwriteAsync(IUser user, RequestOptions options) => RemovePermissionOverwriteAsync(user, options); /// IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => AsyncEnumerable.Empty>(); //Overridden in Text/Voice /// Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(null); //Overridden in Text/Voice #endregion #region IChannel /// IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => AsyncEnumerable.Empty>(); //Overridden in Text/Voice /// Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(null); //Overridden in Text/Voice #endregion } }