Browse Source

[ifcbrk] feature: BOOST (#1319)

* add new MessageTypes

* Add new properties to the updated models

* add the SystemChannelMessageDeny

unsure if there would be a better name for this enum, given it's inverted nature, open for suggestions

* add PremiumTier flag, add Guild description property

* add method for getting vanity image from CDN

* make the size of GetGuildVanityUrl optional

* lint: remove commented out code from prev commit

* add a None flag to SystemChannelMessage enum

* implement the new modify guild params

* implement additional model properties in IGuild types

* implement GuildMember PremiumSince

* docs: reword size param explanation

* add extension methods that make it easier to check the SystemChannelMessage flags for end users

because the flag is inverted, this ideally should make it easier for the user. it may also be useful to do something similar for modifying this property

* docs: correct typo from copy-paste

* add the premium_subscription_count property

* fix vanity url code and banner switchup

a mistake was made somewhere, that's all I know for sure

* clarify remark on inverted logic for system channel flags

* fix PremiumSubscriptionCount optional value

* add another example to the systemchannelflags xmldoc remark

* docs: fix typos, clarify wording

* use DateTimeOffset for PremiumSince, follow conventions from other prop
tags/2.2.0
Chris Johnston Christopher F 5 years ago
parent
commit
faf23dee35
18 changed files with 252 additions and 5 deletions
  1. +17
    -1
      src/Discord.Net.Core/CDN.cs
  2. +14
    -0
      src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs
  3. +52
    -0
      src/Discord.Net.Core/Entities/Guilds/IGuild.cs
  4. +22
    -0
      src/Discord.Net.Core/Entities/Guilds/PremiumTier.cs
  5. +22
    -0
      src/Discord.Net.Core/Entities/Guilds/SystemChannelMessageDeny.cs
  6. +17
    -1
      src/Discord.Net.Core/Entities/Messages/MessageType.cs
  7. +7
    -0
      src/Discord.Net.Core/Entities/Users/IGuildUser.cs
  8. +24
    -0
      src/Discord.Net.Core/Extensions/GuildExtensions.cs
  9. +13
    -0
      src/Discord.Net.Rest/API/Common/Guild.cs
  10. +3
    -1
      src/Discord.Net.Rest/API/Common/GuildMember.cs
  11. +2
    -0
      src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs
  12. +5
    -1
      src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
  13. +20
    -0
      src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
  14. +5
    -1
      src/Discord.Net.Rest/Entities/Users/RestGuildUser.cs
  15. +2
    -0
      src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs
  16. +20
    -0
      src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
  17. +5
    -0
      src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
  18. +2
    -0
      src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs

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

@@ -23,7 +23,7 @@ namespace Discord
/// </summary>
/// <param name="userId">The user snowflake identifier.</param>
/// <param name="avatarId">The avatar identifier.</param>
/// <param name="size">The size of the image to return in. This can be any power of two between 16 and 2048.</param>
/// <param name="size">The size of the image to return in horizontal pixels. This can be any power of two between 16 and 2048.</param>
/// <param name="format">The format to return.</param>
/// <returns>
/// A URL pointing to the user's avatar in the specified size.
@@ -76,6 +76,22 @@ namespace Discord
/// </returns>
public static string GetChannelIconUrl(ulong channelId, string iconId)
=> iconId != null ? $"{DiscordConfig.CDNUrl}channel-icons/{channelId}/{iconId}.jpg" : null;

/// <summary>
/// Returns a guild banner URL.
/// </summary>
/// <param name="guildId">The guild snowflake identifier.</param>
/// <param name="bannerId">The banner image identifier.</param>
/// <param name="size">The size of the image to return in horizontal pixels. This can be any power of two between 16 and 2048 inclusive.</param>
/// <returns>
/// A URL pointing to the guild's banner image.
/// </returns>
public static string GetGuildBannerUrl(ulong guildId, string bannerId, ushort? size = null)
{
if (!string.IsNullOrEmpty(bannerId))
return $"{DiscordConfig.CDNUrl}banners/{guildId}/{bannerId}.jpg" + (size.HasValue ? $"?size={size}" : string.Empty);
return null;
}
/// <summary>
/// Returns an emoji URL.
/// </summary>


+ 14
- 0
src/Discord.Net.Core/Entities/Guilds/GuildProperties.cs View File

@@ -70,5 +70,19 @@ namespace Discord
/// Gets or sets the explicit content filter level of this guild.
/// </summary>
public Optional<ExplicitContentFilterLevel> ExplicitContentFilter { get; set; }
/// <summary>
/// Gets or sets the flags that DISABLE types of system channel messages.
/// </summary>
/// <remarks>
/// These flags are inverted. Setting a flag will disable that system channel message from being sent.
/// A value of <see cref="SystemChannelMessageDeny.None"/> will allow all system channel message types to be sent,
/// given that the <see cref="SystemChannelId"/> has also been set.
/// A value of <see cref="SystemChannelMessageDeny.GuildBoost"/> will deny guild boost messages from being sent, and allow all
/// other types of messages.
/// Refer to the extension methods <see cref="GuildExtensions.GetGuildBoostMessagesEnabled(IGuild)"/> and
/// <see cref="GuildExtensions.GetWelcomeMessagesEnabled(IGuild)"/> to check if these system channel message types
/// are enabled, without the need to manipulate the logic of the flag.
/// </remarks>
public Optional<SystemChannelMessageDeny> SystemChannelFlags { get; set; }
}
}

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

@@ -196,6 +196,58 @@ namespace Discord
/// A read-only collection of roles found within this guild.
/// </returns>
IReadOnlyCollection<IRole> Roles { get; }
/// <summary>
/// Gets the tier of guild boosting in this guild.
/// </summary>
/// <returns>
/// The tier of guild boosting in this guild.
/// </returns>
PremiumTier PremiumTier { get; }
/// <summary>
/// Gets the identifier for this guilds banner image.
/// </summary>
/// <returns>
/// An identifier for the banner image; <c>null</c> if none is set.
/// </returns>
string BannerId { get; }
/// <summary>
/// Gets the URL of this guild's banner image.
/// </summary>
/// <returns>
/// A URL pointing to the guild's banner image; <c>null</c> if none is set.
/// </returns>
string BannerUrl { get; }
/// <summary>
/// Gets the code for this guild's vanity invite URL.
/// </summary>
/// <returns>
/// A string containing the vanity invite code for this guild; <c>null</c> if none is set.
/// </returns>
string VanityURLCode { get; }
/// <summary>
/// Gets the flags for the types of system channel messages that are disabled.
/// </summary>
/// <returns>
/// The flags for the types of system channel messages that are disabled.
/// </returns>
SystemChannelMessageDeny SystemChannelFlags { get; }
/// <summary>
/// Gets the description for the guild.
/// </summary>
/// <returns>
/// The description for the guild; <c>null</c> if none is set.
/// </returns>
string Description { get; }
/// <summary>
/// Gets the number of premium subscribers of this guild.
/// </summary>
/// <remarks>
/// This is the number of users who have boosted this guild.
/// </remarks>
/// <returns>
/// The number of premium subscribers of this guild.
/// </returns>
int PremiumSubscriptionCount { get; }

/// <summary>
/// Modifies this guild.


+ 22
- 0
src/Discord.Net.Core/Entities/Guilds/PremiumTier.cs View File

@@ -0,0 +1,22 @@
namespace Discord
{
public enum PremiumTier
{
/// <summary>
/// Used for guilds that have no guild boosts.
/// </summary>
None = 0,
/// <summary>
/// Used for guilds that have Tier 1 guild boosts.
/// </summary>
Tier1 = 1,
/// <summary>
/// Used for guilds that have Tier 2 guild boosts.
/// </summary>
Tier2 = 2,
/// <summary>
/// Used for guilds that have Tier 3 guild boosts.
/// </summary>
Tier3 = 3
}
}

+ 22
- 0
src/Discord.Net.Core/Entities/Guilds/SystemChannelMessageDeny.cs View File

@@ -0,0 +1,22 @@
using System;

namespace Discord
{
[Flags]
public enum SystemChannelMessageDeny
{
/// <summary>
/// Deny none of the system channel messages.
/// This will enable all of the system channel messages.
/// </summary>
None = 0,
/// <summary>
/// Deny the messages that are sent when a user joins the guild.
/// </summary>
WelcomeMessage = 0b1,
/// <summary>
/// Deny the messages that are sent when a user boosts the guild.
/// </summary>
GuildBoost = 0b10
}
}

+ 17
- 1
src/Discord.Net.Core/Entities/Messages/MessageType.cs View File

@@ -36,6 +36,22 @@ namespace Discord
/// <summary>
/// The message when a new member joined.
/// </summary>
GuildMemberJoin = 7
GuildMemberJoin = 7,
/// <summary>
/// The message for when a user boosts a guild.
/// </summary>
UserPremiumGuildSubscription = 8,
/// <summary>
/// The message for when a guild reaches Tier 1 of Nitro boosts.
/// </summary>
UserPremiumGuildSubscriptionTier1 = 9,
/// <summary>
/// The message for when a guild reaches Tier 2 of Nitro boosts.
/// </summary>
UserPremiumGuildSubscriptionTier2 = 10,
/// <summary>
/// The message for when a guild reaches Tier 3 of Nitro boosts.
/// </summary>
UserPremiumGuildSubscriptionTier3 = 11
}
}

+ 7
- 0
src/Discord.Net.Core/Entities/Users/IGuildUser.cs View File

@@ -48,6 +48,13 @@ namespace Discord
/// </returns>
ulong GuildId { get; }
/// <summary>
/// Gets the date and time for when this user's guild boost began.
/// </summary>
/// <returns>
/// A <see cref="DateTimeOffset"/> for when the user began boosting this guild; <c>null</c> if they are not boosting the guild.
/// </returns>
DateTimeOffset? PremiumSince { get; }
/// <summary>
/// Gets a collection of IDs for the roles that this user currently possesses in the guild.
/// </summary>
/// <remarks>


+ 24
- 0
src/Discord.Net.Core/Extensions/GuildExtensions.cs View File

@@ -0,0 +1,24 @@
namespace Discord
{
/// <summary>
/// An extension class for <see cref="IGuild"/>.
/// </summary>
public static class GuildExtensions
{
/// <summary>
/// Gets if welcome system messages are enabled.
/// </summary>
/// <param name="guild"> The guild to check. </param>
/// <returns> A <c>bool</c> indicating if the welcome messages are enabled in the system channel. </returns>
public static bool GetWelcomeMessagesEnabled(this IGuild guild)
=> !guild.SystemChannelFlags.HasFlag(SystemChannelMessageDeny.WelcomeMessage);

/// <summary>
/// Gets if guild boost system messages are enabled.
/// </summary>
/// <param name="guild"> The guild to check. </param>
/// <returns> A <c>bool</c> indicating if the guild boost messages are enabled in the system channel. </returns>
public static bool GetGuildBoostMessagesEnabled(this IGuild guild)
=> !guild.SystemChannelFlags.HasFlag(SystemChannelMessageDeny.GuildBoost);
}
}

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

@@ -45,5 +45,18 @@ namespace Discord.API
public ulong? ApplicationId { get; set; }
[JsonProperty("system_channel_id")]
public ulong? SystemChannelId { get; set; }
[JsonProperty("premium_tier")]
public PremiumTier PremiumTier { get; set; }
[JsonProperty("vanity_url_code")]
public string VanityURLCode { get; set; }
[JsonProperty("banner")]
public string Banner { get; set; }
[JsonProperty("description")]
public string Description { get; set; }
// this value is inverted, flags set will turn OFF features
[JsonProperty("system_channel_flags")]
public SystemChannelMessageDeny SystemChannelFlags { get; set; }
[JsonProperty("premium_subscription_count")]
public int? PremiumSubscriptionCount { get; set; }
}
}

+ 3
- 1
src/Discord.Net.Rest/API/Common/GuildMember.cs View File

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

@@ -18,5 +18,7 @@ namespace Discord.API
public Optional<bool> Deaf { get; set; }
[JsonProperty("mute")]
public Optional<bool> Mute { get; set; }
[JsonProperty("premium_since")]
public Optional<DateTimeOffset?> PremiumSince { get; set; }
}
}

+ 2
- 0
src/Discord.Net.Rest/API/Rest/ModifyGuildParams.cs View File

@@ -30,5 +30,7 @@ namespace Discord.API.Rest
public Optional<ulong> OwnerId { get; set; }
[JsonProperty("explicit_content_filter")]
public Optional<ExplicitContentFilterLevel> ExplicitContentFilter { get; set; }
[JsonProperty("system_channel_flags")]
public Optional<SystemChannelMessageDeny> SystemChannelFlags { get; set; }
}
}

+ 5
- 1
src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs View File

@@ -33,7 +33,8 @@ namespace Discord.Rest
Name = args.Name,
Splash = args.Splash.IsSpecified ? args.Splash.Value?.ToModel() : Optional.Create<ImageModel?>(),
VerificationLevel = args.VerificationLevel,
ExplicitContentFilter = args.ExplicitContentFilter
ExplicitContentFilter = args.ExplicitContentFilter,
SystemChannelFlags = args.SystemChannelFlags
};

if (args.AfkChannel.IsSpecified)
@@ -64,6 +65,9 @@ namespace Discord.Rest
if (args.ExplicitContentFilter.IsSpecified)
apiArgs.ExplicitContentFilter = args.ExplicitContentFilter.Value;

if (args.SystemChannelFlags.IsSpecified)
apiArgs.SystemChannelFlags = args.SystemChannelFlags.Value;

return await client.ApiClient.ModifyGuildAsync(guild.Id, apiArgs, options).ConfigureAwait(false);
}
/// <exception cref="ArgumentNullException"><paramref name="func"/> is <c>null</c>.</exception>


+ 20
- 0
src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs View File

@@ -52,6 +52,18 @@ namespace Discord.Rest
internal bool Available { get; private set; }
/// <inheritdoc />
public ulong? ApplicationId { get; private set; }
/// <inheritdoc />
public PremiumTier PremiumTier { get; private set; }
/// <inheritdoc />
public string BannerId { get; private set; }
/// <inheritdoc />
public string VanityURLCode { get; private set; }
/// <inheritdoc />
public SystemChannelMessageDeny SystemChannelFlags { get; private set; }
/// <inheritdoc />
public string Description { get; private set; }
/// <inheritdoc />
public int PremiumSubscriptionCount { get; private set; }

/// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
@@ -62,6 +74,8 @@ namespace Discord.Rest
public string IconUrl => CDN.GetGuildIconUrl(Id, IconId);
/// <inheritdoc />
public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
/// <inheritdoc />
public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId);

/// <summary>
/// Gets the built-in role containing all users in this guild.
@@ -104,6 +118,12 @@ namespace Discord.Rest
DefaultMessageNotifications = model.DefaultMessageNotifications;
ExplicitContentFilter = model.ExplicitContentFilter;
ApplicationId = model.ApplicationId;
PremiumTier = model.PremiumTier;
VanityURLCode = model.VanityURLCode;
BannerId = model.Banner;
SystemChannelFlags = model.SystemChannelFlags;
Description = model.Description;
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault();

if (model.Emojis != null)
{


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

@@ -14,6 +14,7 @@ namespace Discord.Rest
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class RestGuildUser : RestUser, IGuildUser
{
private long? _premiumSinceTicks;
private long? _joinedAtTicks;
private ImmutableArray<ulong> _roleIds;

@@ -24,7 +25,8 @@ namespace Discord.Rest
public bool IsDeafened { get; private set; }
/// <inheritdoc />
public bool IsMuted { get; private set; }

/// <inheritdoc />
public DateTimeOffset? PremiumSince => DateTimeUtils.FromTicks(_premiumSinceTicks);
/// <inheritdoc />
public ulong GuildId => Guild.Id;

@@ -69,6 +71,8 @@ namespace Discord.Rest
IsMuted = model.Mute.Value;
if (model.Roles.IsSpecified)
UpdateRoles(model.Roles.Value);
if (model.PremiumSince.IsSpecified)
_premiumSinceTicks = model.PremiumSince.Value?.UtcTicks;
}
private void UpdateRoles(ulong[] roleIds)
{


+ 2
- 0
src/Discord.Net.Rest/Entities/Users/RestWebhookUser.cs View File

@@ -13,6 +13,8 @@ namespace Discord.Rest
/// <inheritdoc />
public ulong WebhookId { get; }
internal IGuild Guild { get; }
/// <inheritdoc />
public DateTimeOffset? PremiumSince { get; private set; }

/// <inheritdoc />
public override bool IsWebhook => true;


+ 20
- 0
src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs View File

@@ -93,6 +93,18 @@ namespace Discord.WebSocket
public string IconId { get; private set; }
/// <inheritdoc />
public string SplashId { get; private set; }
/// <inheritdoc />
public PremiumTier PremiumTier { get; private set; }
/// <inheritdoc />
public string BannerId { get; private set; }
/// <inheritdoc />
public string VanityURLCode { get; private set; }
/// <inheritdoc />
public SystemChannelMessageDeny SystemChannelFlags { get; private set; }
/// <inheritdoc />
public string Description { get; private set; }
/// <inheritdoc />
public int PremiumSubscriptionCount { get; private set; }

/// <inheritdoc />
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
@@ -100,6 +112,8 @@ namespace Discord.WebSocket
public string IconUrl => CDN.GetGuildIconUrl(Id, IconId);
/// <inheritdoc />
public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
/// <inheritdoc />
public string BannerUrl => CDN.GetGuildBannerUrl(Id, BannerId);
/// <summary> Indicates whether the client has all the members downloaded to the local guild cache. </summary>
public bool HasAllMembers => MemberCount == DownloadedMemberCount;// _downloaderPromise.Task.IsCompleted;
/// <summary> Indicates whether the guild cache is synced to this guild. </summary>
@@ -354,6 +368,12 @@ namespace Discord.WebSocket
DefaultMessageNotifications = model.DefaultMessageNotifications;
ExplicitContentFilter = model.ExplicitContentFilter;
ApplicationId = model.ApplicationId;
PremiumTier = model.PremiumTier;
VanityURLCode = model.VanityURLCode;
BannerId = model.Banner;
SystemChannelFlags = model.SystemChannelFlags;
Description = model.Description;
PremiumSubscriptionCount = model.PremiumSubscriptionCount.GetValueOrDefault();

if (model.Emojis != null)
{


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

@@ -18,6 +18,7 @@ namespace Discord.WebSocket
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
public class SocketGuildUser : SocketUser, IGuildUser
{
private long? _premiumSinceTicks;
private long? _joinedAtTicks;
private ImmutableArray<ulong> _roleIds;

@@ -75,6 +76,8 @@ namespace Discord.WebSocket
/// </returns>
public SocketVoiceState? VoiceState => Guild.GetVoiceState(Id);
public AudioInStream AudioStream => Guild.GetAudioStream(Id);
/// <inheritdoc />
public DateTimeOffset? PremiumSince => DateTimeUtils.FromTicks(_premiumSinceTicks);

/// <summary>
/// Returns the position of the user within the role hierarchy.
@@ -135,6 +138,8 @@ namespace Discord.WebSocket
Nickname = model.Nick.Value;
if (model.Roles.IsSpecified)
UpdateRoles(model.Roles.Value);
if (model.PremiumSince.IsSpecified)
_premiumSinceTicks = model.PremiumSince.Value?.UtcTicks;
}
internal void Update(ClientState state, PresenceModel model, bool updatePresence)
{


+ 2
- 0
src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs View File

@@ -63,6 +63,8 @@ namespace Discord.WebSocket
/// <inheritdoc />
string IGuildUser.Nickname => null;
/// <inheritdoc />
DateTimeOffset? IGuildUser.PremiumSince => null;
/// <inheritdoc />
GuildPermissions IGuildUser.GuildPermissions => GuildPermissions.Webhook;

/// <inheritdoc />


Loading…
Cancel
Save