Browse Source

Fixed several channel bugs and cleaned up WS channel entities.

tags/1.0-rc
RogueException 9 years ago
parent
commit
07e8eb4581
15 changed files with 122 additions and 103 deletions
  1. +6
    -2
      src/Discord.Net/Common/Entities/Channels/IMessageChannel.cs
  2. +2
    -2
      src/Discord.Net/Common/Entities/Users/IGuildUser.cs
  3. +3
    -2
      src/Discord.Net/Rest/Entities/Channels/DMChannel.cs
  4. +9
    -14
      src/Discord.Net/Rest/Entities/Channels/GuildChannel.cs
  5. +13
    -6
      src/Discord.Net/Rest/Entities/Channels/TextChannel.cs
  6. +2
    -6
      src/Discord.Net/Rest/Entities/Channels/VoiceChannel.cs
  7. +0
    -1
      src/Discord.Net/Rest/Entities/Guilds/Guild.cs
  8. +1
    -1
      src/Discord.Net/Rest/Entities/Users/GuildUser.cs
  9. +13
    -6
      src/Discord.Net/WebSocket/Entities/Channels/DMChannel.cs
  10. +18
    -32
      src/Discord.Net/WebSocket/Entities/Channels/GuildChannel.cs
  11. +23
    -16
      src/Discord.Net/WebSocket/Entities/Channels/TextChannel.cs
  12. +8
    -3
      src/Discord.Net/WebSocket/Entities/Channels/VoiceChannel.cs
  13. +1
    -0
      src/Discord.Net/WebSocket/Entities/Guilds/Guild.cs
  14. +3
    -1
      src/Discord.Net/WebSocket/Entities/Users/GuildUser.cs
  15. +20
    -11
      src/Discord.Net/WebSocket/MessageCache.cs

+ 6
- 2
src/Discord.Net/Common/Entities/Channels/IMessageChannel.cs View File

@@ -6,8 +6,12 @@ namespace Discord
{ {
public interface IMessageChannel : IChannel 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> /// <summary> Gets the last N messages from this message channel. </summary>
Task<IEnumerable<IMessage>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch); Task<IEnumerable<IMessage>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch);
/// <summary> Gets a collection of messages in this channel. </summary> /// <summary> Gets a collection of messages in this channel. </summary>


+ 2
- 2
src/Discord.Net/Common/Entities/Users/IGuildUser.cs View File

@@ -21,8 +21,8 @@ namespace Discord
IGuild Guild { get; } 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> /// <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; } 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> /// <summary> Gets the guild-level permissions granted to this user by their roles. </summary>
GuildPermissions GetGuildPermissions(); GuildPermissions GetGuildPermissions();


+ 3
- 2
src/Discord.Net/Rest/Entities/Channels/DMChannel.cs View File

@@ -124,13 +124,14 @@ namespace Discord.Rest
public override string ToString() => $"@{Recipient} [DM]"; public override string ToString() => $"@{Recipient} [DM]";
IDMUser IDMChannel.Recipient => Recipient; IDMUser IDMChannel.Recipient => Recipient;
IEnumerable<IMessage> IMessageChannel.CachedMessages => Array.Empty<Message>();


async Task<IEnumerable<IUser>> IChannel.GetUsers() async Task<IEnumerable<IUser>> IChannel.GetUsers()
=> await GetUsers().ConfigureAwait(false); => await GetUsers().ConfigureAwait(false);
async Task<IUser> IChannel.GetUser(ulong id) async Task<IUser> IChannel.GetUser(ulong id)
=> await GetUser(id).ConfigureAwait(false); => 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) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit)
=> await GetMessages(limit).ConfigureAwait(false); => await GetMessages(limit).ConfigureAwait(false);
async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit)


+ 9
- 14
src/Discord.Net/Rest/Entities/Channels/GuildChannel.cs View File

@@ -60,16 +60,11 @@ namespace Discord.Rest
} }


/// <summary> Gets a user in this channel with the given id. </summary> /// <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) public OverwritePermissions? GetPermissionOverwrite(IUser user)
{ {
Overwrite value; Overwrite value;
@@ -77,7 +72,7 @@ namespace Discord.Rest
return value.Permissions; return value.Permissions;
return null; 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) public OverwritePermissions? GetPermissionOverwrite(IRole role)
{ {
Overwrite value; Overwrite value;
@@ -92,21 +87,21 @@ namespace Discord.Rest
return models.Select(x => new GuildInvite(Guild, x)); 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) public async Task AddPermissionOverwrite(IUser user, OverwritePermissions perms)
{ {
var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue };
await Discord.BaseClient.ModifyChannelPermissions(Id, user.Id, args).ConfigureAwait(false); 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 }); _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) public async Task AddPermissionOverwrite(IRole role, OverwritePermissions perms)
{ {
var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue };
await Discord.BaseClient.ModifyChannelPermissions(Id, role.Id, args).ConfigureAwait(false); 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 }); _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) public async Task RemovePermissionOverwrite(IUser user)
{ {
await Discord.BaseClient.DeleteChannelPermission(Id, user.Id).ConfigureAwait(false); await Discord.BaseClient.DeleteChannelPermission(Id, user.Id).ConfigureAwait(false);
@@ -114,7 +109,7 @@ namespace Discord.Rest
Overwrite value; Overwrite value;
_overwrites.TryRemove(user.Id, out 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) public async Task RemovePermissionOverwrite(IRole role)
{ {
await Discord.BaseClient.DeleteChannelPermission(Id, role.Id).ConfigureAwait(false); await Discord.BaseClient.DeleteChannelPermission(Id, role.Id).ConfigureAwait(false);


+ 13
- 6
src/Discord.Net/Rest/Entities/Channels/TextChannel.cs View File

@@ -37,14 +37,19 @@ namespace Discord.Rest
Update(model); 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); var users = await Guild.GetUsers().ConfigureAwait(false);
return users.Where(x => PermissionUtilities.GetValue(PermissionHelper.Resolve(x, this), ChannelPermission.ReadMessages)); 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 /> /// <inheritdoc />
public async Task<IEnumerable<Message>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch) public async Task<IEnumerable<Message>> GetMessages(int limit = DiscordConfig.MaxMessagesPerBatch)
{ {
@@ -101,8 +106,10 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() => $"{base.ToString()} [Text]"; 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) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit)
=> await GetMessages(limit).ConfigureAwait(false); => await GetMessages(limit).ConfigureAwait(false);
async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit)


+ 2
- 6
src/Discord.Net/Rest/Entities/Channels/VoiceChannel.cs View File

@@ -1,7 +1,6 @@
using Discord.API.Rest; using Discord.API.Rest;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Model = Discord.API.Channel; using Model = Discord.API.Channel;


@@ -33,11 +32,8 @@ namespace Discord.Rest
Update(model); 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 /> /// <inheritdoc />
public override string ToString() => $"{base.ToString()} [Voice]"; public override string ToString() => $"{base.ToString()} [Voice]";


+ 0
- 1
src/Discord.Net/Rest/Entities/Guilds/Guild.cs View File

@@ -134,7 +134,6 @@ namespace Discord.Rest
var args = new ModifyGuildEmbedParams(); var args = new ModifyGuildEmbedParams();
func(args); func(args);
var model = await Discord.BaseClient.ModifyGuildEmbed(Id, args).ConfigureAwait(false); var model = await Discord.BaseClient.ModifyGuildEmbed(Id, args).ConfigureAwait(false);

Update(model); Update(model);
} }
/// <inheritdoc /> /// <inheritdoc />


+ 1
- 1
src/Discord.Net/Rest/Entities/Users/GuildUser.cs View File

@@ -109,7 +109,7 @@ namespace Discord.Rest


IGuild IGuildUser.Guild => Guild; IGuild IGuildUser.Guild => Guild;
IReadOnlyList<IRole> IGuildUser.Roles => Roles; IReadOnlyList<IRole> IGuildUser.Roles => Roles;
ulong? IGuildUser.VoiceChannelId => null;
IVoiceChannel IGuildUser.VoiceChannel => null;


ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel)
=> GetPermissions(channel); => GetPermissions(channel);


+ 13
- 6
src/Discord.Net/WebSocket/Entities/Channels/DMChannel.cs View File

@@ -24,6 +24,7 @@ namespace Discord.WebSocket
public DateTime CreatedAt => DateTimeHelper.FromSnowflake(Id); public DateTime CreatedAt => DateTimeHelper.FromSnowflake(Id);
/// <inheritdoc /> /// <inheritdoc />
public IEnumerable<IUser> Users => ImmutableArray.Create<IUser>(Discord.CurrentUser, Recipient); public IEnumerable<IUser> Users => ImmutableArray.Create<IUser>(Discord.CurrentUser, Recipient);
public IEnumerable<Message> CachedMessages => _messages.Messages;


internal DMChannel(DiscordClient discord, Model model) internal DMChannel(DiscordClient discord, Model model)
{ {
@@ -52,15 +53,20 @@ namespace Discord.WebSocket
return null; 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) 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) 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 /> /// <inheritdoc />
@@ -111,13 +117,14 @@ namespace Discord.WebSocket
public override string ToString() => $"@{Recipient} [DM]"; public override string ToString() => $"@{Recipient} [DM]";
IDMUser IDMChannel.Recipient => Recipient; IDMUser IDMChannel.Recipient => Recipient;
IEnumerable<IMessage> IMessageChannel.CachedMessages => CachedMessages;


Task<IEnumerable<IUser>> IChannel.GetUsers() Task<IEnumerable<IUser>> IChannel.GetUsers()
=> Task.FromResult(Users); => Task.FromResult(Users);
Task<IUser> IChannel.GetUser(ulong id) Task<IUser> IChannel.GetUser(ulong id)
=> Task.FromResult(GetUser(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) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit)
=> await GetMessages(limit).ConfigureAwait(false); => await GetMessages(limit).ConfigureAwait(false);
async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit)


+ 18
- 32
src/Discord.Net/WebSocket/Entities/Channels/GuildChannel.cs View File

@@ -11,7 +11,7 @@ namespace Discord.WebSocket
public abstract class GuildChannel : IGuildChannel public abstract class GuildChannel : IGuildChannel
{ {
private ConcurrentDictionary<ulong, Overwrite> _overwrites; private ConcurrentDictionary<ulong, Overwrite> _overwrites;
private ChannelPermissionsCache _permissions;
internal ChannelPermissionsCache _permissions;


/// <inheritdoc /> /// <inheritdoc />
public ulong Id { get; } public ulong Id { get; }
@@ -22,6 +22,7 @@ namespace Discord.WebSocket
public string Name { get; private set; } public string Name { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public int Position { get; private set; } public int Position { get; private set; }
public abstract IEnumerable<GuildUser> Users { get; }


/// <inheritdoc /> /// <inheritdoc />
public DateTime CreatedAt => DateTimeHelper.FromSnowflake(Id); public DateTime CreatedAt => DateTimeHelper.FromSnowflake(Id);
@@ -56,20 +57,13 @@ namespace Discord.WebSocket


var args = new ModifyGuildChannelParams(); var args = new ModifyGuildChannelParams();
func(args); 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> /// <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) public OverwritePermissions? GetPermissionOverwrite(IUser user)
{ {
Overwrite value; Overwrite value;
@@ -77,7 +71,7 @@ namespace Discord.WebSocket
return value.Permissions; return value.Permissions;
return null; 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) public OverwritePermissions? GetPermissionOverwrite(IRole role)
{ {
Overwrite value; Overwrite value;
@@ -92,35 +86,27 @@ namespace Discord.WebSocket
return models.Select(x => new GuildInvite(Guild, x)); 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) public async Task AddPermissionOverwrite(IUser user, OverwritePermissions perms)
{ {
var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue };
await Discord.BaseClient.ModifyChannelPermissions(Id, user.Id, args).ConfigureAwait(false); 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) public async Task AddPermissionOverwrite(IRole role, OverwritePermissions perms)
{ {
var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue }; var args = new ModifyChannelPermissionsParams { Allow = perms.AllowValue, Deny = perms.DenyValue };
await Discord.BaseClient.ModifyChannelPermissions(Id, role.Id, args).ConfigureAwait(false); 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) public async Task RemovePermissionOverwrite(IUser user)
{ {
await Discord.BaseClient.DeleteChannelPermission(Id, user.Id).ConfigureAwait(false); 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) public async Task RemovePermissionOverwrite(IRole role)
{ {
await Discord.BaseClient.DeleteChannelPermission(Id, role.Id).ConfigureAwait(false); 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> /// <summary> Creates a new invite to this channel. </summary>
@@ -152,14 +138,14 @@ namespace Discord.WebSocket
=> await CreateInvite(maxAge, maxUses, isTemporary, withXkcd).ConfigureAwait(false); => await CreateInvite(maxAge, maxUses, isTemporary, withXkcd).ConfigureAwait(false);
async Task<IEnumerable<IGuildInvite>> IGuildChannel.GetInvites() async Task<IEnumerable<IGuildInvite>> IGuildChannel.GetInvites()
=> await GetInvites().ConfigureAwait(false); => 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 IUpdateable.Update()
=> Task.CompletedTask; => Task.CompletedTask;
} }


+ 23
- 16
src/Discord.Net/WebSocket/Entities/Channels/TextChannel.cs View File

@@ -1,6 +1,7 @@
using Discord.API.Rest; using Discord.API.Rest;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -17,6 +18,9 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
public string Mention => MentionHelper.Mention(this); 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) internal TextChannel(Guild guild, Model model)
: base(guild, model) : base(guild, model)
@@ -39,27 +43,28 @@ namespace Discord.WebSocket
await Discord.BaseClient.ModifyGuildChannel(Id, args).ConfigureAwait(false); 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) 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) 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 /> /// <inheritdoc />
@@ -103,8 +108,10 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public override string ToString() => $"{base.ToString()} [Text]"; 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) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(int limit)
=> await GetMessages(limit).ConfigureAwait(false); => await GetMessages(limit).ConfigureAwait(false);
async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit) async Task<IEnumerable<IMessage>> IMessageChannel.GetMessages(ulong fromMessageId, Direction dir, int limit)


+ 8
- 3
src/Discord.Net/WebSocket/Entities/Channels/VoiceChannel.cs View File

@@ -12,6 +12,9 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public int Bitrate { get; private set; } public int Bitrate { get; private set; }


public override IEnumerable<GuildUser> Users
=> Guild.Users.Where(x => x.VoiceChannel == this);

internal VoiceChannel(Guild guild, Model model) internal VoiceChannel(Guild guild, Model model)
: base(guild, model) : base(guild, model)
{ {
@@ -32,10 +35,12 @@ namespace Discord.WebSocket
await Discord.BaseClient.ModifyGuildChannel(Id, args).ConfigureAwait(false); 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 /> /// <inheritdoc />


+ 1
- 0
src/Discord.Net/WebSocket/Entities/Guilds/Guild.cs View File

@@ -56,6 +56,7 @@ namespace Discord.WebSocket
public Role EveryoneRole => GetRole(Id); public Role EveryoneRole => GetRole(Id);
/// <summary> Gets a collection of all roles in this guild. </summary> /// <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<Role> Roles => _roles?.Select(x => x.Value) ?? Enumerable.Empty<Role>();
public IEnumerable<GuildUser> Users => Array.Empty<GuildUser>();


internal Guild(DiscordClient discord, Model model) internal Guild(DiscordClient discord, Model model)
{ {


+ 3
- 1
src/Discord.Net/WebSocket/Entities/Users/GuildUser.cs View File

@@ -22,6 +22,8 @@ namespace Discord.WebSocket
public DateTime JoinedAt { get; private set; } public DateTime JoinedAt { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string Nickname { get; private set; } public string Nickname { get; private set; }
/// <inheritdoc />
public VoiceChannel VoiceChannel { get; private set; }


/// <inheritdoc /> /// <inheritdoc />
public IReadOnlyList<Role> Roles => _roles; public IReadOnlyList<Role> Roles => _roles;
@@ -103,7 +105,7 @@ namespace Discord.WebSocket


IGuild IGuildUser.Guild => Guild; IGuild IGuildUser.Guild => Guild;
IReadOnlyList<IRole> IGuildUser.Roles => Roles; IReadOnlyList<IRole> IGuildUser.Roles => Roles;
ulong? IGuildUser.VoiceChannelId => null;
IVoiceChannel IGuildUser.VoiceChannel => VoiceChannel;


ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel) ChannelPermissions IGuildUser.GetPermissions(IGuildChannel channel)
=> GetPermissions(channel); => GetPermissions(channel);


+ 20
- 11
src/Discord.Net/WebSocket/MessageCache.cs View File

@@ -16,6 +16,8 @@ namespace Discord.WebSocket
private readonly ConcurrentQueue<ulong> _orderedMessages; private readonly ConcurrentQueue<ulong> _orderedMessages;
private readonly int _size; private readonly int _size;


public IEnumerable<Message> Messages => _messages.Select(x => x.Value);

public MessageCache(DiscordClient discord, IMessageChannel channel) public MessageCache(DiscordClient discord, IMessageChannel channel)
{ {
_discord = discord; _discord = discord;
@@ -51,13 +53,11 @@ namespace Discord.WebSocket
return result; return result;
return null; 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) throw new ArgumentOutOfRangeException(nameof(limit));
if (limit == 0) return ImmutableArray<Message>.Empty; if (limit == 0) return ImmutableArray<Message>.Empty;
IEnumerable<ulong> cachedMessageIds; IEnumerable<ulong> cachedMessageIds;
if (fromMessageId == null) if (fromMessageId == null)
cachedMessageIds = _orderedMessages; cachedMessageIds = _orderedMessages;
@@ -66,7 +66,7 @@ namespace Discord.WebSocket
else else
cachedMessageIds = _orderedMessages.Where(x => x > fromMessageId.Value); cachedMessageIds = _orderedMessages.Where(x => x > fromMessageId.Value);


var cachedMessages = cachedMessageIds
return cachedMessageIds
.Take(limit) .Take(limit)
.Select(x => .Select(x =>
{ {
@@ -76,19 +76,28 @@ namespace Discord.WebSocket
return null; return null;
}) })
.Where(x => x != 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; 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 else
{ {
var args = new GetChannelMessagesParams var args = new GetChannelMessagesParams
{ {
Limit = limit - cachedMessages.Length,
Limit = limit - cachedMessages.Count,
RelativeDirection = dir, 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); var downloadedMessages = await _discord.BaseClient.GetChannelMessages(_channel.Id, args).ConfigureAwait(false);
return cachedMessages.AsEnumerable().Concat(downloadedMessages.Select(x => new Message(_channel, x))).ToImmutableArray(); return cachedMessages.AsEnumerable().Concat(downloadedMessages.Select(x => new Message(_channel, x))).ToImmutableArray();


Loading…
Cancel
Save