Browse Source

Add missing properties to Guild, related methods, and deprecate GuildEmbed endpoints

- Add missing guild properties: `discovery_splash`, `widget_enabled`, `widget_channel_id`, `rules_channel_id`, `max_presences`, `max_presences`, `max_members`, `public_updates_channel_id`, `max_video_channel_users`, `approximate_member_count`, `approximate_presence_count`
- Update guild properties: `embed_enabled`, `embed_channel_id`
- Add `GetGuildDiscoverySplashUrl` to `CDN`
- Add classes related to the guild widget
- Add `withCounts` parameter to `GetGuild(s)Async`
- Make GuildEmbed related methods obsolete with a message redirecting to widget ones
pull/1573/head
SubZero0 5 years ago
parent
commit
13d1f5c274
15 changed files with 569 additions and 22 deletions
  1. +11
    -1
      src/Discord.Net.Core/CDN.cs
  2. +21
    -0
      src/Discord.Net.Core/Entities/Guilds/GuildWidgetProperties.cs
  3. +128
    -0
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  4. +1
    -0
      src/Discord.Net.Core/Entities/IUpdateable.cs
  5. +22
    -2
      src/Discord.Net.Rest/API/Common/Guild.cs
  6. +2
    -2
      src/Discord.Net.Rest/API/Common/GuildEmbed.cs
  7. +13
    -0
      src/Discord.Net.Rest/API/Common/GuildWidget.cs
  8. +14
    -0
      src/Discord.Net.Rest/API/Rest/ModifyGuildWidgetParams.cs
  9. +13
    -5
      src/Discord.Net.Rest/ClientHelper.cs
  10. +28
    -2
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  11. +10
    -2
      src/Discord.Net.Rest/DiscordRestClient.cs
  12. +22
    -0
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  13. +157
    -6
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  14. +25
    -0
      src/Discord.Net.Rest/Entities/Guilds/RestGuildWidget.cs
  15. +102
    -2
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs

+ 11
- 1
src/Discord.Net.Core/CDN.cs View File

@@ -62,11 +62,21 @@ namespace Discord
/// <param name="guildId">The guild snowflake identifier.</param> /// <param name="guildId">The guild snowflake identifier.</param>
/// <param name="splashId">The splash icon identifier.</param> /// <param name="splashId">The splash icon identifier.</param>
/// <returns> /// <returns>
/// A URL pointing to the guild's icon.
/// A URL pointing to the guild's splash.
/// </returns> /// </returns>
public static string GetGuildSplashUrl(ulong guildId, string splashId) public static string GetGuildSplashUrl(ulong guildId, string splashId)
=> splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null; => splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null;
/// <summary> /// <summary>
/// Returns a guild discovery splash URL.
/// </summary>
/// <param name="guildId">The guild snowflake identifier.</param>
/// <param name="discoverySplashId">The discovery splash icon identifier.</param>
/// <returns>
/// A URL pointing to the guild's discovery splash.
/// </returns>
public static string GetGuildDiscoverySplashUrl(ulong guildId, string discoverySplashId)
=> discoverySplashId != null ? $"{DiscordConfig.CDNUrl}discovery-splashes/{guildId}/{discoverySplashId}.jpg" : null;
/// <summary>
/// Returns a channel icon URL. /// Returns a channel icon URL.
/// </summary> /// </summary>
/// <param name="channelId">The channel snowflake identifier.</param> /// <param name="channelId">The channel snowflake identifier.</param>


+ 21
- 0
src/Discord.Net.Core/Entities/Guilds/GuildWidgetProperties.cs View File

@@ -0,0 +1,21 @@
namespace Discord
{
/// <summary>
/// Provides properties that are used to modify the widget of an <see cref="IGuild" /> with the specified changes.
/// </summary>
public class GuildWidgetProperties
{
/// <summary>
/// Sets whether the widget should be enabled.
/// </summary>
public Optional<bool> Enabled { get; set; }
/// <summary>
/// Sets the channel that the invite should place its users in, if not <c>null</c>.
/// </summary>
public Optional<IChannel> Channel { get; set; }
/// <summary>
/// Sets the channel the invite should place its users in, if not <c>null</c>.
/// </summary>
public Optional<ulong?> ChannelId { get; set; }
}
}

+ 128
- 0
src/Discord.Net.Core/Entities/Guilds/IGuild.cs View File

@@ -35,6 +35,13 @@ namespace Discord
/// </returns> /// </returns>
bool IsEmbeddable { get; } bool IsEmbeddable { get; }
/// <summary> /// <summary>
/// Gets a value that indicates whether this guild has the widget enabled.
/// </summary>
/// <returns>
/// <c>true</c> if this guild has a widget enabled; otherwise <c>false</c>.
/// </returns>
bool IsWidgetEnabled { get; }
/// <summary>
/// Gets the default message notifications for users who haven't explicitly set their notification settings. /// Gets the default message notifications for users who haven't explicitly set their notification settings.
/// </summary> /// </summary>
DefaultMessageNotifications DefaultMessageNotifications { get; } DefaultMessageNotifications DefaultMessageNotifications { get; }
@@ -89,6 +96,20 @@ namespace Discord
/// </returns> /// </returns>
string SplashUrl { get; } string SplashUrl { get; }
/// <summary> /// <summary>
/// Gets the ID of this guild's discovery splash image.
/// </summary>
/// <returns>
/// An identifier for the discovery splash image; <c>null</c> if none is set.
/// </returns>
string DiscoverySplashId { get; }
/// <summary>
/// Gets the URL of this guild's discovery splash image.
/// </summary>
/// <returns>
/// A URL pointing to the guild's discovery splash image; <c>null</c> if none is set.
/// </returns>
string DiscoverySplashUrl { get; }
/// <summary>
/// Determines if this guild is currently connected and ready to be used. /// Determines if this guild is currently connected and ready to be used.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
@@ -134,6 +155,14 @@ namespace Discord
/// </returns> /// </returns>
ulong? EmbedChannelId { get; } ulong? EmbedChannelId { get; }
/// <summary> /// <summary>
/// Gets the ID of the channel assigned to the widget of this guild.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the channel assigned to the widget found
/// within the widget settings of this guild; <c>null</c> if none is set.
/// </returns>
ulong? WidgetChannelId { get; }
/// <summary>
/// Gets the ID of the channel where randomized welcome messages are sent. /// Gets the ID of the channel where randomized welcome messages are sent.
/// </summary> /// </summary>
/// <returns> /// <returns>
@@ -142,6 +171,23 @@ namespace Discord
/// </returns> /// </returns>
ulong? SystemChannelId { get; } ulong? SystemChannelId { get; }
/// <summary> /// <summary>
/// Gets the ID of the channel with the rules.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the channel that contains the rules;
/// <c>null</c> if none is set.
/// </returns>
ulong? RulesChannelId { get; }
/// <summary>
/// Gets the ID of the channel where admins and moderators of guilds with the "PUBLIC" feature
/// receive notices from Discord.
/// </summary>
/// <returns>
/// A <see cref="ulong"/> representing the snowflake identifier of the channel where admins and moderators
/// of guilds with the "PUBLIC" feature receive notices from Discord; <c>null</c> if none is set.
/// </returns>
ulong? PublicUpdatesChannelId { get; }
/// <summary>
/// Gets the ID of the user that owns this guild. /// Gets the ID of the user that owns this guild.
/// </summary> /// </summary>
/// <returns> /// <returns>
@@ -249,6 +295,47 @@ namespace Discord
/// The number of premium subscribers of this guild. /// The number of premium subscribers of this guild.
/// </returns> /// </returns>
int PremiumSubscriptionCount { get; } int PremiumSubscriptionCount { get; }
/// <summary>
/// Gets the maximum number of presences for the guild.
/// </summary>
/// <returns>
/// The maximum number of presences for the guild.
/// </returns>
int? MaxPresences { get; }
/// <summary>
/// Gets the maximum number of members for the guild.
/// </summary>
/// <returns>
/// The maximum number of members for the guild.
/// </returns>
int? MaxMembers { get; }
/// <summary>
/// Gets the maximum amount of users in a video channel.
/// </summary>
/// <returns>
/// The maximum amount of users in a video channel.
/// </returns>
int? MaxVideoChannelUsers { get; }
/// <summary>
/// Gets the approximate number of members in this guild.
/// </summary>
/// <remarks>
/// Only available when getting a guild via REST when `with_counts` is true.
/// </remarks>
/// <returns>
/// The approximate number of members in this guild.
/// </returns>
int? ApproximateMemberCount { get; }
/// <summary>
/// Gets the approximate number of non-offline members in this guild.
/// </summary>
/// <remarks>
/// Only available when getting a guild via REST when `with_counts` is true.
/// </remarks>
/// <returns>
/// The approximate number of non-offline members in this guild.
/// </returns>
int? ApproximatePresenceCount { get; }


/// <summary> /// <summary>
/// Gets the preferred locale of this guild in IETF BCP 47 /// Gets the preferred locale of this guild in IETF BCP 47
@@ -285,8 +372,18 @@ namespace Discord
/// <returns> /// <returns>
/// A task that represents the asynchronous modification operation. /// A task that represents the asynchronous modification operation.
/// </returns> /// </returns>
[Obsolete("This endpoint is deprecated, use ModifyWidgetAsync instead.")]
Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null); Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null);
/// <summary> /// <summary>
/// Modifies this guild's widget.
/// </summary>
/// <param name="func">The delegate containing the properties to modify the guild widget with.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous modification operation.
/// </returns>
Task ModifyWidgetAsync(Action<GuildWidgetProperties> func, RequestOptions options = null);
/// <summary>
/// Bulk-modifies the order of channels in this guild. /// Bulk-modifies the order of channels in this guild.
/// </summary> /// </summary>
/// <param name="args">The properties used to modify the channel positions with.</param> /// <param name="args">The properties used to modify the channel positions with.</param>
@@ -504,7 +601,38 @@ namespace Discord
/// A task that represents the asynchronous get operation. The task result contains the embed channel set /// A task that represents the asynchronous get operation. The task result contains the embed channel set
/// within the server's widget settings; <c>null</c> if none is set. /// within the server's widget settings; <c>null</c> if none is set.
/// </returns> /// </returns>
[Obsolete("This endpoint is deprecated, use GetWidgetChannelAsync instead.")]
Task<IGuildChannel> GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null); Task<IGuildChannel> GetEmbedChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
/// <summary>
/// Gets the widget channel (i.e. the channel set in the guild's widget settings) in this guild.
/// </summary>
/// <param name="mode">The <see cref="CacheMode" /> that determines whether the object should be fetched from cache.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the widget channel set
/// within the server's widget settings; <c>null</c> if none is set.
/// </returns>
Task<IGuildChannel> GetWidgetChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
/// <summary>
/// Gets the text channel where guilds with the "PUBLIC" feature can display rules and/or guidelines.
/// </summary>
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the text channel
/// where guilds with the "PUBLIC" feature can display rules and/or guidelines; <c>null</c> if none is set.
/// </returns>
Task<ITextChannel> GetRulesChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
/// <summary>
/// Gets the text channel channel where admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord.
/// </summary>
/// <param name="mode">The <see cref="CacheMode"/> that determines whether the object should be fetched from cache.</param>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the text channel channel where
/// admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord; <c>null</c> if none is set.
/// </returns>
Task<ITextChannel> GetPublicUpdatesChannelAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);


/// <summary> /// <summary>
/// Creates a new text channel in this guild. /// Creates a new text channel in this guild.


+ 1
- 0
src/Discord.Net.Core/Entities/IUpdateable.cs View File

@@ -10,6 +10,7 @@ namespace Discord
/// <summary> /// <summary>
/// Updates this object's properties with its current state. /// Updates this object's properties with its current state.
/// </summary> /// </summary>
/// <param name="options">The options to be used when sending the request.</param>
Task UpdateAsync(RequestOptions options = null); Task UpdateAsync(RequestOptions options = null);
} }
} }

+ 22
- 2
src/Discord.Net.Rest/API/Common/Guild.cs View File

@@ -13,6 +13,8 @@ namespace Discord.API
public string Icon { get; set; } public string Icon { get; set; }
[JsonProperty("splash")] [JsonProperty("splash")]
public string Splash { get; set; } public string Splash { get; set; }
[JsonProperty("discovery_splash")]
public string DiscoverySplash { get; set; }
[JsonProperty("owner_id")] [JsonProperty("owner_id")]
public ulong OwnerId { get; set; } public ulong OwnerId { get; set; }
[JsonProperty("region")] [JsonProperty("region")]
@@ -22,9 +24,9 @@ namespace Discord.API
[JsonProperty("afk_timeout")] [JsonProperty("afk_timeout")]
public int AFKTimeout { get; set; } public int AFKTimeout { get; set; }
[JsonProperty("embed_enabled")] [JsonProperty("embed_enabled")]
public bool EmbedEnabled { get; set; }
public Optional<bool> EmbedEnabled { get; set; }
[JsonProperty("embed_channel_id")] [JsonProperty("embed_channel_id")]
public ulong? EmbedChannelId { get; set; }
public Optional<ulong?> EmbedChannelId { get; set; }
[JsonProperty("verification_level")] [JsonProperty("verification_level")]
public VerificationLevel VerificationLevel { get; set; } public VerificationLevel VerificationLevel { get; set; }
[JsonProperty("default_message_notifications")] [JsonProperty("default_message_notifications")]
@@ -43,6 +45,10 @@ namespace Discord.API
public MfaLevel MfaLevel { get; set; } public MfaLevel MfaLevel { get; set; }
[JsonProperty("application_id")] [JsonProperty("application_id")]
public ulong? ApplicationId { get; set; } public ulong? ApplicationId { get; set; }
[JsonProperty("widget_enabled")]
public Optional<bool> WidgetEnabled { get; set; }
[JsonProperty("widget_channel_id")]
public Optional<ulong?> WidgetChannelId { get; set; }
[JsonProperty("system_channel_id")] [JsonProperty("system_channel_id")]
public ulong? SystemChannelId { get; set; } public ulong? SystemChannelId { get; set; }
[JsonProperty("premium_tier")] [JsonProperty("premium_tier")]
@@ -56,9 +62,23 @@ namespace Discord.API
// this value is inverted, flags set will turn OFF features // this value is inverted, flags set will turn OFF features
[JsonProperty("system_channel_flags")] [JsonProperty("system_channel_flags")]
public SystemChannelMessageDeny SystemChannelFlags { get; set; } public SystemChannelMessageDeny SystemChannelFlags { get; set; }
[JsonProperty("rules_channel_id")]
public ulong? RulesChannelId { get; set; }
[JsonProperty("max_presences")]
public Optional<int?> MaxPresences { get; set; }
[JsonProperty("max_members")]
public Optional<int> MaxMembers { get; set; }
[JsonProperty("premium_subscription_count")] [JsonProperty("premium_subscription_count")]
public int? PremiumSubscriptionCount { get; set; } public int? PremiumSubscriptionCount { get; set; }
[JsonProperty("preferred_locale")] [JsonProperty("preferred_locale")]
public string PreferredLocale { get; set; } public string PreferredLocale { get; set; }
[JsonProperty("public_updates_channel_id")]
public ulong? PublicUpdatesChannelId { get; set; }
[JsonProperty("max_video_channel_users")]
public Optional<int> MaxVideoChannelUsers { get; set; }
[JsonProperty("approximate_member_count")]
public Optional<int> ApproximateMemberCount { get; set; }
[JsonProperty("approximate_presence_count")]
public Optional<int> ApproximatePresenceCount { get; set; }
} }
} }

+ 2
- 2
src/Discord.Net.Rest/API/Common/GuildEmbed.cs View File

@@ -1,4 +1,4 @@
#pragma warning disable CS1591
#pragma warning disable CS1591
using Newtonsoft.Json; using Newtonsoft.Json;


namespace Discord.API namespace Discord.API
@@ -8,6 +8,6 @@ namespace Discord.API
[JsonProperty("enabled")] [JsonProperty("enabled")]
public bool Enabled { get; set; } public bool Enabled { get; set; }
[JsonProperty("channel_id")] [JsonProperty("channel_id")]
public ulong ChannelId { get; set; }
public ulong? ChannelId { get; set; }
} }
} }

+ 13
- 0
src/Discord.Net.Rest/API/Common/GuildWidget.cs View File

@@ -0,0 +1,13 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API
{
internal class GuildWidget
{
[JsonProperty("enabled")]
public bool Enabled { get; set; }
[JsonProperty("channel_id")]
public ulong? ChannelId { get; set; }
}
}

+ 14
- 0
src/Discord.Net.Rest/API/Rest/ModifyGuildWidgetParams.cs View File

@@ -0,0 +1,14 @@
#pragma warning disable CS1591
using Newtonsoft.Json;

namespace Discord.API.Rest
{
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
internal class ModifyGuildWidgetParams
{
[JsonProperty("enabled")]
public Optional<bool> Enabled { get; set; }
[JsonProperty("channel")]
public Optional<ulong?> ChannelId { get; set; }
}
}

+ 13
- 5
src/Discord.Net.Rest/ClientHelper.cs View File

@@ -62,9 +62,9 @@ namespace Discord.Rest
} }
public static async Task<RestGuild> GetGuildAsync(BaseDiscordClient client, public static async Task<RestGuild> GetGuildAsync(BaseDiscordClient client,
ulong id, RequestOptions options)
ulong id, bool withCounts, RequestOptions options)
{ {
var model = await client.ApiClient.GetGuildAsync(id, options).ConfigureAwait(false);
var model = await client.ApiClient.GetGuildAsync(id, withCounts, options).ConfigureAwait(false);
if (model != null) if (model != null)
return RestGuild.Create(client, model); return RestGuild.Create(client, model);
return null; return null;
@@ -77,6 +77,14 @@ namespace Discord.Rest
return RestGuildEmbed.Create(model); return RestGuildEmbed.Create(model);
return null; return null;
} }
public static async Task<RestGuildWidget?> GetGuildWidgetAsync(BaseDiscordClient client,
ulong id, RequestOptions options)
{
var model = await client.ApiClient.GetGuildWidgetAsync(id, options).ConfigureAwait(false);
if (model != null)
return RestGuildWidget.Create(model);
return null;
}
public static IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(BaseDiscordClient client, public static IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(BaseDiscordClient client,
ulong? fromGuildId, int? limit, RequestOptions options) ulong? fromGuildId, int? limit, RequestOptions options)
{ {
@@ -106,13 +114,13 @@ namespace Discord.Rest
count: limit count: limit
); );
} }
public static async Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(BaseDiscordClient client, RequestOptions options)
public static async Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(BaseDiscordClient client, bool withCounts, RequestOptions options)
{ {
var summaryModels = await GetGuildSummariesAsync(client, null, null, options).FlattenAsync().ConfigureAwait(false); var summaryModels = await GetGuildSummariesAsync(client, null, null, options).FlattenAsync().ConfigureAwait(false);
var guilds = ImmutableArray.CreateBuilder<RestGuild>(); var guilds = ImmutableArray.CreateBuilder<RestGuild>();
foreach (var summaryModel in summaryModels) foreach (var summaryModel in summaryModels)
{ {
var guildModel = await client.ApiClient.GetGuildAsync(summaryModel.Id).ConfigureAwait(false);
var guildModel = await client.ApiClient.GetGuildAsync(summaryModel.Id, withCounts).ConfigureAwait(false);
if (guildModel != null) if (guildModel != null)
guilds.Add(RestGuild.Create(client, guildModel)); guilds.Add(RestGuild.Create(client, guildModel));
} }
@@ -140,7 +148,7 @@ namespace Discord.Rest
public static async Task<RestGuildUser> GetGuildUserAsync(BaseDiscordClient client, public static async Task<RestGuildUser> GetGuildUserAsync(BaseDiscordClient client,
ulong guildId, ulong id, RequestOptions options) ulong guildId, ulong id, RequestOptions options)
{ {
var guild = await GetGuildAsync(client, guildId, options).ConfigureAwait(false);
var guild = await GetGuildAsync(client, guildId, false, options).ConfigureAwait(false);
if (guild == null) if (guild == null)
return null; return null;




+ 28
- 2
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -789,7 +789,7 @@ namespace Discord.API
} }


//Guilds //Guilds
public async Task<Guild> GetGuildAsync(ulong guildId, RequestOptions options = null)
public async Task<Guild> GetGuildAsync(ulong guildId, bool withCounts, RequestOptions options = null)
{ {
Preconditions.NotEqual(guildId, 0, nameof(guildId)); Preconditions.NotEqual(guildId, 0, nameof(guildId));
options = RequestOptions.CreateOrClone(options); options = RequestOptions.CreateOrClone(options);
@@ -797,7 +797,7 @@ namespace Discord.API
try try
{ {
var ids = new BucketIds(guildId: guildId); var ids = new BucketIds(guildId: guildId);
return await SendAsync<Guild>("GET", () => $"guilds/{guildId}", ids, options: options).ConfigureAwait(false);
return await SendAsync<Guild>("GET", () => $"guilds/{guildId}?with_counts={(withCounts ? "true" : "false")}", ids, options: options).ConfigureAwait(false);
} }
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; } catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
} }
@@ -935,6 +935,32 @@ namespace Discord.API
return await SendJsonAsync<GuildEmbed>("PATCH", () => $"guilds/{guildId}/embed", args, ids, options: options).ConfigureAwait(false); return await SendJsonAsync<GuildEmbed>("PATCH", () => $"guilds/{guildId}/embed", args, ids, options: options).ConfigureAwait(false);
} }


//Guild Widget
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception>
public async Task<GuildWidget> GetGuildWidgetAsync(ulong guildId, RequestOptions options = null)
{
Preconditions.NotEqual(guildId, 0, nameof(guildId));
options = RequestOptions.CreateOrClone(options);

try
{
var ids = new BucketIds(guildId: guildId);
return await SendAsync<GuildWidget>("GET", () => $"guilds/{guildId}/widget", ids, options: options).ConfigureAwait(false);
}
catch (HttpException ex) when (ex.HttpCode == HttpStatusCode.NotFound) { return null; }
}
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception>
/// <exception cref="ArgumentNullException"><paramref name="args"/> must not be <see langword="null"/>.</exception>
public async Task<GuildWidget> ModifyGuildWidgetAsync(ulong guildId, Rest.ModifyGuildWidgetParams args, RequestOptions options = null)
{
Preconditions.NotNull(args, nameof(args));
Preconditions.NotEqual(guildId, 0, nameof(guildId));
options = RequestOptions.CreateOrClone(options);

var ids = new BucketIds(guildId: guildId);
return await SendJsonAsync<GuildWidget>("PATCH", () => $"guilds/{guildId}/widget", args, ids, options: options).ConfigureAwait(false);
}

//Guild Integrations //Guild Integrations
/// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception> /// <exception cref="ArgumentException"><paramref name="guildId"/> must not be equal to zero.</exception>
public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null) public async Task<IReadOnlyCollection<Integration>> GetGuildIntegrationsAsync(ulong guildId, RequestOptions options = null)


+ 10
- 2
src/Discord.Net.Rest/DiscordRestClient.cs View File

@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Immutable; using System.Collections.Immutable;
using System.IO; using System.IO;
@@ -76,15 +77,22 @@ namespace Discord.Rest
=> ClientHelper.GetInviteAsync(this, inviteId, options); => ClientHelper.GetInviteAsync(this, inviteId, options);


public Task<RestGuild> GetGuildAsync(ulong id, RequestOptions options = null) public Task<RestGuild> GetGuildAsync(ulong id, RequestOptions options = null)
=> ClientHelper.GetGuildAsync(this, id, options);
=> ClientHelper.GetGuildAsync(this, id, false, options);
public Task<RestGuild> GetGuildAsync(ulong id, bool withCounts, RequestOptions options = null)
=> ClientHelper.GetGuildAsync(this, id, withCounts, options);
[Obsolete("This endpoint is deprecated, use GetGuildWidgetAsync instead.")]
public Task<RestGuildEmbed?> GetGuildEmbedAsync(ulong id, RequestOptions options = null) public Task<RestGuildEmbed?> GetGuildEmbedAsync(ulong id, RequestOptions options = null)
=> ClientHelper.GetGuildEmbedAsync(this, id, options); => ClientHelper.GetGuildEmbedAsync(this, id, options);
public Task<RestGuildWidget?> GetGuildWidgetAsync(ulong id, RequestOptions options = null)
=> ClientHelper.GetGuildWidgetAsync(this, id, options);
public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(RequestOptions options = null) public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(RequestOptions options = null)
=> ClientHelper.GetGuildSummariesAsync(this, null, null, options); => ClientHelper.GetGuildSummariesAsync(this, null, null, options);
public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(ulong fromGuildId, int limit, RequestOptions options = null) public IAsyncEnumerable<IReadOnlyCollection<RestUserGuild>> GetGuildSummariesAsync(ulong fromGuildId, int limit, RequestOptions options = null)
=> ClientHelper.GetGuildSummariesAsync(this, fromGuildId, limit, options); => ClientHelper.GetGuildSummariesAsync(this, fromGuildId, limit, options);
public Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(RequestOptions options = null) public Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(RequestOptions options = null)
=> ClientHelper.GetGuildsAsync(this, options);
=> ClientHelper.GetGuildsAsync(this, false, options);
public Task<IReadOnlyCollection<RestGuild>> GetGuildsAsync(bool withCounts, RequestOptions options = null)
=> ClientHelper.GetGuildsAsync(this, withCounts, options);
public Task<RestGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null) public Task<RestGuild> CreateGuildAsync(string name, IVoiceRegion region, Stream jpegIcon = null, RequestOptions options = null)
=> ClientHelper.CreateGuildAsync(this, name, region, jpegIcon, options); => ClientHelper.CreateGuildAsync(this, name, region, jpegIcon, options);




+ 22
- 0
src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs View File

@@ -5,6 +5,7 @@ using System.Collections.Immutable;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EmbedModel = Discord.API.GuildEmbed; using EmbedModel = Discord.API.GuildEmbed;
using WidgetModel = Discord.API.GuildWidget;
using Model = Discord.API.Guild; using Model = Discord.API.Guild;
using RoleModel = Discord.API.Role; using RoleModel = Discord.API.Role;
using ImageModel = Discord.API.Image; using ImageModel = Discord.API.Image;
@@ -99,6 +100,27 @@ namespace Discord.Rest


return await client.ApiClient.ModifyGuildEmbedAsync(guild.Id, apiArgs, options).ConfigureAwait(false); return await client.ApiClient.ModifyGuildEmbedAsync(guild.Id, apiArgs, options).ConfigureAwait(false);
} }
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
public static async Task<WidgetModel> ModifyWidgetAsync(IGuild guild, BaseDiscordClient client,
Action<GuildWidgetProperties> func, RequestOptions options)
{
if (func == null)
throw new ArgumentNullException(nameof(func));

var args = new GuildWidgetProperties();
func(args);
var apiArgs = new API.Rest.ModifyGuildWidgetParams
{
Enabled = args.Enabled
};

if (args.Channel.IsSpecified)
apiArgs.ChannelId = args.Channel.Value?.Id;
else if (args.ChannelId.IsSpecified)
apiArgs.ChannelId = args.ChannelId.Value;

return await client.ApiClient.ModifyGuildWidgetAsync(guild.Id, apiArgs, options).ConfigureAwait(false);
}
public static async Task ReorderChannelsAsync(IGuild guild, BaseDiscordClient client, public static async Task ReorderChannelsAsync(IGuild guild, BaseDiscordClient client,
IEnumerable<ReorderChannelProperties> args, RequestOptions options) IEnumerable<ReorderChannelProperties> args, RequestOptions options)
{ {


+ 157
- 6
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -7,6 +7,7 @@ using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using EmbedModel = Discord.API.GuildEmbed; using EmbedModel = Discord.API.GuildEmbed;
using WidgetModel = Discord.API.GuildWidget;
using Model = Discord.API.Guild; using Model = Discord.API.Guild;


namespace Discord.Rest namespace Discord.Rest
@@ -28,6 +29,8 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public bool IsEmbeddable { get; private set; } public bool IsEmbeddable { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool IsWidgetEnabled { get; private set; }
/// <inheritdoc />
public VerificationLevel VerificationLevel { get; private set; } public VerificationLevel VerificationLevel { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public MfaLevel MfaLevel { get; private set; } public MfaLevel MfaLevel { get; private set; }
@@ -41,8 +44,14 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public ulong? EmbedChannelId { get; private set; } public ulong? EmbedChannelId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ulong? WidgetChannelId { get; private set; }
/// <inheritdoc />
public ulong? SystemChannelId { get; private set; } public ulong? SystemChannelId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ulong? RulesChannelId { get; private set; }
/// <inheritdoc />
public ulong? PublicUpdatesChannelId { get; private set; }
/// <inheritdoc />
public ulong OwnerId { get; private set; } public ulong OwnerId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string VoiceRegionId { get; private set; } public string VoiceRegionId { get; private set; }
@@ -50,6 +59,8 @@ namespace Discord.Rest
public string IconId { get; private set; } public string IconId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string SplashId { get; private set; } public string SplashId { get; private set; }
/// <inheritdoc />
public string DiscoverySplashId { get; private set; }
internal bool Available { get; private set; } internal bool Available { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ulong? ApplicationId { get; private set; } public ulong? ApplicationId { get; private set; }
@@ -67,6 +78,16 @@ namespace Discord.Rest
public int PremiumSubscriptionCount { get; private set; } public int PremiumSubscriptionCount { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string PreferredLocale { get; private set; } public string PreferredLocale { get; private set; }
/// <inheritdoc />
public int? MaxPresences { get; private set; }
/// <inheritdoc />
public int? MaxMembers { get; private set; }
/// <inheritdoc />
public int? MaxVideoChannelUsers { get; private set; }
/// <inheritdoc />
public int? ApproximateMemberCount { get; private set; }
/// <inheritdoc />
public int? ApproximatePresenceCount { get; private set; }


/// <inheritdoc /> /// <inheritdoc />
public CultureInfo PreferredCulture { get; private set; } public CultureInfo PreferredCulture { get; private set; }
@@ -81,6 +102,8 @@ namespace Discord.Rest
/// <inheritdoc /> /// <inheritdoc />
public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId); public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
/// <inheritdoc /> /// <inheritdoc />
public string DiscoverySplashUrl => CDN.GetGuildDiscoverySplashUrl(Id, DiscoverySplashId);
/// <inheritdoc />
public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId); public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId);


/// <summary> /// <summary>
@@ -110,15 +133,24 @@ namespace Discord.Rest
internal void Update(Model model) internal void Update(Model model)
{ {
AFKChannelId = model.AFKChannelId; AFKChannelId = model.AFKChannelId;
EmbedChannelId = model.EmbedChannelId;
if (model.EmbedChannelId.IsSpecified)
EmbedChannelId = model.EmbedChannelId.Value;
if (model.WidgetChannelId.IsSpecified)
WidgetChannelId = model.WidgetChannelId.Value;
SystemChannelId = model.SystemChannelId; SystemChannelId = model.SystemChannelId;
RulesChannelId = model.RulesChannelId;
PublicUpdatesChannelId = model.PublicUpdatesChannelId;
AFKTimeout = model.AFKTimeout; AFKTimeout = model.AFKTimeout;
IsEmbeddable = model.EmbedEnabled;
if (model.EmbedEnabled.IsSpecified)
IsEmbeddable = model.EmbedEnabled.Value;
if (model.WidgetEnabled.IsSpecified)
IsWidgetEnabled = model.WidgetEnabled.Value;
IconId = model.Icon; IconId = model.Icon;
Name = model.Name; Name = model.Name;
OwnerId = model.OwnerId; OwnerId = model.OwnerId;
VoiceRegionId = model.Region; VoiceRegionId = model.Region;
SplashId = model.Splash; SplashId = model.Splash;
DiscoverySplashId = model.DiscoverySplash;
VerificationLevel = model.VerificationLevel; VerificationLevel = model.VerificationLevel;
MfaLevel = model.MfaLevel; MfaLevel = model.MfaLevel;
DefaultMessageNotifications = model.DefaultMessageNotifications; DefaultMessageNotifications = model.DefaultMessageNotifications;
@@ -130,8 +162,18 @@ namespace Discord.Rest
SystemChannelFlags = model.SystemChannelFlags; SystemChannelFlags = model.SystemChannelFlags;
Description = model.Description; Description = model.Description;
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault();
if (model.MaxPresences.IsSpecified)
MaxPresences = model.MaxPresences.Value ?? 25000;
if (model.MaxMembers.IsSpecified)
MaxMembers = model.MaxMembers.Value;
if (model.MaxVideoChannelUsers.IsSpecified)
MaxVideoChannelUsers = model.MaxVideoChannelUsers.Value;
PreferredLocale = model.PreferredLocale; PreferredLocale = model.PreferredLocale;
PreferredCulture = new CultureInfo(PreferredLocale); PreferredCulture = new CultureInfo(PreferredLocale);
if (model.ApproximateMemberCount.IsSpecified)
ApproximateMemberCount = model.ApproximateMemberCount.Value;
if (model.ApproximatePresenceCount.IsSpecified)
ApproximatePresenceCount = model.ApproximatePresenceCount.Value;


if (model.Emojis != null) if (model.Emojis != null)
{ {
@@ -163,11 +205,30 @@ namespace Discord.Rest
EmbedChannelId = model.ChannelId; EmbedChannelId = model.ChannelId;
IsEmbeddable = model.Enabled; IsEmbeddable = model.Enabled;
} }
internal void Update(WidgetModel model)
{
WidgetChannelId = model.ChannelId;
IsWidgetEnabled = model.Enabled;
}


//General //General
/// <inheritdoc /> /// <inheritdoc />
public async Task UpdateAsync(RequestOptions options = null) public async Task UpdateAsync(RequestOptions options = null)
=> Update(await Discord.ApiClient.GetGuildAsync(Id, options).ConfigureAwait(false));
=> Update(await Discord.ApiClient.GetGuildAsync(Id, false, options).ConfigureAwait(false));
/// <summary>
/// Updates this object's properties with its current state.
/// </summary>
/// <param name="withCounts">
/// If true, <see cref="ApproximateMemberCount"/> and <see cref="ApproximatePresenceCount"/>
/// will be updated as well.
/// </param>
/// <param name="options">The options to be used when sending the request.</param>
/// <remarks>
/// If <paramref name="withCounts"/> is true, <see cref="ApproximateMemberCount"/> and
/// <see cref="ApproximatePresenceCount"/> will be updated as well.
/// </remarks>
public async Task UpdateAsync(bool withCounts, RequestOptions options = null)
=> Update(await Discord.ApiClient.GetGuildAsync(Id, withCounts, options).ConfigureAwait(false));
/// <inheritdoc /> /// <inheritdoc />
public Task DeleteAsync(RequestOptions options = null) public Task DeleteAsync(RequestOptions options = null)
=> GuildHelper.DeleteAsync(this, Discord, options); => GuildHelper.DeleteAsync(this, Discord, options);
@@ -182,12 +243,21 @@ namespace Discord.Rest


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
[Obsolete("This endpoint is deprecated, use ModifyWidgetAsync instead.")]
public async Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null) public async Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null)
{ {
var model = await GuildHelper.ModifyEmbedAsync(this, Discord, func, options).ConfigureAwait(false); var model = await GuildHelper.ModifyEmbedAsync(this, Discord, func, options).ConfigureAwait(false);
Update(model); Update(model);
} }


/// <inheritdoc />
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
public async Task ModifyWidgetAsync(Action<GuildWidgetProperties> func, RequestOptions options = null)
{
var model = await GuildHelper.ModifyWidgetAsync(this, Discord, func, options).ConfigureAwait(false);
Update(model);
}

/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentNullException"><paramref name="args" /> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="args" /> is <c>null</c>.</exception>
public async Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null) public async Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null)
@@ -401,6 +471,7 @@ namespace Discord.Rest
/// A task that represents the asynchronous get operation. The task result contains the embed channel set /// A task that represents the asynchronous get operation. The task result contains the embed channel set
/// within the server's widget settings; <c>null</c> if none is set. /// within the server's widget settings; <c>null</c> if none is set.
/// </returns> /// </returns>
[Obsolete("This endpoint is deprecated, use GetWidgetChannelAsync instead.")]
public async Task<RestGuildChannel> GetEmbedChannelAsync(RequestOptions options = null) public async Task<RestGuildChannel> GetEmbedChannelAsync(RequestOptions options = null)
{ {
var embedId = EmbedChannelId; var embedId = EmbedChannelId;
@@ -410,12 +481,28 @@ namespace Discord.Rest
} }


/// <summary> /// <summary>
/// Gets the first viewable text channel in this guild.
/// Gets the widget channel (i.e. the channel set in the guild's widget settings) in this guild.
/// </summary> /// </summary>
/// <param name="options">The options to be used when sending the request.</param> /// <param name="options">The options to be used when sending the request.</param>
/// <returns> /// <returns>
/// A task that represents the asynchronous get operation. The task result contains the first viewable text
/// channel in this guild; <c>null</c> if none is found.
/// A task that represents the asynchronous get operation. The task result contains the widget channel set
/// within the server's widget settings; <c>null</c> if none is set.
/// </returns>
public async Task<RestGuildChannel> GetWidgetChannelAsync(RequestOptions options = null)
{
var widgetChannelId = WidgetChannelId;
if (widgetChannelId.HasValue)
return await GuildHelper.GetChannelAsync(this, Discord, widgetChannelId.Value, options).ConfigureAwait(false);
return null;
}

/// <summary>
/// Gets the text channel where guild notices such as welcome messages and boost events are posted.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the text channel
/// where guild notices such as welcome messages and boost events are poste; <c>null</c> if none is found.
/// </returns> /// </returns>
public async Task<RestTextChannel> GetSystemChannelAsync(RequestOptions options = null) public async Task<RestTextChannel> GetSystemChannelAsync(RequestOptions options = null)
{ {
@@ -427,6 +514,45 @@ namespace Discord.Rest
} }
return null; return null;
} }

/// <summary>
/// Gets the text channel where guilds with the "PUBLIC" feature can display rules and/or guidelines.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the text channel
/// where guilds with the "PUBLIC" feature can display rules and/or guidelines; <c>null</c> if none is set.
/// </returns>
public async Task<RestTextChannel> GetRulesChannelAsync(RequestOptions options = null)
{
var rulesChannelId = RulesChannelId;
if (rulesChannelId.HasValue)
{
var channel = await GuildHelper.GetChannelAsync(this, Discord, rulesChannelId.Value, options).ConfigureAwait(false);
return channel as RestTextChannel;
}
return null;
}

/// <summary>
/// Gets the text channel channel where admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord.
/// </summary>
/// <param name="options">The options to be used when sending the request.</param>
/// <returns>
/// A task that represents the asynchronous get operation. The task result contains the text channel channel where
/// admins and moderators of guilds with the "PUBLIC" feature receive notices from Discord; <c>null</c> if none is set.
/// </returns>
public async Task<RestTextChannel> GetPublicUpdatesChannelAsync(RequestOptions options = null)
{
var publicUpdatesChannelId = PublicUpdatesChannelId;
if (publicUpdatesChannelId.HasValue)
{
var channel = await GuildHelper.GetChannelAsync(this, Discord, publicUpdatesChannelId.Value, options).ConfigureAwait(false);
return channel as RestTextChannel;
}
return null;
}

/// <summary> /// <summary>
/// Creates a new text channel in this guild. /// Creates a new text channel in this guild.
/// </summary> /// </summary>
@@ -808,6 +934,7 @@ namespace Discord.Rest
return null; return null;
} }
/// <inheritdoc /> /// <inheritdoc />
[Obsolete("This endpoint is deprecated, use GetWidgetChannelAsync instead.")]
async Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) async Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options)
{ {
if (mode == CacheMode.AllowDownload) if (mode == CacheMode.AllowDownload)
@@ -816,6 +943,14 @@ namespace Discord.Rest
return null; return null;
} }
/// <inheritdoc /> /// <inheritdoc />
async Task<IGuildChannel> IGuild.GetWidgetChannelAsync(CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetWidgetChannelAsync(options).ConfigureAwait(false);
else
return null;
}
/// <inheritdoc />
async Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) async Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options)
{ {
if (mode == CacheMode.AllowDownload) if (mode == CacheMode.AllowDownload)
@@ -824,6 +959,22 @@ namespace Discord.Rest
return null; return null;
} }
/// <inheritdoc /> /// <inheritdoc />
async Task<ITextChannel> IGuild.GetRulesChannelAsync(CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetRulesChannelAsync(options).ConfigureAwait(false);
else
return null;
}
/// <inheritdoc />
async Task<ITextChannel> IGuild.GetPublicUpdatesChannelAsync(CacheMode mode, RequestOptions options)
{
if (mode == CacheMode.AllowDownload)
return await GetPublicUpdatesChannelAsync(options).ConfigureAwait(false);
else
return null;
}
/// <inheritdoc />
async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options) async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options)
=> await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />


+ 25
- 0
src/Discord.Net.Rest/Entities/Guilds/RestGuildWidget.cs View File

@@ -0,0 +1,25 @@
using System.Diagnostics;
using Model = Discord.API.GuildWidget;

namespace Discord.Rest
{
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public struct RestGuildWidget
{
public bool IsEnabled { get; private set; }
public ulong? ChannelId { get; private set; }

internal RestGuildWidget(bool isEnabled, ulong? channelId)
{
ChannelId = channelId;
IsEnabled = isEnabled;
}
internal static RestGuildWidget Create(Model model)
{
return new RestGuildWidget(model.Enabled, model.ChannelId);
}

public override string ToString() => ChannelId?.ToString() ?? "Unknown";
private string DebuggerDisplay => $"{ChannelId} ({(IsEnabled ? "Enabled" : "Disabled")})";
}
}

+ 102
- 2
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -48,6 +48,8 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public bool IsEmbeddable { get; private set; } public bool IsEmbeddable { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public bool IsWidgetEnabled { get; private set; }
/// <inheritdoc />
public VerificationLevel VerificationLevel { get; private set; } public VerificationLevel VerificationLevel { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public MfaLevel MfaLevel { get; private set; } public MfaLevel MfaLevel { get; private set; }
@@ -83,7 +85,10 @@ namespace Discord.WebSocket


internal ulong? AFKChannelId { get; private set; } internal ulong? AFKChannelId { get; private set; }
internal ulong? EmbedChannelId { get; private set; } internal ulong? EmbedChannelId { get; private set; }
internal ulong? WidgetChannelId { get; private set; }
internal ulong? SystemChannelId { get; private set; } internal ulong? SystemChannelId { get; private set; }
internal ulong? RulesChannelId { get; private set; }
internal ulong? PublicUpdatesChannelId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public ulong OwnerId { get; private set; } public ulong OwnerId { get; private set; }
/// <summary> Gets the user that owns this guild. </summary> /// <summary> Gets the user that owns this guild. </summary>
@@ -95,6 +100,8 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public string SplashId { get; private set; } public string SplashId { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string DiscoverySplashId { get; private set; }
/// <inheritdoc />
public PremiumTier PremiumTier { get; private set; } public PremiumTier PremiumTier { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string BannerId { get; private set; } public string BannerId { get; private set; }
@@ -108,6 +115,12 @@ namespace Discord.WebSocket
public int PremiumSubscriptionCount { get; private set; } public int PremiumSubscriptionCount { get; private set; }
/// <inheritdoc /> /// <inheritdoc />
public string PreferredLocale { get; private set; } public string PreferredLocale { get; private set; }
/// <inheritdoc />
public int? MaxPresences { get; private set; }
/// <inheritdoc />
public int? MaxMembers { get; private set; }
/// <inheritdoc />
public int? MaxVideoChannelUsers { get; private set; }


/// <inheritdoc /> /// <inheritdoc />
public CultureInfo PreferredCulture { get; private set; } public CultureInfo PreferredCulture { get; private set; }
@@ -119,6 +132,8 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId); public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
/// <inheritdoc /> /// <inheritdoc />
public string DiscoverySplashUrl => CDN.GetGuildDiscoverySplashUrl(Id, DiscoverySplashId);
/// <inheritdoc />
public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId); public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId);
/// <summary> Indicates whether the client has all the members downloaded to the local guild cache. </summary> /// <summary> Indicates whether the client has all the members downloaded to the local guild cache. </summary>
public bool HasAllMembers => MemberCount == DownloadedMemberCount;// _downloaderPromise.Task.IsCompleted; public bool HasAllMembers => MemberCount == DownloadedMemberCount;// _downloaderPromise.Task.IsCompleted;
@@ -168,6 +183,7 @@ namespace Discord.WebSocket
/// <returns> /// <returns>
/// A channel set within the server's widget settings; <c>null</c> if none is set. /// A channel set within the server's widget settings; <c>null</c> if none is set.
/// </returns> /// </returns>
[Obsolete("This property is deprecated, use WidgetChannel instead.")]
public SocketGuildChannel EmbedChannel public SocketGuildChannel EmbedChannel
{ {
get get
@@ -177,6 +193,20 @@ namespace Discord.WebSocket
} }
} }
/// <summary> /// <summary>
/// Gets the widget channel (i.e. the channel set in the guild's widget settings) in this guild.
/// </summary>
/// <returns>
/// A channel set within the server's widget settings; <c>null</c> if none is set.
/// </returns>
public SocketGuildChannel WidgetChannel
{
get
{
var id = WidgetChannelId;
return id.HasValue ? GetChannel(id.Value) : null;
}
}
/// <summary>
/// Gets the system channel where randomized welcome messages are sent in this guild. /// Gets the system channel where randomized welcome messages are sent in this guild.
/// </summary> /// </summary>
/// <returns> /// <returns>
@@ -191,6 +221,36 @@ namespace Discord.WebSocket
} }
} }
/// <summary> /// <summary>
/// Gets the channel with the guild rules.
/// </summary>
/// <returns>
/// A text channel with the guild rules; <c>null</c> if none is set.
/// </returns>
public SocketTextChannel RulesChannel
{
get
{
var id = RulesChannelId;
return id.HasValue ? GetTextChannel(id.Value) : null;
}
}
/// <summary>
/// Gets the channel where admins and moderators of guilds with the "PUBLIC"
/// feature receive notices from Discord.
/// </summary>
/// <returns>
/// A text channel where admins and moderators of guilds with the "PUBLIC"
/// feature receive notices from Discord; <c>null</c> if none is set.
/// </returns>
public SocketTextChannel PublicUpdatesChannel
{
get
{
var id = PublicUpdatesChannelId;
return id.HasValue ? GetTextChannel(id.Value) : null;
}
}
/// <summary>
/// Gets a collection of all text channels in this guild. /// Gets a collection of all text channels in this guild.
/// </summary> /// </summary>
/// <returns> /// <returns>
@@ -360,15 +420,24 @@ namespace Discord.WebSocket
internal void Update(ClientState state, Model model) internal void Update(ClientState state, Model model)
{ {
AFKChannelId = model.AFKChannelId; AFKChannelId = model.AFKChannelId;
EmbedChannelId = model.EmbedChannelId;
if (model.EmbedChannelId.IsSpecified)
EmbedChannelId = model.EmbedChannelId.Value;
if (model.WidgetChannelId.IsSpecified)
WidgetChannelId = model.WidgetChannelId.Value;
SystemChannelId = model.SystemChannelId; SystemChannelId = model.SystemChannelId;
RulesChannelId = model.RulesChannelId;
PublicUpdatesChannelId = model.PublicUpdatesChannelId;
AFKTimeout = model.AFKTimeout; AFKTimeout = model.AFKTimeout;
IsEmbeddable = model.EmbedEnabled;
if (model.EmbedEnabled.IsSpecified)
IsEmbeddable = model.EmbedEnabled.Value;
if (model.WidgetEnabled.IsSpecified)
IsWidgetEnabled = model.WidgetEnabled.Value;
IconId = model.Icon; IconId = model.Icon;
Name = model.Name; Name = model.Name;
OwnerId = model.OwnerId; OwnerId = model.OwnerId;
VoiceRegionId = model.Region; VoiceRegionId = model.Region;
SplashId = model.Splash; SplashId = model.Splash;
DiscoverySplashId = model.DiscoverySplash;
VerificationLevel = model.VerificationLevel; VerificationLevel = model.VerificationLevel;
MfaLevel = model.MfaLevel; MfaLevel = model.MfaLevel;
DefaultMessageNotifications = model.DefaultMessageNotifications; DefaultMessageNotifications = model.DefaultMessageNotifications;
@@ -380,6 +449,12 @@ namespace Discord.WebSocket
SystemChannelFlags = model.SystemChannelFlags; SystemChannelFlags = model.SystemChannelFlags;
Description = model.Description; Description = model.Description;
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault(); PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault();
if (model.MaxPresences.IsSpecified)
MaxPresences = model.MaxPresences.Value ?? 25000;
if (model.MaxMembers.IsSpecified)
MaxMembers = model.MaxMembers.Value;
if (model.MaxVideoChannelUsers.IsSpecified)
MaxVideoChannelUsers = model.MaxVideoChannelUsers.Value;
PreferredLocale = model.PreferredLocale; PreferredLocale = model.PreferredLocale;
PreferredCulture = new CultureInfo(PreferredLocale); PreferredCulture = new CultureInfo(PreferredLocale);


@@ -453,9 +528,14 @@ namespace Discord.WebSocket


/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception> /// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
[Obsolete("This endpoint is deprecated, use ModifyWidgetAsync instead.")]
public Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null) public Task ModifyEmbedAsync(Action<GuildEmbedProperties> func, RequestOptions options = null)
=> GuildHelper.ModifyEmbedAsync(this, Discord, func, options); => GuildHelper.ModifyEmbedAsync(this, Discord, func, options);
/// <inheritdoc /> /// <inheritdoc />
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>
public Task ModifyWidgetAsync(Action<GuildWidgetProperties> func, RequestOptions options = null)
=> GuildHelper.ModifyWidgetAsync(this, Discord, func, options);
/// <inheritdoc />
public Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null) public Task ReorderChannelsAsync(IEnumerable<ReorderChannelProperties> args, RequestOptions options = null)
=> GuildHelper.ReorderChannelsAsync(this, Discord, args, options); => GuildHelper.ReorderChannelsAsync(this, Discord, args, options);
/// <inheritdoc /> /// <inheritdoc />
@@ -1133,11 +1213,21 @@ namespace Discord.WebSocket
/// <inheritdoc /> /// <inheritdoc />
ulong? IGuild.EmbedChannelId => EmbedChannelId; ulong? IGuild.EmbedChannelId => EmbedChannelId;
/// <inheritdoc /> /// <inheritdoc />
ulong? IGuild.WidgetChannelId => WidgetChannelId;
/// <inheritdoc />
ulong? IGuild.SystemChannelId => SystemChannelId; ulong? IGuild.SystemChannelId => SystemChannelId;
/// <inheritdoc /> /// <inheritdoc />
ulong? IGuild.RulesChannelId => RulesChannelId;
/// <inheritdoc />
ulong? IGuild.PublicUpdatesChannelId => PublicUpdatesChannelId;
/// <inheritdoc />
IRole IGuild.EveryoneRole => EveryoneRole; IRole IGuild.EveryoneRole => EveryoneRole;
/// <inheritdoc /> /// <inheritdoc />
IReadOnlyCollection<IRole> IGuild.Roles => Roles; IReadOnlyCollection<IRole> IGuild.Roles => Roles;
/// <inheritdoc />
int? IGuild.ApproximateMemberCount => null;
/// <inheritdoc />
int? IGuild.ApproximatePresenceCount => null;


/// <inheritdoc /> /// <inheritdoc />
async Task<IReadOnlyCollection<IBan>> IGuild.GetBansAsync(RequestOptions options) async Task<IReadOnlyCollection<IBan>> IGuild.GetBansAsync(RequestOptions options)
@@ -1177,12 +1267,22 @@ namespace Discord.WebSocket
Task<ITextChannel> IGuild.GetDefaultChannelAsync(CacheMode mode, RequestOptions options) Task<ITextChannel> IGuild.GetDefaultChannelAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<ITextChannel>(DefaultChannel); => Task.FromResult<ITextChannel>(DefaultChannel);
/// <inheritdoc /> /// <inheritdoc />
[Obsolete("This method is deprecated, use GetWidgetChannelAsync instead.")]
Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options) Task<IGuildChannel> IGuild.GetEmbedChannelAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildChannel>(EmbedChannel); => Task.FromResult<IGuildChannel>(EmbedChannel);
/// <inheritdoc /> /// <inheritdoc />
Task<IGuildChannel> IGuild.GetWidgetChannelAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<IGuildChannel>(WidgetChannel);
/// <inheritdoc />
Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options) Task<ITextChannel> IGuild.GetSystemChannelAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<ITextChannel>(SystemChannel); => Task.FromResult<ITextChannel>(SystemChannel);
/// <inheritdoc /> /// <inheritdoc />
Task<ITextChannel> IGuild.GetRulesChannelAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<ITextChannel>(RulesChannel);
/// <inheritdoc />
Task<ITextChannel> IGuild.GetPublicUpdatesChannelAsync(CacheMode mode, RequestOptions options)
=> Task.FromResult<ITextChannel>(PublicUpdatesChannel);
/// <inheritdoc />
async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options) async Task<ITextChannel> IGuild.CreateTextChannelAsync(string name, Action<TextChannelProperties> func, RequestOptions options)
=> await CreateTextChannelAsync(name, func, options).ConfigureAwait(false); => await CreateTextChannelAsync(name, func, options).ConfigureAwait(false);
/// <inheritdoc /> /// <inheritdoc />


Loading…
Cancel
Save