diff --git a/src/Discord.Net.Core/Discord.Net.Core.xml b/src/Discord.Net.Core/Discord.Net.Core.xml
index 94b0c5cf6..989f35ec1 100644
--- a/src/Discord.Net.Core/Discord.Net.Core.xml
+++ b/src/Discord.Net.Core/Discord.Net.Core.xml
@@ -212,6 +212,16 @@
A URL pointing to the Spotify track.
+
+
+ Gets a stickers url based off the id and format.
+
+ The id of the sticker.
+ The format of the sticker
+
+ A URL to the sticker.
+
+
Represents a context of a command. This may include the client, guild, channel, user, and message.
@@ -3121,6 +3131,14 @@
A read-only collection of all custom emotes for this guild.
+
+
+ Gets a collection of all custom stickers for this guild.
+
+
+ A read-only collection of all custom stickers for this guild.
+
+
Gets a collection of all extra features added to this guild.
@@ -3914,6 +3932,52 @@
A task that represents the asynchronous removal operation.
+
+
+ Creates a new sticker in this guild.
+
+ The name of the sticker.
+ The description of the sticker.
+ The tags of the sticker.
+ The image of the new emote.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous creation operation. The task result contains the created sticker.
+
+
+
+
+ Gets a specific sticker within this guild.
+
+ The id of the sticker to get.
+ The that determines whether the object should be fetched from cache.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains the sticker found with the
+ specified ; if none is found.
+
+
+
+
+ Gets a collection of all stickers within this guild.
+
+ The that determines whether the object should be fetched from cache.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains a read-only collection
+ of stickers found within the guild.
+
+
+
+
+ Deletes a sticker within this guild.
+
+ The sticker to delete.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous removal operation.
+
+
Gets this guilds slash commands commands
@@ -7282,7 +7346,14 @@
The 's attached to this message
-
+
+
+ Gets all stickers items included in this message.
+
+
+ A read-only collection of sticker item objects.
+
+
Gets the flags related to this message.
@@ -7411,75 +7482,6 @@
The used in the reaction.
-
-
- Represents a discord sticker.
-
-
-
-
- Gets the ID of this sticker.
-
-
- A snowflake ID associated with this sticker.
-
-
-
-
- Gets the ID of the pack of this sticker.
-
-
- A snowflake ID associated with the pack of this sticker.
-
-
-
-
- Gets the name of this sticker.
-
-
- A with the name of this sticker.
-
-
-
-
- Gets the description of this sticker.
-
-
- A with the description of this sticker.
-
-
-
-
- Gets the list of tags of this sticker.
-
-
- A read-only list with the tags of this sticker.
-
-
-
-
- Gets the asset hash of this sticker.
-
-
- A with the asset hash of this sticker.
-
-
-
-
- Gets the preview asset hash of this sticker.
-
-
- A with the preview asset hash of this sticker.
-
-
-
-
- Gets the format type of this sticker.
-
-
- A with the format type of this sticker.
-
-
Represents a generic message sent by the system.
@@ -9329,6 +9331,214 @@
otherwise .
+
+
+ Represents a custom sticker within a guild.
+
+
+
+
+ Gets the users id who uploaded the sticker.
+
+
+ In order to get the author id, the bot needs the MANAGE_EMOJIS_AND_STICKERS permission.
+
+
+
+
+ Gets the guild that this custom sticker is in.
+
+
+
+
+ Modifies this sticker.
+
+
+ This method modifies this sticker with the specified properties. To see an example of this
+ method and what properties are available, please refer to .
+
+
+ The bot needs the MANAGE_EMOJIS_AND_STICKERS permission within the guild in order to modify stickers.
+
+
+ The following example replaces the name of the sticker with kekw.
+
+ await sticker.ModifyAsync(x => x.Name = "kekw");
+
+
+ A delegate containing the properties to modify the sticker with.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous modification operation.
+
+
+
+
+ Deletes the current sticker.
+
+
+ The bot neeeds the MANAGE_EMOJIS_AND_STICKERS permission inside the guild in order to delete stickers.
+
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous deletion operation.
+
+
+
+
+ Represents a discord sticker.
+
+
+
+
+ Gets the ID of this sticker.
+
+
+ A snowflake ID associated with this sticker.
+
+
+
+
+ Gets the ID of the pack of this sticker.
+
+
+ A snowflake ID associated with the pack of this sticker.
+
+
+
+
+ Gets the name of this sticker.
+
+
+ A with the name of this sticker.
+
+
+
+
+ Gets the description of this sticker.
+
+
+ A with the description of this sticker.
+
+
+
+
+ Gets the list of tags of this sticker.
+
+
+ A read-only list with the tags of this sticker.
+
+
+
+
+ Gets the asset hash of this sticker.
+
+
+ A with the asset hash of this sticker.
+
+
+
+
+ Gets the preview asset hash of this sticker.
+
+
+ A with the preview asset hash of this sticker.
+
+
+
+
+ Gets the format type of this sticker.
+
+
+ A with the format type of this sticker.
+
+
+
+
+ Gets the image url for this sticker.
+
+
+
+
+ Represents a partial sticker item received with a message.
+
+
+
+
+ The id of the sticker.
+
+
+
+
+ The name of the sticker.
+
+
+
+
+ The format of the sticker.
+
+
+
+
+ Represents a discord sticker pack.
+
+ The type of the stickers within the collection
+
+
+
+ Gets the id of the sticker pack.
+
+
+
+
+ Gets a collection of the stickers in the pack.
+
+
+
+
+ Gets the name of the sticker pack.
+
+
+
+
+ Gets the id of the pack's SKU.
+
+
+
+
+ Gets the id of a sticker in the pack which is shown as the pack's icon.
+
+
+
+
+ Gets the description of the sticker pack.
+
+
+
+
+ Gets the id of the sticker pack's banner image
+
+
+
+
+ Represents a class used to modify stickers.
+
+
+
+
+ Gets or sets the name of the sticker.
+
+
+
+
+ Gets or sets the description of the sticker.
+
+
+
+
+ Gets or sets the tags of the sticker.
+
+
Represents a Discord Team.
diff --git a/src/Discord.Net.Core/Entities/Messages/IMessage.cs b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
index f80abbe38..39419f068 100644
--- a/src/Discord.Net.Core/Entities/Messages/IMessage.cs
+++ b/src/Discord.Net.Core/Entities/Messages/IMessage.cs
@@ -169,12 +169,13 @@ namespace Discord
///
IReadOnlyCollection Components { get; }
- /// Gets all stickers included in this message.
+ ///
+ /// Gets all stickers items included in this message.
///
///
- /// A read-only collection of sticker objects.
+ /// A read-only collection of sticker item objects.
///
- IReadOnlyCollection Stickers { get; }
+ IReadOnlyCollection Stickers { get; }
///
/// Gets the flags related to this message.
diff --git a/src/Discord.Net.Core/Entities/Stickers/ISticker.cs b/src/Discord.Net.Core/Entities/Stickers/ISticker.cs
index eca613051..e16e03990 100644
--- a/src/Discord.Net.Core/Entities/Stickers/ISticker.cs
+++ b/src/Discord.Net.Core/Entities/Stickers/ISticker.cs
@@ -7,7 +7,7 @@ namespace Discord
///
/// Represents a discord sticker.
///
- public interface ISticker
+ public interface ISticker : IStickerItem
{
///
/// Gets the ID of this sticker.
@@ -64,7 +64,7 @@ namespace Discord
///
/// A with the format type of this sticker.
///
- StickerFormatType FormatType { get; }
+ StickerFormatType Format { get; }
///
/// Gets the image url for this sticker.
diff --git a/src/Discord.Net.Core/Entities/Stickers/IStickerItem.cs b/src/Discord.Net.Core/Entities/Stickers/IStickerItem.cs
new file mode 100644
index 000000000..3825a2702
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Stickers/IStickerItem.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Represents a partial sticker item received with a message.
+ ///
+ public interface IStickerItem
+ {
+ ///
+ /// The id of the sticker.
+ ///
+ ulong Id { get; }
+
+ ///
+ /// The name of the sticker.
+ ///
+ string Name { get; }
+
+ ///
+ /// The format of the sticker.
+ ///
+ StickerFormatType Format { get; }
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Stickers/StickerPack.cs b/src/Discord.Net.Core/Entities/Stickers/StickerPack.cs
new file mode 100644
index 000000000..b0750efc1
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Stickers/StickerPack.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Represents a discord sticker pack.
+ ///
+ /// The type of the stickers within the collection
+ public class StickerPack where TSticker : ISticker
+ {
+ ///
+ /// Gets the id of the sticker pack.
+ ///
+ public ulong Id { get; }
+
+ ///
+ /// Gets a collection of the stickers in the pack.
+ ///
+ public IReadOnlyCollection Stickers { get; }
+
+ ///
+ /// Gets the name of the sticker pack.
+ ///
+ public string Name { get; }
+
+ ///
+ /// Gets the id of the pack's SKU.
+ ///
+ public ulong SkuId { get; }
+
+ ///
+ /// Gets the id of a sticker in the pack which is shown as the pack's icon.
+ ///
+ public ulong? CoverStickerId { get; }
+
+ ///
+ /// Gets the description of the sticker pack.
+ ///
+ public string Description { get; }
+
+ ///
+ /// Gets the id of the sticker pack's banner image
+ ///
+ public ulong BannerAssetId { get; }
+
+ internal StickerPack(string name, ulong id, ulong skuid, ulong? coverStickerId, string description, ulong bannerAssetId, IEnumerable stickers)
+ {
+ this.Name = name;
+ this.Id = id;
+ this.SkuId = skuid;
+ this.CoverStickerId = coverStickerId;
+ this.Description = description;
+ this.BannerAssetId = bannerAssetId;
+
+ this.Stickers = stickers.ToImmutableArray();
+ }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/Sticker.cs b/src/Discord.Net.Rest/API/Common/Sticker.cs
index 31bd97370..da171a802 100644
--- a/src/Discord.Net.Rest/API/Common/Sticker.cs
+++ b/src/Discord.Net.Rest/API/Common/Sticker.cs
@@ -21,6 +21,8 @@ namespace Discord.API
public string PreviewAsset { get; set; }
[JsonProperty("format_type")]
public StickerFormatType FormatType { get; set; }
+ [JsonProperty("guild_id")]
+ public Optional GuildId { get; set; }
[JsonProperty("user")]
public Optional User { get; set; }
}
diff --git a/src/Discord.Net.Rest/Discord.Net.Rest.xml b/src/Discord.Net.Rest/Discord.Net.Rest.xml
index 8aa36360f..4cb5f6e02 100644
--- a/src/Discord.Net.Rest/Discord.Net.Rest.xml
+++ b/src/Discord.Net.Rest/Discord.Net.Rest.xml
@@ -3527,6 +3527,50 @@
+
+
+ Creates a new sticker in this guild.
+
+ The name of the sticker.
+ The description of the sticker.
+ The tags of the sticker.
+ The image of the new emote.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous creation operation. The task result contains the created sticker.
+
+
+
+
+ Gets a specific sticker within this guild.
+
+ The id of the sticker to get.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains the sticker found with the
+ specified ; if none is found.
+
+
+
+
+ Gets a collection of all stickers within this guild.
+
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains a read-only collection
+ of stickers found within the guild.
+
+
+
+
+ Deletes a sticker within this guild.
+
+ The sticker to delete.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous removal operation.
+
+
@@ -3970,6 +4014,33 @@
+
+
+ Represents a Rest-based custom sticker within a guild.
+
+
+
+
+ Gets the users id who uploaded the sticker.
+
+
+ In order to get the author id, the bot needs the MANAGE_EMOJIS_AND_STICKERS permission.
+
+
+
+
+ Gets the guild that this custom sticker is in.
+
+
+ Note: This property can be if the sticker wasnt fetched from a guild.
+
+
+
+
+
+
+
+
Regex used to check if some text is formatted as inline code.
@@ -4268,6 +4339,52 @@
This operation may only be called on a channel.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents a partial sticker received in a message.
+
+
+
+
+
+
+
+
+
+
+ Resolves this sticker item by fetching the from the API.
+
+
+ A task representing the download operation, the result of the task is a sticker object.
+
+
Represents a REST-based entity that contains information about a Discord application created via the developer portal.
@@ -4870,32 +4987,5 @@
A string containing the filename of this attachment.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index 820461e9a..bedb9de2f 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -559,7 +559,7 @@ namespace Discord.Rest
return await client.ApiClient.CreateGuildStickerAsync(apiArgs, guild.Id, options).ConfigureAwait(false);
}
- public static async Task ModifyStickerAsync(BaseDiscordClient client, IGuild guild, ISticker sticker, Action func,
+ public static async Task ModifyStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, Action func,
RequestOptions options = null)
{
if (func == null)
@@ -577,10 +577,10 @@ namespace Discord.Rest
Optional.Unspecified
};
- return await client.ApiClient.ModifyStickerAsync(apiArgs, guild.Id, sticker.Id, options).ConfigureAwait(false);
+ return await client.ApiClient.ModifyStickerAsync(apiArgs, guildId, sticker.Id, options).ConfigureAwait(false);
}
- public static async Task DeleteStickerAsync(BaseDiscordClient client, IGuild guild, ISticker sticker, RequestOptions options = null)
- => await client.ApiClient.DeleteStickerAsync(guild.Id, sticker.Id, options).ConfigureAwait(false);
+ public static async Task DeleteStickerAsync(BaseDiscordClient client, ulong guildId, ISticker sticker, RequestOptions options = null)
+ => await client.ApiClient.DeleteStickerAsync(guildId, sticker.Id, options).ConfigureAwait(false);
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index 126a211c8..e87e24b25 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -19,6 +19,7 @@ namespace Discord.Rest
{
private ImmutableDictionary _roles;
private ImmutableArray _emotes;
+ private ImmutableArray _stickers;
private ImmutableArray _features;
///
@@ -112,6 +113,7 @@ namespace Discord.Rest
public IReadOnlyCollection Roles => _roles.ToReadOnlyCollection();
///
public IReadOnlyCollection Emotes => _emotes;
+ public IReadOnlyCollection Stickers => _stickers;
///
public IReadOnlyCollection Features => _features;
@@ -190,6 +192,23 @@ namespace Discord.Rest
}
_roles = roles.ToImmutable();
+ if (model.Stickers != null)
+ {
+ var stickers = new ImmutableArray();
+ for (int i = 0; i < model.Stickers.Length; i++)
+ {
+ var sticker = model.Stickers[i];
+
+ var entity = CustomSticker.Create(Discord, sticker, this, sticker.User.IsSpecified ? sticker.User.Value.Id : null);
+
+ stickers.Add(entity);
+ }
+
+ _stickers = stickers;
+ }
+ else
+ _stickers = new ImmutableArray();
+
Available = true;
}
internal void Update(WidgetModel model)
@@ -908,6 +927,78 @@ namespace Discord.Rest
public Task DeleteEmoteAsync(GuildEmote emote, RequestOptions options = null)
=> GuildHelper.DeleteEmoteAsync(this, Discord, emote.Id, options);
+ //Stickers
+ ///
+ /// Creates a new sticker in this guild.
+ ///
+ /// The name of the sticker.
+ /// The description of the sticker.
+ /// The tags of the sticker.
+ /// The image of the new emote.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous creation operation. The task result contains the created sticker.
+ ///
+ public async Task CreateStickerAsync(string name, string description, IEnumerable tags, Image image, RequestOptions options = null)
+ {
+ var model = await GuildHelper.CreateStickerAsync(Discord, this, name, description, tags, image, options).ConfigureAwait(false);
+
+ return CustomSticker.Create(Discord, model, this, model.User.IsSpecified ? model.User.Value.Id : null);
+ }
+ ///
+ /// Gets a specific sticker within this guild.
+ ///
+ /// The id of the sticker to get.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous get operation. The task result contains the sticker found with the
+ /// specified ; if none is found.
+ ///
+ public async Task GetStickerAsync(ulong id, RequestOptions options = null)
+ {
+ var model = await Discord.ApiClient.GetGuildStickerAsync(this.Id, id, options).ConfigureAwait(false);
+
+ if (model == null)
+ return null;
+
+ return CustomSticker.Create(Discord, model, this, model.User.IsSpecified ? model.User.Value.Id : null);
+ }
+ ///
+ /// Gets a collection of all stickers within this guild.
+ ///
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous get operation. The task result contains a read-only collection
+ /// of stickers found within the guild.
+ ///
+ public async Task> GetStickersAsync(RequestOptions options = null)
+ {
+ var models = await Discord.ApiClient.ListGuildStickersAsync(this.Id, options).ConfigureAwait(false);
+
+ if (models.Length == 0)
+ return null;
+
+ List stickers = new List();
+
+ foreach(var model in models)
+ {
+ var entity = CustomSticker.Create(Discord, model, this, model.User.IsSpecified ? model.User.Value.Id : null);
+ stickers.Add(entity);
+ }
+
+ return stickers.ToImmutableArray();
+ }
+ ///
+ /// Deletes a sticker within this guild.
+ ///
+ /// The sticker to delete.
+ /// The options to be used when sending the request.
+ ///
+ /// A task that represents the asynchronous removal operation.
+ ///
+ public Task DeleteStickerAsync(CustomSticker sticker, RequestOptions options = null)
+ => sticker.DeleteAsync(options);
+
//IGuild
///
bool IGuild.Available => Available;
@@ -918,6 +1009,8 @@ namespace Discord.Rest
///
IReadOnlyCollection IGuild.Roles => Roles;
+ IReadOnlyCollection IGuild.Stickers => Stickers;
+
///
async Task> IGuild.GetBansAsync(RequestOptions options)
=> await GetBansAsync(options).ConfigureAwait(false);
@@ -1169,5 +1262,23 @@ namespace Discord.Rest
///
async Task> IGuild.GetApplicationCommandsAsync (RequestOptions options)
=> await GetApplicationCommandsAsync(options).ConfigureAwait(false);
+ async Task IGuild.CreateStickerAsync(string name, string description, IEnumerable tags, Image image, RequestOptions options)
+ => await CreateStickerAsync(name, description, tags, image, options);
+ async Task IGuild.GetStickerAsync(ulong id, CacheMode mode, RequestOptions options)
+ {
+ if (mode != CacheMode.AllowDownload)
+ return null;
+
+ return await GetStickerAsync(id, options);
+ }
+ async Task> IGuild.GetStickersAsync(CacheMode mode, RequestOptions options)
+ {
+ if (mode != CacheMode.AllowDownload)
+ return null;
+
+ return await GetStickersAsync(options);
+ }
+ Task IGuild.DeleteStickerAsync(ICustomSticker sticker, RequestOptions options)
+ => sticker.DeleteAsync();
}
}
diff --git a/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs b/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs
new file mode 100644
index 000000000..41462572c
--- /dev/null
+++ b/src/Discord.Net.Rest/Entities/Messages/CustomSticker.cs
@@ -0,0 +1,73 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Model = Discord.API.Sticker;
+
+namespace Discord.Rest
+{
+ ///
+ /// Represents a Rest-based custom sticker within a guild.
+ ///
+ public class CustomSticker : Sticker, ICustomSticker
+ {
+ ///
+ /// Gets the users id who uploaded the sticker.
+ ///
+ ///
+ /// In order to get the author id, the bot needs the MANAGE_EMOJIS_AND_STICKERS permission.
+ ///
+ public ulong? AuthorId { get; private set; }
+
+ ///
+ /// Gets the guild that this custom sticker is in.
+ ///
+ ///
+ /// Note: This property can be if the sticker wasnt fetched from a guild.
+ ///
+ public RestGuild Guild { get; private set; }
+
+ private ulong GuildId { get; set; }
+
+ internal CustomSticker(BaseDiscordClient client, ulong id, RestGuild guild, ulong? authorId = null)
+ : base(client, id)
+ {
+ this.AuthorId = authorId;
+ this.Guild = guild;
+ }
+ internal CustomSticker(BaseDiscordClient client, ulong id, ulong guildId, ulong? authorId = null)
+ : base(client, id)
+ {
+ this.AuthorId = authorId;
+ this.GuildId = guildId;
+ }
+
+ internal static CustomSticker Create(BaseDiscordClient client, Model model, RestGuild guild, ulong? authorId = null)
+ {
+ var entity = new CustomSticker(client, model.Id, guild, authorId);
+ entity.Update(model);
+ return entity;
+ }
+
+ internal static CustomSticker Create(BaseDiscordClient client, Model model, ulong guildId, ulong? authorId = null)
+ {
+ var entity = new CustomSticker(client, model.Id, guildId, authorId);
+ entity.Update(model);
+ return entity;
+ }
+
+ ///
+ public Task DeleteAsync(RequestOptions options = null)
+ => GuildHelper.DeleteStickerAsync(Discord, GuildId, this, options);
+
+ ///
+ public async Task ModifyAsync(Action func, RequestOptions options = null)
+ {
+ var model = await GuildHelper.ModifyStickerAsync(Discord, GuildId, this, func, options);
+ Update(model);
+ }
+
+ IGuild ICustomSticker.Guild => Guild;
+ }
+}
diff --git a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
index c9aba15f8..cc77beba2 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestMessage.cs
@@ -60,7 +60,7 @@ namespace Discord.Rest
///
public virtual IReadOnlyCollection Tags => ImmutableArray.Create();
///
- public virtual IReadOnlyCollection Stickers => ImmutableArray.Create();
+ public virtual IReadOnlyCollection Stickers => ImmutableArray.Create();
///
public DateTimeOffset Timestamp => DateTimeUtils.FromTicks(_timestampTicks);
@@ -236,7 +236,7 @@ namespace Discord.Rest
IReadOnlyCollection IMessage.Components => Components;
///
- IReadOnlyCollection IMessage.Stickers => Stickers;
+ 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 aa6b44da6..e6f3ac30d 100644
--- a/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/RestUserMessage.cs
@@ -21,7 +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();
+ private ImmutableArray _stickers = ImmutableArray.Create();
///
public override bool IsTTS => _isTTS;
@@ -46,7 +46,7 @@ namespace Discord.Rest
///
public override IReadOnlyCollection Tags => _tags;
///
- public override IReadOnlyCollection Stickers => _stickers;
+ public override IReadOnlyCollection Stickers => _stickers;
///
public IUserMessage ReferencedMessage => _referencedMessage;
@@ -136,18 +136,18 @@ namespace Discord.Rest
_referencedMessage = RestUserMessage.Create(Discord, Channel, refMsgAuthor, refMsg);
}
- if (model.Stickers.IsSpecified)
+ if (model.StickerItems.IsSpecified)
{
- var value = model.Stickers.Value;
+ var value = model.StickerItems.Value;
if (value.Length > 0)
{
- var stickers = ImmutableArray.CreateBuilder(value.Length);
+ var stickers = ImmutableArray.CreateBuilder(value.Length);
for (int i = 0; i < value.Length; i++)
- stickers.Add(Sticker.Create(value[i]));
+ stickers.Add(new StickerItem(Discord, value[i]));
_stickers = stickers.ToImmutable();
}
else
- _stickers = ImmutableArray.Create();
+ _stickers = ImmutableArray.Create();
}
}
diff --git a/src/Discord.Net.Rest/Entities/Messages/Sticker.cs b/src/Discord.Net.Rest/Entities/Messages/Sticker.cs
index aa4960f5b..6a5d35a3b 100644
--- a/src/Discord.Net.Rest/Entities/Messages/Sticker.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/Sticker.cs
@@ -3,45 +3,49 @@ using System.Diagnostics;
using System.Linq;
using Model = Discord.API.Sticker;
-namespace Discord
+namespace Discord.Rest
{
///
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
- public class Sticker : ISticker
+ public class Sticker : RestEntity, ISticker
{
///
- public ulong Id { get; }
+ public ulong PackId { get; internal set; }
///
- public ulong PackId { get; }
+ public string Name { get; internal set; }
///
- public string Name { get; }
+ public string Description { get; internal set; }
///
- public string Description { get; }
+ public IReadOnlyCollection Tags { get; internal set; }
///
- public IReadOnlyCollection Tags { get; }
+ public string Asset { get; internal set; }
///
- public string Asset { get; }
+ public string PreviewAsset { get; internal set; }
///
- public string PreviewAsset { get; }
- ///
- public StickerFormatType FormatType { get; }
+ public StickerFormatType Format { get; internal set; }
+
+ ///
+ public string GetStickerUrl()
+ => CDN.GetStickerUrl(this.Id, this.Format);
- internal Sticker(ulong id, ulong packId, string name, string description, string[] tags, string asset, string previewAsset, StickerFormatType formatType)
+ internal Sticker(BaseDiscordClient client, ulong id)
+ : base(client, id) { }
+ internal static Sticker Create(BaseDiscordClient client, Model model)
{
- Id = id;
- PackId = packId;
- Name = name;
- Description = description;
- Tags = tags.ToReadOnlyCollection();
- Asset = asset;
- PreviewAsset = previewAsset;
- FormatType = formatType;
+ var entity = new Sticker(client, model.Id);
+ entity.Update(model);
+ return entity;
}
- internal static Sticker Create(Model model)
+
+ internal void Update(Model model)
{
- return new Sticker(model.Id, model.PackId, model.Name, model.Desription,
- model.Tags.IsSpecified ? model.Tags.Value.Split(',').Select(x => x.Trim()).ToArray() : new string[0],
- model.Asset, model.PreviewAsset, model.FormatType);
+ PackId = model.PackId;
+ Name = model.Name;
+ Description = model.Desription;
+ Tags = model.Tags.IsSpecified ? model.Tags.Value.Split(',').Select(x => x.Trim()).ToArray() : new string[0];
+ Asset = model.Asset;
+ PreviewAsset = model.PreviewAsset;
+ Format = model.FormatType;
}
private string DebuggerDisplay => $"{Name} ({Id})";
diff --git a/src/Discord.Net.Rest/Entities/Messages/StickerItem.cs b/src/Discord.Net.Rest/Entities/Messages/StickerItem.cs
index 61284e604..dade33bb9 100644
--- a/src/Discord.Net.Rest/Entities/Messages/StickerItem.cs
+++ b/src/Discord.Net.Rest/Entities/Messages/StickerItem.cs
@@ -10,17 +10,13 @@ namespace Discord.Rest
///
/// Represents a partial sticker received in a message.
///
- public class StickerItem : RestEntity
+ public class StickerItem : RestEntity, IStickerItem
{
- ///
- /// The name of this sticker.
- ///
- public readonly string Name;
+ ///
+ public string Name { get; }
- ///
- /// The format of this sticker.
- ///
- public readonly StickerFormatType Format;
+ ///
+ public StickerFormatType Format { get; }
internal StickerItem(BaseDiscordClient client, Model model)
: base(client, model.Id)
@@ -40,7 +36,10 @@ namespace Discord.Rest
{
var model = await Discord.ApiClient.GetStickerAsync(this.Id);
- return Sticker.Create(model);
+ if (model.GuildId.IsSpecified)
+ return CustomSticker.Create(Discord, model, model.GuildId.Value, model.User.IsSpecified ? model.User.Value.Id : null);
+ else
+ return Sticker.Create(Discord, model);
}
}
}
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.cs b/src/Discord.Net.WebSocket/BaseSocketClient.cs
index 1cfe6c8bf..e8c5ca6ca 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.cs
@@ -44,6 +44,10 @@ namespace Discord.WebSocket
internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
+ ///
+ /// Gets a collection of default stickers.
+ ///
+ public abstract IReadOnlyCollection> DefaultStickerPacks { get; }
///
/// Gets the current logged-in user.
///
@@ -268,6 +272,16 @@ namespace Discord.WebSocket
///
public Task GetInviteAsync(string inviteId, RequestOptions options = null)
=> ClientHelper.GetInviteAsync(this, inviteId, options ?? RequestOptions.Default);
+ ///
+ /// Gets a sticker.
+ ///
+ /// Whether or not to allow downloading from the api.
+ /// The id of the sticker to get.
+ /// The options to be used when sending the request.
+ ///
+ /// A if found, otherwise .
+ ///
+ public abstract Task GetStickerAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null);
// IDiscordClient
///
diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
index 167ccebb0..bcaf81f31 100644
--- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
+++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.csproj
@@ -20,7 +20,7 @@
3.0.1
- TRACE;
+ TRACE;DEBUG;DEBUG_PACKETS
diff --git a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
index 61e22ffaa..60a45c005 100644
--- a/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
+++ b/src/Discord.Net.WebSocket/Discord.Net.WebSocket.xml
@@ -118,6 +118,11 @@
Provides access to a REST-only client with a shared state from this client.
+
+
+ Gets a collection of default stickers.
+
+
Gets the current logged-in user.
@@ -349,6 +354,17 @@
A task that represents the asynchronous get operation. The task result contains the invite information.
+
+
+ Gets a sticker.
+
+ Whether or not to allow downloading from the api.
+ The id of the sticker to get.
+ The options to be used when sending the request.
+
+ A if found, otherwise .
+
+
@@ -820,6 +836,9 @@
+
+
+
@@ -858,6 +877,9 @@
+
+
+
@@ -959,6 +981,9 @@
+
+
+
@@ -1083,6 +1108,16 @@
Clears cached users from the client.
+
+
+
+
+
+ Gets a sticker.
+
+ The unique identifier of the sticker.
+ A sticker if found, otherwise .
+
@@ -3030,6 +3065,11 @@
+
+
+ Gets a collection of all custom stickers for this guild.
+
+
@@ -3438,6 +3478,59 @@
+
+
+ Gets a specific sticker within this guild.
+
+ The id of the sticker to get.
+ The that determines whether the object should be fetched from cache.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains the sticker found with the
+ specified ; if none is found.
+
+
+
+
+ Gets a specific sticker within this guild.
+
+ The id of the sticker to get.
+ A sticker, if none is found then .
+
+
+
+ Gets a collection of all stickers within this guild.
+
+ The that determines whether the object should be fetched from cache.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous get operation. The task result contains a read-only collection
+ of stickers found within the guild.
+
+
+
+
+ Creates a new sticker in this guild.
+
+ The name of the sticker.
+ The description of the sticker.
+ The tags of the sticker.
+ The image of the new emote.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous creation operation. The task result contains the created sticker.
+
+
+
+
+ Deletes a sticker within this guild.
+
+ The sticker to delete.
+ The options to be used when sending the request.
+
+ A task that represents the asynchronous removal operation.
+
+
Gets the name of the guild.
@@ -3479,6 +3572,9 @@
+
+
+
@@ -4417,6 +4513,83 @@
+
+
+ Gets the user that uploaded the guild sticker.
+
+
+
+ This may return in the WebSocket implementation due to incomplete user collection in
+ large guilds, or the bot doesnt have the MANAGE_EMOJIS_AND_STICKERS permission.
+
+
+
+
+
+ Gets the guild the sticker lives in.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Represents an unknown sticker received over the gateway.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Attempts to try to find the sticker.
+
+
+ The sticker representing this unknown stickers Id, if none is found then .
+
+
Represents a WebSocket-based group user.
diff --git a/src/Discord.Net.WebSocket/DiscordShardedClient.cs b/src/Discord.Net.WebSocket/DiscordShardedClient.cs
index 450145f1c..30ec5ef19 100644
--- a/src/Discord.Net.WebSocket/DiscordShardedClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordShardedClient.cs
@@ -6,6 +6,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Threading;
+using System.Collections.Immutable;
namespace Discord.WebSocket
{
@@ -16,6 +17,7 @@ namespace Discord.WebSocket
private readonly bool _automaticShards;
private int[] _shardIds;
private DiscordSocketClient[] _shards;
+ private ImmutableArray> _defaultStickers;
private int _totalShards;
private SemaphoreSlim[] _identifySemaphores;
private object _semaphoreResetLock;
@@ -40,6 +42,10 @@ namespace Discord.WebSocket
return base.ApiClient;
}
}
+ ///
+ public override IReadOnlyCollection> DefaultStickerPacks
+ => _defaultStickers.ToReadOnlyCollection();
+
///
public override IReadOnlyCollection Guilds => GetGuilds().ToReadOnlyCollection(GetGuildCount);
///
@@ -77,6 +83,7 @@ namespace Discord.WebSocket
_shardIdsToIndex = new Dictionary();
config.DisplayInitialLog = false;
_baseConfig = config;
+ _defaultStickers = new ImmutableArray>();
if (config.TotalShards == null)
_automaticShards = true;
@@ -155,6 +162,10 @@ namespace Discord.WebSocket
//Assume thread safe: already in a connection lock
for (int i = 0; i < _shards.Length; i++)
await _shards[i].LoginAsync(tokenType, token);
+
+ if(this._defaultStickers.Length == 0)
+ await DownloadDefaultStickersAsync().ConfigureAwait(false);
+
}
internal override async Task OnLogoutAsync()
{
@@ -247,6 +258,63 @@ namespace Discord.WebSocket
result += _shards[i].Guilds.Count;
return result;
}
+ ///
+ public override async Task GetStickerAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
+ {
+ var sticker = _defaultStickers.FirstOrDefault(x => x.Stickers.Any(y => y.Id == id))?.Stickers.FirstOrDefault(x => x.Id == id);
+
+ if (sticker != null)
+ return sticker;
+
+ foreach (var guild in Guilds)
+ {
+ sticker = await guild.GetStickerAsync(id, CacheMode.CacheOnly).ConfigureAwait(false);
+
+ if (sticker != null)
+ return sticker;
+ }
+
+ if (mode == CacheMode.CacheOnly)
+ return null;
+
+ var model = await ApiClient.GetStickerAsync(id, options).ConfigureAwait(false);
+
+ if (model == null)
+ return null;
+
+
+ if (model.GuildId.IsSpecified)
+ {
+ var guild = GetGuild(model.GuildId.Value);
+ sticker = guild.AddOrUpdateSticker(model);
+ return sticker;
+ }
+ else
+ {
+ return SocketSticker.Create(_shards[0], model);
+ }
+ }
+ private async Task DownloadDefaultStickersAsync()
+ {
+ var models = await ApiClient.ListNitroStickerPacksAsync().ConfigureAwait(false);
+
+ foreach(var model in models.StickerPacks)
+ {
+ var stickers = model.Stickers.Select(x => SocketSticker.Create(_shards[0], x));
+
+ var pack = new StickerPack(
+ model.Name,
+ model.Id,
+ model.SkuId,
+ model.CoverStickerId.ToNullable(),
+ model.Description,
+ model.BannerAssetId,
+ stickers
+ );
+
+ _defaultStickers.Add(pack);
+ }
+ }
///
public override SocketUser GetUser(ulong id)
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index 52a5d309d..789f4aa53 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -44,6 +44,7 @@ namespace Discord.WebSocket
private RestApplication _applicationInfo;
private bool _isDisposed;
private GatewayIntents _gatewayIntents;
+ private ImmutableArray> _defaultStickers;
///
/// Provides access to a REST-only client with a shared state from this client.
@@ -76,6 +77,17 @@ namespace Discord.WebSocket
internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
///
public override IReadOnlyCollection Guilds => State.Guilds;
+ ///
+ public override IReadOnlyCollection> DefaultStickerPacks
+ {
+ get
+ {
+ if (this._shardedClient != null)
+ return this._shardedClient.DefaultStickerPacks;
+ else
+ return _defaultStickers.ToReadOnlyCollection();
+ }
+ }
///
public override IReadOnlyCollection PrivateChannels => State.PrivateChannels;
///
@@ -137,6 +149,7 @@ namespace Discord.WebSocket
Rest = new DiscordSocketRestClient(config, ApiClient);
_heartbeatTimes = new ConcurrentQueue();
_gatewayIntents = config.GatewayIntents;
+ _defaultStickers = new ImmutableArray>();
_stateLock = new SemaphoreSlim(1, 1);
_gatewayLogger = LogManager.CreateLogger(ShardId == 0 && TotalShards == 1 ? "Gateway" : $"Shard #{ShardId}");
@@ -195,6 +208,31 @@ namespace Discord.WebSocket
base.Dispose(disposing);
}
+ internal override async Task OnLoginAsync(TokenType tokenType, string token)
+ {
+ if(this._shardedClient != null && this._defaultStickers.Length == 0)
+ {
+ var models = await ApiClient.ListNitroStickerPacksAsync().ConfigureAwait(false);
+
+ foreach (var model in models.StickerPacks)
+ {
+ var stickers = model.Stickers.Select(x => SocketSticker.Create(this, x));
+
+ var pack = new StickerPack(
+ model.Name,
+ model.Id,
+ model.SkuId,
+ model.CoverStickerId.ToNullable(),
+ model.Description,
+ model.BannerAssetId,
+ stickers
+ );
+
+ _defaultStickers.Add(pack);
+ }
+ }
+ }
+
///
internal override async Task OnLogoutAsync()
{
@@ -368,6 +406,51 @@ namespace Discord.WebSocket
internal void RemoveUser(ulong id)
=> State.RemoveUser(id);
+ ///
+ public override async Task GetStickerAsync(ulong id, CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
+ {
+ var sticker = _defaultStickers.FirstOrDefault(x => x.Stickers.Any(y => y.Id == id))?.Stickers.FirstOrDefault(x => x.Id == id);
+
+ if (sticker != null)
+ return sticker;
+
+ foreach(var guild in Guilds)
+ {
+ sticker = await guild.GetStickerAsync(id, CacheMode.CacheOnly).ConfigureAwait(false);
+
+ if (sticker != null)
+ return sticker;
+ }
+
+ if (mode == CacheMode.CacheOnly)
+ return null;
+
+ var model = await ApiClient.GetStickerAsync(id, options).ConfigureAwait(false);
+
+ if(model == null)
+ return null;
+
+
+ if (model.GuildId.IsSpecified)
+ {
+ var guild = State.GetGuild(model.GuildId.Value);
+ sticker = guild.AddOrUpdateSticker(model);
+ return sticker;
+ }
+ else
+ {
+ return SocketSticker.Create(this, model);
+ }
+ }
+
+ ///
+ /// Gets a sticker.
+ ///
+ /// The unique identifier of the sticker.
+ /// A sticker if found, otherwise .
+ public SocketSticker GetSticker(ulong id)
+ => GetStickerAsync(id, CacheMode.CacheOnly).GetAwaiter().GetResult();
+
///
public override async ValueTask> GetVoiceRegionsAsync(RequestOptions options = null)
{
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 2521d6b2b..390bc0512 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -533,6 +533,8 @@ namespace Discord.WebSocket
stickers.TryAdd(sticker.Id, entity);
}
+
+ _stickers = stickers;
}
else
_stickers = new ConcurrentDictionary(ConcurrentHashSet.DefaultConcurrencyLevel, 7);
@@ -1192,6 +1194,13 @@ namespace Discord.WebSocket
return AddOrUpdateSticker(model);
}
///
+ /// Gets a specific sticker within this guild.
+ ///
+ /// The id of the sticker to get.
+ /// A sticker, if none is found then .
+ public SocketCustomSticker GetSticker(ulong id)
+ => GetStickerAsync(id, CacheMode.CacheOnly).GetAwaiter().GetResult();
+ ///
/// Gets a collection of all stickers within this guild.
///
/// The that determines whether the object should be fetched from cache.
@@ -1629,7 +1638,8 @@ namespace Discord.WebSocket
=> await GetStickerAsync(id, mode, options);
async Task> IGuild.GetStickersAsync(CacheMode mode, RequestOptions options)
=> await GetStickersAsync(mode, options);
- Task IGuild.DeleteStickerAsync(ICustomSticker sticker, RequestOptions options) => throw new NotImplementedException();
+ Task IGuild.DeleteStickerAsync(ICustomSticker sticker, RequestOptions options)
+ => DeleteStickerAsync(_stickers[sticker.Id], options);
void IDisposable.Dispose()
{
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
index 1b62d14dd..167440069 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketMessage.cs
@@ -106,7 +106,7 @@ namespace Discord.WebSocket
///
public virtual IReadOnlyCollection Tags => ImmutableArray.Create();
///
- public virtual IReadOnlyCollection Stickers => 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) });
@@ -261,7 +261,7 @@ namespace Discord.WebSocket
IReadOnlyCollection IMessage.Components => Components;
///
- IReadOnlyCollection IMessage.Stickers => Stickers;
+ 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 597544f4d..8127d54f5 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
+++ b/src/Discord.Net.WebSocket/Entities/Messages/SocketUserMessage.cs
@@ -23,7 +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();
+ private ImmutableArray _stickers = ImmutableArray.Create();
///
public override bool IsTTS => _isTTS;
@@ -48,7 +48,7 @@ namespace Discord.WebSocket
///
public override IReadOnlyCollection MentionedUsers => _userMentions;
///
- public override IReadOnlyCollection Stickers => _stickers;
+ public override IReadOnlyCollection Stickers => _stickers;
///
public IUserMessage ReferencedMessage => _referencedMessage;
@@ -162,18 +162,35 @@ namespace Discord.WebSocket
_referencedMessage = SocketUserMessage.Create(Discord, state, refMsgAuthor, Channel, refMsg);
}
- if (model.Stickers.IsSpecified)
+ if (model.StickerItems.IsSpecified)
{
- var value = model.Stickers.Value;
+ var value = model.StickerItems.Value;
if (value.Length > 0)
{
- var stickers = ImmutableArray.CreateBuilder(value.Length);
+ var stickers = ImmutableArray.CreateBuilder(value.Length);
for (int i = 0; i < value.Length; i++)
- stickers.Add(Sticker.Create(value[i]));
+ {
+ var stickerItem = value[i];
+ SocketSticker sticker = null;
+
+ if (guild != null)
+ {
+ sticker = guild.GetSticker(stickerItem.Id);
+ }
+
+ if(sticker == null)
+ {
+ sticker = Discord.GetSticker(stickerItem.Id);
+ }
+
+ // if its still null, create an unknown
+ sticker = SocketUnknownSticker.Create(Discord, stickerItem);
+ }
+
_stickers = stickers.ToImmutable();
}
else
- _stickers = ImmutableArray.Create();
+ _stickers = ImmutableArray.Create();
}
}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketCustomSticker.cs b/src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs
similarity index 94%
rename from src/Discord.Net.WebSocket/Entities/Messages/SocketCustomSticker.cs
rename to src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs
index 4e00873c7..b8c29ed35 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketCustomSticker.cs
+++ b/src/Discord.Net.WebSocket/Entities/Stickers/SocketCustomSticker.cs
@@ -51,7 +51,7 @@ namespace Discord.WebSocket
if(!Guild.CurrentUser.GuildPermissions.Has(GuildPermission.ManageEmojisAndStickers))
throw new InvalidOperationException($"Missing permission {nameof(GuildPermission.ManageEmojisAndStickers)}");
- var model = await GuildHelper.ModifyStickerAsync(this.Discord, this.Guild, this, func, options);
+ var model = await GuildHelper.ModifyStickerAsync(this.Discord, this.Guild.Id, this, func, options);
this.Update(model);
}
@@ -59,7 +59,7 @@ namespace Discord.WebSocket
///
public async Task DeleteAsync(RequestOptions options = null)
{
- await GuildHelper.DeleteStickerAsync(Discord, Guild, this, options);
+ await GuildHelper.DeleteStickerAsync(Discord, this.Guild.Id, this, options);
Guild.RemoveSticker(this.Id);
}
diff --git a/src/Discord.Net.WebSocket/Entities/Messages/SocketSticker.cs b/src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
similarity index 62%
rename from src/Discord.Net.WebSocket/Entities/Messages/SocketSticker.cs
rename to src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
index 4b4f6a605..b450e4c36 100644
--- a/src/Discord.Net.WebSocket/Entities/Messages/SocketSticker.cs
+++ b/src/Discord.Net.WebSocket/Entities/Stickers/SocketSticker.cs
@@ -12,36 +12,42 @@ namespace Discord.WebSocket
public class SocketSticker : SocketEntity, ISticker
{
///
- public ulong PackId { get; private set; }
+ public virtual ulong PackId { get; private set; }
///
- public string Name { get; private set; }
+ public string Name { get; internal set; }
///
- public string Description { get; private set; }
+ public virtual string Description { get; private set; }
///
- public IReadOnlyCollection Tags { get; private set; }
+ public virtual IReadOnlyCollection Tags { get; private set; }
///
- public string Asset { get; private set; }
+ public virtual string Asset { get; private set; }
///
- public string PreviewAsset { get; private set; }
+ public virtual string PreviewAsset { get; private set; }
///
- public StickerFormatType FormatType { get; private set; }
+ public StickerFormatType Format { get; internal set; }
///
public string GetStickerUrl()
- => CDN.GetStickerUrl(this.Id, this.FormatType);
+ => CDN.GetStickerUrl(this.Id, this.Format);
internal SocketSticker(DiscordSocketClient client, ulong id)
: base(client, id) { }
internal static SocketSticker Create(DiscordSocketClient client, Model model)
{
- var entity = new SocketSticker(client, model.Id);
+ SocketSticker entity;
+
+ if (model.GuildId.IsSpecified)
+ entity = new SocketCustomSticker(client, model.Id, client.GetGuild(model.GuildId.Value), model.User.IsSpecified ? model.User.Value.Id : null);
+ else
+ entity = new SocketSticker(client, model.Id);
+
entity.Update(model);
return entity;
}
@@ -53,7 +59,7 @@ namespace Discord.WebSocket
this.PackId = model.PackId;
this.Asset = model.Asset;
this.PreviewAsset = model.PreviewAsset;
- this.FormatType = model.FormatType;
+ this.Format = model.FormatType;
if (model.Tags.IsSpecified)
{
diff --git a/src/Discord.Net.WebSocket/Entities/Stickers/SocketUnknownSticker.cs b/src/Discord.Net.WebSocket/Entities/Stickers/SocketUnknownSticker.cs
new file mode 100644
index 000000000..b54af3729
--- /dev/null
+++ b/src/Discord.Net.WebSocket/Entities/Stickers/SocketUnknownSticker.cs
@@ -0,0 +1,60 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Model = Discord.API.StickerItem;
+
+namespace Discord.WebSocket
+{
+ ///
+ /// Represents an unknown sticker received over the gateway.
+ ///
+ public class SocketUnknownSticker : SocketSticker
+ {
+ ///
+ public override string Asset
+ => null;
+
+ ///
+ public override IReadOnlyCollection Tags
+ => null;
+
+ ///
+ public override string Description
+ => null;
+
+ ///
+ public override ulong PackId
+ => 0;
+
+ ///
+ public override string PreviewAsset
+ => null;
+
+ internal SocketUnknownSticker(DiscordSocketClient client, ulong id)
+ : base(client, id) { }
+
+ internal static SocketUnknownSticker Create(DiscordSocketClient client, Model model)
+ {
+ var entity = new SocketUnknownSticker(client, model.Id);
+ entity.Update(model);
+ return entity;
+ }
+
+ internal void Update(Model model)
+ {
+ this.Name = model.Name;
+ this.Format = model.FormatType;
+ }
+
+ ///
+ /// Attempts to try to find the sticker.
+ ///
+ ///
+ /// The sticker representing this unknown stickers Id, if none is found then .
+ ///
+ public Task ResolveAsync(CacheMode mode = CacheMode.AllowDownload, RequestOptions options = null)
+ => Discord.GetStickerAsync(this.Id, mode, options);
+ }
+}