Browse Source

Regions discord.net.websocket (#169)

* BaseSocketClient

* BaseSocketClient.Events

* DiscordShardedClient

* DiscordShardedClient.Events

* DiscordVoiceAPIClient

* SocketGroupUser

* DiscordSocketApiClient

* DiscordSocketClient

* DiscordSocketClient.Events

* -||-

* SocketGuildUser

* SocketWebhookUser

* SocketCustomSticker

* SocketRole

* SocketMessage

* SocketSlashCommandDataOption

* SocketInteraction

* SocketApplicationCommand

* DiscordSocketClient

* SocketApplicationCommand

* SocketCategoryChannel

* SocketChannel

* SocketDMChannel

* SocketGroupChannel

* SocketGuildChannel

* SocketTextChannel

* SocketVoiceChannel

* SocketGuild

* ShardedCommandContext

* SocketCommandContext
pull/1923/head
Simon Hjorthøj GitHub 3 years ago
parent
commit
4c2d684d84
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 208 additions and 87 deletions
  1. +27
    -14
      src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
  2. +6
    -3
      src/Discord.Net.WebSocket/BaseSocketClient.cs
  3. +4
    -1
      src/Discord.Net.WebSocket/Commands/ShardedCommandContext.cs
  4. +4
    -1
      src/Discord.Net.WebSocket/Commands/SocketCommandContext.cs
  5. +2
    -1
      src/Discord.Net.WebSocket/DiscordShardedClient.Events.cs
  6. +6
    -1
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  7. +2
    -1
      src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
  8. +2
    -1
      src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs
  9. +2
    -1
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  10. +12
    -5
      src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs
  11. +8
    -3
      src/Discord.Net.WebSocket/Entities/Channels/SocketCategoryChannel.cs
  12. +6
    -2
      src/Discord.Net.WebSocket/Entities/Channels/SocketChannel.cs
  13. +18
    -8
      src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
  14. +20
    -9
      src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs
  15. +10
    -5
      src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs
  16. +18
    -8
      src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs
  17. +8
    -3
      src/Discord.Net.WebSocket/Entities/Channels/SocketVoiceChannel.cs
  18. +10
    -4
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
  19. +6
    -2
      src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandDataOption.cs
  20. +4
    -1
      src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs
  21. +4
    -2
      src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs
  22. +4
    -1
      src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
  23. +6
    -3
      src/Discord.Net.WebSocket/Entities/Roles/SocketRole.cs
  24. +4
    -1
      src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs
  25. +4
    -1
      src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs
  26. +5
    -2
      src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
  27. +6
    -3
      src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs

+ 27
- 14
src/Discord.Net.WebSocket/BaseSocketClient.Events.cs View File

@@ -6,7 +6,7 @@ namespace Discord.WebSocket
{ {
public partial class BaseSocketClient public partial class BaseSocketClient
{ {
//Channels
#region Channels
/// <summary> Fired when a channel is created. </summary> /// <summary> Fired when a channel is created. </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
@@ -74,8 +74,9 @@ namespace Discord.WebSocket
remove { _channelUpdatedEvent.Remove(value); } remove { _channelUpdatedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<SocketChannel, SocketChannel, Task>> _channelUpdatedEvent = new AsyncEvent<Func<SocketChannel, SocketChannel, Task>>(); internal readonly AsyncEvent<Func<SocketChannel, SocketChannel, Task>> _channelUpdatedEvent = new AsyncEvent<Func<SocketChannel, SocketChannel, Task>>();
#endregion


//Messages
#region Messages
/// <summary> Fired when a message is received. </summary> /// <summary> Fired when a message is received. </summary>
/// <remarks> /// <remarks>
/// <para> /// <para>
@@ -128,7 +129,8 @@ namespace Discord.WebSocket
/// source="..\Discord.Net.Examples\WebSocket\BaseSocketClient.Events.Examples.cs" /> /// source="..\Discord.Net.Examples\WebSocket\BaseSocketClient.Events.Examples.cs" />
/// </example> /// </example>


public event Func<Cacheable<IMessage, ulong>, Cacheable<IMessageChannel, ulong>, Task> MessageDeleted {
public event Func<Cacheable<IMessage, ulong>, Cacheable<IMessageChannel, ulong>, Task> MessageDeleted
{
add { _messageDeletedEvent.Add(value); } add { _messageDeletedEvent.Add(value); }
remove { _messageDeletedEvent.Remove(value); } remove { _messageDeletedEvent.Remove(value); }
} }
@@ -222,19 +224,22 @@ namespace Discord.WebSocket
/// <code language="cs" region="ReactionAdded" /// <code language="cs" region="ReactionAdded"
/// source="..\Discord.Net.Examples\WebSocket\BaseSocketClient.Events.Examples.cs"/> /// source="..\Discord.Net.Examples\WebSocket\BaseSocketClient.Events.Examples.cs"/>
/// </example> /// </example>
public event Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task> ReactionAdded {
public event Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task> ReactionAdded
{
add { _reactionAddedEvent.Add(value); } add { _reactionAddedEvent.Add(value); }
remove { _reactionAddedEvent.Remove(value); } remove { _reactionAddedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>> _reactionAddedEvent = new AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>>(); internal readonly AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>> _reactionAddedEvent = new AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>>();
/// <summary> Fired when a reaction is removed from a message. </summary> /// <summary> Fired when a reaction is removed from a message. </summary>
public event Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task> ReactionRemoved {
public event Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task> ReactionRemoved
{
add { _reactionRemovedEvent.Add(value); } add { _reactionRemovedEvent.Add(value); }
remove { _reactionRemovedEvent.Remove(value); } remove { _reactionRemovedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>> _reactionRemovedEvent = new AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>>(); internal readonly AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>> _reactionRemovedEvent = new AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, SocketReaction, Task>>();
/// <summary> Fired when all reactions to a message are cleared. </summary> /// <summary> Fired when all reactions to a message are cleared. </summary>
public event Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, Task> ReactionsCleared {
public event Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, Task> ReactionsCleared
{
add { _reactionsClearedEvent.Add(value); } add { _reactionsClearedEvent.Add(value); }
remove { _reactionsClearedEvent.Remove(value); } remove { _reactionsClearedEvent.Remove(value); }
} }
@@ -261,8 +266,9 @@ namespace Discord.WebSocket
remove { _reactionsRemovedForEmoteEvent.Remove(value); } remove { _reactionsRemovedForEmoteEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, IEmote, Task>> _reactionsRemovedForEmoteEvent = new AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, IEmote, Task>>(); internal readonly AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, IEmote, Task>> _reactionsRemovedForEmoteEvent = new AsyncEvent<Func<Cacheable<IUserMessage, ulong>, Cacheable<IMessageChannel, ulong>, IEmote, Task>>();
#endregion


//Roles
#region Roles
/// <summary> Fired when a role is created. </summary> /// <summary> Fired when a role is created. </summary>
public event Func<SocketRole, Task> RoleCreated public event Func<SocketRole, Task> RoleCreated
{ {
@@ -284,8 +290,9 @@ namespace Discord.WebSocket
remove { _roleUpdatedEvent.Remove(value); } remove { _roleUpdatedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<SocketRole, SocketRole, Task>> _roleUpdatedEvent = new AsyncEvent<Func<SocketRole, SocketRole, Task>>(); internal readonly AsyncEvent<Func<SocketRole, SocketRole, Task>> _roleUpdatedEvent = new AsyncEvent<Func<SocketRole, SocketRole, Task>>();
#endregion


//Guilds
#region Guilds
/// <summary> Fired when the connected account joins a guild. </summary> /// <summary> Fired when the connected account joins a guild. </summary>
public event Func<SocketGuild, Task> JoinedGuild public event Func<SocketGuild, Task> JoinedGuild
{ {
@@ -328,8 +335,9 @@ namespace Discord.WebSocket
remove { _guildUpdatedEvent.Remove(value); } remove { _guildUpdatedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<SocketGuild, SocketGuild, Task>> _guildUpdatedEvent = new AsyncEvent<Func<SocketGuild, SocketGuild, Task>>(); internal readonly AsyncEvent<Func<SocketGuild, SocketGuild, Task>> _guildUpdatedEvent = new AsyncEvent<Func<SocketGuild, SocketGuild, Task>>();
#endregion


//Users
#region Users
/// <summary> Fired when a user joins a guild. </summary> /// <summary> Fired when a user joins a guild. </summary>
public event Func<SocketGuildUser, Task> UserJoined public event Func<SocketGuildUser, Task> UserJoined
{ {
@@ -366,11 +374,12 @@ namespace Discord.WebSocket
} }
internal readonly AsyncEvent<Func<SocketUser, SocketUser, Task>> _userUpdatedEvent = new AsyncEvent<Func<SocketUser, SocketUser, Task>>(); internal readonly AsyncEvent<Func<SocketUser, SocketUser, Task>> _userUpdatedEvent = new AsyncEvent<Func<SocketUser, SocketUser, Task>>();
/// <summary> Fired when a guild member is updated, or a member presence is updated. </summary> /// <summary> Fired when a guild member is updated, or a member presence is updated. </summary>
public event Func<Cacheable<SocketGuildUser, ulong>, SocketGuildUser, Task> GuildMemberUpdated {
public event Func<Cacheable<SocketGuildUser, ulong>, SocketGuildUser, Task> GuildMemberUpdated
{
add { _guildMemberUpdatedEvent.Add(value); } add { _guildMemberUpdatedEvent.Add(value); }
remove { _guildMemberUpdatedEvent.Remove(value); } remove { _guildMemberUpdatedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<Cacheable<SocketGuildUser, ulong>, SocketGuildUser, Task>> _guildMemberUpdatedEvent = new AsyncEvent<Func<Cacheable<SocketGuildUser, ulong>, SocketGuildUser, Task>>();
internal readonly AsyncEvent<Func<Cacheable<SocketGuildUser, ulong>, SocketGuildUser, Task>> _guildMemberUpdatedEvent = new AsyncEvent<Func<Cacheable<SocketGuildUser, ulong>, SocketGuildUser, Task>>();
/// <summary> Fired when a user joins, leaves, or moves voice channels. </summary> /// <summary> Fired when a user joins, leaves, or moves voice channels. </summary>
public event Func<SocketUser, SocketVoiceState, SocketVoiceState, Task> UserVoiceStateUpdated public event Func<SocketUser, SocketVoiceState, SocketVoiceState, Task> UserVoiceStateUpdated
{ {
@@ -393,7 +402,8 @@ namespace Discord.WebSocket
} }
internal readonly AsyncEvent<Func<SocketSelfUser, SocketSelfUser, Task>> _selfUpdatedEvent = new AsyncEvent<Func<SocketSelfUser, SocketSelfUser, Task>>(); internal readonly AsyncEvent<Func<SocketSelfUser, SocketSelfUser, Task>> _selfUpdatedEvent = new AsyncEvent<Func<SocketSelfUser, SocketSelfUser, Task>>();
/// <summary> Fired when a user starts typing. </summary> /// <summary> Fired when a user starts typing. </summary>
public event Func<Cacheable<IUser, ulong>, Cacheable<IMessageChannel, ulong>, Task> UserIsTyping {
public event Func<Cacheable<IUser, ulong>, Cacheable<IMessageChannel, ulong>, Task> UserIsTyping
{
add { _userIsTypingEvent.Add(value); } add { _userIsTypingEvent.Add(value); }
remove { _userIsTypingEvent.Remove(value); } remove { _userIsTypingEvent.Remove(value); }
} }
@@ -412,8 +422,9 @@ namespace Discord.WebSocket
remove { _recipientRemovedEvent.Remove(value); } remove { _recipientRemovedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<SocketGroupUser, Task>> _recipientRemovedEvent = new AsyncEvent<Func<SocketGroupUser, Task>>(); internal readonly AsyncEvent<Func<SocketGroupUser, Task>> _recipientRemovedEvent = new AsyncEvent<Func<SocketGroupUser, Task>>();
#endregion


//Invites
#region Invites
/// <summary> /// <summary>
/// Fired when an invite is created. /// Fired when an invite is created.
/// </summary> /// </summary>
@@ -454,8 +465,9 @@ namespace Discord.WebSocket
remove { _inviteDeletedEvent.Remove(value); } remove { _inviteDeletedEvent.Remove(value); }
} }
internal readonly AsyncEvent<Func<SocketGuildChannel, string, Task>> _inviteDeletedEvent = new AsyncEvent<Func<SocketGuildChannel, string, Task>>(); internal readonly AsyncEvent<Func<SocketGuildChannel, string, Task>> _inviteDeletedEvent = new AsyncEvent<Func<SocketGuildChannel, string, Task>>();
#endregion


//Interactions
#region Interactions
/// <summary> /// <summary>
/// Fired when an Interaction is created. This event covers all types of interactions including but not limited to: buttons, select menus, slash commands. /// Fired when an Interaction is created. This event covers all types of interactions including but not limited to: buttons, select menus, slash commands.
/// </summary> /// </summary>
@@ -730,5 +742,6 @@ namespace Discord.WebSocket
remove { _guildStickerDeleted.Remove(value); } remove { _guildStickerDeleted.Remove(value); }
} }
internal readonly AsyncEvent<Func<SocketCustomSticker, Task>> _guildStickerDeleted = new AsyncEvent<Func<SocketCustomSticker, Task>>(); internal readonly AsyncEvent<Func<SocketCustomSticker, Task>> _guildStickerDeleted = new AsyncEvent<Func<SocketCustomSticker, Task>>();
#endregion
} }
} }

+ 6
- 3
src/Discord.Net.WebSocket/BaseSocketClient.cs View File

@@ -12,6 +12,7 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public abstract partial class BaseSocketClient : BaseDiscordClient, IDiscordClient public abstract partial class BaseSocketClient : BaseDiscordClient, IDiscordClient
{ {
#region BaseSocketClient
protected readonly DiscordSocketConfig BaseConfig; protected readonly DiscordSocketConfig BaseConfig;


/// <summary> /// <summary>
@@ -79,7 +80,7 @@ namespace Discord.WebSocket
: base(config, client) => BaseConfig = config; : base(config, client) => BaseConfig = config;
private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config) private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, => new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent,
useSystemClock: config.UseSystemClock);
useSystemClock: config.UseSystemClock);


/// <summary> /// <summary>
/// Gets a Discord application information for the logged-in user. /// Gets a Discord application information for the logged-in user.
@@ -282,8 +283,9 @@ namespace Discord.WebSocket
/// A <see cref="SocketSticker"/> if found, otherwise <see langword="null"/>. /// A <see cref="SocketSticker"/> if found, otherwise <see langword="null"/>.
/// </returns> /// </returns>
public abstract Task<SocketSticker> GetStickerAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); public abstract Task<SocketSticker> GetStickerAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
// IDiscordClient
#endregion

#region IDiscordClient
/// <inheritdoc /> /// <inheritdoc />
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options) async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
=> await GetApplicationInfoAsync(options).ConfigureAwait(false); => await GetApplicationInfoAsync(options).ConfigureAwait(false);
@@ -331,5 +333,6 @@ namespace Discord.WebSocket
{ {
return await GetVoiceRegionsAsync().ConfigureAwait(false); return await GetVoiceRegionsAsync().ConfigureAwait(false);
} }
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.WebSocket/Commands/ShardedCommandContext.cs View File

@@ -5,6 +5,7 @@ namespace Discord.Commands
/// <summary> The sharded variant of <see cref="ICommandContext"/>, which may contain the client, user, guild, channel, and message. </summary> /// <summary> The sharded variant of <see cref="ICommandContext"/>, which may contain the client, user, guild, channel, and message. </summary>
public class ShardedCommandContext : SocketCommandContext, ICommandContext public class ShardedCommandContext : SocketCommandContext, ICommandContext
{ {
#region ShardedCommandContext
/// <summary> Gets the <see cref="DiscordShardedClient"/> that the command is executed with. </summary> /// <summary> Gets the <see cref="DiscordShardedClient"/> that the command is executed with. </summary>
public new DiscordShardedClient Client { get; } public new DiscordShardedClient Client { get; }


@@ -17,9 +18,11 @@ namespace Discord.Commands
/// <summary> Gets the shard ID of the command context. </summary> /// <summary> Gets the shard ID of the command context. </summary>
private static int GetShardId(DiscordShardedClient client, IGuild guild) private static int GetShardId(DiscordShardedClient client, IGuild guild)
=> guild == null ? 0 : client.GetShardIdFor(guild); => guild == null ? 0 : client.GetShardIdFor(guild);
#endregion


//ICommandContext
#region ICommandContext
/// <inheritdoc /> /// <inheritdoc />
IDiscordClient ICommandContext.Client => Client; IDiscordClient ICommandContext.Client => Client;
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.WebSocket/Commands/SocketCommandContext.cs View File

@@ -7,6 +7,7 @@ namespace Discord.Commands
/// </summary> /// </summary>
public class SocketCommandContext : ICommandContext public class SocketCommandContext : ICommandContext
{ {
#region SocketCommandContext
/// <summary> /// <summary>
/// Gets the <see cref="DiscordSocketClient" /> that the command is executed with. /// Gets the <see cref="DiscordSocketClient" /> that the command is executed with.
/// </summary> /// </summary>
@@ -46,8 +47,9 @@ namespace Discord.Commands
User = msg.Author; User = msg.Author;
Message = msg; Message = msg;
} }
#endregion


//ICommandContext
#region ICommandContext
/// <inheritdoc/> /// <inheritdoc/>
IDiscordClient ICommandContext.Client => Client; IDiscordClient ICommandContext.Client => Client;
/// <inheritdoc/> /// <inheritdoc/>
@@ -58,5 +60,6 @@ namespace Discord.Commands
IUser ICommandContext.User => User; IUser ICommandContext.User => User;
/// <inheritdoc/> /// <inheritdoc/>
IUserMessage ICommandContext.Message => Message; IUserMessage ICommandContext.Message => Message;
#endregion
} }
} }

+ 2
- 1
src/Discord.Net.WebSocket/DiscordShardedClient.Events.cs View File

@@ -5,7 +5,7 @@ namespace Discord.WebSocket
{ {
public partial class DiscordShardedClient public partial class DiscordShardedClient
{ {
//General
#region General
/// <summary> Fired when a shard is connected to the Discord gateway. </summary> /// <summary> Fired when a shard is connected to the Discord gateway. </summary>
public event Func<DiscordSocketClient, Task> ShardConnected public event Func<DiscordSocketClient, Task> ShardConnected
{ {
@@ -34,5 +34,6 @@ namespace Discord.WebSocket
remove { _shardLatencyUpdatedEvent.Remove(value); } remove { _shardLatencyUpdatedEvent.Remove(value); }
} }
private readonly AsyncEvent<Func<int, int, DiscordSocketClient, Task>> _shardLatencyUpdatedEvent = new AsyncEvent<Func<int, int, DiscordSocketClient, Task>>(); private readonly AsyncEvent<Func<int, int, DiscordSocketClient, Task>> _shardLatencyUpdatedEvent = new AsyncEvent<Func<int, int, DiscordSocketClient, Task>>();
#endregion
} }
} }

+ 6
- 1
src/Discord.Net.WebSocket/DiscordShardedClient.cs View File

@@ -12,6 +12,7 @@ namespace Discord.WebSocket
{ {
public partial class DiscordShardedClient : BaseSocketClient, IDiscordClient public partial class DiscordShardedClient : BaseSocketClient, IDiscordClient
{ {
#region DiscordShardedClient
private readonly DiscordSocketConfig _baseConfig; private readonly DiscordSocketConfig _baseConfig;
private readonly Dictionary<int, int> _shardIdsToIndex; private readonly Dictionary<int, int> _shardIdsToIndex;
private readonly bool _automaticShards; private readonly bool _automaticShards;
@@ -484,8 +485,9 @@ namespace Discord.WebSocket
client.GuildStickerDeleted += (sticker) => _guildStickerDeleted.InvokeAsync(sticker); client.GuildStickerDeleted += (sticker) => _guildStickerDeleted.InvokeAsync(sticker);
client.GuildStickerUpdated += (before, after) => _guildStickerUpdated.InvokeAsync(before, after); client.GuildStickerUpdated += (before, after) => _guildStickerUpdated.InvokeAsync(before, after);
} }
#endregion


//IDiscordClient
#region IDiscordClient
/// <inheritdoc /> /// <inheritdoc />
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options) async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
=> await GetApplicationInfoAsync().ConfigureAwait(false); => await GetApplicationInfoAsync().ConfigureAwait(false);
@@ -532,7 +534,9 @@ namespace Discord.WebSocket
{ {
return await GetVoiceRegionAsync(id).ConfigureAwait(false); return await GetVoiceRegionAsync(id).ConfigureAwait(false);
} }
#endregion


#region Dispose
internal override void Dispose(bool disposing) internal override void Dispose(bool disposing)
{ {
if (!_isDisposed) if (!_isDisposed)
@@ -551,5 +555,6 @@ namespace Discord.WebSocket


base.Dispose(disposing); base.Dispose(disposing);
} }
#endregion
} }
} }

+ 2
- 1
src/Discord.Net.WebSocket/DiscordSocketApiClient.cs View File

@@ -217,7 +217,7 @@ namespace Discord.API
ConnectionState = ConnectionState.Disconnected; ConnectionState = ConnectionState.Disconnected;
} }


//Core
#region Core
public Task SendGatewayAsync(GatewayOpCode opCode, object payload, RequestOptions options = null) public Task SendGatewayAsync(GatewayOpCode opCode, object payload, RequestOptions options = null)
=> SendGatewayInternalAsync(opCode, payload, options); => SendGatewayInternalAsync(opCode, payload, options);
private async Task SendGatewayInternalAsync(GatewayOpCode opCode, object payload, RequestOptions options) private async Task SendGatewayInternalAsync(GatewayOpCode opCode, object payload, RequestOptions options)
@@ -327,5 +327,6 @@ namespace Discord.API
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
await SendGatewayAsync(GatewayOpCode.GuildSync, guildIds, options: options).ConfigureAwait(false); await SendGatewayAsync(GatewayOpCode.GuildSync, guildIds, options: options).ConfigureAwait(false);
} }
#endregion
} }
} }

+ 2
- 1
src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs View File

@@ -6,7 +6,7 @@ namespace Discord.WebSocket
{ {
public partial class DiscordSocketClient public partial class DiscordSocketClient
{ {
//General
#region General
/// <summary> Fired when connected to the Discord gateway. </summary> /// <summary> Fired when connected to the Discord gateway. </summary>
public event Func<Task> Connected public event Func<Task> Connected
{ {
@@ -45,5 +45,6 @@ namespace Discord.WebSocket
internal DiscordSocketClient(DiscordSocketConfig config, DiscordRestApiClient client) : base(config, client) internal DiscordSocketClient(DiscordSocketConfig config, DiscordRestApiClient client) : base(config, client)
{ {
} }
#endregion
} }
} }

+ 2
- 1
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -2815,7 +2815,7 @@ namespace Discord.WebSocket


internal int GetAudioId() => _nextAudioId++; internal int GetAudioId() => _nextAudioId++;


//IDiscordClient
#region IDiscordClient
/// <inheritdoc /> /// <inheritdoc />
async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options) async Task<IApplication> IDiscordClient.GetApplicationInfoAsync(RequestOptions options)
=> await GetApplicationInfoAsync().ConfigureAwait(false); => await GetApplicationInfoAsync().ConfigureAwait(false);
@@ -2878,5 +2878,6 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
async Task IDiscordClient.StopAsync() async Task IDiscordClient.StopAsync()
=> await StopAsync().ConfigureAwait(false); => await StopAsync().ConfigureAwait(false);
#endregion
} }
} }

+ 12
- 5
src/Discord.Net.WebSocket/DiscordVoiceApiClient.cs View File

@@ -18,6 +18,7 @@ namespace Discord.Audio
{ {
internal class DiscordVoiceAPIClient : IDisposable internal class DiscordVoiceAPIClient : IDisposable
{ {
#region DiscordVoiceAPIClient
public const int MaxBitrate = 128 * 1024; public const int MaxBitrate = 128 * 1024;
public const string Mode = "xsalsa20_poly1305"; public const string Mode = "xsalsa20_poly1305";


@@ -126,8 +127,9 @@ namespace Discord.Audio
await _udp.SendAsync(data, offset, bytes).ConfigureAwait(false); await _udp.SendAsync(data, offset, bytes).ConfigureAwait(false);
await _sentDataEvent.InvokeAsync(bytes).ConfigureAwait(false); await _sentDataEvent.InvokeAsync(bytes).ConfigureAwait(false);
} }
#endregion


//WebSocket
#region WebSocket
public async Task SendHeartbeatAsync(RequestOptions options = null) public async Task SendHeartbeatAsync(RequestOptions options = null)
{ {
await SendAsync(VoiceOpCode.Heartbeat, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), options: options).ConfigureAwait(false); await SendAsync(VoiceOpCode.Heartbeat, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), options: options).ConfigureAwait(false);
@@ -208,10 +210,12 @@ namespace Discord.Audio
} }
private async Task DisconnectInternalAsync() private async Task DisconnectInternalAsync()
{ {
if (ConnectionState == ConnectionState.Disconnected) return;
if (ConnectionState == ConnectionState.Disconnected)
return;
ConnectionState = ConnectionState.Disconnecting; ConnectionState = ConnectionState.Disconnecting;


try { _connectCancelToken?.Cancel(false); }
try
{ _connectCancelToken?.Cancel(false); }
catch { } catch { }


//Wait for tasks to complete //Wait for tasks to complete
@@ -220,8 +224,9 @@ namespace Discord.Audio


ConnectionState = ConnectionState.Disconnected; ConnectionState = ConnectionState.Disconnected;
} }
#endregion


//Udp
#region Udp
public async Task SendDiscoveryAsync(uint ssrc) public async Task SendDiscoveryAsync(uint ssrc)
{ {
var packet = new byte[70]; var packet = new byte[70];
@@ -252,8 +257,9 @@ namespace Discord.Audio
{ {
_udp.SetDestination(ip, port); _udp.SetDestination(ip, port);
} }
#endregion


//Helpers
#region Helpers
private static double ToMilliseconds(Stopwatch stopwatch) => Math.Round((double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2); private static double ToMilliseconds(Stopwatch stopwatch) => Math.Round((double)stopwatch.ElapsedTicks / (double)Stopwatch.Frequency * 1000.0, 2);
private string SerializeJson(object value) private string SerializeJson(object value)
{ {
@@ -269,5 +275,6 @@ namespace Discord.Audio
using (JsonReader reader = new JsonTextReader(text)) using (JsonReader reader = new JsonTextReader(text))
return _serializer.Deserialize<T>(reader); return _serializer.Deserialize<T>(reader);
} }
#endregion
} }
} }

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

@@ -14,6 +14,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketCategoryChannel : SocketGuildChannel, ICategoryChannel public class SocketCategoryChannel : SocketGuildChannel, ICategoryChannel
{ {
#region SocketCategoryChannel
/// <inheritdoc /> /// <inheritdoc />
public override IReadOnlyCollection<SocketGuildUser> Users public override IReadOnlyCollection<SocketGuildUser> Users
=> Guild.Users.Where(x => Permissions.GetValue( => Guild.Users.Where(x => Permissions.GetValue(
@@ -41,8 +42,9 @@ namespace Discord.WebSocket
entity.Update(state, model); entity.Update(state, model);
return entity; return entity;
} }
#endregion


//Users
#region Users
/// <inheritdoc /> /// <inheritdoc />
public override SocketGuildUser GetUser(ulong id) public override SocketGuildUser GetUser(ulong id)
{ {
@@ -59,21 +61,24 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"{Name} ({Id}, Category)"; private string DebuggerDisplay => $"{Name} ({Id}, Category)";
internal new SocketCategoryChannel Clone() => MemberwiseClone() as SocketCategoryChannel; internal new SocketCategoryChannel Clone() => MemberwiseClone() as SocketCategoryChannel;
#endregion


// IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable(); => ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable();
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(GetUser(id)); => Task.FromResult<IGuildUser>(GetUser(id));
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); => ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable();
/// <inheritdoc /> /// <inheritdoc />
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(GetUser(id)); => Task.FromResult<IUser>(GetUser(id));
#endregion
} }
} }

+ 6
- 2
src/Discord.Net.WebSocket/Entities/Channels/SocketChannel.cs View File

@@ -13,6 +13,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public abstract class SocketChannel : SocketEntity<ulong>, IChannel public abstract class SocketChannel : SocketEntity<ulong>, IChannel
{ {
#region SocketChannel
/// <summary> /// <summary>
/// Gets when the channel is created. /// Gets when the channel is created.
/// </summary> /// </summary>
@@ -41,8 +42,9 @@ namespace Discord.WebSocket
} }
} }
internal abstract void Update(ClientState state, Model model); internal abstract void Update(ClientState state, Model model);
#endregion


//User
#region User
/// <summary> /// <summary>
/// Gets a generic user from this channel. /// Gets a generic user from this channel.
/// </summary> /// </summary>
@@ -56,8 +58,9 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"Unknown ({Id}, Channel)"; private string DebuggerDisplay => $"Unknown ({Id}, Channel)";
internal SocketChannel Clone() => MemberwiseClone() as SocketChannel; internal SocketChannel Clone() => MemberwiseClone() as SocketChannel;
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
string IChannel.Name => null; string IChannel.Name => null;


@@ -67,5 +70,6 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden => AsyncEnumerable.Empty<IReadOnlyCollection<IUser>>(); //Overridden
#endregion
} }
} }

+ 18
- 8
src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs View File

@@ -16,6 +16,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketDMChannel : SocketChannel, IDMChannel, ISocketPrivateChannel, ISocketMessageChannel public class SocketDMChannel : SocketChannel, IDMChannel, ISocketPrivateChannel, ISocketMessageChannel
{ {
#region SocketDMChannel
/// <summary> /// <summary>
/// Gets the recipient of the channel. /// Gets the recipient of the channel.
/// </summary> /// </summary>
@@ -58,8 +59,9 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public Task CloseAsync(RequestOptions options = null) public Task CloseAsync(RequestOptions options = null)
=> ChannelHelper.DeleteAsync(this, Discord, options); => ChannelHelper.DeleteAsync(this, Discord, options);
#endregion


//Messages
#region Messages
/// <inheritdoc /> /// <inheritdoc />
public SocketMessage GetCachedMessage(ulong id) public SocketMessage GetCachedMessage(ulong id)
=> null; => null;
@@ -172,8 +174,9 @@ namespace Discord.WebSocket
{ {
return null; return null;
} }
#endregion


//Users
#region Users
/// <summary> /// <summary>
/// Gets a user in this channel from the provided <paramref name="id"/>. /// Gets a user in this channel from the provided <paramref name="id"/>.
/// </summary> /// </summary>
@@ -197,26 +200,31 @@ namespace Discord.WebSocket
public override string ToString() => $"@{Recipient}"; public override string ToString() => $"@{Recipient}";
private string DebuggerDisplay => $"@{Recipient} ({Id}, DM)"; private string DebuggerDisplay => $"@{Recipient} ({Id}, DM)";
internal new SocketDMChannel Clone() => MemberwiseClone() as SocketDMChannel; internal new SocketDMChannel Clone() => MemberwiseClone() as SocketDMChannel;
#endregion


//SocketChannel
#region SocketChannel
/// <inheritdoc /> /// <inheritdoc />
internal override IReadOnlyCollection<SocketUser> GetUsersInternal() => Users; internal override IReadOnlyCollection<SocketUser> GetUsersInternal() => Users;
/// <inheritdoc /> /// <inheritdoc />
internal override SocketUser GetUserInternal(ulong id) => GetUser(id); internal override SocketUser GetUserInternal(ulong id) => GetUser(id);
#endregion


//IDMChannel
#region IDMChannel
/// <inheritdoc /> /// <inheritdoc />
IUser IDMChannel.Recipient => Recipient; IUser IDMChannel.Recipient => Recipient;
#endregion


//ISocketPrivateChannel
#region ISocketPrivateChannel
/// <inheritdoc /> /// <inheritdoc />
IReadOnlyCollection<SocketUser> ISocketPrivateChannel.Recipients => ImmutableArray.Create(Recipient); IReadOnlyCollection<SocketUser> ISocketPrivateChannel.Recipients => ImmutableArray.Create(Recipient);
#endregion


//IPrivateChannel
#region IPrivateChannel
/// <inheritdoc /> /// <inheritdoc />
IReadOnlyCollection<IUser> IPrivateChannel.Recipients => ImmutableArray.Create<IUser>(Recipient); IReadOnlyCollection<IUser> IPrivateChannel.Recipients => ImmutableArray.Create<IUser>(Recipient);
#endregion


//IMessageChannel
#region IMessageChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -246,8 +254,9 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers) async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false); => await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
string IChannel.Name => $"@{Recipient}"; string IChannel.Name => $"@{Recipient}";


@@ -257,5 +266,6 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); => ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable();
#endregion
} }
} }

+ 20
- 9
src/Discord.Net.WebSocket/Entities/Channels/SocketGroupChannel.cs View File

@@ -20,6 +20,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel public class SocketGroupChannel : SocketChannel, IGroupChannel, ISocketPrivateChannel, ISocketMessageChannel, ISocketAudioChannel
{ {
#region SocketGroupChannel
private readonly MessageCache _messages; private readonly MessageCache _messages;
private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates; private readonly ConcurrentDictionary<ulong, SocketVoiceState> _voiceStates;


@@ -84,8 +85,9 @@ namespace Discord.WebSocket
{ {
throw new NotSupportedException("Voice is not yet supported for group channels."); throw new NotSupportedException("Voice is not yet supported for group channels.");
} }
#endregion


//Messages
#region Messages
/// <inheritdoc /> /// <inheritdoc />
public SocketMessage GetCachedMessage(ulong id) public SocketMessage GetCachedMessage(ulong id)
=> _messages?.Get(id); => _messages?.Get(id);
@@ -204,8 +206,9 @@ namespace Discord.WebSocket
=> _messages?.Add(msg); => _messages?.Add(msg);
internal SocketMessage RemoveMessage(ulong id) internal SocketMessage RemoveMessage(ulong id)
=> _messages?.Remove(id); => _messages?.Remove(id);
#endregion


//Users
#region Users
/// <summary> /// <summary>
/// Gets a user from this group. /// Gets a user from this group.
/// </summary> /// </summary>
@@ -240,8 +243,9 @@ namespace Discord.WebSocket
} }
return null; return null;
} }
#endregion


//Voice States
#region Voice States
internal SocketVoiceState AddOrUpdateVoiceState(ClientState state, VoiceStateModel model) internal SocketVoiceState AddOrUpdateVoiceState(ClientState state, VoiceStateModel model)
{ {
var voiceChannel = state.GetChannel(model.ChannelId.Value) as SocketVoiceChannel; var voiceChannel = state.GetChannel(model.ChannelId.Value) as SocketVoiceChannel;
@@ -268,22 +272,26 @@ namespace Discord.WebSocket
public override string ToString() => Name; public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id}, Group)"; private string DebuggerDisplay => $"{Name} ({Id}, Group)";
internal new SocketGroupChannel Clone() => MemberwiseClone() as SocketGroupChannel; internal new SocketGroupChannel Clone() => MemberwiseClone() as SocketGroupChannel;
#endregion


//SocketChannel
#region SocketChannel
/// <inheritdoc /> /// <inheritdoc />
internal override IReadOnlyCollection<SocketUser> GetUsersInternal() => Users; internal override IReadOnlyCollection<SocketUser> GetUsersInternal() => Users;
/// <inheritdoc /> /// <inheritdoc />
internal override SocketUser GetUserInternal(ulong id) => GetUser(id); internal override SocketUser GetUserInternal(ulong id) => GetUser(id);
#endregion


//ISocketPrivateChannel
#region ISocketPrivateChannel
/// <inheritdoc /> /// <inheritdoc />
IReadOnlyCollection<SocketUser> ISocketPrivateChannel.Recipients => Recipients; IReadOnlyCollection<SocketUser> ISocketPrivateChannel.Recipients => Recipients;
#endregion


//IPrivateChannel
#region IPrivateChannel
/// <inheritdoc /> /// <inheritdoc />
IReadOnlyCollection<IUser> IPrivateChannel.Recipients => Recipients; IReadOnlyCollection<IUser> IPrivateChannel.Recipients => Recipients;
#endregion


//IMessageChannel
#region IMessageChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -314,19 +322,22 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers) async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false); => await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
#endregion


//IAudioChannel
#region IAudioChannel
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="NotSupportedException">Connecting to a group channel is not supported.</exception> /// <exception cref="NotSupportedException">Connecting to a group channel is not supported.</exception>
Task<IAudioClient> IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); } Task<IAudioClient> IAudioChannel.ConnectAsync(bool selfDeaf, bool selfMute, bool external) { throw new NotSupportedException(); }
Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); } Task IAudioChannel.DisconnectAsync() { throw new NotSupportedException(); }
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(GetUser(id)); => Task.FromResult<IUser>(GetUser(id));
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); => ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable();
#endregion
} }
} }

+ 10
- 5
src/Discord.Net.WebSocket/Entities/Channels/SocketGuildChannel.cs View File

@@ -15,6 +15,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketGuildChannel : SocketChannel, IGuildChannel public class SocketGuildChannel : SocketChannel, IGuildChannel
{ {
#region SocketGuildChannel
private ImmutableArray<Overwrite> _overwrites; private ImmutableArray<Overwrite> _overwrites;


/// <summary> /// <summary>
@@ -27,7 +28,7 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
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; }


/// <inheritdoc /> /// <inheritdoc />
public virtual IReadOnlyCollection<Overwrite> PermissionOverwrites => _overwrites; public virtual IReadOnlyCollection<Overwrite> PermissionOverwrites => _overwrites;
@@ -69,7 +70,7 @@ namespace Discord.WebSocket
{ {
Name = model.Name.Value; Name = model.Name.Value;
Position = model.Position.GetValueOrDefault(0); Position = model.Position.GetValueOrDefault(0);
var overwrites = model.PermissionOverwrites.GetValueOrDefault(new API.Overwrite[0]); var overwrites = model.PermissionOverwrites.GetValueOrDefault(new API.Overwrite[0]);
var newOverwrites = ImmutableArray.CreateBuilder<Overwrite>(overwrites.Length); var newOverwrites = ImmutableArray.CreateBuilder<Overwrite>(overwrites.Length);
for (int i = 0; i < overwrites.Length; i++) for (int i = 0; i < overwrites.Length; i++)
@@ -180,14 +181,16 @@ namespace Discord.WebSocket
public override string ToString() => Name; public override string ToString() => Name;
private string DebuggerDisplay => $"{Name} ({Id}, Guild)"; private string DebuggerDisplay => $"{Name} ({Id}, Guild)";
internal new SocketGuildChannel Clone() => MemberwiseClone() as SocketGuildChannel; internal new SocketGuildChannel Clone() => MemberwiseClone() as SocketGuildChannel;
#endregion


//SocketChannel
#region SocketChannel
/// <inheritdoc /> /// <inheritdoc />
internal override IReadOnlyCollection<SocketUser> GetUsersInternal() => Users; internal override IReadOnlyCollection<SocketUser> GetUsersInternal() => Users;
/// <inheritdoc /> /// <inheritdoc />
internal override SocketUser GetUserInternal(ulong id) => GetUser(id); internal override SocketUser GetUserInternal(ulong id) => GetUser(id);
#endregion


//IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
IGuild IGuildChannel.Guild => Guild; IGuild IGuildChannel.Guild => Guild;
/// <inheritdoc /> /// <inheritdoc />
@@ -218,13 +221,15 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(GetUser(id)); => Task.FromResult<IGuildUser>(GetUser(id));
#endregion


//IChannel
#region IChannel
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IUser>> IChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice => ImmutableArray.Create<IReadOnlyCollection<IUser>>(Users).ToAsyncEnumerable(); //Overridden in Text/Voice
/// <inheritdoc /> /// <inheritdoc />
Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IUser> IChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IUser>(GetUser(id)); //Overridden in Text/Voice => Task.FromResult<IUser>(GetUser(id)); //Overridden in Text/Voice
#endregion
} }
} }

+ 18
- 8
src/Discord.Net.WebSocket/Entities/Channels/SocketTextChannel.cs View File

@@ -16,6 +16,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketTextChannel : SocketGuildChannel, ITextChannel, ISocketMessageChannel public class SocketTextChannel : SocketGuildChannel, ITextChannel, ISocketMessageChannel
{ {
#region SocketTextChannel
private readonly MessageCache _messages; private readonly MessageCache _messages;


/// <inheritdoc /> /// <inheritdoc />
@@ -122,8 +123,9 @@ namespace Discord.WebSocket


return thread; return thread;
} }
#endregion


//Messages
#region Messages
/// <inheritdoc /> /// <inheritdoc />
public SocketMessage GetCachedMessage(ulong id) public SocketMessage GetCachedMessage(ulong id)
=> _messages?.Get(id); => _messages?.Get(id);
@@ -250,8 +252,9 @@ namespace Discord.WebSocket
=> _messages?.Add(msg); => _messages?.Add(msg);
internal SocketMessage RemoveMessage(ulong id) internal SocketMessage RemoveMessage(ulong id)
=> _messages?.Remove(id); => _messages?.Remove(id);
#endregion


//Users
#region Users
/// <inheritdoc /> /// <inheritdoc />
public override SocketGuildUser GetUser(ulong id) public override SocketGuildUser GetUser(ulong id)
{ {
@@ -265,8 +268,9 @@ namespace Discord.WebSocket
} }
return null; return null;
} }
#endregion


//Webhooks
#region Webhooks
/// <summary> /// <summary>
/// Creates a webhook in this text channel. /// Creates a webhook in this text channel.
/// </summary> /// </summary>
@@ -300,8 +304,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public virtual Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null) public virtual Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> ChannelHelper.GetWebhooksAsync(this, Discord, options); => ChannelHelper.GetWebhooksAsync(this, Discord, options);
#endregion


//Invites
#region Invites
/// <inheritdoc /> /// <inheritdoc />
public virtual async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) public virtual async Task<IInviteMetadata> 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); => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
@@ -317,8 +322,9 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"{Name} ({Id}, Text)"; private string DebuggerDisplay => $"{Name} ({Id}, Text)";
internal new SocketTextChannel Clone() => MemberwiseClone() as SocketTextChannel; internal new SocketTextChannel Clone() => MemberwiseClone() as SocketTextChannel;
#endregion


//ITextChannel
#region ITextChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options) async Task<IWebhook> ITextChannel.CreateWebhookAsync(string name, Stream avatar, RequestOptions options)
=> await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false); => await CreateWebhookAsync(name, avatar, options).ConfigureAwait(false);
@@ -331,16 +337,18 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
async Task<IThreadChannel> ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, RequestOptions options) async Task<IThreadChannel> ITextChannel.CreateThreadAsync(string name, ThreadType type, ThreadArchiveDuration autoArchiveDuration, IMessage message, RequestOptions options)
=> await CreateThreadAsync(name, type, autoArchiveDuration, message, options); => await CreateThreadAsync(name, type, autoArchiveDuration, message, options);
#endregion


//IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(GetUser(id)); => Task.FromResult<IGuildUser>(GetUser(id));
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable(); => ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable();
#endregion


//IMessageChannel
#region IMessageChannel
/// <inheritdoc /> /// <inheritdoc />
async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options) async Task<IMessage> IMessageChannel.GetMessageAsync(ulong id, CacheMode mode, RequestOptions options)
{ {
@@ -371,10 +379,12 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers) async Task<IUserMessage> IMessageChannel.SendMessageAsync(string text, bool isTTS, Embed embed, RequestOptions options, AllowedMentions allowedMentions, MessageReference messageReference, MessageComponent component, ISticker[] stickers)
=> await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false); => await SendMessageAsync(text, isTTS, embed, options, allowedMentions, messageReference, component, stickers).ConfigureAwait(false);
#endregion


// INestedChannel
#region INestedChannel
/// <inheritdoc /> /// <inheritdoc />
Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult(Category); => Task.FromResult(Category);
#endregion
} }
} }

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

@@ -16,6 +16,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel, ISocketAudioChannel public class SocketVoiceChannel : SocketGuildChannel, IVoiceChannel, ISocketAudioChannel
{ {
#region SocketVoiceChannel
/// <inheritdoc /> /// <inheritdoc />
public int Bitrate { get; private set; } public int Bitrate { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
@@ -84,8 +85,9 @@ namespace Discord.WebSocket
return user; return user;
return null; return null;
} }
#endregion


//Invites
#region Invites
/// <inheritdoc /> /// <inheritdoc />
public async Task<IInviteMetadata> CreateInviteAsync(int? maxAge = 86400, int? maxUses = null, bool isTemporary = false, bool isUnique = false, RequestOptions options = null) public async Task<IInviteMetadata> 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); => await ChannelHelper.CreateInviteAsync(this, Discord, maxAge, maxUses, isTemporary, isUnique, options).ConfigureAwait(false);
@@ -101,18 +103,21 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"{Name} ({Id}, Voice)"; private string DebuggerDisplay => $"{Name} ({Id}, Voice)";
internal new SocketVoiceChannel Clone() => MemberwiseClone() as SocketVoiceChannel; internal new SocketVoiceChannel Clone() => MemberwiseClone() as SocketVoiceChannel;
#endregion


//IGuildChannel
#region IGuildChannel
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options) Task<IGuildUser> IGuildChannel.GetUserAsync(ulong id, CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildUser>(GetUser(id)); => Task.FromResult<IGuildUser>(GetUser(id));
/// <inheritdoc /> /// <inheritdoc />
IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options) IAsyncEnumerable<IReadOnlyCollection<IGuildUser>> IGuildChannel.GetUsersAsync(CacheMode mode, RequestOptions options)
=> ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable(); => ImmutableArray.Create<IReadOnlyCollection<IGuildUser>>(Users).ToAsyncEnumerable();
#endregion


// INestedChannel
#region INestedChannel
/// <inheritdoc /> /// <inheritdoc />
Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options) Task<ICategoryChannel> INestedChannel.GetCategoryAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult(Category); => Task.FromResult(Category);
#endregion
} }
} }

+ 10
- 4
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -30,6 +30,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketGuild : SocketEntity<ulong>, IGuild, IDisposable public class SocketGuild : SocketEntity<ulong>, IGuild, IDisposable
{ {
#region SocketGuild
#pragma warning disable IDISP002, IDISP006 #pragma warning disable IDISP002, IDISP006
private readonly SemaphoreSlim _audioLock; private readonly SemaphoreSlim _audioLock;
private TaskCompletionSource<bool> _syncPromise, _downloaderPromise; private TaskCompletionSource<bool> _syncPromise, _downloaderPromise;
@@ -571,6 +572,7 @@ namespace Discord.WebSocket
emotes.Add(model.Emojis[i].ToEntity()); emotes.Add(model.Emojis[i].ToEntity());
_emotes = emotes.ToImmutable(); _emotes = emotes.ToImmutable();
} }
#endregion


#region General #region General
/// <inheritdoc /> /// <inheritdoc />
@@ -960,8 +962,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null) public Task<RestInviteMetadata> GetVanityInviteAsync(RequestOptions options = null)
=> GuildHelper.GetVanityInviteAsync(this, Discord, options); => GuildHelper.GetVanityInviteAsync(this, Discord, options);
#endregion


//Roles
#region Roles
/// <summary> /// <summary>
/// Gets a role in this guild. /// Gets a role in this guild.
/// </summary> /// </summary>
@@ -1189,8 +1192,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public Task<IReadOnlyCollection<RestGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null) public Task<IReadOnlyCollection<RestGuildUser>> SearchUsersAsync(string query, int limit = DiscordConfig.MaxUsersPerBatch, RequestOptions options = null)
=> GuildHelper.SearchUsersAsync(this, Discord, query, limit, options); => GuildHelper.SearchUsersAsync(this, Discord, query, limit, options);
#endregion


//Audit logs
#region Audit logs
/// <summary> /// <summary>
/// Gets the specified number of audit log entries for this guild. /// Gets the specified number of audit log entries for this guild.
/// </summary> /// </summary>
@@ -1205,8 +1209,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null) public IAsyncEnumerable<IReadOnlyCollection<RestAuditLogEntry>> GetAuditLogsAsync(int limit, RequestOptions options = null, ulong? beforeId = null, ulong? userId = null, ActionType? actionType = null)
=> GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType); => GuildHelper.GetAuditLogsAsync(this, Discord, beforeId, limit, options, userId: userId, actionType: actionType);
#endregion


//Webhooks
#region Webhooks
/// <summary> /// <summary>
/// Gets a webhook found within this guild. /// Gets a webhook found within this guild.
/// </summary> /// </summary>
@@ -1228,8 +1233,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestWebhook>> GetWebhooksAsync(RequestOptions options = null)
=> GuildHelper.GetWebhooksAsync(this, Discord, options); => GuildHelper.GetWebhooksAsync(this, Discord, options);
#endregion


//Emotes
#region Emotes
/// <inheritdoc /> /// <inheritdoc />
public Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(RequestOptions options = null) public Task<IReadOnlyCollection<GuildEmote>> GetEmotesAsync(RequestOptions options = null)
=> GuildHelper.GetEmotesAsync(this, Discord, options); => GuildHelper.GetEmotesAsync(this, Discord, options);


+ 6
- 2
src/Discord.Net.WebSocket/Entities/Interaction/Slash Commands/SocketSlashCommandDataOption.cs View File

@@ -10,6 +10,7 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public class SocketSlashCommandDataOption : IApplicationCommandInteractionDataOption public class SocketSlashCommandDataOption : IApplicationCommandInteractionDataOption
{ {
#region SocketSlashCommandDataOption
/// <inheritdoc/> /// <inheritdoc/>
public string Name { get; private set; } public string Name { get; private set; }


@@ -116,17 +117,20 @@ namespace Discord.WebSocket
? model.Options.Value.Select(x => new SocketSlashCommandDataOption(data, x)).ToImmutableArray() ? model.Options.Value.Select(x => new SocketSlashCommandDataOption(data, x)).ToImmutableArray()
: null; : null;
} }
#endregion


// Converters
#region Converters
public static explicit operator bool(SocketSlashCommandDataOption option) public static explicit operator bool(SocketSlashCommandDataOption option)
=> (bool)option.Value; => (bool)option.Value;
public static explicit operator int(SocketSlashCommandDataOption option) public static explicit operator int(SocketSlashCommandDataOption option)
=> (int)option.Value; => (int)option.Value;
public static explicit operator string(SocketSlashCommandDataOption option) public static explicit operator string(SocketSlashCommandDataOption option)
=> option.Value.ToString(); => option.Value.ToString();
#endregion


// IApplicationCommandInteractionDataOption
#region IApplicationCommandInteractionDataOption
IReadOnlyCollection<IApplicationCommandInteractionDataOption> IApplicationCommandInteractionDataOption.Options IReadOnlyCollection<IApplicationCommandInteractionDataOption> IApplicationCommandInteractionDataOption.Options
=> this.Options; => this.Options;
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.WebSocket/Entities/Interaction/SocketBaseCommand/SocketApplicationCommand.cs View File

@@ -15,6 +15,7 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public class SocketApplicationCommand : SocketEntity<ulong>, IApplicationCommand public class SocketApplicationCommand : SocketEntity<ulong>, IApplicationCommand
{ {
#region SocketApplicationCommand
/// <summary> /// <summary>
/// <see langword="true"/> if this command is a global command, otherwise <see langword="false"/>. /// <see langword="true"/> if this command is a global command, otherwise <see langword="false"/>.
/// </summary> /// </summary>
@@ -113,8 +114,10 @@ namespace Discord.WebSocket


this.Update(command); this.Update(command);
} }
#endregion


// IApplicationCommand
#region IApplicationCommand
IReadOnlyCollection<IApplicationCommandOption> IApplicationCommand.Options => Options; IReadOnlyCollection<IApplicationCommandOption> IApplicationCommand.Options => Options;
#endregion
} }
} }

+ 4
- 2
src/Discord.Net.WebSocket/Entities/Interaction/SocketInteraction.cs View File

@@ -12,6 +12,7 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public abstract class SocketInteraction : SocketEntity<ulong>, IDiscordInteraction public abstract class SocketInteraction : SocketEntity<ulong>, IDiscordInteraction
{ {
#region SocketInteraction
/// <summary> /// <summary>
/// The <see cref="ISocketMessageChannel"/> this interaction was used in. /// The <see cref="ISocketMessageChannel"/> this interaction was used in.
/// </summary> /// </summary>
@@ -219,9 +220,9 @@ namespace Discord.WebSocket
// Tokens last for 15 minutes according to https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction // Tokens last for 15 minutes according to https://discord.com/developers/docs/interactions/slash-commands#responding-to-an-interaction
return (DateTime.UtcNow - this.CreatedAt.UtcDateTime).TotalMinutes <= 15d; return (DateTime.UtcNow - this.CreatedAt.UtcDateTime).TotalMinutes <= 15d;
} }
#endregion


// IDiscordInteraction

#region IDiscordInteraction
/// <inheritdoc/> /// <inheritdoc/>
async Task<IUserMessage> IDiscordInteraction.FollowupAsync (string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions, async Task<IUserMessage> IDiscordInteraction.FollowupAsync (string text, Embed[] embeds, bool isTTS, bool ephemeral, AllowedMentions allowedMentions,
RequestOptions options, MessageComponent component, Embed embed) RequestOptions options, MessageComponent component, Embed embed)
@@ -234,5 +235,6 @@ namespace Discord.WebSocket
/// <inheritdoc/> /// <inheritdoc/>
async Task<IUserMessage> IDiscordInteraction.ModifyOriginalResponseAsync (Action<MessageProperties> func, RequestOptions options) async Task<IUserMessage> IDiscordInteraction.ModifyOriginalResponseAsync (Action<MessageProperties> func, RequestOptions options)
=> await ModifyOriginalResponseAsync(func, options).ConfigureAwait(false); => await ModifyOriginalResponseAsync(func, options).ConfigureAwait(false);
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs View File

@@ -14,6 +14,7 @@ namespace Discord.WebSocket
/// </summary> /// </summary>
public abstract class SocketMessage : SocketEntity<ulong>, IMessage public abstract class SocketMessage : SocketEntity<ulong>, IMessage
{ {
#region SocketMessage
private long _timestampTicks; private long _timestampTicks;
private readonly List<SocketReaction> _reactions = new List<SocketReaction>(); private readonly List<SocketReaction> _reactions = new List<SocketReaction>();


@@ -240,8 +241,9 @@ namespace Discord.WebSocket
/// </returns> /// </returns>
public override string ToString() => Content; public override string ToString() => Content;
internal SocketMessage Clone() => MemberwiseClone() as SocketMessage; internal SocketMessage Clone() => MemberwiseClone() as SocketMessage;
#endregion


//IMessage
#region IMessage
/// <inheritdoc /> /// <inheritdoc />
IUser IMessage.Author => Author; IUser IMessage.Author => Author;
/// <inheritdoc /> /// <inheritdoc />
@@ -299,5 +301,6 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null) public IAsyncEnumerable<IReadOnlyCollection<IUser>> GetReactionUsersAsync(IEmote emote, int limit, RequestOptions options = null)
=> MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options); => MessageHelper.GetReactionUsersAsync(this, emote, limit, Discord, options);
#endregion
} }
} }

+ 6
- 3
src/Discord.Net.WebSocket/Entities/Roles/SocketRole.cs View File

@@ -1,6 +1,6 @@
using Discord.Rest; using Discord.Rest;
using System; using System;
using System.Collections.Generic;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
@@ -14,6 +14,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketRole : SocketEntity<ulong>, IRole public class SocketRole : SocketEntity<ulong>, IRole
{ {
#region SocketRole
/// <summary> /// <summary>
/// Gets the guild that owns this role. /// Gets the guild that owns this role.
/// </summary> /// </summary>
@@ -54,7 +55,7 @@ namespace Discord.WebSocket
/// <summary> /// <summary>
/// Returns an IEnumerable containing all <see cref="SocketGuildUser"/> that have this role. /// Returns an IEnumerable containing all <see cref="SocketGuildUser"/> that have this role.
/// </summary> /// </summary>
public IEnumerable<SocketGuildUser> Members
public IEnumerable<SocketGuildUser> Members
=> Guild.Users.Where(x => x.Roles.Any(r => r.Id == Id)); => Guild.Users.Where(x => x.Roles.Any(r => r.Id == Id));


internal SocketRole(SocketGuild guild, ulong id) internal SocketRole(SocketGuild guild, ulong id)
@@ -100,9 +101,11 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
public int CompareTo(IRole role) => RoleUtils.Compare(this, role); public int CompareTo(IRole role) => RoleUtils.Compare(this, role);
#endregion


//IRole
#region IRole
/// <inheritdoc /> /// <inheritdoc />
IGuild IRole.Guild => Guild; IGuild IRole.Guild => Guild;
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs View File

@@ -16,6 +16,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketCustomSticker : SocketSticker, ICustomSticker public class SocketCustomSticker : SocketSticker, ICustomSticker
{ {
#region SocketCustomSticker
/// <summary> /// <summary>
/// Gets the user that uploaded the guild sticker. /// Gets the user that uploaded the guild sticker.
/// </summary> /// </summary>
@@ -71,12 +72,14 @@ namespace Discord.WebSocket
internal SocketCustomSticker Clone() => MemberwiseClone() as SocketCustomSticker; internal SocketCustomSticker Clone() => MemberwiseClone() as SocketCustomSticker;


private new string DebuggerDisplay => Guild == null ? base.DebuggerDisplay : $"{Name} in {Guild.Name} ({Id})"; private new string DebuggerDisplay => Guild == null ? base.DebuggerDisplay : $"{Name} in {Guild.Name} ({Id})";
#endregion


// ICustomSticker
#region ICustomSticker
ulong? ICustomSticker.AuthorId ulong? ICustomSticker.AuthorId
=> this.AuthorId; => this.AuthorId;


IGuild ICustomSticker.Guild IGuild ICustomSticker.Guild
=> this.Guild; => this.Guild;
#endregion
} }
} }

+ 4
- 1
src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs View File

@@ -10,6 +10,7 @@ namespace Discord.WebSocket
[DebuggerDisplay("{DebuggerDisplay,nq}")] [DebuggerDisplay("{DebuggerDisplay,nq}")]
public class SocketGroupUser : SocketUser, IGroupUser public class SocketGroupUser : SocketUser, IGroupUser
{ {
#region SocketGroupUser
/// <summary> /// <summary>
/// Gets the group channel of the user. /// Gets the group channel of the user.
/// </summary> /// </summary>
@@ -53,8 +54,9 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Group)"; private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Group)";
internal new SocketGroupUser Clone() => MemberwiseClone() as SocketGroupUser; internal new SocketGroupUser Clone() => MemberwiseClone() as SocketGroupUser;
#endregion


//IVoiceState
#region IVoiceState
/// <inheritdoc /> /// <inheritdoc />
bool IVoiceState.IsDeafened => false; bool IVoiceState.IsDeafened => false;
/// <inheritdoc /> /// <inheritdoc />
@@ -73,5 +75,6 @@ namespace Discord.WebSocket
bool IVoiceState.IsStreaming => false; bool IVoiceState.IsStreaming => false;
/// <inheritdoc /> /// <inheritdoc />
DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null;
#endregion
} }
} }

+ 5
- 2
src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs View File

@@ -18,6 +18,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketGuildUser : SocketUser, IGuildUser public class SocketGuildUser : SocketUser, IGuildUser
{ {
#region SocketGuildUser
private long? _premiumSinceTicks; private long? _premiumSinceTicks;
private long? _joinedAtTicks; private long? _joinedAtTicks;
private ImmutableArray<ulong> _roleIds; private ImmutableArray<ulong> _roleIds;
@@ -65,7 +66,7 @@ namespace Discord.WebSocket
public DateTimeOffset? RequestToSpeakTimestamp => VoiceState?.RequestToSpeakTimestamp ?? null; public DateTimeOffset? RequestToSpeakTimestamp => VoiceState?.RequestToSpeakTimestamp ?? null;
/// <inheritdoc /> /// <inheritdoc />
public bool? IsPending { get; private set; } public bool? IsPending { get; private set; }


/// <inheritdoc /> /// <inheritdoc />
public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks); public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks);
@@ -220,8 +221,9 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Guild)"; private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Guild)";
internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser; internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser;
#endregion


//IGuildUser
#region IGuildUser
/// <inheritdoc /> /// <inheritdoc />
IGuild IGuildUser.Guild => Guild; IGuild IGuildUser.Guild => Guild;
/// <inheritdoc /> /// <inheritdoc />
@@ -232,5 +234,6 @@ namespace Discord.WebSocket
//IVoiceState //IVoiceState
/// <inheritdoc /> /// <inheritdoc />
IVoiceChannel IVoiceState.VoiceChannel => VoiceChannel; IVoiceChannel IVoiceState.VoiceChannel => VoiceChannel;
#endregion
} }
} }

+ 6
- 3
src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs View File

@@ -13,6 +13,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] [DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketWebhookUser : SocketUser, IWebhookUser public class SocketWebhookUser : SocketUser, IWebhookUser
{ {
#region SocketWebhookUser
/// <summary> Gets the guild of this webhook. </summary> /// <summary> Gets the guild of this webhook. </summary>
public SocketGuild Guild { get; } public SocketGuild Guild { get; }
/// <inheritdoc /> /// <inheritdoc />
@@ -66,9 +67,9 @@ namespace Discord.WebSocket


private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Webhook)"; private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Webhook)";
internal new SocketWebhookUser Clone() => MemberwiseClone() as SocketWebhookUser; internal new SocketWebhookUser Clone() => MemberwiseClone() as SocketWebhookUser;
#endregion



//IGuildUser
#region IGuildUser
/// <inheritdoc /> /// <inheritdoc />
IGuild IGuildUser.Guild => Guild; IGuild IGuildUser.Guild => Guild;
/// <inheritdoc /> /// <inheritdoc />
@@ -139,8 +140,9 @@ namespace Discord.WebSocket
/// <exception cref="NotSupportedException">Roles are not supported on webhook users.</exception> /// <exception cref="NotSupportedException">Roles are not supported on webhook users.</exception>
Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) => Task IGuildUser.RemoveRolesAsync(IEnumerable<IRole> roles, RequestOptions options) =>
throw new NotSupportedException("Roles are not supported on webhook users."); throw new NotSupportedException("Roles are not supported on webhook users.");
#endregion


//IVoiceState
#region IVoiceState
/// <inheritdoc /> /// <inheritdoc />
bool IVoiceState.IsDeafened => false; bool IVoiceState.IsDeafened => false;
/// <inheritdoc /> /// <inheritdoc />
@@ -159,5 +161,6 @@ namespace Discord.WebSocket
bool IVoiceState.IsStreaming => false; bool IVoiceState.IsStreaming => false;
/// <inheritdoc /> /// <inheritdoc />
DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null; DateTimeOffset? IVoiceState.RequestToSpeakTimestamp => null;
#endregion
} }
} }

Loading…
Cancel
Save