@@ -8,13 +8,26 @@ namespace Discord | |||
public static class CDN | |||
{ | |||
/// <summary> | |||
/// Returns the Discord developer application icon. | |||
/// Returns an application icon URL. | |||
/// </summary> | |||
/// <param name="appId">The application identifier.</param> | |||
/// <param name="iconId">The icon identifier.</param> | |||
/// <returns> | |||
/// A URL pointing to the application's icon. | |||
/// </returns> | |||
public static string GetApplicationIconUrl(ulong appId, string iconId) | |||
=> iconId != null ? $"{DiscordConfig.CDNUrl}app-icons/{appId}/{iconId}.jpg" : null; | |||
/// <summary> | |||
/// Returns the user avatar URL based on the <paramref name="size"/> and <see cref="ImageFormat" />. | |||
/// Returns a user avatar URL. | |||
/// </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="format">The format to return.</param> | |||
/// <returns> | |||
/// A URL pointing to the user's avatar in the specified size. | |||
/// </returns> | |||
public static string GetUserAvatarUrl(ulong userId, string avatarId, ushort size, ImageFormat format) | |||
{ | |||
if (avatarId == null) | |||
@@ -26,34 +39,64 @@ namespace Discord | |||
/// Returns the default user avatar URL. | |||
/// </summary> | |||
/// <param name="discriminator">The discriminator value of a user.</param> | |||
/// <returns> | |||
/// A URL pointing to the user's default avatar when one isn't set. | |||
/// </returns> | |||
public static string GetDefaultUserAvatarUrl(ushort discriminator) | |||
{ | |||
return $"{DiscordConfig.CDNUrl}embed/avatars/{discriminator % 5}.png"; | |||
} | |||
/// <summary> | |||
/// Returns the icon URL associated with the given guild ID. | |||
/// Returns an icon URL. | |||
/// </summary> | |||
/// <param name="guildId">The guild snowflake identifier.</param> | |||
/// <param name="iconId">The icon identifier.</param> | |||
/// <returns> | |||
/// A URL pointing to the guild's icon. | |||
/// </returns> | |||
public static string GetGuildIconUrl(ulong guildId, string iconId) | |||
=> iconId != null ? $"{DiscordConfig.CDNUrl}icons/{guildId}/{iconId}.jpg" : null; | |||
/// <summary> | |||
/// Returns the guild splash URL associated with the given guild and splash ID. | |||
/// Returns a guild splash URL. | |||
/// </summary> | |||
/// <param name="guildId">The guild snowflake identifier.</param> | |||
/// <param name="splashId">The splash icon identifier.</param> | |||
/// <returns> | |||
/// A URL pointing to the guild's icon. | |||
/// </returns> | |||
public static string GetGuildSplashUrl(ulong guildId, string splashId) | |||
=> splashId != null ? $"{DiscordConfig.CDNUrl}splashes/{guildId}/{splashId}.jpg" : null; | |||
/// <summary> | |||
/// Returns the channel icon URL associated with the given guild and icon ID. | |||
/// Returns a channel icon URL. | |||
/// </summary> | |||
/// <param name="channelId">The channel snowflake identifier.</param> | |||
/// <param name="iconId">The icon identifier.</param> | |||
/// <returns> | |||
/// A URL pointing to the channel's icon. | |||
/// </returns> | |||
public static string GetChannelIconUrl(ulong channelId, string iconId) | |||
=> iconId != null ? $"{DiscordConfig.CDNUrl}channel-icons/{channelId}/{iconId}.jpg" : null; | |||
/// <summary> | |||
/// Returns the emoji URL based on the emoji ID. | |||
/// Returns an emoji URL. | |||
/// </summary> | |||
/// <param name="emojiId">The emoji snowflake identifier.</param> | |||
/// <param name="animated">Whether this emoji is animated.</param> | |||
/// <returns> | |||
/// A URL pointing to the custom emote. | |||
/// </returns> | |||
public static string GetEmojiUrl(ulong emojiId, bool animated) | |||
=> $"{DiscordConfig.CDNUrl}emojis/{emojiId}.{(animated ? "gif" : "png")}"; | |||
/// <summary> | |||
/// Returns the rich presence asset URL based on the asset ID and <see cref="ImageFormat" />. | |||
/// Returns a Rich Presence asset URL. | |||
/// </summary> | |||
/// <param name="appId">The application identifier.</param> | |||
/// <param name="assetId">The asset 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="format">The format to return.</param> | |||
/// <returns> | |||
/// A URL pointing to the asset image in the specified size. | |||
/// </returns> | |||
public static string GetRichAssetUrl(ulong appId, string assetId, ushort size, ImageFormat format) | |||
{ | |||
string extension = FormatToExtension(format, ""); | |||
@@ -61,10 +104,21 @@ namespace Discord | |||
} | |||
/// <summary> | |||
/// Returns the Spotify album URL based on the album art ID. | |||
/// Returns a Spotify album URL. | |||
/// </summary> | |||
/// <param name="albumArtId">The identifier for the album art (e.g. 6be8f4c8614ecf4f1dd3ebba8d8692d8ce4951ac).</param> | |||
/// <returns> | |||
/// A URL pointing to the Spotify album art. | |||
/// </returns> | |||
public static string GetSpotifyAlbumArtUrl(string albumArtId) | |||
=> $"https://i.scdn.co/image/{albumArtId}"; | |||
/// <summary> | |||
/// Returns a Spotify direct URL for a track. | |||
/// </summary> | |||
/// <param name="trackId">The identifier for the track (e.g. 4uLU6hMCjMI75M1A2tKUQC).</param> | |||
/// <returns> | |||
/// A URL pointing to the Spotify track. | |||
/// </returns> | |||
public static string GetSpotifyDirectUrl(string trackId) | |||
=> $"https://open.spotify.com/track/{trackId}"; | |||
@@ -8,12 +8,22 @@ namespace Discord | |||
public class DiscordConfig | |||
{ | |||
/// <summary> | |||
/// Returns the gateway version Discord.Net uses. | |||
/// Returns the API version Discord.Net uses. | |||
/// </summary> | |||
/// <returns> | |||
/// A 32-bit integer representing the API version that Discord.Net uses to communicate with Discord. | |||
/// <para>A list of available API version can be seen on the official | |||
/// <see href="https://discordapp.com/developers/docs/reference#api-versioning">Discord API documentation</see> | |||
/// .</para> | |||
/// </returns> | |||
public const int APIVersion = 6; | |||
/// <summary> | |||
/// Gets the Discord.Net version, including the build number. | |||
/// </summary> | |||
/// <returns> | |||
/// A string containing the detailed version information, including its build number; <c>Unknown</c> when | |||
/// the version fails to be fetched. | |||
/// </returns> | |||
public static string Version { get; } = | |||
typeof(DiscordConfig).GetTypeInfo().Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion ?? | |||
typeof(DiscordConfig).GetTypeInfo().Assembly.GetName().Version.ToString(3) ?? | |||
@@ -22,54 +32,91 @@ namespace Discord | |||
/// <summary> | |||
/// Gets the user agent that Discord.Net uses in its clients. | |||
/// </summary> | |||
/// <returns> | |||
/// The user agent used in each Discord.Net request. | |||
/// </returns> | |||
public static string UserAgent { get; } = $"DiscordBot (https://github.com/RogueException/Discord.Net, v{Version})"; | |||
/// <summary> | |||
/// Returns the base Discord API URL. | |||
/// </summary> | |||
/// <returns> | |||
/// The Discord API URL using <see cref="APIVersion"/>. | |||
/// </returns> | |||
public static readonly string APIUrl = $"https://discordapp.com/api/v{APIVersion}/"; | |||
/// <summary> | |||
/// Returns the base Discord CDN URL. | |||
/// </summary> | |||
/// <returns> | |||
/// The base Discord Content Delivery Network (CDN) URL. | |||
/// </returns> | |||
public const string CDNUrl = "https://cdn.discordapp.com/"; | |||
/// <summary> | |||
/// Returns the base Discord invite URL. | |||
/// Returns the base Discord invite URL. | |||
/// </summary> | |||
/// <returns> | |||
/// The base Discord invite URL. | |||
/// </returns> | |||
public const string InviteUrl = "https://discord.gg/"; | |||
/// <summary> | |||
/// Returns the default timeout for requests. | |||
/// </summary> | |||
/// <returns> | |||
/// The amount of time it takes in milliseconds before a request is timed out. | |||
/// </returns> | |||
public const int DefaultRequestTimeout = 15000; | |||
/// <summary> | |||
/// Returns the max length for a Discord message. | |||
/// </summary> | |||
/// <returns> | |||
/// The maximum length of a message allowed by Discord. | |||
/// </returns> | |||
public const int MaxMessageSize = 2000; | |||
/// <summary> | |||
/// Returns the max messages allowed to be in a request. | |||
/// </summary> | |||
/// <returns> | |||
/// The maximum number of messages that can be gotten per-batch. | |||
/// </returns> | |||
public const int MaxMessagesPerBatch = 100; | |||
/// <summary> | |||
/// Returns the max users allowed to be in a request. | |||
/// </summary> | |||
/// <returns> | |||
/// The maximum number of users that can be gotten per-batch. | |||
/// </returns> | |||
public const int MaxUsersPerBatch = 1000; | |||
/// <summary> | |||
/// Returns the max guilds allowed to be in a request. | |||
/// </summary> | |||
/// <returns> | |||
/// The maximum number of guilds that can be gotten per-batch. | |||
/// </returns> | |||
public const int MaxGuildsPerBatch = 100; | |||
/// <summary> | |||
/// Gets or sets how a request should act in the case of an error, by default. | |||
/// </summary> | |||
/// <returns> | |||
/// The currently set <see cref="RetryMode"/>. | |||
/// </returns> | |||
public RetryMode DefaultRetryMode { get; set; } = RetryMode.AlwaysRetry; | |||
/// <summary> | |||
/// Gets or sets the minimum log level severity that will be sent to the Log event. | |||
/// </summary> | |||
/// <returns> | |||
/// The currently set <see cref="LogSeverity"/> for logging level. | |||
/// </returns> | |||
public LogSeverity LogLevel { get; set; } = LogSeverity.Info; | |||
/// <summary> | |||
/// Gets or sets whether the initial log entry should be printed. | |||
/// </summary> | |||
/// <remarks> | |||
/// If set to <c>true</c>, the library will attempt to print the current version of the library, as well as | |||
/// the API version it uses on startup. | |||
/// </remarks> | |||
internal bool DisplayInitialLog { get; set; } = true; | |||
} | |||
} |
@@ -6,33 +6,54 @@ namespace Discord | |||
public interface IAttachment | |||
{ | |||
/// <summary> | |||
/// Gets the snowflake ID of the attachment. | |||
/// Gets the ID of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// A snowflake ID associated with this attachment. | |||
/// </returns> | |||
ulong Id { get; } | |||
/// <summary> | |||
/// Gets the filename of the attachment. | |||
/// Gets the filename of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// A string containing the full filename of this attachment (e.g. textFile.txt). | |||
/// </returns> | |||
string Filename { get; } | |||
/// <summary> | |||
/// Gets the URL of the attachment. | |||
/// Gets the URL of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// A string containing the URL of this attachment. | |||
/// </returns> | |||
string Url { get; } | |||
/// <summary> | |||
/// Gets the proxied URL of the attachment. | |||
/// Gets a proxied URL of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// A string containing the proxied URL of this attachment. | |||
/// </returns> | |||
string ProxyUrl { get; } | |||
/// <summary> | |||
/// Gets the file size of the attachment. | |||
/// Gets the file size of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// The size of this attachment in bytes. | |||
/// </returns> | |||
int Size { get; } | |||
/// <summary> | |||
/// Gets the height of the attachment if it is an image, or return <see langword="null" /> when it is not. | |||
/// Gets the height of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// The height of this attachment if it is a picture; otherwise <see langword="null"/>. | |||
/// </returns> | |||
int? Height { get; } | |||
/// <summary> | |||
/// Gets the width of the attachment if it is an image, or return <see langword="null" /> when it is not. | |||
/// Gets the width of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// The width of this attachment if it is a picture; otherwise <see langword="null"/>. | |||
/// </returns> | |||
int? Width { get; } | |||
} | |||
} |
@@ -9,56 +9,96 @@ namespace Discord | |||
public interface IEmbed | |||
{ | |||
/// <summary> | |||
/// Gets the title URL of the embed. | |||
/// Gets the title URL of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// A string containing the URL set in a title of the embed. | |||
/// </returns> | |||
string Url { get; } | |||
/// <summary> | |||
/// Gets the title of the embed. | |||
/// Gets the title of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The title of the embed. | |||
/// </returns> | |||
string Title { get; } | |||
/// <summary> | |||
/// Gets the description of the embed. | |||
/// Gets the description of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The description field of the embed. | |||
/// </returns> | |||
string Description { get; } | |||
/// <summary> | |||
/// Gets the type of the embed. | |||
/// Gets the type of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The type of the embed. | |||
/// </returns> | |||
EmbedType Type { get; } | |||
/// <summary> | |||
/// Gets the timestamp of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the timestamp of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// A <see cref="DateTimeOffset"/> based on the timestamp present at the bottom left of the embed, or | |||
/// <see langword="null" /> if none is set. | |||
/// </returns> | |||
DateTimeOffset? Timestamp { get; } | |||
/// <summary> | |||
/// Gets the sidebar color of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the color of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The color of the embed present on the side of the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
Color? Color { get; } | |||
/// <summary> | |||
/// Gets the image of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the image of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The image of the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
EmbedImage? Image { get; } | |||
/// <summary> | |||
/// Gets the video of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the video of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The video of the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
EmbedVideo? Video { get; } | |||
/// <summary> | |||
/// Gets the author field of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the author field of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The author field of the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
EmbedAuthor? Author { get; } | |||
/// <summary> | |||
/// Gets the footer field of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the footer field of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The author field of the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
EmbedFooter? Footer { get; } | |||
/// <summary> | |||
/// Gets the provider of the embed, or <see langword="null" /> if none is set. | |||
/// Gets the provider of this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The source of the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
EmbedProvider? Provider { get; } | |||
/// <summary> | |||
/// Gets the thumbnail featured in the embed, or <see langword="null" /> if none is set. | |||
/// Gets the thumbnail featured in this embed. | |||
/// </summary> | |||
/// <returns> | |||
/// The thumbnail featured in the embed, or <see langword="null" /> if none is set. | |||
/// </returns> | |||
EmbedThumbnail? Thumbnail { get; } | |||
/// <summary> | |||
/// Gets the fields of the embed. | |||
/// </summary> | |||
/// <returns> | |||
/// An array of the fields of the embed. | |||
/// </returns> | |||
ImmutableArray<EmbedField> Fields { get; } | |||
} | |||
} |
@@ -4,7 +4,7 @@ using System.Diagnostics; | |||
namespace Discord | |||
{ | |||
/// <summary> | |||
/// Represents a Discord color. | |||
/// Represents a color used in Discord. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public struct Color | |||
@@ -65,7 +65,7 @@ namespace Discord | |||
/// <summary> | |||
/// Initializes a <see cref="Color" /> struct with the given raw value. | |||
/// </summary> | |||
/// <param name="rawValue">A raw value for the color (e.g. <c>0x607D8B</c>).</param> | |||
/// <param name="rawValue">The raw value of the color (e.g. <c>0x607D8B</c>).</param> | |||
public Color(uint rawValue) | |||
{ | |||
RawValue = rawValue; | |||
@@ -73,9 +73,9 @@ namespace Discord | |||
/// <summary> | |||
/// Initializes a <see cref="Color" /> struct with the given RGB bytes. | |||
/// </summary> | |||
/// <param name="r">The <see langword="byte"/> that represents the red color.</param> | |||
/// <param name="g">The <see langword="byte"/> that represents the green color.</param> | |||
/// <param name="b">The <see langword="byte"/> that represents the blue color.</param> | |||
/// <param name="r">The byte that represents the red color.</param> | |||
/// <param name="g">The byte that represents the green color.</param> | |||
/// <param name="b">The byte that represents the blue color.</param> | |||
public Color(byte r, byte g, byte b) | |||
{ | |||
RawValue = | |||
@@ -126,8 +126,11 @@ namespace Discord | |||
} | |||
/// <summary> | |||
/// Gets the hexadecimal representation of the color (e.g. #000ccc). | |||
/// Gets the hexadecimal representation of the color (e.g. <c>#000ccc</c>). | |||
/// </summary> | |||
/// <returns> | |||
/// A hexadecimal string of the color. | |||
/// </returns> | |||
public override string ToString() => | |||
$"#{Convert.ToString(RawValue, 16)}"; | |||
private string DebuggerDisplay => | |||
@@ -12,11 +12,11 @@ namespace Discord | |||
/// </summary> | |||
string AvatarId { get; } | |||
/// <summary> | |||
/// Returns the URL to this user's avatar. | |||
/// Returns a URL to this user's avatar. | |||
/// </summary> | |||
/// <param name="format">The format to return.</param> | |||
/// <param name="size"> | |||
/// The size of the image to return in. Image size can be any power of two between 16 and 2048. | |||
/// The size of the image to return in. This can be any power of two between 16 and 2048. | |||
/// </param> | |||
/// <returns> | |||
/// User's avatar URL. | |||
@@ -3,7 +3,9 @@ using Model = Discord.API.Attachment; | |||
namespace Discord | |||
{ | |||
/// <summary> A Discord attachment. </summary> | |||
/// <summary> | |||
/// An attachment file seen in a <see cref="IUserMessage" />. | |||
/// </summary> | |||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | |||
public class Attachment : IAttachment | |||
{ | |||
@@ -39,7 +41,12 @@ namespace Discord | |||
model.Width.IsSpecified ? model.Width.Value : (int?)null); | |||
} | |||
/// <summary> Returns the filename of the attachment. </summary> | |||
/// <summary> | |||
/// Returns the filename of this attachment. | |||
/// </summary> | |||
/// <returns> | |||
/// A string containing the filename of this attachment. | |||
/// </returns> | |||
public override string ToString() => Filename; | |||
private string DebuggerDisplay => $"{Filename} ({Size} bytes)"; | |||
} | |||