diff --git a/docs/_overwrites/Common/EmbedBuilder.Overwrites.md b/docs/_overwrites/Common/EmbedBuilder.Overwrites.md
index 409a78e94..85c292dd2 100644
--- a/docs/_overwrites/Common/EmbedBuilder.Overwrites.md
+++ b/docs/_overwrites/Common/EmbedBuilder.Overwrites.md
@@ -28,7 +28,7 @@ public async Task SendRichEmbedAsync()
var embed = new EmbedBuilder
{
// Embed property can be set within object initializer
- Title = "Hello world!"
+ Title = "Hello world!",
Description = "I am a description set by initializer."
};
// Or with methods
diff --git a/docs/guides/commands/intro.md b/docs/guides/commands/intro.md
index abe7065c1..14341a32b 100644
--- a/docs/guides/commands/intro.md
+++ b/docs/guides/commands/intro.md
@@ -134,7 +134,7 @@ If, for whatever reason, you have two commands which are ambiguous to
each other, you may use the @Discord.Commands.PriorityAttribute to
specify which should be tested before the other.
-The `Priority` attributes are sorted in ascending order; the higher
+The `Priority` attributes are sorted in descending order; the higher
priority will be called first.
### Command Context
diff --git a/src/Discord.Net.Core/DiscordConfig.cs b/src/Discord.Net.Core/DiscordConfig.cs
index 429ad7b0c..da8525644 100644
--- a/src/Discord.Net.Core/DiscordConfig.cs
+++ b/src/Discord.Net.Core/DiscordConfig.cs
@@ -16,7 +16,7 @@ namespace Discord
/// Discord API documentation
/// .
///
- public const int APIVersion = 6;
+ public const int APIVersion = 9;
///
/// Returns the Voice API version Discord.Net uses.
///
@@ -43,7 +43,7 @@ namespace Discord
///
/// The user agent used in each Discord.Net request.
///
- public static string UserAgent { get; } = $"DiscordBot (https://github.com/RogueException/Discord.Net, v{Version})";
+ public static string UserAgent { get; } = $"DiscordBot (https://github.com/discord-net/Discord.Net, v{Version})";
///
/// Returns the base Discord API URL.
///
@@ -141,18 +141,6 @@ namespace Discord
///
internal bool DisplayInitialLog { get; set; } = true;
- ///
- /// Gets or sets the level of precision of the rate limit reset response.
- ///
- ///
- /// If set to , this value will be rounded up to the
- /// nearest second.
- ///
- ///
- /// The currently set .
- ///
- public RateLimitPrecision RateLimitPrecision { get; set; } = RateLimitPrecision.Millisecond;
-
///
/// Gets or sets whether or not rate-limits should use the system clock.
///
diff --git a/src/Discord.Net.Core/Entities/Guilds/PermissionTarget.cs b/src/Discord.Net.Core/Entities/Guilds/PermissionTarget.cs
index 3da2fb147..fb759e4c5 100644
--- a/src/Discord.Net.Core/Entities/Guilds/PermissionTarget.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/PermissionTarget.cs
@@ -8,10 +8,10 @@ namespace Discord
///
/// The target of the permission is a role.
///
- Role,
+ Role = 0,
///
/// The target of the permission is a user.
///
- User
+ User = 1,
}
}
diff --git a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
index 1589e2ae5..c2d0e13bc 100644
--- a/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IUserMessage.cs
@@ -36,18 +36,6 @@ namespace Discord
///
Task ModifyAsync(Action func, RequestOptions options = null);
///
- /// Modifies the suppression of this message.
- ///
- ///
- /// This method modifies whether or not embeds in this message are suppressed (hidden).
- ///
- /// Whether or not embeds in this message should be suppressed.
- /// The options to be used when sending the request.
- ///
- /// A task that represents the asynchronous modification operation.
- ///
- Task ModifySuppressionAsync(bool suppressEmbeds, RequestOptions options = null);
- ///
/// Adds this message to its channel's pinned messages.
///
/// The options to be used when sending the request.
diff --git a/src/Discord.Net.Core/Entities/Messages/MessageType.cs b/src/Discord.Net.Core/Entities/Messages/MessageType.cs
index ad1f3a3cd..bfe763cad 100644
--- a/src/Discord.Net.Core/Entities/Messages/MessageType.cs
+++ b/src/Discord.Net.Core/Entities/Messages/MessageType.cs
@@ -60,9 +60,6 @@ namespace Discord
///
/// The message is an inline reply.
///
- ///
- /// Only available in API v8.
- ///
Reply = 19,
}
}
diff --git a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
index 73663d106..b03c0e1a8 100644
--- a/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/GuildPermissions.cs
@@ -87,6 +87,9 @@ namespace Discord
/// Creates a new with the provided packed value.
public GuildPermissions(ulong rawValue) { RawValue = rawValue; }
+ /// Creates a new with the provided packed value after converting to ulong.
+ public GuildPermissions(string rawValue) { RawValue = ulong.Parse(rawValue); }
+
private GuildPermissions(ulong initialValue,
bool? createInstantInvite = null,
bool? kickMembers = null,
diff --git a/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs b/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs
index d8e63fe3a..4f144c74b 100644
--- a/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs
+++ b/src/Discord.Net.Core/Entities/Permissions/OverwritePermissions.cs
@@ -90,6 +90,13 @@ namespace Discord
DenyValue = denyValue;
}
+ /// Creates a new OverwritePermissions with the provided allow and deny packed values after converting to ulong.
+ public OverwritePermissions(string allowValue, string denyValue)
+ {
+ AllowValue = ulong.Parse(allowValue);
+ DenyValue = ulong.Parse(denyValue);
+ }
+
private OverwritePermissions(ulong allowValue, ulong denyValue,
PermValue? createInstantInvite = null,
PermValue? manageChannel = null,
diff --git a/src/Discord.Net.Core/Entities/Users/IPresence.cs b/src/Discord.Net.Core/Entities/Users/IPresence.cs
index a17ac0df2..6972037f0 100644
--- a/src/Discord.Net.Core/Entities/Users/IPresence.cs
+++ b/src/Discord.Net.Core/Entities/Users/IPresence.cs
@@ -7,10 +7,6 @@ namespace Discord
///
public interface IPresence
{
- ///
- /// Gets the activity this user is currently doing.
- ///
- IActivity Activity { get; }
///
/// Gets the current status of this user.
///
diff --git a/src/Discord.Net.Core/Entities/Users/IUser.cs b/src/Discord.Net.Core/Entities/Users/IUser.cs
index e6008aab6..9596a8338 100644
--- a/src/Discord.Net.Core/Entities/Users/IUser.cs
+++ b/src/Discord.Net.Core/Entities/Users/IUser.cs
@@ -87,7 +87,7 @@ namespace Discord
UserProperties? PublicFlags { get; }
///
- /// Gets the direct message channel of this user, or create one if it does not already exist.
+ /// Creates the direct message channel of this user.
///
///
/// This method is used to obtain or create a channel used to send a direct message.
@@ -102,7 +102,7 @@ namespace Discord
///
/// The following example attempts to send a direct message to the target user and logs the incident should
/// it fail.
- ///
///
/// The options to be used when sending the request.
@@ -110,6 +110,6 @@ namespace Discord
/// A task that represents the asynchronous operation for getting or creating a DM channel. The task result
/// contains the DM channel associated with this user.
///
- Task GetOrCreateDMChannelAsync(RequestOptions options = null);
+ Task CreateDMChannelAsync(RequestOptions options = null);
}
}
diff --git a/src/Discord.Net.Core/Extensions/UserExtensions.cs b/src/Discord.Net.Core/Extensions/UserExtensions.cs
index 90f26828a..3e46308e6 100644
--- a/src/Discord.Net.Core/Extensions/UserExtensions.cs
+++ b/src/Discord.Net.Core/Extensions/UserExtensions.cs
@@ -42,7 +42,7 @@ namespace Discord
RequestOptions options = null,
AllowedMentions allowedMentions = null)
{
- return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(text, isTTS, embed, options, allowedMentions).ConfigureAwait(false);
+ return await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendMessageAsync(text, isTTS, embed, options, allowedMentions).ConfigureAwait(false);
}
///
@@ -94,7 +94,7 @@ namespace Discord
RequestOptions options = null
)
{
- return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
+ return await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(stream, filename, text, isTTS, embed, options).ConfigureAwait(false);
}
///
@@ -149,7 +149,7 @@ namespace Discord
Embed embed = null,
RequestOptions options = null)
{
- return await (await user.GetOrCreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
+ return await (await user.CreateDMChannelAsync().ConfigureAwait(false)).SendFileAsync(filePath, text, isTTS, embed, options).ConfigureAwait(false);
}
///
diff --git a/src/Discord.Net.Core/GatewayIntents.cs b/src/Discord.Net.Core/GatewayIntents.cs
index f3dc5ceb9..6976806b2 100644
--- a/src/Discord.Net.Core/GatewayIntents.cs
+++ b/src/Discord.Net.Core/GatewayIntents.cs
@@ -39,5 +39,16 @@ namespace Discord
DirectMessageReactions = 1 << 13,
/// This intent includes TYPING_START
DirectMessageTyping = 1 << 14,
+ ///
+ /// This intent includes all but and
+ /// that are privileged must be enabled for the application.
+ ///
+ AllUnprivileged = Guilds | GuildBans | GuildEmojis | GuildIntegrations | GuildWebhooks | GuildInvites |
+ GuildVoiceStates | GuildMessages | GuildMessageReactions | GuildMessageTyping | DirectMessages |
+ DirectMessageReactions | DirectMessageTyping,
+ ///
+ /// This intent includes all of them, including privileged ones.
+ ///
+ All = AllUnprivileged | GuildMembers | GuildPresences
}
}
diff --git a/src/Discord.Net.Core/RateLimitPrecision.cs b/src/Discord.Net.Core/RateLimitPrecision.cs
deleted file mode 100644
index fe3c1b90e..000000000
--- a/src/Discord.Net.Core/RateLimitPrecision.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-namespace Discord
-{
- ///
- /// Specifies the level of precision to request in the rate limit
- /// response header.
- ///
- public enum RateLimitPrecision
- {
- ///
- /// Specifies precision rounded up to the nearest whole second
- ///
- Second,
- ///
- /// Specifies precision rounded to the nearest millisecond.
- ///
- Millisecond
- }
-}
diff --git a/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs b/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs
index 79a90b46d..83daedaa0 100644
--- a/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs
+++ b/src/Discord.Net.Examples/Core/Entities/Users/IUser.Examples.cs
@@ -18,11 +18,11 @@ namespace Discord.Net.Examples.Core.Entities.Users
#endregion
- #region GetOrCreateDMChannelAsync
+ #region CreateDMChannelAsync
public async Task MessageUserAsync(IUser user)
{
- var channel = await user.GetOrCreateDMChannelAsync();
+ var channel = await user.CreateDMChannelAsync();
try
{
await channel.SendMessageAsync("Awesome stuff!");
diff --git a/src/Discord.Net.Rest/API/Common/Overwrite.cs b/src/Discord.Net.Rest/API/Common/Overwrite.cs
index 1f3548a1c..3d94b0640 100644
--- a/src/Discord.Net.Rest/API/Common/Overwrite.cs
+++ b/src/Discord.Net.Rest/API/Common/Overwrite.cs
@@ -10,8 +10,8 @@ namespace Discord.API
[JsonProperty("type")]
public PermissionTarget TargetType { get; set; }
[JsonProperty("deny"), Int53]
- public ulong Deny { get; set; }
+ public string Deny { get; set; }
[JsonProperty("allow"), Int53]
- public ulong Allow { get; set; }
+ public string Allow { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/Presence.cs b/src/Discord.Net.Rest/API/Common/Presence.cs
index b37ad4229..b44e9185d 100644
--- a/src/Discord.Net.Rest/API/Common/Presence.cs
+++ b/src/Discord.Net.Rest/API/Common/Presence.cs
@@ -13,8 +13,6 @@ namespace Discord.API
public Optional GuildId { get; set; }
[JsonProperty("status")]
public UserStatus Status { get; set; }
- [JsonProperty("game")]
- public Game Game { get; set; }
[JsonProperty("roles")]
public Optional Roles { get; set; }
diff --git a/src/Discord.Net.Rest/API/Common/Role.cs b/src/Discord.Net.Rest/API/Common/Role.cs
index 190ae25c0..c655175da 100644
--- a/src/Discord.Net.Rest/API/Common/Role.cs
+++ b/src/Discord.Net.Rest/API/Common/Role.cs
@@ -18,7 +18,7 @@ namespace Discord.API
[JsonProperty("position")]
public int Position { get; set; }
[JsonProperty("permissions"), Int53]
- public ulong Permissions { get; set; }
+ public string Permissions { get; set; }
[JsonProperty("managed")]
public bool Managed { get; set; }
[JsonProperty("tags")]
diff --git a/src/Discord.Net.Rest/API/Common/UserGuild.cs b/src/Discord.Net.Rest/API/Common/UserGuild.cs
index f4f763885..825e9a09a 100644
--- a/src/Discord.Net.Rest/API/Common/UserGuild.cs
+++ b/src/Discord.Net.Rest/API/Common/UserGuild.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API
@@ -14,6 +14,6 @@ namespace Discord.API
[JsonProperty("owner")]
public bool Owner { get; set; }
[JsonProperty("permissions"), Int53]
- public ulong Permissions { get; set; }
+ public string Permissions { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/API/Rest/ModifyChannelPermissionsParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyChannelPermissionsParams.cs
index 0fe5f7e5a..269111a61 100644
--- a/src/Discord.Net.Rest/API/Rest/ModifyChannelPermissionsParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/ModifyChannelPermissionsParams.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Rest
@@ -7,13 +7,13 @@ namespace Discord.API.Rest
internal class ModifyChannelPermissionsParams
{
[JsonProperty("type")]
- public string Type { get; }
+ public int Type { get; }
[JsonProperty("allow")]
- public ulong Allow { get; }
+ public string Allow { get; }
[JsonProperty("deny")]
- public ulong Deny { get; }
+ public string Deny { get; }
- public ModifyChannelPermissionsParams(string type, ulong allow, ulong deny)
+ public ModifyChannelPermissionsParams(int type, string allow, string deny)
{
Type = type;
Allow = allow;
diff --git a/src/Discord.Net.Rest/API/Rest/ModifyGuildRoleParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyGuildRoleParams.cs
index 287e1cafe..8605411c5 100644
--- a/src/Discord.Net.Rest/API/Rest/ModifyGuildRoleParams.cs
+++ b/src/Discord.Net.Rest/API/Rest/ModifyGuildRoleParams.cs
@@ -1,4 +1,4 @@
-#pragma warning disable CS1591
+#pragma warning disable CS1591
using Newtonsoft.Json;
namespace Discord.API.Rest
@@ -9,7 +9,7 @@ namespace Discord.API.Rest
[JsonProperty("name")]
public Optional Name { get; set; }
[JsonProperty("permissions")]
- public Optional Permissions { get; set; }
+ public Optional Permissions { get; set; }
[JsonProperty("color")]
public Optional Color { get; set; }
[JsonProperty("hoist")]
diff --git a/src/Discord.Net.Rest/API/Rest/SuppressEmbedParams.cs b/src/Discord.Net.Rest/API/Rest/SuppressEmbedParams.cs
deleted file mode 100644
index 9139627b8..000000000
--- a/src/Discord.Net.Rest/API/Rest/SuppressEmbedParams.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-using Newtonsoft.Json;
-
-namespace Discord.API.Rest
-{
- [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
- internal class SuppressEmbedParams
- {
- [JsonProperty("suppress")]
- public bool Suppressed { get; set; }
- }
-}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index d14b03114..002472e5a 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -45,20 +45,18 @@ namespace Discord.API
internal string AuthToken { get; private set; }
internal IRestClient RestClient { get; private set; }
internal ulong? CurrentUserId { get; set; }
- public RateLimitPrecision RateLimitPrecision { get; private set; }
internal bool UseSystemClock { get; set; }
internal JsonSerializer Serializer => _serializer;
/// Unknown OAuth token type.
public DiscordRestApiClient(RestClientProvider restClientProvider, string userAgent, RetryMode defaultRetryMode = RetryMode.AlwaysRetry,
- JsonSerializer serializer = null, RateLimitPrecision rateLimitPrecision = RateLimitPrecision.Second, bool useSystemClock = true)
+ JsonSerializer serializer = null, bool useSystemClock = true)
{
_restClientProvider = restClientProvider;
UserAgent = userAgent;
DefaultRetryMode = defaultRetryMode;
_serializer = serializer ?? new JsonSerializer { ContractResolver = new DiscordContractResolver() };
- RateLimitPrecision = rateLimitPrecision;
UseSystemClock = useSystemClock;
RequestQueue = new RequestQueue();
@@ -75,7 +73,6 @@ namespace Discord.API
RestClient.SetHeader("accept", "*/*");
RestClient.SetHeader("user-agent", UserAgent);
RestClient.SetHeader("authorization", GetPrefixedToken(AuthTokenType, AuthToken));
- RestClient.SetHeader("X-RateLimit-Precision", RateLimitPrecision.ToString().ToLower());
}
/// Unknown OAuth token type.
internal static string GetPrefixedToken(TokenType tokenType, string token)
@@ -645,16 +642,6 @@ namespace Discord.API
return await SendJsonAsync("PATCH", () => $"channels/{channelId}/messages/{messageId}", args, ids, clientBucket: ClientBucketType.SendEdit, options: options).ConfigureAwait(false);
}
- public async Task SuppressEmbedAsync(ulong channelId, ulong messageId, Rest.SuppressEmbedParams args, RequestOptions options = null)
- {
- Preconditions.NotEqual(channelId, 0, nameof(channelId));
- Preconditions.NotEqual(messageId, 0, nameof(messageId));
- options = RequestOptions.CreateOrClone(options);
-
- var ids = new BucketIds(channelId: channelId);
- await SendJsonAsync("POST", () => $"channels/{channelId}/messages/{messageId}/suppress-embeds", args, ids, options: options).ConfigureAwait(false);
- }
-
public async Task AddReactionAsync(ulong channelId, ulong messageId, string emoji, RequestOptions options = null)
{
Preconditions.NotEqual(channelId, 0, nameof(channelId));
@@ -936,7 +923,7 @@ namespace Discord.API
var ids = new BucketIds(guildId: guildId);
string reason = string.IsNullOrWhiteSpace(args.Reason) ? "" : $"&reason={Uri.EscapeDataString(args.Reason)}";
- await SendAsync("PUT", () => $"guilds/{guildId}/bans/{userId}?delete-message-days={args.DeleteMessageDays}{reason}", ids, options: options).ConfigureAwait(false);
+ await SendAsync("PUT", () => $"guilds/{guildId}/bans/{userId}?delete_message_days={args.DeleteMessageDays}{reason}", ids, options: options).ConfigureAwait(false);
}
/// and must not be equal to zero.
public async Task RemoveGuildBanAsync(ulong guildId, ulong userId, RequestOptions options = null)
diff --git a/src/Discord.Net.Rest/DiscordRestClient.cs b/src/Discord.Net.Rest/DiscordRestClient.cs
index 3864538a9..9cdb8e409 100644
--- a/src/Discord.Net.Rest/DiscordRestClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestClient.cs
@@ -29,10 +29,7 @@ namespace Discord.Rest
internal DiscordRestClient(DiscordRestConfig config, API.DiscordRestApiClient api) : base(config, api) { }
private static API.DiscordRestApiClient CreateApiClient(DiscordRestConfig config)
- => new API.DiscordRestApiClient(config.RestClientProvider,
- DiscordRestConfig.UserAgent,
- rateLimitPrecision: config.RateLimitPrecision,
- useSystemClock: config.UseSystemClock);
+ => new API.DiscordRestApiClient(config.RestClientProvider, DiscordRestConfig.UserAgent, useSystemClock: config.UseSystemClock);
internal override void Dispose(bool disposing)
{
diff --git a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
index 7c4edb43e..22395ab3a 100644
--- a/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Channels/ChannelHelper.cs
@@ -33,8 +33,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create(),
};
@@ -59,8 +59,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create(),
};
@@ -84,8 +84,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create(),
};
@@ -328,13 +328,13 @@ namespace Discord.Rest
public static async Task AddPermissionOverwriteAsync(IGuildChannel channel, BaseDiscordClient client,
IUser user, OverwritePermissions perms, RequestOptions options)
{
- var args = new ModifyChannelPermissionsParams("member", perms.AllowValue, perms.DenyValue);
+ var args = new ModifyChannelPermissionsParams((int)PermissionTarget.User, perms.AllowValue.ToString(), perms.DenyValue.ToString());
await client.ApiClient.ModifyChannelPermissionsAsync(channel.Id, user.Id, args, options).ConfigureAwait(false);
}
public static async Task AddPermissionOverwriteAsync(IGuildChannel channel, BaseDiscordClient client,
IRole role, OverwritePermissions perms, RequestOptions options)
{
- var args = new ModifyChannelPermissionsParams("role", perms.AllowValue, perms.DenyValue);
+ var args = new ModifyChannelPermissionsParams((int)PermissionTarget.Role, perms.AllowValue.ToString(), perms.DenyValue.ToString());
await client.ApiClient.ModifyChannelPermissionsAsync(channel.Id, role.Id, args, options).ConfigureAwait(false);
}
public static async Task RemovePermissionOverwriteAsync(IGuildChannel channel, BaseDiscordClient client,
@@ -450,8 +450,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
};
await client.ApiClient.ModifyGuildChannelAsync(channel.Id, apiArgs, options).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index 0827aa71d..331c6f615 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -184,8 +184,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create(),
};
@@ -212,8 +212,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create(),
};
@@ -237,8 +237,8 @@ namespace Discord.Rest
{
TargetId = overwrite.TargetId,
TargetType = overwrite.TargetType,
- Allow = overwrite.Permissions.AllowValue,
- Deny = overwrite.Permissions.DenyValue
+ Allow = overwrite.Permissions.AllowValue.ToString(),
+ Deny = overwrite.Permissions.DenyValue.ToString()
}).ToArray()
: Optional.Create(),
};
@@ -299,7 +299,7 @@ namespace Discord.Rest
Hoist = isHoisted,
Mentionable = isMentionable,
Name = name,
- Permissions = permissions?.RawValue ?? Optional.Create()
+ Permissions = permissions?.RawValue.ToString() ?? Optional.Create()
};
var model = await client.ApiClient.CreateGuildRoleAsync(guild.Id, createGuildRoleParams, options).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
index 1bc284836..31252466b 100644
--- a/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/MessageHelper.cs
@@ -122,15 +122,6 @@ namespace Discord.Rest
await client.ApiClient.DeleteMessageAsync(channelId, msgId, options).ConfigureAwait(false);
}
- public static async Task SuppressEmbedsAsync(IMessage msg, BaseDiscordClient client, bool suppress, RequestOptions options)
- {
- var apiArgs = new API.Rest.SuppressEmbedParams
- {
- Suppressed = suppress
- };
- await client.ApiClient.SuppressEmbedAsync(msg.Channel.Id, msg.Id, apiArgs, options).ConfigureAwait(false);
- }
-
public static async Task AddReactionAsync(ulong channelId, ulong messageId, IEmote emote, BaseDiscordClient client, RequestOptions options)
{
await client.ApiClient.AddReactionAsync(channelId, messageId, emote is Emote e ? $"{e.Name}:{e.Id}" : UrlEncode(emote.Name), options).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
index 1274f1fd3..aa6b44da6 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
@@ -164,9 +164,6 @@ namespace Discord.Rest
///
public Task UnpinAsync(RequestOptions options = null)
=> MessageHelper.UnpinAsync(this, Discord, options);
- ///
- public Task ModifySuppressionAsync(bool suppressEmbeds, RequestOptions options = null)
- => MessageHelper.SuppressEmbedsAsync(this, Discord, suppressEmbeds, options);
public string Resolve(int startIndex, TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
diff --git a/src/Discord.Net.Rest/Entities/Roles/RoleHelper.cs b/src/Discord.Net.Rest/Entities/Roles/RoleHelper.cs
index d570f078b..73ab7ca31 100644
--- a/src/Discord.Net.Rest/Entities/Roles/RoleHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Roles/RoleHelper.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Threading.Tasks;
using Model = Discord.API.Role;
using BulkParams = Discord.API.Rest.ModifyGuildRolesParams;
@@ -24,7 +24,7 @@ namespace Discord.Rest
Hoist = args.Hoist,
Mentionable = args.Mentionable,
Name = args.Name,
- Permissions = args.Permissions.IsSpecified ? args.Permissions.Value.RawValue : Optional.Create()
+ Permissions = args.Permissions.IsSpecified ? args.Permissions.Value.RawValue.ToString() : Optional.Create()
};
var model = await client.ApiClient.ModifyGuildRoleAsync(role.Guild.Id, role.Id, apiArgs, options).ConfigureAwait(false);
diff --git a/src/Discord.Net.Rest/Entities/Users/RestUser.cs b/src/Discord.Net.Rest/Entities/Users/RestUser.cs
index 131a4ec73..7bc1447fe 100644
--- a/src/Discord.Net.Rest/Entities/Users/RestUser.cs
+++ b/src/Discord.Net.Rest/Entities/Users/RestUser.cs
@@ -79,13 +79,13 @@ namespace Discord.Rest
}
///
- /// Returns a direct message channel to this user, or create one if it does not already exist.
+ /// Creates a direct message channel to this user.
///
/// The options to be used when sending the request.
///
/// A task that represents the asynchronous get operation. The task result contains a rest DM channel where the user is the recipient.
///
- public Task GetOrCreateDMChannelAsync(RequestOptions options = null)
+ public Task CreateDMChannelAsync(RequestOptions options = null)
=> UserHelper.CreateDMChannelAsync(this, Discord, options);
///
@@ -107,7 +107,7 @@ namespace Discord.Rest
//IUser
///
- async Task IUser.GetOrCreateDMChannelAsync(RequestOptions options)
- => await GetOrCreateDMChannelAsync(options).ConfigureAwait(false);
+ async Task IUser.CreateDMChannelAsync(RequestOptions options)
+ => await CreateDMChannelAsync(options).ConfigureAwait(false);
}
}
diff --git a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
index a1ed20c6f..931c0c4c9 100644
--- a/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
+++ b/src/Discord.Net.Rest/Net/Converters/DiscordContractResolver.cs
@@ -73,8 +73,6 @@ namespace Discord.Net.Converters
}
//Enums
- if (type == typeof(PermissionTarget))
- return PermissionTargetConverter.Instance;
if (type == typeof(UserStatus))
return UserStatusConverter.Instance;
if (type == typeof(EmbedType))
diff --git a/src/Discord.Net.Rest/Net/Converters/PermissionTargetConverter.cs b/src/Discord.Net.Rest/Net/Converters/PermissionTargetConverter.cs
deleted file mode 100644
index de2e379d7..000000000
--- a/src/Discord.Net.Rest/Net/Converters/PermissionTargetConverter.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Newtonsoft.Json;
-using System;
-
-namespace Discord.Net.Converters
-{
- internal class PermissionTargetConverter : JsonConverter
- {
- public static readonly PermissionTargetConverter Instance = new PermissionTargetConverter();
-
- public override bool CanConvert(Type objectType) => true;
- public override bool CanRead => true;
- public override bool CanWrite => true;
-
- /// Unknown permission target.
- public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
- {
- switch ((string)reader.Value)
- {
- case "member":
- return PermissionTarget.User;
- case "role":
- return PermissionTarget.Role;
- default:
- throw new JsonSerializationException("Unknown permission target.");
- }
- }
-
- /// Invalid permission target.
- public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
- {
- switch ((PermissionTarget)value)
- {
- case PermissionTarget.User:
- writer.WriteValue("member");
- break;
- case PermissionTarget.Role:
- writer.WriteValue("role");
- break;
- default:
- throw new JsonSerializationException("Invalid permission target.");
- }
- }
- }
-}
diff --git a/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs b/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs
index 92a494b71..bb54d4cdd 100644
--- a/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs
+++ b/src/Discord.Net.WebSocket/API/Gateway/IdentifyParams.cs
@@ -17,8 +17,6 @@ namespace Discord.API.Gateway
public Optional ShardingParams { get; set; }
[JsonProperty("presence")]
public Optional Presence { get; set; }
- [JsonProperty("guild_subscriptions")]
- public Optional GuildSubscriptions { get; set; }
[JsonProperty("intents")]
public Optional Intents { get; set; }
}
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs
index 36e6c02a9..b1b430178 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs
@@ -70,20 +70,11 @@ namespace Discord.WebSocket
/// A read-only collection of private channels that the user currently partakes in.
///
public abstract IReadOnlyCollection PrivateChannels { get; }
- ///
- /// Gets a collection of available voice regions.
- ///
- ///
- /// A read-only collection of voice regions that the user has access to.
- ///
- [Obsolete("This property is obsolete, use the GetVoiceRegionsAsync method instead.")]
- public abstract IReadOnlyCollection VoiceRegions { get; }
internal BaseSocketClient(DiscordSocketConfig config, DiscordRestApiClient client)
: base(config, client) => BaseConfig = config;
private static DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
=> new DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent,
- rateLimitPrecision: config.RateLimitPrecision,
useSystemClock: config.UseSystemClock);
///
@@ -164,16 +155,6 @@ namespace Discord.WebSocket
///
public abstract SocketGuild GetGuild(ulong id);
///
- /// Gets a voice region.
- ///
- /// The identifier of the voice region (e.g. eu-central ).
- ///
- /// A REST-based voice region associated with the identifier; null if the voice region is not
- /// found.
- ///
- [Obsolete("This method is obsolete, use GetVoiceRegionAsync instead.")]
- public abstract RestVoiceRegion GetVoiceRegion(string id);
- ///
/// Gets all voice regions.
///
/// The options to be used when sending the request.
@@ -327,10 +308,14 @@ namespace Discord.WebSocket
=> Task.FromResult(GetUser(username, discriminator));
///
- Task IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
- => Task.FromResult(GetVoiceRegion(id));
+ async Task IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
+ {
+ return await GetVoiceRegionAsync(id).ConfigureAwait(false);
+ }
///
- Task> IDiscordClient.GetVoiceRegionsAsync(RequestOptions options)
- => Task.FromResult>(VoiceRegions);
+ async Task> IDiscordClient.GetVoiceRegionsAsync(RequestOptions options)
+ {
+ return await GetVoiceRegionsAsync().ConfigureAwait(false);
+ }
}
}
diff --git a/src/Discord.Net.WebSocket/DiscordShardedClient.cs b/src/Discord.Net.WebSocket/DiscordShardedClient.cs
index 4c94b14e8..ea50a571e 100644
--- a/src/Discord.Net.WebSocket/DiscordShardedClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordShardedClient.cs
@@ -36,9 +36,6 @@ namespace Discord.WebSocket
///
public override IReadOnlyCollection PrivateChannels => GetPrivateChannels().ToReadOnlyCollection(GetPrivateChannelCount);
public IReadOnlyCollection Shards => _shards;
- ///
- [Obsolete("This property is obsolete, use the GetVoiceRegionsAsync method instead.")]
- public override IReadOnlyCollection VoiceRegions => _shards[0].VoiceRegions;
///
/// Provides access to a REST-only client with a shared state from this client.
@@ -91,8 +88,7 @@ namespace Discord.WebSocket
}
}
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
- => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent,
- rateLimitPrecision: config.RateLimitPrecision);
+ => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent);
internal async Task AcquireIdentifyLockAsync(int shardId, CancellationToken token)
{
@@ -264,11 +260,6 @@ namespace Discord.WebSocket
return null;
}
- ///
- [Obsolete("This method is obsolete, use GetVoiceRegionAsync instead.")]
- public override RestVoiceRegion GetVoiceRegion(string id)
- => _shards[0].GetVoiceRegion(id);
-
///
public override async ValueTask> GetVoiceRegionsAsync(RequestOptions options = null)
{
@@ -432,11 +423,15 @@ namespace Discord.WebSocket
=> Task.FromResult(GetUser(username, discriminator));
///
- Task> IDiscordClient.GetVoiceRegionsAsync(RequestOptions options)
- => Task.FromResult>(VoiceRegions);
+ async Task> IDiscordClient.GetVoiceRegionsAsync(RequestOptions options)
+ {
+ return await GetVoiceRegionsAsync().ConfigureAwait(false);
+ }
///
- Task IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
- => Task.FromResult(GetVoiceRegion(id));
+ async Task IDiscordClient.GetVoiceRegionAsync(string id, RequestOptions options)
+ {
+ return await GetVoiceRegionAsync(id).ConfigureAwait(false);
+ }
internal override void Dispose(bool disposing)
{
diff --git a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
index d14a314d6..d1407da01 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketApiClient.cs
@@ -40,9 +40,8 @@ namespace Discord.API
public DiscordSocketApiClient(RestClientProvider restClientProvider, WebSocketProvider webSocketProvider, string userAgent,
string url = null, RetryMode defaultRetryMode = RetryMode.AlwaysRetry, JsonSerializer serializer = null,
- RateLimitPrecision rateLimitPrecision = RateLimitPrecision.Second,
bool useSystemClock = true)
- : base(restClientProvider, userAgent, defaultRetryMode, serializer, rateLimitPrecision, useSystemClock)
+ : base(restClientProvider, userAgent, defaultRetryMode, serializer, useSystemClock)
{
_gatewayUrl = url;
if (url != null)
@@ -216,7 +215,7 @@ namespace Discord.API
await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false);
}
- public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, bool guildSubscriptions = true, GatewayIntents? gatewayIntents = null, (UserStatus, bool, long?, GameModel)? presence = null, RequestOptions options = null)
+ public async Task SendIdentifyAsync(int largeThreshold = 100, int shardID = 0, int totalShards = 1, GatewayIntents gatewayIntents = GatewayIntents.AllUnprivileged, (UserStatus, bool, long?, GameModel)? presence = null, RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
var props = new Dictionary
@@ -234,10 +233,7 @@ namespace Discord.API
options.BucketId = GatewayBucket.Get(GatewayBucketType.Identify).Id;
- if (gatewayIntents.HasValue)
- msg.Intents = (int)gatewayIntents.Value;
- else
- msg.GuildSubscriptions = guildSubscriptions;
+ msg.Intents = (int)gatewayIntents;
if (presence.HasValue)
{
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index e284fd883..d4ca6329d 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -43,8 +43,7 @@ namespace Discord.WebSocket
private DateTimeOffset? _statusSince;
private RestApplication _applicationInfo;
private bool _isDisposed;
- private bool _guildSubscriptions;
- private GatewayIntents? _gatewayIntents;
+ private GatewayIntents _gatewayIntents;
///
/// Provides access to a REST-only client with a shared state from this client.
@@ -109,9 +108,6 @@ namespace Discord.WebSocket
///
public IReadOnlyCollection GroupChannels
=> State.PrivateChannels.OfType().ToImmutableArray();
- ///
- [Obsolete("This property is obsolete, use the GetVoiceRegionsAsync method instead.")]
- public override IReadOnlyCollection VoiceRegions => GetVoiceRegionsAsync().GetAwaiter().GetResult();
///
/// Initializes a new REST/WebSocket-based Discord client.
@@ -140,7 +136,6 @@ namespace Discord.WebSocket
State = new ClientState(0, 0);
Rest = new DiscordSocketRestClient(config, ApiClient);
_heartbeatTimes = new ConcurrentQueue();
- _guildSubscriptions = config.GuildSubscriptions;
_gatewayIntents = config.GatewayIntents;
_stateLock = new SemaphoreSlim(1, 1);
@@ -182,8 +177,7 @@ namespace Discord.WebSocket
_largeGuilds = new ConcurrentQueue();
}
private static API.DiscordSocketApiClient CreateApiClient(DiscordSocketConfig config)
- => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost,
- rateLimitPrecision: config.RateLimitPrecision);
+ => new API.DiscordSocketApiClient(config.RestClientProvider, config.WebSocketProvider, DiscordRestConfig.UserAgent, config.GatewayHost);
///
internal override void Dispose(bool disposing)
{
@@ -243,7 +237,7 @@ namespace Discord.WebSocket
else
{
await _gatewayLogger.DebugAsync("Identifying").ConfigureAwait(false);
- await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions, gatewayIntents: _gatewayIntents, presence: BuildCurrentStatus()).ConfigureAwait(false);
+ await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, gatewayIntents: _gatewayIntents, presence: BuildCurrentStatus()).ConfigureAwait(false);
}
}
finally
@@ -308,7 +302,7 @@ namespace Discord.WebSocket
///
/// Clears cached DM channels from the client.
///
- public void PurgeDMChannelCache() => State.PurgeDMChannels();
+ public void PurgeDMChannelCache() => RemoveDMChannels();
///
public override SocketUser GetUser(ulong id)
@@ -320,14 +314,11 @@ namespace Discord.WebSocket
/// Clears cached users from the client.
///
public void PurgeUserCache() => State.PurgeUsers();
- internal SocketGlobalUser GetOrCreateUser(ClientState state, Discord.API.User model)
+ internal SocketGlobalUser GetOrCreateUser(ClientState state, Discord.API.User model, bool cache)
{
- return state.GetOrAddUser(model.Id, x =>
- {
- var user = SocketGlobalUser.Create(this, state, model);
- user.GlobalUser.AddRef();
- return user;
- });
+ if (cache)
+ return state.GetOrAddUser(model.Id, x => SocketGlobalUser.Create(this, state, model));
+ return state.GetUser(model.Id) ?? SocketGlobalUser.Create(this, state, model);
}
internal SocketGlobalUser GetOrCreateSelfUser(ClientState state, Discord.API.User model)
{
@@ -335,18 +326,13 @@ namespace Discord.WebSocket
{
var user = SocketGlobalUser.Create(this, state, model);
user.GlobalUser.AddRef();
- user.Presence = new SocketPresence(UserStatus.Online, null, null, null);
+ user.Presence = new SocketPresence(UserStatus.Online, null, null);
return user;
});
}
internal void RemoveUser(ulong id)
=> State.RemoveUser(id);
- ///
- [Obsolete("This method is obsolete, use GetVoiceRegionAsync instead.")]
- public override RestVoiceRegion GetVoiceRegion(string id)
- => GetVoiceRegionAsync(id).GetAwaiter().GetResult();
-
///
public override async ValueTask> GetVoiceRegionsAsync(RequestOptions options = null)
{
@@ -469,7 +455,8 @@ namespace Discord.WebSocket
{
if (CurrentUser == null)
return;
- CurrentUser.Presence = new SocketPresence(Status, Activity, null, null);
+ var activities = _activity.IsSpecified ? ImmutableList.Create(_activity.Value) : null;
+ CurrentUser.Presence = new SocketPresence(Status, null, activities);
var presence = BuildCurrentStatus() ?? (UserStatus.Online, false, null, null);
@@ -564,7 +551,7 @@ namespace Discord.WebSocket
await _shardedClient.AcquireIdentifyLockAsync(ShardId, _connection.CancelToken).ConfigureAwait(false);
try
{
- await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions, gatewayIntents: _gatewayIntents, presence: BuildCurrentStatus()).ConfigureAwait(false);
+ await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, gatewayIntents: _gatewayIntents, presence: BuildCurrentStatus()).ConfigureAwait(false);
}
finally
{
@@ -572,7 +559,7 @@ namespace Discord.WebSocket
}
}
else
- await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, guildSubscriptions: _guildSubscriptions, gatewayIntents: _gatewayIntents, presence: BuildCurrentStatus()).ConfigureAwait(false);
+ await ApiClient.SendIdentifyAsync(shardID: ShardId, totalShards: TotalShards, gatewayIntents: _gatewayIntents, presence: BuildCurrentStatus()).ConfigureAwait(false);
}
break;
case GatewayOpCode.Reconnect:
@@ -595,7 +582,8 @@ namespace Discord.WebSocket
var state = new ClientState(data.Guilds.Length, data.PrivateChannels.Length);
var currentUser = SocketSelfUser.Create(this, state, data.User);
- currentUser.Presence = new SocketPresence(Status, Activity, null, null);
+ var activities = _activity.IsSpecified ? ImmutableList.Create(_activity.Value) : null;
+ currentUser.Presence = new SocketPresence(Status, null, activities);
ApiClient.CurrentUserId = currentUser.Id;
int unavailableGuilds = 0;
for (int i = 0; i < data.Guilds.Length; i++)
@@ -1237,56 +1225,63 @@ namespace Discord.WebSocket
await _gatewayLogger.DebugAsync("Received Dispatch (MESSAGE_CREATE)").ConfigureAwait(false);
var data = (payload as JToken).ToObject(_serializer);
- if (State.GetChannel(data.ChannelId) is ISocketMessageChannel channel)
+ var channel = State.GetChannel(data.ChannelId) as ISocketMessageChannel;
+
+ var guild = (channel as SocketGuildChannel)?.Guild;
+ if (guild != null && !guild.IsSynced)
{
- var guild = (channel as SocketGuildChannel)?.Guild;
- if (guild != null && !guild.IsSynced)
+ await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
+ return;
+ }
+
+ if (channel == null)
+ {
+ if (!data.GuildId.IsSpecified) // assume it is a DM
{
- await UnsyncedGuildAsync(type, guild.Id).ConfigureAwait(false);
- return;
+ channel = CreateDMChannel(data.ChannelId, data.Author.Value, State);
}
-
- SocketUser author;
- if (guild != null)
+ else
{
- if (data.WebhookId.IsSpecified)
- author = SocketWebhookUser.Create(guild, State, data.Author.Value, data.WebhookId.Value);
- else
- author = guild.GetUser(data.Author.Value.Id);
+ await UnknownChannelAsync(type, data.ChannelId).ConfigureAwait(false);
+ return;
}
+ }
+
+ SocketUser author;
+ if (guild != null)
+ {
+ if (data.WebhookId.IsSpecified)
+ author = SocketWebhookUser.Create(guild, State, data.Author.Value, data.WebhookId.Value);
else
- author = (channel as SocketChannel).GetUser(data.Author.Value.Id);
+ author = guild.GetUser(data.Author.Value.Id);
+ }
+ else
+ author = (channel as SocketChannel).GetUser(data.Author.Value.Id);
- if (author == null)
+ if (author == null)
+ {
+ if (guild != null)
{
- if (guild != null)
+ if (data.Member.IsSpecified) // member isn't always included, but use it when we can
{
- if (data.Member.IsSpecified) // member isn't always included, but use it when we can
- {
- data.Member.Value.User = data.Author.Value;
- author = guild.AddOrUpdateUser(data.Member.Value);
- }
- else
- author = guild.AddOrUpdateUser(data.Author.Value); // user has no guild-specific data
+ data.Member.Value.User = data.Author.Value;
+ author = guild.AddOrUpdateUser(data.Member.Value);
}
- else if (channel is SocketGroupChannel)
- author = (channel as SocketGroupChannel).GetOrAddUser(data.Author.Value);
else
- {
- await UnknownChannelUserAsync(type, data.Author.Value.Id, channel.Id).ConfigureAwait(false);
- return;
- }
+ author = guild.AddOrUpdateUser(data.Author.Value); // user has no guild-specific data
+ }
+ else if (channel is SocketGroupChannel groupChannel)
+ author = groupChannel.GetOrAddUser(data.Author.Value);
+ else
+ {
+ await UnknownChannelUserAsync(type, data.Author.Value.Id, channel.Id).ConfigureAwait(false);
+ return;
}
-
- var msg = SocketMessage.Create(this, State, author, channel, data);
- SocketChannelHelper.AddMessage(channel, this, msg);
- await TimedInvokeAsync(_messageReceivedEvent, nameof(MessageReceived), msg).ConfigureAwait(false);
- }
- else
- {
- await UnknownChannelAsync(type, data.ChannelId).ConfigureAwait(false);
- return;
}
+
+ var msg = SocketMessage.Create(this, State, author, channel, data);
+ SocketChannelHelper.AddMessage(channel, this, msg);
+ await TimedInvokeAsync(_messageReceivedEvent, nameof(MessageReceived), msg).ConfigureAwait(false);
}
break;
case "MESSAGE_UPDATE":
@@ -1938,24 +1933,29 @@ namespace Discord.WebSocket
{
var channel = SocketChannel.CreatePrivate(this, state, model);
state.AddChannel(channel as SocketChannel);
- if (channel is SocketDMChannel dm)
- dm.Recipient.GlobalUser.DMChannel = dm;
-
return channel;
}
+ internal SocketDMChannel CreateDMChannel(ulong channelId, API.User model, ClientState state)
+ {
+ return SocketDMChannel.Create(this, state, channelId, model);
+ }
internal ISocketPrivateChannel RemovePrivateChannel(ulong id)
{
var channel = State.RemoveChannel(id) as ISocketPrivateChannel;
if (channel != null)
{
- if (channel is SocketDMChannel dmChannel)
- dmChannel.Recipient.GlobalUser.DMChannel = null;
-
foreach (var recipient in channel.Recipients)
recipient.GlobalUser.RemoveRef(this);
}
return channel;
}
+ internal void RemoveDMChannels()
+ {
+ var channels = State.DMChannels;
+ State.PurgeDMChannels();
+ foreach (var channel in channels)
+ channel.Recipient.GlobalUser.RemoveRef(this);
+ }
private async Task GuildAvailableAsync(SocketGuild guild)
{
diff --git a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs
index a45d4f5be..90b746787 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketConfig.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketConfig.cs
@@ -127,12 +127,6 @@ namespace Discord.WebSocket
///
public bool? ExclusiveBulkDelete { get; set; } = null;
- ///
- /// Gets or sets enabling dispatching of guild subscription events e.g. presence and typing events.
- /// This is not used if are provided.
- ///
- public bool GuildSubscriptions { get; set; } = true;
-
///
/// Gets or sets the maximum identify concurrency.
///
@@ -172,14 +166,15 @@ namespace Discord.WebSocket
private int maxWaitForGuildAvailable = 10000;
///
- /// Gets or sets gateway intents to limit what events are sent from Discord. Allows for more granular control than the property.
+ /// Gets or sets gateway intents to limit what events are sent from Discord.
+ /// The default is .
///
///
/// For more information, please see
/// GatewayIntents
/// on the official Discord API documentation.
///
- public GatewayIntents? GatewayIntents { get; set; }
+ public GatewayIntents GatewayIntents { get; set; } = GatewayIntents.AllUnprivileged;
///
/// Initializes a new instance of the class with the default configuration.
diff --git a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
index 5de417036..a42db3b5f 100644
--- a/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
+++ b/src/Discord.Net.WebSocket/Entities/Channels/SocketDMChannel.cs
@@ -16,15 +16,13 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketDMChannel : SocketChannel, IDMChannel, ISocketPrivateChannel, ISocketMessageChannel
{
- private readonly MessageCache _messages;
-
///
/// Gets the recipient of the channel.
///
public SocketUser Recipient { get; }
///
- public IReadOnlyCollection CachedMessages => _messages?.Messages ?? ImmutableArray.Create();
+ public IReadOnlyCollection CachedMessages => ImmutableArray.Create();
///
/// Gets a collection that is the current logged-in user and the recipient.
@@ -35,13 +33,10 @@ namespace Discord.WebSocket
: base(discord, id)
{
Recipient = recipient;
- recipient.GlobalUser.AddRef();
- if (Discord.MessageCacheSize > 0)
- _messages = new MessageCache(Discord);
}
internal static SocketDMChannel Create(DiscordSocketClient discord, ClientState state, Model model)
{
- var entity = new SocketDMChannel(discord, model.Id, discord.GetOrCreateUser(state, model.Recipients.Value[0]));
+ var entity = new SocketDMChannel(discord, model.Id, discord.GetOrCreateUser(state, model.Recipients.Value[0], false));
entity.Update(state, model);
return entity;
}
@@ -49,6 +44,16 @@ namespace Discord.WebSocket
{
Recipient.Update(state, model.Recipients.Value[0]);
}
+ internal static SocketDMChannel Create(DiscordSocketClient discord, ClientState state, ulong channelId, API.User recipient)
+ {
+ var entity = new SocketDMChannel(discord, channelId, discord.GetOrCreateUser(state, recipient, false));
+ entity.Update(state, recipient);
+ return entity;
+ }
+ internal void Update(ClientState state, API.User recipient)
+ {
+ Recipient.Update(state, recipient);
+ }
///
public Task CloseAsync(RequestOptions options = null)
@@ -57,7 +62,7 @@ namespace Discord.WebSocket
//Messages
///
public SocketMessage GetCachedMessage(ulong id)
- => _messages?.Get(id);
+ => null;
///
/// Gets the message associated with the given .
///
@@ -68,10 +73,7 @@ namespace Discord.WebSocket
///
public async Task GetMessageAsync(ulong id, RequestOptions options = null)
{
- IMessage msg = _messages?.Get(id);
- if (msg == null)
- msg = await ChannelHelper.GetMessageAsync(this, Discord, id, options).ConfigureAwait(false);
- return msg;
+ return await ChannelHelper.GetMessageAsync(this, Discord, id, options).ConfigureAwait(false);
}
///
@@ -87,7 +89,7 @@ namespace Discord.WebSocket
/// Paged collection of messages.
///
public IAsyncEnumerable> GetMessagesAsync(int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
- => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, null, Direction.Before, limit, CacheMode.AllowDownload, options);
+ => ChannelHelper.GetMessagesAsync(this, Discord, null, Direction.Before, limit, options);
///
/// Gets a collection of messages in this channel.
///
@@ -103,7 +105,7 @@ namespace Discord.WebSocket
/// Paged collection of messages.
///
public IAsyncEnumerable> GetMessagesAsync(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
- => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessageId, dir, limit, CacheMode.AllowDownload, options);
+ => ChannelHelper.GetMessagesAsync(this, Discord, fromMessageId, dir, limit, options);
///
/// Gets a collection of messages in this channel.
///
@@ -119,16 +121,16 @@ namespace Discord.WebSocket
/// Paged collection of messages.
///
public IAsyncEnumerable> GetMessagesAsync(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch, RequestOptions options = null)
- => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, CacheMode.AllowDownload, options);
+ => ChannelHelper.GetMessagesAsync(this, Discord, fromMessage.Id, dir, limit, options);
///
public IReadOnlyCollection GetCachedMessages(int limit = DiscordConfig.MaxMessagesPerBatch)
- => SocketChannelHelper.GetCachedMessages(this, Discord, _messages, null, Direction.Before, limit);
+ => ImmutableArray.Create();
///
public IReadOnlyCollection GetCachedMessages(ulong fromMessageId, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch)
- => SocketChannelHelper.GetCachedMessages(this, Discord, _messages, fromMessageId, dir, limit);
+ => ImmutableArray.Create();
///
public IReadOnlyCollection GetCachedMessages(IMessage fromMessage, Direction dir, int limit = DiscordConfig.MaxMessagesPerBatch)
- => SocketChannelHelper.GetCachedMessages(this, Discord, _messages, fromMessage.Id, dir, limit);
+ => ImmutableArray.Create();
///
public Task> GetPinnedMessagesAsync(RequestOptions options = null)
=> ChannelHelper.GetPinnedMessagesAsync(this, Discord, options);
@@ -164,9 +166,12 @@ namespace Discord.WebSocket
=> ChannelHelper.EnterTypingState(this, Discord, options);
internal void AddMessage(SocketMessage msg)
- => _messages?.Add(msg);
+ {
+ }
internal SocketMessage RemoveMessage(ulong id)
- => _messages?.Remove(id);
+ {
+ return null;
+ }
//Users
///
@@ -222,13 +227,13 @@ namespace Discord.WebSocket
}
///
IAsyncEnumerable> IMessageChannel.GetMessagesAsync(int limit, CacheMode mode, RequestOptions options)
- => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, null, Direction.Before, limit, mode, options);
+ => mode == CacheMode.CacheOnly ? null : GetMessagesAsync(limit, options);
///
IAsyncEnumerable> IMessageChannel.GetMessagesAsync(ulong fromMessageId, Direction dir, int limit, CacheMode mode, RequestOptions options)
- => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessageId, dir, limit, mode, options);
+ => mode == CacheMode.CacheOnly ? null : GetMessagesAsync(fromMessageId, dir, limit, options);
///
IAsyncEnumerable> IMessageChannel.GetMessagesAsync(IMessage fromMessage, Direction dir, int limit, CacheMode mode, RequestOptions options)
- => SocketChannelHelper.GetMessagesAsync(this, Discord, _messages, fromMessage.Id, dir, limit, mode, options);
+ => mode == CacheMode.CacheOnly ? null : GetMessagesAsync(fromMessage.Id, dir, limit, options);
///
async Task> IMessageChannel.GetPinnedMessagesAsync(RequestOptions options)
=> await GetPinnedMessagesAsync(options).ConfigureAwait(false);
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
index 2a8b45ca1..597544f4d 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
@@ -189,9 +189,6 @@ namespace Discord.WebSocket
///
public Task UnpinAsync(RequestOptions options = null)
=> MessageHelper.UnpinAsync(this, Discord, options);
- ///
- public Task ModifySuppressionAsync(bool suppressEmbeds, RequestOptions options = null)
- => MessageHelper.SuppressEmbedsAsync(this, Discord, suppressEmbeds, options);
public string Resolve(int startIndex, TagHandling userHandling = TagHandling.Name, TagHandling channelHandling = TagHandling.Name,
TagHandling roleHandling = TagHandling.Name, TagHandling everyoneHandling = TagHandling.Ignore, TagHandling emojiHandling = TagHandling.Name)
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketGlobalUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketGlobalUser.cs
index 48de7552a..15c5182fc 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketGlobalUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketGlobalUser.cs
@@ -12,7 +12,6 @@ namespace Discord.WebSocket
public override string Username { get; internal set; }
public override ushort DiscriminatorValue { get; internal set; }
public override string AvatarId { get; internal set; }
- public SocketDMChannel DMChannel { get; internal set; }
internal override SocketPresence Presence { get; set; }
public override bool IsWebhook => false;
@@ -52,7 +51,6 @@ namespace Discord.WebSocket
internal void Update(ClientState state, PresenceModel model)
{
Presence = SocketPresence.Create(model);
- DMChannel = state.DMChannels.FirstOrDefault(x => x.Recipient.Id == Id);
}
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id}{(IsBot ? ", Bot" : "")}, Global)";
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs
index 676c0a86c..9f66bed12 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketGroupUser.cs
@@ -38,7 +38,7 @@ namespace Discord.WebSocket
}
internal static SocketGroupUser Create(SocketGroupChannel channel, ClientState state, Model model)
{
- var entity = new SocketGroupUser(channel, channel.Discord.GetOrCreateUser(state, model));
+ var entity = new SocketGroupUser(channel, channel.Discord.GetOrCreateUser(state, model, true));
entity.Update(state, model);
return entity;
}
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
index 9263fe642..6362d4891 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
@@ -116,20 +116,20 @@ namespace Discord.WebSocket
}
internal static SocketGuildUser Create(SocketGuild guild, ClientState state, UserModel model)
{
- var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model));
+ var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model, true));
entity.Update(state, model);
entity.UpdateRoles(new ulong[0]);
return entity;
}
internal static SocketGuildUser Create(SocketGuild guild, ClientState state, MemberModel model)
{
- var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model.User));
+ var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model.User, true));
entity.Update(state, model);
return entity;
}
internal static SocketGuildUser Create(SocketGuild guild, ClientState state, PresenceModel model)
{
- var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model.User));
+ var entity = new SocketGuildUser(guild, guild.Discord.GetOrCreateUser(state, model.User, true));
entity.Update(state, model, false);
return entity;
}
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
index 407e14419..fe672a4d6 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
@@ -2,6 +2,7 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
+using System.Linq;
using Model = Discord.API.Presence;
namespace Discord.WebSocket
@@ -15,15 +16,12 @@ namespace Discord.WebSocket
///
public UserStatus Status { get; }
///
- public IActivity Activity { get; }
- ///
public IImmutableSet ActiveClients { get; }
///
public IImmutableList Activities { get; }
- internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet activeClients, IImmutableList activities)
+ internal SocketPresence(UserStatus status, IImmutableSet activeClients, IImmutableList activities)
{
Status = status;
- Activity = activity;
ActiveClients = activeClients ?? ImmutableHashSet.Empty;
Activities = activities ?? ImmutableList.Empty;
}
@@ -31,7 +29,7 @@ namespace Discord.WebSocket
{
var clients = ConvertClientTypesDict(model.ClientStatus.GetValueOrDefault());
var activities = ConvertActivitiesList(model.Activities);
- return new SocketPresence(model.Status, model.Game?.ToEntity(), clients, activities);
+ return new SocketPresence(model.Status, clients, activities);
}
///
/// Creates a new containing all of the client types
@@ -84,7 +82,7 @@ namespace Discord.WebSocket
/// A string that resolves to .
///
public override string ToString() => Status.ToString();
- private string DebuggerDisplay => $"{Status}{(Activity != null ? $", {Activity.Name}": "")}";
+ private string DebuggerDisplay => $"{Status}{(Activities?.FirstOrDefault()?.Name ?? "")}";
internal SocketPresence Clone() => this;
}
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs
index dd2e747b4..840a1c30b 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs
@@ -25,7 +25,7 @@ namespace Discord.WebSocket
///
public override bool IsWebhook => false;
///
- internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null, null); } set { } }
+ internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null); } set { } }
///
/// This field is not supported for an unknown user.
internal override SocketGlobalUser GlobalUser =>
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
index 4e6d4b3f8..025daf29a 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
@@ -38,8 +38,6 @@ namespace Discord.WebSocket
///
public string Mention => MentionUtils.MentionUser(Id);
///
- public IActivity Activity => Presence.Activity;
- ///
public UserStatus Status => Presence.Status;
///
public IImmutableSet ActiveClients => Presence.ActiveClients ?? ImmutableHashSet.Empty;
@@ -94,8 +92,8 @@ namespace Discord.WebSocket
}
///
- public async Task GetOrCreateDMChannelAsync(RequestOptions options = null)
- => GlobalUser.DMChannel ?? await UserHelper.CreateDMChannelAsync(this, Discord, options).ConfigureAwait(false) as IDMChannel;
+ public async Task CreateDMChannelAsync(RequestOptions options = null)
+ => await UserHelper.CreateDMChannelAsync(this, Discord, options).ConfigureAwait(false);
///
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs
index c22164f95..404ab116d 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs
@@ -30,7 +30,7 @@ namespace Discord.WebSocket
///
public override bool IsWebhook => true;
///
- internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null, null); } set { } }
+ internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null); } set { } }
internal override SocketGlobalUser GlobalUser =>
throw new NotSupportedException();