diff --git a/Discord.Net/API/Endpoints.cs b/Discord.Net/API/Endpoints.cs index 554fb1913..4b07edc2e 100644 --- a/Discord.Net/API/Endpoints.cs +++ b/Discord.Net/API/Endpoints.cs @@ -3,6 +3,7 @@ internal static class Endpoints { public static readonly string BaseUrl = "discordapp.com"; + public static readonly string BaseShortUrl = "discord.gg"; public static readonly string BaseHttps = $"https://{BaseUrl}"; // /api @@ -49,5 +50,8 @@ //Web Sockets public static readonly string BaseWss = "wss://" + BaseUrl; public static readonly string WebSocket_Hub = $"{BaseWss}/hub"; + + //Website + public static string InviteUrl(string code) => $"{BaseShortUrl}/{code}"; } } diff --git a/Discord.Net/API/Models/Common.cs b/Discord.Net/API/Models/Common.cs index 8893aad38..fbbcfc062 100644 --- a/Discord.Net/API/Models/Common.cs +++ b/Discord.Net/API/Models/Common.cs @@ -117,7 +117,7 @@ namespace Discord.API.Models public class Membership { [JsonProperty(PropertyName = "roles")] - public object[] Roles; + public string[] Roles; [JsonProperty(PropertyName = "mute")] public bool IsMuted; [JsonProperty(PropertyName = "deaf")] diff --git a/Discord.Net/API/Models/WebSocketEvents.cs b/Discord.Net/API/Models/WebSocketEvents.cs index 58860df14..bb49e6fb8 100644 --- a/Discord.Net/API/Models/WebSocketEvents.cs +++ b/Discord.Net/API/Models/WebSocketEvents.cs @@ -48,12 +48,12 @@ namespace Discord.API.Models [JsonProperty(PropertyName = "joined_at")] public DateTime JoinedAt; [JsonProperty(PropertyName = "roles")] - public object[] Roles; + public string[] Roles; } public sealed class GuildMemberUpdate : GuildMemberEvent { [JsonProperty(PropertyName = "roles")] - public object[] Roles; + public string[] Roles; } public sealed class GuildMemberRemove : GuildMemberEvent { } diff --git a/Discord.Net/Discord.Net.csproj b/Discord.Net/Discord.Net.csproj index ca9170401..9325d90be 100644 --- a/Discord.Net/Discord.Net.csproj +++ b/Discord.Net/Discord.Net.csproj @@ -55,6 +55,7 @@ + diff --git a/Discord.Net/DiscordClient.Events.cs b/Discord.Net/DiscordClient.Events.cs index 6e604e021..fd6b9765f 100644 --- a/Discord.Net/DiscordClient.Events.cs +++ b/Discord.Net/DiscordClient.Events.cs @@ -176,32 +176,27 @@ namespace Discord //Member public sealed class MemberEventArgs : EventArgs { - public readonly User User; - public readonly Server Server; - internal MemberEventArgs(User user, Server server) - { - User = user; - Server = server; - } + public readonly Membership Membership; + internal MemberEventArgs(Membership membership) { Membership = membership; } } public event EventHandler MemberAdded; - private void RaiseMemberAdded(User user, Server server) + private void RaiseMemberAdded(Membership membership, Server server) { if (MemberAdded != null) - MemberAdded(this, new MemberEventArgs(user, server)); + MemberAdded(this, new MemberEventArgs(membership)); } public event EventHandler MemberRemoved; - private void RaiseMemberRemoved(User user, Server server) + private void RaiseMemberRemoved(Membership membership, Server server) { if (MemberRemoved != null) - MemberRemoved(this, new MemberEventArgs(user, server)); + MemberRemoved(this, new MemberEventArgs(membership)); } public event EventHandler MemberUpdated; - private void RaiseMemberUpdated(User user, Server server) + private void RaiseMemberUpdated(Membership membership, Server server) { if (MemberUpdated != null) - MemberUpdated(this, new MemberEventArgs(user, server)); + MemberUpdated(this, new MemberEventArgs(membership)); } //Status diff --git a/Discord.Net/DiscordClient.cs b/Discord.Net/DiscordClient.cs index c68720254..dcff97205 100644 --- a/Discord.Net/DiscordClient.cs +++ b/Discord.Net/DiscordClient.cs @@ -71,7 +71,7 @@ namespace Discord foreach (var channel in extendedModel.Channels) { _channels.Update(channel.Id, model.Id, channel); - if (channel.Type == ChannelTypes.Text) + /*if (channel.Type == ChannelTypes.Text) { try { @@ -84,12 +84,12 @@ namespace Discord } } catch { } //Bad Permissions? - } + }*/ } foreach (var membership in extendedModel.Members) { _users.Update(membership.User.Id, membership.User); - server.AddMember(membership.User.Id); + server.AddMember(new Membership(server.Id, membership.User.Id, membership.JoinedAt, this) { RoleIds = membership.Roles, IsMuted = membership.IsMuted, IsDeafened = membership.IsDeaf }); } } }, @@ -118,12 +118,13 @@ namespace Discord { var extendedModel = model as API.Models.Message; message.Attachments = extendedModel.Attachments; - message.Text = extendedModel.Content; message.Embeds = extendedModel.Embeds; message.IsMentioningEveryone = extendedModel.IsMentioningEveryone; message.IsTTS = extendedModel.IsTextToSpeech; - message.UserId = extendedModel.Author.Id; + message.MentionIds = extendedModel.Mentions.Select(x => x.Id).ToArray(); + message.UserId = extendedModel.Author.Id; message.Timestamp = extendedModel.Timestamp; + message.Text = extendedModel.Content; } if (model is WebSocketEvents.MessageUpdate) { @@ -137,8 +138,9 @@ namespace Discord (key, parentKey) => new Role(key, parentKey, this), (role, model) => { + role.Name = model.Name; role.Permissions = model.Permissions; - }, + }, role => { } ); _users = new AsyncCache( @@ -153,13 +155,13 @@ namespace Discord var extendedModel = model as SelfUserInfo; user.Email = extendedModel.Email; user.IsVerified = extendedModel.IsVerified; - } + } if (model is PresenceUserInfo) { var extendedModel = model as PresenceUserInfo; user.GameId = extendedModel.GameId; user.Status = extendedModel.Status; - } + } }, user => { } ); @@ -261,8 +263,9 @@ namespace Discord var data = e.Event.ToObject(); var user = _users.Update(data.User.Id, data.User); var server = _servers[data.GuildId]; - server._members[user.Id] = true; - RaiseMemberAdded(user, server); + var membership = new Membership(server.Id, data.User.Id, data.JoinedAt, this) { RoleIds = data.Roles }; + server.AddMember(membership); + RaiseMemberAdded(membership, server); } break; case "GUILD_MEMBER_UPDATE": @@ -270,7 +273,10 @@ namespace Discord var data = e.Event.ToObject(); var user = _users.Update(data.User.Id, data.User); var server = _servers[data.GuildId]; - RaiseMemberUpdated(user, server); + var membership = server.GetMembership(data.User.Id); + if (membership != null) + membership.RoleIds = data.Roles; + RaiseMemberUpdated(membership, server); } break; case "GUILD_MEMBER_REMOVE": @@ -278,8 +284,12 @@ namespace Discord var data = e.Event.ToObject(); var user = _users.Update(data.User.Id, data.User); var server = _servers[data.GuildId]; - if (server != null && server.RemoveMember(user.Id)) - RaiseMemberRemoved(user, server); + if (server != null) + { + var membership = server.RemoveMember(user.Id); + if (membership != null) + RaiseMemberRemoved(membership, server); + } } break; @@ -287,14 +297,14 @@ namespace Discord case "GUILD_ROLE_CREATE": { var data = e.Event.ToObject(); - var role = _roles.Update(data.Role.Id, data.Role); + var role = _roles.Update(data.Role.Id, data.GuildId, data.Role); RaiseRoleCreated(role); } break; case "GUILD_ROLE_UPDATE": { var data = e.Event.ToObject(); - var role = _roles.Update(data.Role.Id, data.Role); + var role = _roles.Update(data.Role.Id, data.GuildId, data.Role); RaiseRoleUpdated(role); } break; @@ -454,7 +464,9 @@ namespace Discord } public Role GetRole(string id) => _roles[id]; - public Role FindRole(string name) + public Role FindRole(Server server, string name) + => FindRole(server.Id, name); + public Role FindRole(string serverId, string name) { return _roles .Where(x => string.Equals(x.Name, name, StringComparison.InvariantCultureIgnoreCase)) @@ -515,13 +527,13 @@ namespace Discord } //Channels - public Task CreateChannel(Server server, string name, string region) - => CreateChannel(server.Id, name, region); - public async Task CreateChannel(string serverId, string name, string region) + public Task CreateChannel(Server server, string name, string type) + => CreateChannel(server.Id, name, type); + public async Task CreateChannel(string serverId, string name, string type) { CheckReady(); - var response = await DiscordAPI.CreateChannel(serverId, name, region, _httpOptions); - return _channels.Update(response.Id, response); + var response = await DiscordAPI.CreateChannel(serverId, name, type, _httpOptions); + return _channels.Update(response.Id, serverId, response); } public Task CreatePMChannel(User user) => CreatePMChannel(user.Id); diff --git a/Discord.Net/Invite.cs b/Discord.Net/Invite.cs index 64481a651..581007ff6 100644 --- a/Discord.Net/Invite.cs +++ b/Discord.Net/Invite.cs @@ -10,6 +10,8 @@ namespace Discord public bool IsRevoked, IsTemporary; public readonly string Code, XkcdPass; + public string Url { get { return API.Endpoints.InviteUrl(XkcdPass ?? Code); } } + public string InviterId { get; internal set; } [JsonIgnore] public User Inviter { get { return _client.GetUser(InviterId); } } diff --git a/Discord.Net/Membership.cs b/Discord.Net/Membership.cs new file mode 100644 index 000000000..f3f0ae6ca --- /dev/null +++ b/Discord.Net/Membership.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Discord +{ + public class Membership + { + private readonly DiscordClient _client; + + public DateTime JoinedAt; + + public bool IsMuted { get; internal set; } + public bool IsDeafened { get; internal set; } + + public string ServerId { get; } + public Server Server { get { return _client.GetServer(ServerId); } } + + public string UserId { get; } + public User User { get { return _client.GetUser(UserId); } } + + public string[] RoleIds { get; internal set; } + public IEnumerable Roles { get { return RoleIds.Select(x => _client.GetRole((string)x)); } } + + public Membership(string serverId, string userId, DateTime joinedAt, DiscordClient client) + { + ServerId = serverId; + UserId = userId; + _client = client; + JoinedAt = joinedAt; + } + } +} diff --git a/Discord.Net/Message.cs b/Discord.Net/Message.cs index fce6aa722..a4974c2db 100644 --- a/Discord.Net/Message.cs +++ b/Discord.Net/Message.cs @@ -1,5 +1,7 @@ using Newtonsoft.Json; using System; +using System.Collections.Generic; +using System.Linq; namespace Discord { @@ -14,6 +16,10 @@ namespace Discord public string Text { get; internal set; } public DateTime Timestamp { get; internal set; } + public string[] MentionIds { get; internal set; } + [JsonIgnore] + public IEnumerable Mentions { get { return MentionIds.Select(x => _client.GetUser(x)).Where(x => x != null); } } + public string ChannelId { get; } [JsonIgnore] public Channel Channel { get { return _client.GetChannel(ChannelId); } } diff --git a/Discord.Net/Properties/AssemblyInfo.cs b/Discord.Net/Properties/AssemblyInfo.cs index 927d3ed0f..1610bf95c 100644 --- a/Discord.Net/Properties/AssemblyInfo.cs +++ b/Discord.Net/Properties/AssemblyInfo.cs @@ -9,5 +9,5 @@ [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] -[assembly: AssemblyVersion("0.3.0.0")] -[assembly: AssemblyFileVersion("0.3.0.0")] +[assembly: AssemblyVersion("0.3.1.0")] +[assembly: AssemblyFileVersion("0.3.1.0")] diff --git a/Discord.Net/Role.cs b/Discord.Net/Role.cs index ccc774dfc..8178b57ca 100644 --- a/Discord.Net/Role.cs +++ b/Discord.Net/Role.cs @@ -18,6 +18,7 @@ namespace Discord internal Role(string id, string serverId, DiscordClient client) { Id = id; + ServerId = serverId; _client = client; } diff --git a/Discord.Net/Server.cs b/Discord.Net/Server.cs index 6796639da..993d40295 100644 --- a/Discord.Net/Server.cs +++ b/Discord.Net/Server.cs @@ -24,8 +24,8 @@ namespace Discord public string DefaultChannelId { get { return Id; } } public Channel DefaultChannel { get { return _client.GetChannel(DefaultChannelId); } } - internal ConcurrentDictionary _members; - public IEnumerable Members { get { return _members.Keys.Select(x => _client.GetUser(x)); } } + internal ConcurrentDictionary _members; + public IEnumerable Members { get { return _members.Values; } } internal ConcurrentDictionary _bans; public IEnumerable Bans { get { return _bans.Keys.Select(x => _client.GetUser(x)); } } @@ -41,7 +41,7 @@ namespace Discord { Id = id; _client = client; - _members = new ConcurrentDictionary(); + _members = new ConcurrentDictionary(); _bans = new ConcurrentDictionary(); } @@ -50,24 +50,33 @@ namespace Discord return Name; } - internal void AddMember(string id) + internal void AddMember(Membership membership) { - _members.TryAdd(id, true); + _members[membership.UserId] = membership; } - internal bool RemoveMember(string id) + internal Membership RemoveMember(string userId) { - bool ignored; - return _members.TryRemove(id, out ignored); + Membership result = null; + _members.TryRemove(userId, out result); + return result; + } + public Membership GetMembership(User user) + => GetMembership(user.Id); + public Membership GetMembership(string userId) + { + Membership result = null; + _members.TryGetValue(userId, out result); + return result; } - internal void AddBan(string id) + internal void AddBan(string banId) { - _bans.TryAdd(id, true); + _bans.TryAdd(banId, true); } - internal bool RemoveBan(string id) + internal bool RemoveBan(string banId) { bool ignored; - return _bans.TryRemove(id, out ignored); + return _bans.TryRemove(banId, out ignored); } } }