using Discord.Rest; using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using Model = Discord.API.Channel; namespace Discord.WebSocket { /// /// Represents a WebSocket-based guild channel. /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class SocketGuildChannel : SocketChannel, IGuildChannel { private ImmutableArray _overwrites; /// /// Gets the guild associated with this channel. /// /// /// A guild that this channel belongs to. /// public SocketGuild Guild { get; } /// public string Name { get; private set; } /// public int Position { get; private set; } /// public IReadOnlyCollection PermissionOverwrites => _overwrites; /// /// Gets a collection of users that are able to view the channel. /// /// /// A collection of users that can access the channel (i.e. the users seen in the user list). /// public new virtual IReadOnlyCollection Users => ImmutableArray.Create(); internal SocketGuildChannel(DiscordSocketClient discord, ulong id, SocketGuild guild) : base(discord, id) { Guild = guild; } internal static SocketGuildChannel Create(SocketGuild guild, ClientState state, Model model) { switch (model.Type) { case ChannelType.Text: return SocketTextChannel.Create(guild, state, model); case ChannelType.Voice: return SocketVoiceChannel.Create(guild, state, model); case ChannelType.Category: return SocketCategoryChannel.Create(guild, state, model); default: // TODO: Proper implementation for channel categories return new SocketGuildChannel(guild.Discord, model.Id, guild); } } internal override void Update(ClientState state, Model model) { Name = model.Name.Value; Position = model.Position.Value; 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(); } /// public Task ModifyAsync(Action func, RequestOptions options = null) => ChannelHelper.ModifyAsync(this, Discord, func, options); /// public Task DeleteAsync(RequestOptions options = null) => ChannelHelper.DeleteAsync(this, Discord, options); /// /// Gets the overwrite permissions of the specified . /// /// The user that you want to get the overwrite permissions for. /// /// The overwrite permissions for the requested user; otherwise null. /// public 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 overwrite permissions of the specified . /// /// The role that you want to get the overwrite permissions for. /// /// The overwrite permissions for the requested role; otherwise null. /// public 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 an overwrite permission for the specified . /// /// The user you want the overwrite permission to apply to. /// The overwrite permission you want to add. /// The options to be used when sending the request. /// An awaitable . public async Task AddPermissionOverwriteAsync(IUser user, OverwritePermissions perms, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, user, perms, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(user.Id, PermissionTarget.User, new OverwritePermissions(perms.AllowValue, perms.DenyValue))); } /// /// Adds an overwrite permission for the specified . /// /// The role you want the overwrite permission to apply to. /// The overwrite permission you want to add. /// The options to be used when sending the request. /// An awaitable . public async Task AddPermissionOverwriteAsync(IRole role, OverwritePermissions perms, RequestOptions options = null) { await ChannelHelper.AddPermissionOverwriteAsync(this, Discord, role, perms, options).ConfigureAwait(false); _overwrites = _overwrites.Add(new Overwrite(role.Id, PermissionTarget.Role, new OverwritePermissions(perms.AllowValue, perms.DenyValue))); } public 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; } } } public 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; } } } public async Task> GetInvitesAsync(RequestOptions options = null) => await ChannelHelper.GetInvitesAsync(this, Discord, options).ConfigureAwait(false); public async Task CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); public new virtual SocketGuildUser GetUser(ulong id) => null; /// /// Gets the name of the channel. /// public override string ToString() => Name; private string DebuggerDisplay => $"{Name} ({Id}, Guild)"; internal new SocketGuildChannel Clone() => MemberwiseClone() as SocketGuildChannel; //SocketChannel internal override IReadOnlyCollection GetUsersInternal() => Users; internal override SocketUser GetUserInternal(ulong id) => GetUser(id); //IGuildChannel /// IGuild IGuildChannel.Guild => Guild; /// ulong IGuildChannel.GuildId => Guild.Id; /// async Task> IGuildChannel.GetInvitesAsync(RequestOptions options) => await GetInvitesAsync(options).ConfigureAwait(false); /// async Task IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, bool isUnique, RequestOptions options) => await CreateInviteAsync(maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false); /// OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IRole role) => GetPermissionOverwrite(role); /// OverwritePermissions? IGuildChannel.GetPermissionOverwrite(IUser user) => GetPermissionOverwrite(user); /// async Task IGuildChannel.AddPermissionOverwriteAsync(IRole role, OverwritePermissions permissions, RequestOptions options) => await AddPermissionOverwriteAsync(role, permissions, options).ConfigureAwait(false); /// async Task IGuildChannel.AddPermissionOverwriteAsync(IUser user, OverwritePermissions permissions, RequestOptions options) => await AddPermissionOverwriteAsync(user, permissions, options).ConfigureAwait(false); /// async Task IGuildChannel.RemovePermissionOverwriteAsync(IRole role, RequestOptions options) => await RemovePermissionOverwriteAsync(role, options).ConfigureAwait(false); /// async Task IGuildChannel.RemovePermissionOverwriteAsync(IUser user, RequestOptions options) => await RemovePermissionOverwriteAsync(user, options).ConfigureAwait(false); /// IAsyncEnumerable> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => ImmutableArray.Create>(Users).ToAsyncEnumerable(); /// Task IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(GetUser(id)); //IChannel /// IAsyncEnumerable> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) => ImmutableArray.Create>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice /// Task IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) => Task.FromResult(GetUser(id)); //Overridden in Text/Voice } }