diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs index 80b1ffa68..eb135768c 100644 --- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs +++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs @@ -164,6 +164,14 @@ namespace Discord /// IReadOnlyDictionary Reactions { get; } + /// + /// Gets all stickers included in this message. + /// + /// + /// A read-only collection of sticker objects. + /// + IReadOnlyCollection Stickers { get; } + /// /// Gets the flags related to this message. /// diff --git a/src/Discord.Net.Core/Entities/Messages/ISticker.cs b/src/Discord.Net.Core/Entities/Messages/ISticker.cs new file mode 100644 index 000000000..e7e4405b6 --- /dev/null +++ b/src/Discord.Net.Core/Entities/Messages/ISticker.cs @@ -0,0 +1,67 @@ +using System.Collections.Generic; + +namespace Discord +{ + /// + /// Represents a discord sticker. + /// + public interface ISticker + { + /// + /// Gets the ID of this sticker. + /// + /// + /// A snowflake ID associated with this sticker. + /// + ulong Id { get; } + /// + /// Gets the ID of the pack of this sticker. + /// + /// + /// A snowflake ID associated with the pack of this sticker. + /// + ulong PackId { get; } + /// + /// Gets the name of this sticker. + /// + /// + /// A with the name of this sticker. + /// + string Name { get; } + /// + /// Gets the description of this sticker. + /// + /// + /// A with the description of this sticker. + /// + string Description { get; } + /// + /// Gets the list of tags of this sticker. + /// + /// + /// A read-only list with the tags of this sticker. + /// + IReadOnlyCollection Tags { get; } + /// + /// Gets the asset hash of this sticker. + /// + /// + /// A with the asset hash of this sticker. + /// + string Asset { get; } + /// + /// Gets the preview asset hash of this sticker. + /// + /// + /// A with the preview asset hash of this sticker. + /// + string PreviewAsset { get; } + /// + /// Gets the format type of this sticker. + /// + /// + /// A with the format type of this sticker. + /// + StickerFormatType FormatType { get; } + } +} diff --git a/src/Discord.Net.Core/Entities/Messages/SticketFormatType.cs b/src/Discord.Net.Core/Entities/Messages/SticketFormatType.cs new file mode 100644 index 000000000..d24a38534 --- /dev/null +++ b/src/Discord.Net.Core/Entities/Messages/SticketFormatType.cs @@ -0,0 +1,15 @@ +namespace Discord +{ + /// Defines the types of formats for stickers. + public enum StickerFormatType + { + /// Default value for a sticker format type. + None = 0, + /// The sticker format type is png. + Png = 1, + /// The sticker format type is apng. + Apng = 2, + /// The sticker format type is lottie. + Lottie = 3, + } +} diff --git a/src/Discord.Net.Rest/API/Common/Message.cs b/src/Discord.Net.Rest/API/Common/Message.cs index b781de346..6ea2c29ff 100644 --- a/src/Discord.Net.Rest/API/Common/Message.cs +++ b/src/Discord.Net.Rest/API/Common/Message.cs @@ -58,5 +58,7 @@ namespace Discord.API public Optional AllowedMentions { get; set; } [JsonProperty("referenced_message")] public Optional ReferencedMessage { get; set; } + [JsonProperty("stickers")] + public Optional Stickers { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Common/Sticker.cs b/src/Discord.Net.Rest/API/Common/Sticker.cs new file mode 100644 index 000000000..0d1cac974 --- /dev/null +++ b/src/Discord.Net.Rest/API/Common/Sticker.cs @@ -0,0 +1,25 @@ +#pragma warning disable CS1591 +using Newtonsoft.Json; + +namespace Discord.API +{ + internal class Sticker + { + [JsonProperty("id")] + public ulong Id { get; set; } + [JsonProperty("pack_id")] + public ulong PackId { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("description")] + public string Desription { get; set; } + [JsonProperty("tags")] + public Optional Tags { get; set; } + [JsonProperty("asset")] + public string Asset { get; set; } + [JsonProperty("preview_asset")] + public string PreviewAsset { get; set; } + [JsonProperty("format_type")] + public StickerFormatType FormatType { get; set; } + } +} diff --git a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs index b2a745980..793e89dff 100644 --- a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs +++ b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs @@ -58,6 +58,8 @@ namespace Discord.Rest public virtual IReadOnlyCollection MentionedUsers => ImmutableArray.Create(); /// public virtual IReadOnlyCollection Tags => ImmutableArray.Create(); + /// + public virtual IReadOnlyCollection Stickers => ImmutableArray.Create(); /// public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks); @@ -173,6 +175,8 @@ namespace Discord.Rest IReadOnlyCollection IMessage.Embeds => Embeds; /// IReadOnlyCollection IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray(); + /// + IReadOnlyCollection IMessage.Stickers => Stickers; /// public IReadOnlyDictionary Reactions => _reactions.ToDictionary(x => x.Emote, x => new ReactionMetadata { ReactionCount = x.Count, IsMe = x.Me }); diff --git a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs index cf025aea1..1274f1fd3 100644 --- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs +++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs @@ -21,6 +21,7 @@ namespace Discord.Rest private ImmutableArray _tags = ImmutableArray.Create(); private ImmutableArray _roleMentionIds = ImmutableArray.Create(); private ImmutableArray _userMentions = ImmutableArray.Create(); + private ImmutableArray _stickers = ImmutableArray.Create(); /// public override bool IsTTS => _isTTS; @@ -45,6 +46,8 @@ namespace Discord.Rest /// public override IReadOnlyCollection Tags => _tags; /// + public override IReadOnlyCollection Stickers => _stickers; + /// public IUserMessage ReferencedMessage => _referencedMessage; internal RestUserMessage(BaseDiscordClient discord, ulong id, IMessageChannel channel, IUser author, MessageSource source) @@ -132,6 +135,20 @@ namespace Discord.Rest IUser refMsgAuthor = MessageHelper.GetAuthor(Discord, guild, refMsg.Author.Value, refMsg.WebhookId.ToNullable()); _referencedMessage = RestUserMessage.Create(Discord, Channel, refMsgAuthor, refMsg); } + + if (model.Stickers.IsSpecified) + { + var value = model.Stickers.Value; + if (value.Length > 0) + { + var stickers = ImmutableArray.CreateBuilder(value.Length); + for (int i = 0; i < value.Length; i++) + stickers.Add(Sticker.Create(value[i])); + _stickers = stickers.ToImmutable(); + } + else + _stickers = ImmutableArray.Create(); + } } /// diff --git a/src/Discord.Net.Rest/Entities/Messages/Sticker.cs b/src/Discord.Net.Rest/Entities/Messages/Sticker.cs new file mode 100644 index 000000000..5482bed74 --- /dev/null +++ b/src/Discord.Net.Rest/Entities/Messages/Sticker.cs @@ -0,0 +1,48 @@ +using System.Collections.Generic; +using System.Diagnostics; +using Model = Discord.API.Sticker; + +namespace Discord +{ + /// + [DebuggerDisplay(@"{DebuggerDisplay,nq}")] + public class Sticker : ISticker + { + /// + public ulong Id { get; } + /// + public ulong PackId { get; } + /// + public string Name { get; } + /// + public string Description { get; } + /// + public IReadOnlyCollection Tags { get; } + /// + public string Asset { get; } + /// + public string PreviewAsset { get; } + /// + public StickerFormatType FormatType { get; } + + internal Sticker(ulong id, ulong packId, string name, string description, string[] tags, string asset, string previewAsset, StickerFormatType formatType) + { + Id = id; + PackId = packId; + Name = name; + Description = description; + Tags = tags.ToReadOnlyCollection(); + Asset = asset; + PreviewAsset = previewAsset; + FormatType = formatType; + } + internal static Sticker Create(Model model) + { + return new Sticker(model.Id, model.PackId, model.Name, model.Desription, + model.Tags.IsSpecified ? model.Tags.Value.Split(',') : new string[0], + model.Asset, model.PreviewAsset, model.FormatType); + } + + private string DebuggerDisplay => $"{Name} ({Id})"; + } +} diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs index 2ca53cbb9..8b45d882b 100644 --- a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs +++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs @@ -99,6 +99,8 @@ namespace Discord.WebSocket /// public virtual IReadOnlyCollection Tags => ImmutableArray.Create(); /// + public virtual IReadOnlyCollection Stickers => ImmutableArray.Create(); + /// public IReadOnlyDictionary Reactions => _reactions.GroupBy(r => r.Emote).ToDictionary(x => x.Key, x => new ReactionMetadata { ReactionCount = x.Count(), IsMe = x.Any(y => y.UserId == Discord.CurrentUser.Id) }); /// @@ -194,6 +196,8 @@ namespace Discord.WebSocket IReadOnlyCollection IMessage.MentionedRoleIds => MentionedRoles.Select(x => x.Id).ToImmutableArray(); /// IReadOnlyCollection IMessage.MentionedUserIds => MentionedUsers.Select(x => x.Id).ToImmutableArray(); + /// + IReadOnlyCollection IMessage.Stickers => Stickers; internal void AddReaction(SocketReaction reaction) { diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs index 859b1b80a..2a8b45ca1 100644 --- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs +++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs @@ -23,6 +23,7 @@ namespace Discord.WebSocket private ImmutableArray _tags = ImmutableArray.Create(); private ImmutableArray _roleMentions = ImmutableArray.Create(); private ImmutableArray _userMentions = ImmutableArray.Create(); + private ImmutableArray _stickers = ImmutableArray.Create(); /// public override bool IsTTS => _isTTS; @@ -47,6 +48,8 @@ namespace Discord.WebSocket /// public override IReadOnlyCollection MentionedUsers => _userMentions; /// + public override IReadOnlyCollection Stickers => _stickers; + /// public IUserMessage ReferencedMessage => _referencedMessage; internal SocketUserMessage(DiscordSocketClient discord, ulong id, ISocketMessageChannel channel, SocketUser author, MessageSource source) @@ -158,6 +161,20 @@ namespace Discord.WebSocket refMsgAuthor = new SocketUnknownUser(Discord, id: 0); _referencedMessage = SocketUserMessage.Create(Discord, state, refMsgAuthor, Channel, refMsg); } + + if (model.Stickers.IsSpecified) + { + var value = model.Stickers.Value; + if (value.Length > 0) + { + var stickers = ImmutableArray.CreateBuilder(value.Length); + for (int i = 0; i < value.Length; i++) + stickers.Add(Sticker.Create(value[i])); + _stickers = stickers.ToImmutable(); + } + else + _stickers = ImmutableArray.Create(); + } } ///