| @@ -6,6 +6,20 @@ namespace Discord.API.Client | |||
| { | |||
| public class Guild : GuildReference | |||
| { | |||
| public sealed class EmojiData | |||
| { | |||
| [JsonProperty("id")] | |||
| public string Id { get; set; } | |||
| [JsonProperty("name")] | |||
| public string Name { get; set; } | |||
| [JsonProperty("roles"), JsonConverter(typeof(LongStringArrayConverter))] | |||
| public ulong[] RoleIds { get; set; } | |||
| [JsonProperty("require_colons")] | |||
| public bool RequireColons { get; set; } | |||
| [JsonProperty("managed")] | |||
| public bool IsManaged { get; set; } | |||
| } | |||
| [JsonProperty("afk_channel_id"), JsonConverter(typeof(NullableLongStringConverter))] | |||
| public ulong? AFKChannelId { get; set; } | |||
| [JsonProperty("afk_timeout")] | |||
| @@ -24,13 +38,11 @@ namespace Discord.API.Client | |||
| public string Region { get; set; } | |||
| [JsonProperty("roles")] | |||
| public Role[] Roles { get; set; } | |||
| //Unknown | |||
| [JsonProperty("splash")] | |||
| public object Splash { get; set; } | |||
| [JsonProperty("features")] | |||
| public object Features { get; set; } | |||
| public string[] Features { get; set; } | |||
| [JsonProperty("emojis")] | |||
| public object Emojis { get; set; } | |||
| public EmojiData[] Emojis { get; set; } | |||
| [JsonProperty("splash")] | |||
| public string Splash { get; set; } | |||
| } | |||
| } | |||
| @@ -24,7 +24,7 @@ namespace Discord.API.Client.Rest | |||
| [JsonProperty("afk_timeout")] | |||
| public int AFKTimeout { get; set; } | |||
| [JsonProperty("splash")] | |||
| public string Splash { get; set; } | |||
| public object Splash { get; set; } | |||
| public UpdateGuildRequest(ulong guildId) | |||
| { | |||
| @@ -31,7 +31,7 @@ namespace Discord | |||
| public const string ClientAPIUrl = "https://discordapp.com/api/"; | |||
| public const string StatusAPIUrl = "https://status.discordapp.com/api/v2/"; | |||
| public const string CDNUrl = "https://cdn.discordapp.com/"; | |||
| //public const string CDNUrl = "https://cdn.discordapp.com/"; | |||
| public const string InviteUrl = "https://discord.gg/"; | |||
| //Global | |||
| @@ -0,0 +1,9 @@ | |||
| using Discord.API.Client; | |||
| using System; | |||
| using System.Collections.Generic; | |||
| using System.Linq; | |||
| using System.Threading.Tasks; | |||
| namespace Discord.Models | |||
| { | |||
| } | |||
| @@ -135,23 +135,23 @@ namespace Discord | |||
| /// <summary> Summary of this embed. </summary> | |||
| public string Description { get; internal set; } | |||
| /// <summary> Returns information about the author of this embed. </summary> | |||
| public EmbedReference Author { get; internal set; } | |||
| public EmbedLink Author { get; internal set; } | |||
| /// <summary> Returns information about the providing website of this embed. </summary> | |||
| public EmbedReference Provider { get; internal set; } | |||
| public EmbedLink Provider { get; internal set; } | |||
| /// <summary> Returns the thumbnail of this embed. </summary> | |||
| public File Thumbnail { get; internal set; } | |||
| internal Embed() { } | |||
| } | |||
| public sealed class EmbedReference | |||
| { | |||
| public sealed class EmbedLink | |||
| { | |||
| /// <summary> URL of this embed provider. </summary> | |||
| public string Url { get; internal set; } | |||
| /// <summary> Name of this embed provider. </summary> | |||
| public string Name { get; internal set; } | |||
| internal EmbedReference() { } | |||
| internal EmbedLink() { } | |||
| } | |||
| public class File | |||
| @@ -241,13 +241,13 @@ namespace Discord | |||
| { | |||
| Embeds = model.Embeds.Select(x => | |||
| { | |||
| EmbedReference author = null, provider = null; | |||
| EmbedLink author = null, provider = null; | |||
| File thumbnail = null; | |||
| if (x.Author != null) | |||
| author = new EmbedReference { Url = x.Author.Url, Name = x.Author.Name }; | |||
| author = new EmbedLink { Url = x.Author.Url, Name = x.Author.Name }; | |||
| if (x.Provider != null) | |||
| provider = new EmbedReference { Url = x.Provider.Url, Name = x.Provider.Name }; | |||
| provider = new EmbedLink { Url = x.Provider.Url, Name = x.Provider.Name }; | |||
| if (x.Thumbnail != null) | |||
| thumbnail = new File { Url = x.Thumbnail.Url, ProxyUrl = x.Thumbnail.ProxyUrl, Width = x.Thumbnail.Width, Height = x.Thumbnail.Height }; | |||
| @@ -130,5 +130,10 @@ namespace Discord | |||
| public override bool Equals(object obj) => obj is Role && (obj as Role).Id == Id; | |||
| public override int GetHashCode() => unchecked(Id.GetHashCode() + 6653); | |||
| public override string ToString() => Name ?? Id.ToIdString(); | |||
| } | |||
| internal object Where(Func<object, bool> p) | |||
| { | |||
| throw new NotImplementedException(); | |||
| } | |||
| } | |||
| } | |||
| @@ -15,8 +15,24 @@ namespace Discord | |||
| public sealed class Server | |||
| { | |||
| internal static string GetIconUrl(ulong serverId, string iconId) | |||
| => iconId != null ? $"{DiscordConfig.CDNUrl}icons/{serverId}/{iconId}.jpg" : null; | |||
| => iconId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/${serverId}/icons/${iconId}.jpg" : null; | |||
| internal static string GetSplashUrl(ulong serverId, string splashId) | |||
| => splashId != null ? $"{DiscordConfig.ClientAPIUrl}guilds/{serverId}/splashes/{splashId}.jpg" : null; | |||
| public class Emoji | |||
| { | |||
| public string Id { get; } | |||
| public string Name { get; internal set; } | |||
| public bool IsManaged { get; internal set; } | |||
| public bool RequireColons { get; internal set; } | |||
| public IEnumerable<Role> Roles { get; internal set; } | |||
| internal Emoji(string id) | |||
| { | |||
| Id = id; | |||
| } | |||
| } | |||
| private struct Member | |||
| { | |||
| public readonly User User; | |||
| @@ -27,7 +43,7 @@ namespace Discord | |||
| Permissions = new ServerPermissions(); | |||
| Permissions.Lock(); | |||
| } | |||
| } | |||
| } | |||
| private readonly ConcurrentDictionary<ulong, Role> _roles; | |||
| private readonly ConcurrentDictionary<ulong, Member> _users; | |||
| @@ -50,10 +66,16 @@ namespace Discord | |||
| public Region Region { get; private set; } | |||
| /// <summary> Gets the unique identifier for this user's current avatar. </summary> | |||
| public string IconId { get; private set; } | |||
| /// <summary> Gets the unique identifier for this server's custom splash image. </summary> | |||
| public string SplashId { get; private set; } | |||
| /// <summary> Gets the amount of time (in seconds) a user must be inactive for until they are automatically moved to the AFK voice channel, if one is set. </summary> | |||
| public int AFKTimeout { get; private set; } | |||
| /// <summary> Gets the date and time you joined this server. </summary> | |||
| public DateTime JoinedAt { get; private set; } | |||
| /// <summary> Gets all extra features added to this server. </summary> | |||
| public IEnumerable<string> Features { get; private set; } | |||
| /// <summary> Gets all custom emojis on this server. </summary> | |||
| public IEnumerable<Emoji> CustomEmojis { get; private set; } | |||
| /// <summary> Gets the user that created this server. </summary> | |||
| public User Owner => GetUser(_ownerId); | |||
| @@ -65,7 +87,8 @@ namespace Discord | |||
| public User CurrentUser => GetUser(Client.CurrentUser.Id); | |||
| /// <summary> Gets the URL to this user's current avatar. </summary> | |||
| public string IconUrl => GetIconUrl(Id, IconId); | |||
| public string SplashUrl => GetSplashUrl(Id, SplashId); | |||
| /// <summary> Gets a collection of all channels in this server. </summary> | |||
| public IEnumerable<Channel> AllChannels => _channels.Select(x => x.Value); | |||
| /// <summary> Gets a collection of text channels in this server. </summary> | |||
| @@ -100,7 +123,6 @@ namespace Discord | |||
| if (model.AFKTimeout != null) | |||
| AFKTimeout = model.AFKTimeout.Value; | |||
| _afkChannelId = model.AFKChannelId; //Can be null | |||
| if (model.JoinedAt != null) | |||
| JoinedAt = model.JoinedAt.Value; | |||
| if (model.OwnerId != null) | |||
| @@ -109,6 +131,22 @@ namespace Discord | |||
| Region = Client.GetRegion(model.Region); | |||
| if (model.Icon != null) | |||
| IconId = model.Icon; | |||
| if (model.Features != null) | |||
| Features = model.Features; | |||
| if (model.Emojis != null) | |||
| { | |||
| CustomEmojis = model.Emojis.Select(x => new Emoji(x.Id) | |||
| { | |||
| Name = x.Name, | |||
| IsManaged = x.IsManaged, | |||
| RequireColons = x.RequireColons, | |||
| Roles = x.RoleIds.Select(y => GetRole(y)).Where(y => y != null).ToArray() | |||
| }).ToArray(); | |||
| } | |||
| //Can be null | |||
| _afkChannelId = model.AFKChannelId; | |||
| SplashId = model.Splash; | |||
| if (model.Roles != null) | |||
| { | |||
| @@ -151,7 +189,8 @@ namespace Discord | |||
| Region = region ?? Region.Id, | |||
| IconBase64 = icon.Base64(iconType, IconId), | |||
| AFKChannelId = AFKChannel?.Id, | |||
| AFKTimeout = AFKTimeout | |||
| AFKTimeout = AFKTimeout, | |||
| Splash = SplashId | |||
| }; | |||
| return Client.ClientAPI.Send(request); | |||
| } | |||
| @@ -12,7 +12,7 @@ namespace Discord | |||
| public sealed class User | |||
| { | |||
| internal static string GetAvatarUrl(ulong userId, string avatarId) | |||
| => avatarId != null ? $"{DiscordConfig.CDNUrl}avatars/{userId}/{avatarId}.jpg" : null; | |||
| => avatarId != null ? $"{DiscordConfig.ClientAPIUrl}users/{userId}/avatars/{avatarId}.jpg" : null; | |||
| [Flags] | |||
| private enum VoiceState : byte | |||