@@ -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(); | |||