diff --git a/src/Discord.Net/API/CDN.cs b/src/Discord.Net/API/CDN.cs index 27f0864cd..e3a501687 100644 --- a/src/Discord.Net/API/CDN.cs +++ b/src/Discord.Net/API/CDN.cs @@ -2,12 +2,14 @@ { internal static class CDN { + public static string GetApplicationIconUrl(ulong appId, string iconId) + => iconId != null ? $"{DiscordConfig.ClientAPIUrl}app-icons/{appId}/{iconId}.jpg" : null; public static string GetUserAvatarUrl(ulong userId, string avatarId) - => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null; + => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}avatars/{userId}/{avatarId}.jpg" : null; public static string GetGuildIconUrl(ulong guildId, string iconId) - => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/{guildId}/icons/{iconId}.jpg" : null; + => iconId != null ? $"{DiscordConfig.ClientAPIUrl}icons/{guildId}/{iconId}.jpg" : null; public static string GetGuildSplashUrl(ulong guildId, string splashId) - => splashId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/{guildId}/splashes/{splashId}.jpg" : null; + => splashId != null ? $"{DiscordConfig.ClientAPIUrl}splashes/{guildId}/{splashId}.jpg" : null; public static string GetChannelIconUrl(ulong channelId, string iconId) => iconId != null ? $"{DiscordConfig.ClientAPIUrl}channel-icons/{channelId}/{iconId}.jpg" : null; } diff --git a/src/Discord.Net/API/Common/Application.cs b/src/Discord.Net/API/Common/Application.cs new file mode 100644 index 000000000..751c50d92 --- /dev/null +++ b/src/Discord.Net/API/Common/Application.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; + +namespace Discord.API +{ + public class Application + { + [JsonProperty("description")] + public string Description { get; set; } + [JsonProperty("rpc_origins")] + public string[] RPCOrigins { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + [JsonProperty("flags"), Int53] + public ulong Flags { get; set; } + [JsonProperty("owner")] + public User Owner { get; set; } + [JsonProperty("id")] + public ulong Id { get; set; } + [JsonProperty("icon")] + public string Icon { get; set; } + } +} diff --git a/src/Discord.Net/API/DiscordAPIClient.cs b/src/Discord.Net/API/DiscordAPIClient.cs index 826eb0920..f13439517 100644 --- a/src/Discord.Net/API/DiscordAPIClient.cs +++ b/src/Discord.Net/API/DiscordAPIClient.cs @@ -351,6 +351,13 @@ namespace Discord.API await _sentGatewayMessageEvent.InvokeAsync(opCode).ConfigureAwait(false); } + //Application + public async Task GetMyApplicationInfoAsync(RequestOptions options = null) + { + return await SendAsync("GET", "oauth2/applications/@me", options: options).ConfigureAwait(false); + } + + //Auth public async Task ValidateTokenAsync(RequestOptions options = null) { diff --git a/src/Discord.Net/API/Rest/ApplicationInfo.cs b/src/Discord.Net/API/Rest/ApplicationInfo.cs new file mode 100644 index 000000000..ce9f833af --- /dev/null +++ b/src/Discord.Net/API/Rest/ApplicationInfo.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Discord.API.Rest +{ + public class ApplicationInfo + { + } +} diff --git a/src/Discord.Net/DiscordClient.cs b/src/Discord.Net/DiscordClient.cs index 34d96216d..13ce1632c 100644 --- a/src/Discord.Net/DiscordClient.cs +++ b/src/Discord.Net/DiscordClient.cs @@ -145,12 +145,12 @@ namespace Discord protected virtual Task OnLogoutAsync() => Task.CompletedTask; /// - public async Task> GetConnectionsAsync() + public async Task GetApplicationInfoAsync() { - var models = await ApiClient.GetMyConnectionsAsync().ConfigureAwait(false); - return models.Select(x => new Connection(x)).ToImmutableArray(); + var model = await ApiClient.GetMyApplicationInfoAsync().ConfigureAwait(false); + return new Application(this, model); } - + /// public virtual async Task GetChannelAsync(ulong id) { @@ -185,6 +185,13 @@ namespace Discord var models = await ApiClient.GetMyPrivateChannelsAsync().ConfigureAwait(false); return models.Select(x => new DMChannel(this, new User(x.Recipients.Value[0]), x)).ToImmutableArray(); } + + /// + public async Task> GetConnectionsAsync() + { + var models = await ApiClient.GetMyConnectionsAsync().ConfigureAwait(false); + return models.Select(x => new Connection(x)).ToImmutableArray(); + } /// public virtual async Task GetInviteAsync(string inviteIdOrXkcd) diff --git a/src/Discord.Net/Entities/Application.cs b/src/Discord.Net/Entities/Application.cs new file mode 100644 index 000000000..bee814fb4 --- /dev/null +++ b/src/Discord.Net/Entities/Application.cs @@ -0,0 +1,51 @@ +using System; +using System.Threading.Tasks; +using Model = Discord.API.Application; + +namespace Discord +{ + internal class Application : SnowflakeEntity, IApplication + { + protected string _iconId; + + public string Name { get; private set; } + public string Description { get; private set; } + public string[] RPCOrigins { get; private set; } + public ulong Flags { get; private set; } + + public override DiscordClient Discord { get; } + public IUser Owner { get; private set; } + + public string IconUrl => API.CDN.GetApplicationIconUrl(Id, _iconId); + + public Application(DiscordClient discord, Model model) + : base(model.Id) + { + Discord = discord; + + Update(model, UpdateSource.Creation); + } + + internal void Update(Model model, UpdateSource source) + { + if (source == UpdateSource.Rest && IsAttached) return; + + Description = model.Description; + RPCOrigins = model.RPCOrigins; + Name = model.Name; + Flags = model.Flags; + Owner = new User(model.Owner); + _iconId = model.Icon; + } + + public async Task UpdateAsync() + { + if (IsAttached) throw new NotSupportedException(); + + var response = await Discord.ApiClient.GetMyApplicationInfoAsync().ConfigureAwait(false); + if (response.Id != Id) + throw new InvalidOperationException("Unable to update this object from a different application token."); + Update(response, UpdateSource.Rest); + } + } +} diff --git a/src/Discord.Net/Entities/IApplication.cs b/src/Discord.Net/Entities/IApplication.cs new file mode 100644 index 000000000..157205226 --- /dev/null +++ b/src/Discord.Net/Entities/IApplication.cs @@ -0,0 +1,13 @@ +namespace Discord +{ + public interface IApplication : ISnowflakeEntity, IUpdateable + { + string Name { get; } + string Description { get; } + string[] RPCOrigins { get; } + ulong Flags { get; } + string IconUrl { get; } + + IUser Owner { get; } + } +} diff --git a/src/Discord.Net/IDiscordClient.cs b/src/Discord.Net/IDiscordClient.cs index 4753a7a30..9cc5c79d2 100644 --- a/src/Discord.Net/IDiscordClient.cs +++ b/src/Discord.Net/IDiscordClient.cs @@ -23,6 +23,8 @@ namespace Discord Task ConnectAsync(); Task DisconnectAsync(); + Task GetApplicationInfoAsync(); + Task GetChannelAsync(ulong id); Task> GetPrivateChannelsAsync();