diff --git a/src/Discord.Net.Core/CDN.cs b/src/Discord.Net.Core/CDN.cs
index bc8d96f86..1dbc9a781 100644
--- a/src/Discord.Net.Core/CDN.cs
+++ b/src/Discord.Net.Core/CDN.cs
@@ -12,26 +12,45 @@ namespace Discord
///
/// The application identifier.
/// The icon identifier.
+ /// The format to return. Mustn't be a gif.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the application's icon.
///
- public static string GetApplicationIconUrl(ulong appId, string iconId)
- => iconId != null ? $"{DiscordConfig.CDNUrl}app-icons/{appId}/{iconId}.jpg" : null;
+ public static string GetApplicationIconUrl(ulong appId, string iconId, ImageFormat format, ushort size)
+ {
+ if (string.IsNullOrWhiteSpace(iconId))
+ return null;
+ if (format == ImageFormat.Gif)
+ throw new ArgumentException("Requested image format mustn't be a gif.");
+ if (!(size >= 16 && size <= 2048))
+ throw new ArgumentOutOfRangeException("Size must be a power of two in a range between 16 and 2048.");
+ if ((size & (size - 1)) != 0)
+ throw new ArgumentException("Size must be a power of two.");
+
+ string extension = FormatToExtension(format, iconId);
+ return $"{DiscordConfig.CDNUrl}app-icons/{appId}/{iconId}.{extension}?size={size}";
+ }
///
/// Returns a user avatar URL.
///
/// The user snowflake identifier.
/// The avatar identifier.
- /// The size of the image to return in. This can be any power of two between 16 and 2048.
/// The format to return.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the user's avatar in the specified size.
///
- public static string GetUserAvatarUrl(ulong userId, string avatarId, ushort size, ImageFormat format)
+ public static string GetUserAvatarUrl(ulong userId, string avatarId, ImageFormat format, ushort size)
{
- if (avatarId == null)
+ if (string.IsNullOrWhiteSpace(avatarId))
return null;
+ if (!(size >= 16 && size <= 2048))
+ throw new ArgumentOutOfRangeException("Size must be a power of two in a range between 16 and 2048.");
+ if ((size & (size - 1)) != 0)
+ throw new ArgumentException("Size must be a power of two.");
+
string extension = FormatToExtension(format, avatarId);
return $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.{extension}?size={size}";
}
@@ -51,8 +70,8 @@ namespace Discord
///
/// The guild snowflake identifier.
/// The icon identifier.
+ /// The format to return. Mustn't be a gif.
/// The size of the image to return in. This can be any power of two between 16 and 2048.
- /// The format to return.
///
/// A URL pointing to the guild's icon in the specified size.
///
@@ -62,6 +81,10 @@ namespace Discord
return null;
if (format == ImageFormat.Gif)
throw new ArgumentException("Requested image format mustn't be a gif.");
+ if (!(size >= 16 && size <= 2048))
+ throw new ArgumentOutOfRangeException("Size must be a power of two in a range between 16 and 2048.");
+ if ((size & (size - 1)) != 0)
+ throw new ArgumentException("Size must be a power of two.");
string extension = FormatToExtension(format, iconId);
return $"{DiscordConfig.CDNUrl}icons/{guildId}/{iconId}.{extension}?size={size}";
@@ -71,44 +94,63 @@ namespace Discord
///
/// The guild snowflake identifier.
/// The splash icon identifier.
+ /// The format to return. Mustn't be a gif.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the guild's icon.
///
- public static string GetGuildSplashUrl(ulong guildId, string splashId)
- => splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null;
- ///
- /// Returns a channel icon URL.
- ///
- /// The channel snowflake identifier.
- /// The icon identifier.
- ///
- /// A URL pointing to the channel's icon.
- ///
- public static string GetChannelIconUrl(ulong channelId, string iconId)
- => iconId != null ? $"{DiscordConfig.CDNUrl}channel-icons/{channelId}/{iconId}.jpg" : null;
+ public static string GetGuildSplashUrl(ulong guildId, string splashId, ImageFormat format, ushort size)
+ {
+ if (string.IsNullOrWhiteSpace(splashId))
+ return null;
+ if (format == ImageFormat.Gif)
+ throw new ArgumentException("Requested image format mustn't be a gif.");
+ if (!(size >= 16 && size <= 2048))
+ throw new ArgumentOutOfRangeException("Size must be a power of two in a range between 16 and 2048.");
+ if ((size & (size - 1)) != 0)
+ throw new ArgumentException("Size must be a power of two.");
+
+ string extension = FormatToExtension(format, splashId);
+ return $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.{ extension}?size={size}";
+ }
///
/// Returns an emoji URL.
///
/// The emoji snowflake identifier.
/// Whether this emoji is animated.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the custom emote.
///
- public static string GetEmojiUrl(ulong emojiId, bool animated)
- => $"{DiscordConfig.CDNUrl}emojis/{emojiId}.{(animated ? "gif" : "png")}";
+ public static string GetEmojiUrl(ulong emojiId, bool animated, ushort size)
+ {
+ if (!(size >= 16 && size <= 2048))
+ throw new ArgumentOutOfRangeException("Size must be a power of two in a range between 16 and 2048.");
+ if ((size & (size - 1)) != 0)
+ throw new ArgumentException("Size must be a power of two.");
+
+ return $"{DiscordConfig.CDNUrl}emojis/{emojiId}.{(animated ? "gif" : "png")}?size={size}";
+ }
///
/// Returns a Rich Presence asset URL.
///
/// The application identifier.
/// The asset identifier.
- /// The size of the image to return in. This can be any power of two between 16 and 2048.
/// The format to return.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the asset image in the specified size.
///
- public static string GetRichAssetUrl(ulong appId, string assetId, ushort size, ImageFormat format)
+ public static string GetRichAssetUrl(ulong appId, string assetId, ImageFormat format, ushort size)
{
+ if (string.IsNullOrWhiteSpace(assetId))
+ return null;
+ if (!(size >= 16 && size <= 2048))
+ throw new ArgumentOutOfRangeException("Size must be a power of two in a range between 16 and 2048.");
+ if ((size & (size - 1)) != 0)
+ throw new ArgumentException("Size must be a power of two.");
+
string extension = FormatToExtension(format, "");
return $"{DiscordConfig.CDNUrl}app-assets/{appId}/{assetId}.{extension}?size={size}";
}
diff --git a/src/Discord.Net.Core/Entities/Activities/GameAsset.cs b/src/Discord.Net.Core/Entities/Activities/GameAsset.cs
index 7217bded3..ccd0fa15b 100644
--- a/src/Discord.Net.Core/Entities/Activities/GameAsset.cs
+++ b/src/Discord.Net.Core/Entities/Activities/GameAsset.cs
@@ -33,6 +33,6 @@ namespace Discord
/// A string pointing to the image URL of the asset; null when the application ID does not exist.
///
public string GetImageUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
- => ApplicationId.HasValue ? CDN.GetRichAssetUrl(ApplicationId.Value, ImageId, size, format) : null;
+ => ApplicationId.HasValue ? CDN.GetRichAssetUrl(ApplicationId.Value, ImageId, format, size) : null;
}
}
diff --git a/src/Discord.Net.Core/Entities/Emotes/Emote.cs b/src/Discord.Net.Core/Entities/Emotes/Emote.cs
index bebd9fa4f..172e88794 100644
--- a/src/Discord.Net.Core/Entities/Emotes/Emote.cs
+++ b/src/Discord.Net.Core/Entities/Emotes/Emote.cs
@@ -26,10 +26,11 @@ namespace Discord
///
/// Gets the image URL of this emote.
///
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A string that points to the URL of this emote.
///
- public string Url => CDN.GetEmojiUrl(Id, Animated);
+ public string GetUrl(ushort size = 128) => CDN.GetEmojiUrl(Id, Animated, size);
internal Emote(ulong id, string name, bool animated)
{
diff --git a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
index 826b4ff2f..627195083 100644
--- a/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/IGuild.cs
@@ -69,6 +69,8 @@ namespace Discord
///
/// Gets the URL of this guild's icon.
///
+ /// The format to return. Mustn't be a gif.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the guild's icon; null if none is set.
///
@@ -83,10 +85,12 @@ namespace Discord
///
/// Gets the URL of this guild's splash image.
///
+ /// The format to return. Mustn't be a gif.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
///
/// A URL pointing to the guild's splash image; null if none is set.
///
- string SplashUrl { get; }
+ string GetSplashUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128);
///
/// Determines if this guild is currently connected and ready to be used.
///
diff --git a/src/Discord.Net.Core/Entities/IApplication.cs b/src/Discord.Net.Core/Entities/IApplication.cs
index 78a87dc19..08ae75250 100644
--- a/src/Discord.Net.Core/Entities/IApplication.cs
+++ b/src/Discord.Net.Core/Entities/IApplication.cs
@@ -21,7 +21,9 @@ namespace Discord
///
/// Gets the icon URL of the application.
///
- string IconUrl { get; }
+ /// The format to return. Mustn't be a gif.
+ /// The size of the image to return in. This can be any power of two between 16 and 2048.
+ string GetIconUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128);
///
/// Gets the partial user object containing info on the owner of the application.
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
index 6552dc768..6eb731275 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestGuild.cs
@@ -62,7 +62,8 @@ namespace Discord.Rest
public string GetIconUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> CDN.GetGuildIconUrl(Id, IconId, format, size);
///
- public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
+ public string GetSplashUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
+ => CDN.GetGuildSplashUrl(Id, SplashId, format, size);
///
/// Gets the built-in role containing all users in this guild.
diff --git a/src/Discord.Net.Rest/Entities/RestApplication.cs b/src/Discord.Net.Rest/Entities/RestApplication.cs
index d033978d0..d9ab68388 100644
--- a/src/Discord.Net.Rest/Entities/RestApplication.cs
+++ b/src/Discord.Net.Rest/Entities/RestApplication.cs
@@ -28,7 +28,8 @@ namespace Discord.Rest
///
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
///
- public string IconUrl => CDN.GetApplicationIconUrl(Id, _iconId);
+ public string GetIconUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
+ => CDN.GetApplicationIconUrl(Id, _iconId, format, size);
internal RestApplication(BaseDiscordClient discord, ulong id)
: base(discord, id)
diff --git a/src/Discord.Net.Rest/Entities/Users/RestUser.cs b/src/Discord.Net.Rest/Entities/Users/RestUser.cs
index 6af5b5c95..d938385d2 100644
--- a/src/Discord.Net.Rest/Entities/Users/RestUser.cs
+++ b/src/Discord.Net.Rest/Entities/Users/RestUser.cs
@@ -80,7 +80,7 @@ namespace Discord.Rest
///
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
- => CDN.GetUserAvatarUrl(Id, AvatarId, size, format);
+ => CDN.GetUserAvatarUrl(Id, AvatarId, format, size);
///
public string GetDefaultAvatarUrl()
diff --git a/src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs b/src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs
index 1fdc95a63..3d9ecdfd9 100644
--- a/src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs
+++ b/src/Discord.Net.Rest/Entities/Webhooks/RestWebhook.cs
@@ -75,7 +75,7 @@ namespace Discord.Rest
///
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
- => CDN.GetUserAvatarUrl(Id, AvatarId, size, format);
+ => CDN.GetUserAvatarUrl(Id, AvatarId, format, size);
public async Task ModifyAsync(Action func, RequestOptions options = null)
{
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 2a210ecd3..522aaa431 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -100,7 +100,8 @@ namespace Discord.WebSocket
public string GetIconUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
=> CDN.GetGuildIconUrl(Id, IconId, format, size);
///
- public string SplashUrl => CDN.GetGuildSplashUrl(Id, SplashId);
+ public string GetSplashUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) =>
+ CDN.GetGuildSplashUrl(Id, SplashId, format, size);
/// Indicates whether the client has all the members downloaded to the local guild cache.
public bool HasAllMembers => MemberCount == DownloadedMemberCount;// _downloaderPromise.Task.IsCompleted;
/// Indicates whether the guild cache is synced to this guild.
diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
index 4832e7311..6e1f1ef67 100644
--- a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
+++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
@@ -84,7 +84,7 @@ namespace Discord.WebSocket
///
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
- => CDN.GetUserAvatarUrl(Id, AvatarId, size, format);
+ => CDN.GetUserAvatarUrl(Id, AvatarId, format, size);
///
public string GetDefaultAvatarUrl()
diff --git a/src/Discord.Net.Webhook/Entities/Webhooks/RestInternalWebhook.cs b/src/Discord.Net.Webhook/Entities/Webhooks/RestInternalWebhook.cs
index 60cb89ee2..309c5f62e 100644
--- a/src/Discord.Net.Webhook/Entities/Webhooks/RestInternalWebhook.cs
+++ b/src/Discord.Net.Webhook/Entities/Webhooks/RestInternalWebhook.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Model = Discord.API.Webhook;
@@ -45,7 +45,7 @@ namespace Discord.Webhook
}
public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128)
- => CDN.GetUserAvatarUrl(Id, AvatarId, size, format);
+ => CDN.GetUserAvatarUrl(Id, AvatarId, format, size);
public async Task ModifyAsync(Action func, RequestOptions options = null)
{
diff --git a/test/Discord.Net.Tests/Tests.Emotes.cs b/test/Discord.Net.Tests/Tests.Emotes.cs
index eeadbddf8..26f040306 100644
--- a/test/Discord.Net.Tests/Tests.Emotes.cs
+++ b/test/Discord.Net.Tests/Tests.Emotes.cs
@@ -14,7 +14,7 @@ namespace Discord
Assert.Equal(394207658351263745UL, emote.Id);
Assert.False(emote.Animated);
Assert.Equal(DateTimeOffset.FromUnixTimeMilliseconds(1514056829775), emote.CreatedAt);
- Assert.EndsWith("png", emote.Url);
+ Assert.EndsWith("png", emote.GetUrl());
}
[Fact]
public void Test_Invalid_Emote_Parse()
@@ -32,7 +32,7 @@ namespace Discord
Assert.Equal(394207658351263745UL, emote.Id);
Assert.True(emote.Animated);
Assert.Equal(DateTimeOffset.FromUnixTimeMilliseconds(1514056829775), emote.CreatedAt);
- Assert.EndsWith("gif", emote.Url);
+ Assert.EndsWith("gif", emote.GetUrl());
}
[Fact]
public void Test_Invalid_Amimated_Emote_Parse()