| @@ -6,8 +6,12 @@ namespace Discord | |||
| { | |||
| public interface IMessageChannel : IChannel | |||
| { | |||
| /// <summary> Gets the message in this message channel with the given id, or null if none was found. </summary> | |||
| Task<IMessage> GetMessage(ulong id); | |||
| /// <summary> Gets all messages in this channel's cache. </summary> | |||
| IEnumerable<IMessage> CachedMessages { get; } | |||
| /// <summary> Gets the message from this channel's cache with the given id, or null if none was found. </summary> | |||
| Task<IMessage> GetCachedMessage(ulong id); | |||
| /// <summary> Gets the last N messages from this message channel. </summary> | |||
| Task<IEnumerable<IMessage>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch); | |||
| /// <summary> Gets a collection of messages in this channel. </summary> | |||
| @@ -21,8 +21,8 @@ namespace Discord | |||
| IGuild Guild { get; } | |||
| /// <summary> Returns a collection of the roles this user is a member of in this guild, including the guild's @everyone role. </summary> | |||
| IReadOnlyList<IRole> Roles { get; } | |||
| /// <summary> Gets the id of the voice channel this user is currently in, if any. </summary> | |||
| ulong? VoiceChannelId { get; } | |||
| /// <summary> Gets the voice channel this user is currently in, if any. </summary> | |||
| IVoiceChannel VoiceChannel { get; } | |||
| /// <summary> Gets the guild-level permissions granted to this user by their roles. </summary> | |||
| GuildPermissions GetGuildPermissions(); | |||
| @@ -124,13 +124,14 @@ namespace Discord.Rest | |||
| public override string ToString() => $"@{Recipient} [DM]"; | |||
| IDMUser IDMChannel.Recipient => Recipient; | |||
| IEnumerable<IMessage> IMessageChannel.CachedMessages => Array.Empty<Message>(); | |||
| async Task<IEnumerable<IUser>> IChannel.GetUsers() | |||
| => await GetUsers().ConfigureAwait(false); | |||
| async Task<IUser> IChannel.GetUser(ulong id) | |||
| => await GetUser(id).ConfigureAwait(false); | |||
| Task<IMessage> IMessageChannel.GetMessage(ulong id) | |||
| => throw new NotSupportedException(); | |||
| Task<IMessage> IMessageChannel.GetCachedMessage(ulong id) | |||
| => Task.FromResult<IMessage>(null); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit) | |||
| => await GetMessages(limit).ConfigureAwait(false); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) | |||
| @@ -60,16 +60,11 @@ namespace Discord.Rest | |||
| } | |||
| /// <summary> Gets a user in this channel with the given id. </summary> | |||
| public async Task<GuildUser> GetUser(ulong id) | |||
| { | |||
| var model = await Discord.BaseClient.GetGuildMember(Guild.Id, id).ConfigureAwait(false); | |||
| if (model != null) | |||
| return new GuildUser(Guild, model); | |||
| return null; | |||
| } | |||
| protected abstract Task<IEnumerable<GuildUser>> GetUsers(); | |||
| public abstract Task<GuildUser> GetUser(ulong id); | |||
| /// <summary> Gets all users in this channel. </summary> | |||
| public abstract Task<IEnumerable<GuildUser>> GetUsers(); | |||
| /// <summary> Gets the permission overwrite for a specific user, or null if one does not exist. </summary> | |||
| /// <inheritdoc /> | |||
| public OverwritePermissions? GetPermissionOverwrite(IUser user) | |||
| { | |||
| Overwrite value; | |||
| @@ -77,7 +72,7 @@ namespace Discord.Rest | |||
| return value.Permissions; | |||
| return null; | |||
| } | |||
| /// <summary> Gets the permission overwrite for a specific role, or null if one does not exist. </summary> | |||
| /// <inheritdoc /> | |||
| public OverwritePermissions? GetPermissionOverwrite(IRole role) | |||
| { | |||
| Overwrite value; | |||
| @@ -92,21 +87,21 @@ namespace Discord.Rest | |||
| return models.Select(x => new GuildInvite(Guild, x)); | |||
| } | |||
| /// <summary> Adds or updates the permission overwrite for the given user. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task AddPermissionOverwrite(IUser user, OverwritePermissions perms) | |||
| { | |||
| var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; | |||
| await Discord.BaseClient.ModifyChannelPermissions(Id, user.Id, args).ConfigureAwait(false); | |||
| _overwrites[user.Id] = new Overwrite(new API.Overwrite { Allow = perms.AllowValue, Deny = perms.DenyValue, TargetId = user.Id, TargetType = PermissionTarget.User }); | |||
| } | |||
| /// <summary> Adds or updates the permission overwrite for the given role. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task AddPermissionOverwrite(IRole role, OverwritePermissions perms) | |||
| { | |||
| var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; | |||
| await Discord.BaseClient.ModifyChannelPermissions(Id, role.Id, args).ConfigureAwait(false); | |||
| _overwrites[role.Id] = new Overwrite(new API.Overwrite { Allow = perms.AllowValue, Deny = perms.DenyValue, TargetId = role.Id, TargetType = PermissionTarget.Role }); | |||
| } | |||
| /// <summary> Removes the permission overwrite for the given user, if one exists. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task RemovePermissionOverwrite(IUser user) | |||
| { | |||
| await Discord.BaseClient.DeleteChannelPermission(Id, user.Id).ConfigureAwait(false); | |||
| @@ -114,7 +109,7 @@ namespace Discord.Rest | |||
| Overwrite value; | |||
| _overwrites.TryRemove(user.Id, out value); | |||
| } | |||
| /// <summary> Removes the permission overwrite for the given role, if one exists. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task RemovePermissionOverwrite(IRole role) | |||
| { | |||
| await Discord.BaseClient.DeleteChannelPermission(Id, role.Id).ConfigureAwait(false); | |||
| @@ -37,14 +37,19 @@ namespace Discord.Rest | |||
| Update(model); | |||
| } | |||
| protected override async Task<IEnumerable<GuildUser>> GetUsers() | |||
| public override async Task<GuildUser> GetUser(ulong id) | |||
| { | |||
| var user = await Guild.GetUser(id).ConfigureAwait(false); | |||
| if (user != null && PermissionUtilities.GetValue(PermissionHelper.Resolve(user, this), ChannelPermission.ReadMessages)) | |||
| return user; | |||
| return null; | |||
| } | |||
| public override async Task<IEnumerable<GuildUser>> GetUsers() | |||
| { | |||
| var users = await Guild.GetUsers().ConfigureAwait(false); | |||
| return users.Where(x => PermissionUtilities.GetValue(PermissionHelper.Resolve(x, this), ChannelPermission.ReadMessages)); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task<Message> GetMessage(ulong id) { throw new NotSupportedException(); } //Not implemented | |||
| /// <inheritdoc /> | |||
| public async Task<IEnumerable<Message>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| @@ -101,8 +106,10 @@ namespace Discord.Rest | |||
| /// <inheritdoc /> | |||
| public override string ToString() => $"{base.ToString()} [Text]"; | |||
| async Task<IMessage> IMessageChannel.GetMessage(ulong id) | |||
| => await GetMessage(id).ConfigureAwait(false); | |||
| IEnumerable<IMessage> IMessageChannel.CachedMessages => Array.Empty<Message>(); | |||
| Task<IMessage> IMessageChannel.GetCachedMessage(ulong id) | |||
| => Task.FromResult<IMessage>(null); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit) | |||
| => await GetMessages(limit).ConfigureAwait(false); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) | |||
| @@ -1,7 +1,6 @@ | |||
| using Discord.API.Rest; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| using Model = Discord.API.Channel; | |||
| @@ -33,11 +32,8 @@ namespace Discord.Rest | |||
| Update(model); | |||
| } | |||
| protected override async Task<IEnumerable<GuildUser>> GetUsers() | |||
| { | |||
| var users = await Guild.GetUsers().ConfigureAwait(false); | |||
| return users.Where(x => PermissionUtilities.GetValue(PermissionHelper.Resolve(x, this), ChannelPermission.Connect)); | |||
| } | |||
| public override Task<GuildUser> GetUser(ulong id) { throw new NotSupportedException(); } | |||
| public override Task<IEnumerable<GuildUser>> GetUsers() { throw new NotSupportedException(); } | |||
| /// <inheritdoc /> | |||
| public override string ToString() => $"{base.ToString()} [Voice]"; | |||
| @@ -134,7 +134,6 @@ namespace Discord.Rest | |||
| var args = new ModifyGuildEmbedParams(); | |||
| func(args); | |||
| var model = await Discord.BaseClient.ModifyGuildEmbed(Id, args).ConfigureAwait(false); | |||
| Update(model); | |||
| } | |||
| /// <inheritdoc /> | |||
| @@ -109,7 +109,7 @@ namespace Discord.Rest | |||
| IGuild IGuildUser.Guild => Guild; | |||
| IReadOnlyList<IRole> IGuildUser.Roles => Roles; | |||
| ulong? IGuildUser.VoiceChannelId => null; | |||
| IVoiceChannel IGuildUser.VoiceChannel => null; | |||
| ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) | |||
| => GetPermissions(channel); | |||
| @@ -24,6 +24,7 @@ namespace Discord.WebSocket | |||
| public DateTime CreatedAt => DateTimeHelper.FromSnowflake(Id); | |||
| /// <inheritdoc /> | |||
| public IEnumerable<IUser> Users => ImmutableArray.Create<IUser>(Discord.CurrentUser, Recipient); | |||
| public IEnumerable<Message> CachedMessages => _messages.Messages; | |||
| internal DMChannel(DiscordClient discord, Model model) | |||
| { | |||
| @@ -52,15 +53,20 @@ namespace Discord.WebSocket | |||
| return null; | |||
| } | |||
| /// <inheritdoc /> | |||
| /// <summary> Gets the message from this channel's cache with the given id, or null if none was found. </summary> | |||
| public Message GetCachedMessage(ulong id) | |||
| { | |||
| return _messages.Get(id); | |||
| } | |||
| /// <summary> Gets the last N messages from this message channel. </summary> | |||
| public async Task<IEnumerable<Message>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| return await _messages.GetMany(null, Direction.Before, limit).ConfigureAwait(false); | |||
| return await _messages.Download(null, Direction.Before, limit).ConfigureAwait(false); | |||
| } | |||
| /// <inheritdoc /> | |||
| /// <summary> Gets a collection of messages in this channel. </summary> | |||
| public async Task<IEnumerable<Message>> GetMessages(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| return await _messages.GetMany(fromMessageId, dir, limit).ConfigureAwait(false); | |||
| return await _messages.Download(fromMessageId, dir, limit).ConfigureAwait(false); | |||
| } | |||
| /// <inheritdoc /> | |||
| @@ -111,13 +117,14 @@ namespace Discord.WebSocket | |||
| public override string ToString() => $"@{Recipient} [DM]"; | |||
| IDMUser IDMChannel.Recipient => Recipient; | |||
| IEnumerable<IMessage> IMessageChannel.CachedMessages => CachedMessages; | |||
| Task<IEnumerable<IUser>> IChannel.GetUsers() | |||
| => Task.FromResult(Users); | |||
| Task<IUser> IChannel.GetUser(ulong id) | |||
| => Task.FromResult(GetUser(id)); | |||
| Task<IMessage> IMessageChannel.GetMessage(ulong id) | |||
| => throw new NotSupportedException(); | |||
| Task<IMessage> IMessageChannel.GetCachedMessage(ulong id) | |||
| => Task.FromResult<IMessage>(GetCachedMessage(id)); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit) | |||
| => await GetMessages(limit).ConfigureAwait(false); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) | |||
| @@ -11,7 +11,7 @@ namespace Discord.WebSocket | |||
| public abstract class GuildChannel : IGuildChannel | |||
| { | |||
| private ConcurrentDictionary<ulong, Overwrite> _overwrites; | |||
| private ChannelPermissionsCache _permissions; | |||
| internal ChannelPermissionsCache _permissions; | |||
| /// <inheritdoc /> | |||
| public ulong Id { get; } | |||
| @@ -22,6 +22,7 @@ namespace Discord.WebSocket | |||
| public string Name { get; private set; } | |||
| /// <inheritdoc /> | |||
| public int Position { get; private set; } | |||
| public abstract IEnumerable<GuildUser> Users { get; } | |||
| /// <inheritdoc /> | |||
| public DateTime CreatedAt => DateTimeHelper.FromSnowflake(Id); | |||
| @@ -56,20 +57,13 @@ namespace Discord.WebSocket | |||
| var args = new ModifyGuildChannelParams(); | |||
| func(args); | |||
| var model = await Discord.BaseClient.ModifyGuildChannel(Id, args).ConfigureAwait(false); | |||
| await Discord.BaseClient.ModifyGuildChannel(Id, args).ConfigureAwait(false); | |||
| } | |||
| /// <summary> Gets a user in this channel with the given id. </summary> | |||
| public async Task<GuildUser> GetUser(ulong id) | |||
| { | |||
| var model = await Discord.BaseClient.GetGuildMember(Guild.Id, id).ConfigureAwait(false); | |||
| if (model != null) | |||
| return new GuildUser(Guild, model); | |||
| return null; | |||
| } | |||
| protected abstract Task<IEnumerable<GuildUser>> GetUsers(); | |||
| public abstract GuildUser GetUser(ulong id); | |||
| /// <summary> Gets the permission overwrite for a specific user, or null if one does not exist. </summary> | |||
| /// <inheritdoc /> | |||
| public OverwritePermissions? GetPermissionOverwrite(IUser user) | |||
| { | |||
| Overwrite value; | |||
| @@ -77,7 +71,7 @@ namespace Discord.WebSocket | |||
| return value.Permissions; | |||
| return null; | |||
| } | |||
| /// <summary> Gets the permission overwrite for a specific role, or null if one does not exist. </summary> | |||
| /// <inheritdoc /> | |||
| public OverwritePermissions? GetPermissionOverwrite(IRole role) | |||
| { | |||
| Overwrite value; | |||
| @@ -92,35 +86,27 @@ namespace Discord.WebSocket | |||
| return models.Select(x => new GuildInvite(Guild, x)); | |||
| } | |||
| /// <summary> Adds or updates the permission overwrite for the given user. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task AddPermissionOverwrite(IUser user, OverwritePermissions perms) | |||
| { | |||
| var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; | |||
| await Discord.BaseClient.ModifyChannelPermissions(Id, user.Id, args).ConfigureAwait(false); | |||
| _overwrites[user.Id] = new Overwrite(new API.Overwrite { Allow = perms.AllowValue, Deny = perms.DenyValue, TargetId = user.Id, TargetType = PermissionTarget.User }); | |||
| } | |||
| /// <summary> Adds or updates the permission overwrite for the given role. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task AddPermissionOverwrite(IRole role, OverwritePermissions perms) | |||
| { | |||
| var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; | |||
| await Discord.BaseClient.ModifyChannelPermissions(Id, role.Id, args).ConfigureAwait(false); | |||
| _overwrites[role.Id] = new Overwrite(new API.Overwrite { Allow = perms.AllowValue, Deny = perms.DenyValue, TargetId = role.Id, TargetType = PermissionTarget.Role }); | |||
| } | |||
| /// <summary> Removes the permission overwrite for the given user, if one exists. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task RemovePermissionOverwrite(IUser user) | |||
| { | |||
| await Discord.BaseClient.DeleteChannelPermission(Id, user.Id).ConfigureAwait(false); | |||
| Overwrite value; | |||
| _overwrites.TryRemove(user.Id, out value); | |||
| } | |||
| /// <summary> Removes the permission overwrite for the given role, if one exists. </summary> | |||
| /// <inheritdoc /> | |||
| public async Task RemovePermissionOverwrite(IRole role) | |||
| { | |||
| await Discord.BaseClient.DeleteChannelPermission(Id, role.Id).ConfigureAwait(false); | |||
| Overwrite value; | |||
| _overwrites.TryRemove(role.Id, out value); | |||
| } | |||
| /// <summary> Creates a new invite to this channel. </summary> | |||
| @@ -152,14 +138,14 @@ namespace Discord.WebSocket | |||
| => await CreateInvite(maxAge, maxUses, isTemporary, withXkcd).ConfigureAwait(false); | |||
| async Task<IEnumerable<IGuildInvite>> IGuildChannel.GetInvites() | |||
| => await GetInvites().ConfigureAwait(false); | |||
| async Task<IEnumerable<IGuildUser>> IGuildChannel.GetUsers() | |||
| => await GetUsers().ConfigureAwait(false); | |||
| async Task<IGuildUser> IGuildChannel.GetUser(ulong id) | |||
| => await GetUser(id).ConfigureAwait(false); | |||
| async Task<IEnumerable<IUser>> IChannel.GetUsers() | |||
| => await GetUsers().ConfigureAwait(false); | |||
| async Task<IUser> IChannel.GetUser(ulong id) | |||
| => await GetUser(id).ConfigureAwait(false); | |||
| Task<IEnumerable<IGuildUser>> IGuildChannel.GetUsers() | |||
| => Task.FromResult<IEnumerable<IGuildUser>>(Users); | |||
| Task<IGuildUser> IGuildChannel.GetUser(ulong id) | |||
| => Task.FromResult<IGuildUser>(GetUser(id)); | |||
| Task<IEnumerable<IUser>> IChannel.GetUsers() | |||
| => Task.FromResult<IEnumerable<IUser>>(Users); | |||
| Task<IUser> IChannel.GetUser(ulong id) | |||
| => Task.FromResult<IUser>(GetUser(id)); | |||
| Task IUpdateable.Update() | |||
| => Task.CompletedTask; | |||
| } | |||
| @@ -1,6 +1,7 @@ | |||
| using Discord.API.Rest; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Collections.Immutable; | |||
| using System.IO; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| @@ -17,6 +18,9 @@ namespace Discord.WebSocket | |||
| /// <inheritdoc /> | |||
| public string Mention => MentionHelper.Mention(this); | |||
| public override IEnumerable<GuildUser> Users | |||
| => _permissions.Members.Where(x => x.Permissions.ReadMessages).Select(x => x.User).ToImmutableArray(); | |||
| public IEnumerable<Message> CachedMessages => _messages.Messages; | |||
| internal TextChannel(Guild guild, Model model) | |||
| : base(guild, model) | |||
| @@ -39,27 +43,28 @@ namespace Discord.WebSocket | |||
| await Discord.BaseClient.ModifyGuildChannel(Id, args).ConfigureAwait(false); | |||
| } | |||
| protected override async Task<IEnumerable<GuildUser>> GetUsers() | |||
| /// <summary> Gets the message from this channel's cache with the given id, or null if none was found. </summary> | |||
| public Message GetCachedMessage(ulong id) | |||
| { | |||
| var users = await Guild.GetUsers().ConfigureAwait(false); | |||
| return users.Where(x => PermissionUtilities.GetValue(PermissionHelper.Resolve(x, this), ChannelPermission.ReadMessages)); | |||
| return _messages.Get(id); | |||
| } | |||
| /// <inheritdoc /> | |||
| public Task<Message> GetMessage(ulong id) { throw new NotSupportedException(); } //Not implemented | |||
| /// <inheritdoc /> | |||
| /// <summary> Gets the last N messages from this message channel. </summary> | |||
| public async Task<IEnumerable<Message>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| var args = new GetChannelMessagesParams { Limit = limit }; | |||
| var models = await Discord.BaseClient.GetChannelMessages(Id, args).ConfigureAwait(false); | |||
| return models.Select(x => new Message(this, x)); | |||
| return await _messages.Download(null, Direction.Before, limit).ConfigureAwait(false); | |||
| } | |||
| /// <inheritdoc /> | |||
| /// <summary> Gets a collection of messages in this channel. </summary> | |||
| public async Task<IEnumerable<Message>> GetMessages(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| var args = new GetChannelMessagesParams { Limit = limit }; | |||
| var models = await Discord.BaseClient.GetChannelMessages(Id, args).ConfigureAwait(false); | |||
| return models.Select(x => new Message(this, x)); | |||
| return await _messages.Download(fromMessageId, dir, limit).ConfigureAwait(false); | |||
| } | |||
| public override GuildUser GetUser(ulong id) | |||
| { | |||
| var member = _permissions.Get(id); | |||
| if (member != null && member.Value.Permissions.ReadMessages) | |||
| return member.Value.User; | |||
| return null; | |||
| } | |||
| /// <inheritdoc /> | |||
| @@ -103,8 +108,10 @@ namespace Discord.WebSocket | |||
| /// <inheritdoc /> | |||
| public override string ToString() => $"{base.ToString()} [Text]"; | |||
| async Task<IMessage> IMessageChannel.GetMessage(ulong id) | |||
| => await GetMessage(id).ConfigureAwait(false); | |||
| IEnumerable<IMessage> IMessageChannel.CachedMessages => CachedMessages; | |||
| Task<IMessage> IMessageChannel.GetCachedMessage(ulong id) | |||
| => Task.FromResult<IMessage>(GetCachedMessage(id)); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit) | |||
| => await GetMessages(limit).ConfigureAwait(false); | |||
| async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) | |||
| @@ -12,6 +12,9 @@ namespace Discord.WebSocket | |||
| /// <inheritdoc /> | |||
| public int Bitrate { get; private set; } | |||
| public override IEnumerable<GuildUser> Users | |||
| => Guild.Users.Where(x => x.VoiceChannel == this); | |||
| internal VoiceChannel(Guild guild, Model model) | |||
| : base(guild, model) | |||
| { | |||
| @@ -32,10 +35,12 @@ namespace Discord.WebSocket | |||
| await Discord.BaseClient.ModifyGuildChannel(Id, args).ConfigureAwait(false); | |||
| } | |||
| protected override async Task<IEnumerable<GuildUser>> GetUsers() | |||
| public override GuildUser GetUser(ulong id) | |||
| { | |||
| var users = await Guild.GetUsers().ConfigureAwait(false); | |||
| return users.Where(x => PermissionUtilities.GetValue(PermissionHelper.Resolve(x, this), ChannelPermission.Connect)); | |||
| var member = _permissions.Get(id); | |||
| if (member != null && member.Value.Permissions.ReadMessages) | |||
| return member.Value.User; | |||
| return null; | |||
| } | |||
| /// <inheritdoc /> | |||
| @@ -56,6 +56,7 @@ namespace Discord.WebSocket | |||
| public Role EveryoneRole => GetRole(Id); | |||
| /// <summary> Gets a collection of all roles in this guild. </summary> | |||
| public IEnumerable<Role> Roles => _roles?.Select(x => x.Value) ?? Enumerable.Empty<Role>(); | |||
| public IEnumerable<GuildUser> Users => Array.Empty<GuildUser>(); | |||
| internal Guild(DiscordClient discord, Model model) | |||
| { | |||
| @@ -22,6 +22,8 @@ namespace Discord.WebSocket | |||
| public DateTime JoinedAt { get; private set; } | |||
| /// <inheritdoc /> | |||
| public string Nickname { get; private set; } | |||
| /// <inheritdoc /> | |||
| public VoiceChannel VoiceChannel { get; private set; } | |||
| /// <inheritdoc /> | |||
| public IReadOnlyList<Role> Roles => _roles; | |||
| @@ -103,7 +105,7 @@ namespace Discord.WebSocket | |||
| IGuild IGuildUser.Guild => Guild; | |||
| IReadOnlyList<IRole> IGuildUser.Roles => Roles; | |||
| ulong? IGuildUser.VoiceChannelId => null; | |||
| IVoiceChannel IGuildUser.VoiceChannel => VoiceChannel; | |||
| ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) | |||
| => GetPermissions(channel); | |||
| @@ -16,6 +16,8 @@ namespace Discord.WebSocket | |||
| private readonly ConcurrentQueue<ulong> _orderedMessages; | |||
| private readonly int _size; | |||
| public IEnumerable<Message> Messages => _messages.Select(x => x.Value); | |||
| public MessageCache(DiscordClient discord, IMessageChannel channel) | |||
| { | |||
| _discord = discord; | |||
| @@ -51,13 +53,11 @@ namespace Discord.WebSocket | |||
| return result; | |||
| return null; | |||
| } | |||
| public async Task<IEnumerable<Message>> GetMany(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| public IImmutableList<Message> GetMany(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| //TODO: Test heavily | |||
| if (limit < 0) throw new ArgumentOutOfRangeException(nameof(limit)); | |||
| if (limit == 0) return ImmutableArray<Message>.Empty; | |||
| IEnumerable<ulong> cachedMessageIds; | |||
| if (fromMessageId == null) | |||
| cachedMessageIds = _orderedMessages; | |||
| @@ -66,7 +66,7 @@ namespace Discord.WebSocket | |||
| else | |||
| cachedMessageIds = _orderedMessages.Where(x => x > fromMessageId.Value); | |||
| var cachedMessages = cachedMessageIds | |||
| return cachedMessageIds | |||
| .Take(limit) | |||
| .Select(x => | |||
| { | |||
| @@ -76,19 +76,28 @@ namespace Discord.WebSocket | |||
| return null; | |||
| }) | |||
| .Where(x => x != null) | |||
| .ToArray(); | |||
| .ToImmutableArray(); | |||
| } | |||
| public async Task<IEnumerable<Message>> Download(ulong? fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch) | |||
| { | |||
| //TODO: Test heavily | |||
| if (limit < 0) throw new ArgumentOutOfRangeException(nameof(limit)); | |||
| if (limit == 0) return ImmutableArray<Message>.Empty; | |||
| if (cachedMessages.Length == limit) | |||
| var cachedMessages = GetMany(fromMessageId, dir, limit); | |||
| if (cachedMessages.Count == limit) | |||
| return cachedMessages; | |||
| else if (cachedMessages.Length > limit) | |||
| return cachedMessages.Skip(cachedMessages.Length - limit); | |||
| else if (cachedMessages.Count > limit) | |||
| return cachedMessages.Skip(cachedMessages.Count - limit); | |||
| else | |||
| { | |||
| var args = new GetChannelMessagesParams | |||
| { | |||
| Limit = limit - cachedMessages.Length, | |||
| Limit = limit - cachedMessages.Count, | |||
| RelativeDirection = dir, | |||
| RelativeMessageId = dir == Direction.Before ? cachedMessages[0].Id : cachedMessages[cachedMessages.Length - 1].Id | |||
| RelativeMessageId = dir == Direction.Before ? cachedMessages[0].Id : cachedMessages[cachedMessages.Count - 1].Id | |||
| }; | |||
| var downloadedMessages = await _discord.BaseClient.GetChannelMessages(_channel.Id, args).ConfigureAwait(false); | |||
| return cachedMessages.AsEnumerable().Concat(downloadedMessages.Select(x => new Message(_channel, x))).ToImmutableArray(); | |||