| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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,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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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); | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||
| @@ -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 | |||||
| } | } | ||||
| } | } | ||||