| @@ -10,6 +10,8 @@ namespace Discord | |||||
| /// <summary> Gets the position of this channel in the guild's channel list, relative to others of the same type. </summary> | /// <summary> Gets the position of this channel in the guild's channel list, relative to others of the same type. </summary> | ||||
| int Position { get; } | int Position { get; } | ||||
| /// <summary> Gets the guild this channel is a member of. </summary> | |||||
| IGuild Guild { get; } | |||||
| /// <summary> Gets the id of the guild this channel is a member of. </summary> | /// <summary> Gets the id of the guild this channel is a member of. </summary> | ||||
| ulong GuildId { get; } | ulong GuildId { get; } | ||||
| /// <summary> Gets a collection of permission overwrites for this channel. </summary> | /// <summary> Gets a collection of permission overwrites for this channel. </summary> | ||||
| @@ -14,6 +14,7 @@ namespace Discord | |||||
| DateTimeOffset SyncedAt { get; } | DateTimeOffset SyncedAt { get; } | ||||
| IntegrationAccount Account { get; } | IntegrationAccount Account { get; } | ||||
| IGuild Guild { get; } | |||||
| ulong GuildId { get; } | ulong GuildId { get; } | ||||
| ulong RoleId { get; } | ulong RoleId { get; } | ||||
| IUser User { get; } | IUser User { get; } | ||||
| @@ -9,8 +9,12 @@ namespace Discord | |||||
| /// <summary> Gets the url used to accept this invite, using Code. </summary> | /// <summary> Gets the url used to accept this invite, using Code. </summary> | ||||
| string Url { get; } | string Url { get; } | ||||
| /// <summary> Gets the id of the the channel this invite is linked to. </summary> | |||||
| /// <summary> Gets the channel this invite is linked to. </summary> | |||||
| IChannel Channel { get; } | |||||
| /// <summary> Gets the id of the channel this invite is linked to. </summary> | |||||
| ulong ChannelId { get; } | ulong ChannelId { get; } | ||||
| /// <summary> Gets the guild this invite is linked to. </summary> | |||||
| IGuild Guild { get; } | |||||
| /// <summary> Gets the id of the guild this invite is linked to. </summary> | /// <summary> Gets the id of the guild this invite is linked to. </summary> | ||||
| ulong GuildId { get; } | ulong GuildId { get; } | ||||
| @@ -20,7 +20,7 @@ namespace Discord | |||||
| /// <summary> Gets the time of this message's last edit, if any. </summary> | /// <summary> Gets the time of this message's last edit, if any. </summary> | ||||
| DateTimeOffset? EditedTimestamp { get; } | DateTimeOffset? EditedTimestamp { get; } | ||||
| /// <summary> Gets the id of the channel this message was sent to. </summary> | |||||
| /// <summary> Gets the channel this message was sent to. </summary> | |||||
| IMessageChannel Channel { get; } | IMessageChannel Channel { get; } | ||||
| /// <summary> Gets the author of this message. </summary> | /// <summary> Gets the author of this message. </summary> | ||||
| IUser Author { get; } | IUser Author { get; } | ||||
| @@ -14,6 +14,8 @@ namespace Discord | |||||
| string Nickname { get; } | string Nickname { get; } | ||||
| GuildPermissions GuildPermissions { get; } | GuildPermissions GuildPermissions { get; } | ||||
| /// <summary> Gets the guild for this user. </summary> | |||||
| IGuild Guild { get; } | |||||
| /// <summary> Gets the id of the guild for this user. </summary> | /// <summary> Gets the id of the guild for this user. </summary> | ||||
| ulong GuildId { get; } | ulong GuildId { get; } | ||||
| /// <summary> Returns a collection of the ids of the roles this user is a member of in this guild, including the guild's @everyone role. </summary> | /// <summary> Returns a collection of the ids of the roles this user is a member of in this guild, including the guild's @everyone role. </summary> | ||||
| @@ -41,7 +41,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| var model = await client.ApiClient.GetInviteAsync(inviteId).ConfigureAwait(false); | var model = await client.ApiClient.GetInviteAsync(inviteId).ConfigureAwait(false); | ||||
| if (model != null) | if (model != null) | ||||
| return RestInvite.Create(client, model); | |||||
| return RestInvite.Create(client, null, null, model); | |||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -47,7 +47,7 @@ namespace Discord.Rest | |||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetChannelInvitesAsync(channel.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetChannelInvitesAsync(channel.Id, options).ConfigureAwait(false); | ||||
| return models.Select(x => RestInviteMetadata.Create(client, x)).ToImmutableArray(); | |||||
| return models.Select(x => RestInviteMetadata.Create(client, null, channel, x)).ToImmutableArray(); | |||||
| } | } | ||||
| public static async Task<RestInviteMetadata> CreateInviteAsync(IChannel channel, BaseDiscordClient client, | public static async Task<RestInviteMetadata> CreateInviteAsync(IChannel channel, BaseDiscordClient client, | ||||
| int? maxAge, int? maxUses, bool isTemporary, RequestOptions options) | int? maxAge, int? maxUses, bool isTemporary, RequestOptions options) | ||||
| @@ -58,7 +58,7 @@ namespace Discord.Rest | |||||
| if (maxUses.HasValue) | if (maxUses.HasValue) | ||||
| args.MaxUses = maxUses.Value; | args.MaxUses = maxUses.Value; | ||||
| var model = await client.ApiClient.CreateChannelInviteAsync(channel.Id, args, options).ConfigureAwait(false); | var model = await client.ApiClient.CreateChannelInviteAsync(channel.Id, args, options).ConfigureAwait(false); | ||||
| return RestInviteMetadata.Create(client, model); | |||||
| return RestInviteMetadata.Create(client, null, channel, model); | |||||
| } | } | ||||
| //Messages | //Messages | ||||
| @@ -125,6 +125,16 @@ namespace Discord.Rest | |||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| //IGuildChannel | //IGuildChannel | ||||
| IGuild IGuildChannel.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Guild != null) | |||||
| return Guild; | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | ||||
| => await GetInvitesAsync(options).ConfigureAwait(false); | => await GetInvitesAsync(options).ConfigureAwait(false); | ||||
| async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, RequestOptions options) | async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, RequestOptions options) | ||||
| @@ -117,14 +117,14 @@ namespace Discord.Rest | |||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetGuildIntegrationsAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildIntegrationsAsync(guild.Id, options).ConfigureAwait(false); | ||||
| return models.Select(x => RestGuildIntegration.Create(client, x)).ToImmutableArray(); | |||||
| return models.Select(x => RestGuildIntegration.Create(client, guild, x)).ToImmutableArray(); | |||||
| } | } | ||||
| public static async Task<RestGuildIntegration> CreateIntegrationAsync(IGuild guild, BaseDiscordClient client, | public static async Task<RestGuildIntegration> CreateIntegrationAsync(IGuild guild, BaseDiscordClient client, | ||||
| ulong id, string type, RequestOptions options) | ulong id, string type, RequestOptions options) | ||||
| { | { | ||||
| var args = new CreateGuildIntegrationParams(id, type); | var args = new CreateGuildIntegrationParams(id, type); | ||||
| var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false); | var model = await client.ApiClient.CreateGuildIntegrationAsync(guild.Id, args, options).ConfigureAwait(false); | ||||
| return RestGuildIntegration.Create(client, model); | |||||
| return RestGuildIntegration.Create(client, guild, model); | |||||
| } | } | ||||
| //Invites | //Invites | ||||
| @@ -132,7 +132,7 @@ namespace Discord.Rest | |||||
| RequestOptions options) | RequestOptions options) | ||||
| { | { | ||||
| var models = await client.ApiClient.GetGuildInvitesAsync(guild.Id, options).ConfigureAwait(false); | var models = await client.ApiClient.GetGuildInvitesAsync(guild.Id, options).ConfigureAwait(false); | ||||
| return models.Select(x => RestInviteMetadata.Create(client, x)).ToImmutableArray(); | |||||
| return models.Select(x => RestInviteMetadata.Create(client, guild, null, x)).ToImmutableArray(); | |||||
| } | } | ||||
| //Roles | //Roles | ||||
| @@ -21,16 +21,18 @@ namespace Discord.Rest | |||||
| public ulong RoleId { get; private set; } | public ulong RoleId { get; private set; } | ||||
| public RestUser User { get; private set; } | public RestUser User { get; private set; } | ||||
| public IntegrationAccount Account { get; private set; } | public IntegrationAccount Account { get; private set; } | ||||
| internal IGuild Guild { get; private set; } | |||||
| public DateTimeOffset SyncedAt => DateTimeUtils.FromTicks(_syncedAtTicks); | public DateTimeOffset SyncedAt => DateTimeUtils.FromTicks(_syncedAtTicks); | ||||
| internal RestGuildIntegration(BaseDiscordClient discord, ulong id) | |||||
| internal RestGuildIntegration(BaseDiscordClient discord, IGuild guild, ulong id) | |||||
| : base(discord, id) | : base(discord, id) | ||||
| { | { | ||||
| Guild = guild; | |||||
| } | } | ||||
| internal static RestGuildIntegration Create(BaseDiscordClient discord, Model model) | |||||
| internal static RestGuildIntegration Create(BaseDiscordClient discord, IGuild guild, Model model) | |||||
| { | { | ||||
| var entity = new RestGuildIntegration(discord, model.Id); | |||||
| var entity = new RestGuildIntegration(discord, guild, model.Id); | |||||
| entity.Update(model); | entity.Update(model); | ||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -71,6 +73,15 @@ namespace Discord.Rest | |||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| private string DebuggerDisplay => $"{Name} ({Id}{(IsEnabled ? ", Enabled" : "")})"; | private string DebuggerDisplay => $"{Name} ({Id}{(IsEnabled ? ", Enabled" : "")})"; | ||||
| IGuild IGuildIntegration.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Guild != null) | |||||
| return Guild; | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| IUser IGuildIntegration.User => User; | IUser IGuildIntegration.User => User; | ||||
| } | } | ||||
| } | } | ||||
| @@ -1,4 +1,5 @@ | |||||
| using System.Diagnostics; | |||||
| using System; | |||||
| using System.Diagnostics; | |||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||
| using Model = Discord.API.Invite; | using Model = Discord.API.Invite; | ||||
| @@ -11,17 +12,21 @@ namespace Discord.Rest | |||||
| public string GuildName { get; private set; } | public string GuildName { get; private set; } | ||||
| public ulong ChannelId { get; private set; } | public ulong ChannelId { get; private set; } | ||||
| public ulong GuildId { get; private set; } | public ulong GuildId { get; private set; } | ||||
| internal IChannel Channel { get; private set; } | |||||
| internal IGuild Guild { get; private set; } | |||||
| public string Code => Id; | public string Code => Id; | ||||
| public string Url => $"{DiscordConfig.InviteUrl}/{Code}"; | public string Url => $"{DiscordConfig.InviteUrl}/{Code}"; | ||||
| internal RestInvite(BaseDiscordClient discord, string id) | |||||
| internal RestInvite(BaseDiscordClient discord, IGuild guild, IChannel channel, string id) | |||||
| : base(discord, id) | : base(discord, id) | ||||
| { | { | ||||
| Guild = guild; | |||||
| Channel = channel; | |||||
| } | } | ||||
| internal static RestInvite Create(BaseDiscordClient discord, Model model) | |||||
| internal static RestInvite Create(BaseDiscordClient discord, IGuild guild, IChannel channel, Model model) | |||||
| { | { | ||||
| var entity = new RestInvite(discord, model.Code); | |||||
| var entity = new RestInvite(discord, guild, channel, model.Code); | |||||
| entity.Update(model); | entity.Update(model); | ||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -46,7 +51,27 @@ namespace Discord.Rest | |||||
| public override string ToString() => Url; | public override string ToString() => Url; | ||||
| private string DebuggerDisplay => $"{Url} ({GuildName} / {ChannelName})"; | private string DebuggerDisplay => $"{Url} ({GuildName} / {ChannelName})"; | ||||
| string IEntity<string>.Id => Code; | |||||
| IGuild IInvite.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Guild != null) | |||||
| return Guild; | |||||
| var guildChannel = Channel as IGuildChannel; | |||||
| if (guildChannel != null) | |||||
| return guildChannel.Guild; //If it fails, it'll still return this exception | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| IChannel IInvite.Channel | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Channel != null) | |||||
| return Channel; | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -1,5 +1,4 @@ | |||||
| using System; | using System; | ||||
| using System.Diagnostics; | |||||
| using Model = Discord.API.InviteMetadata; | using Model = Discord.API.InviteMetadata; | ||||
| namespace Discord.Rest | namespace Discord.Rest | ||||
| @@ -17,13 +16,13 @@ namespace Discord.Rest | |||||
| public DateTimeOffset CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks); | public DateTimeOffset CreatedAt => DateTimeUtils.FromTicks(_createdAtTicks); | ||||
| internal RestInviteMetadata(BaseDiscordClient discord, string id) | |||||
| : base(discord, id) | |||||
| internal RestInviteMetadata(BaseDiscordClient discord, IGuild guild, IChannel channel, string id) | |||||
| : base(discord, guild, channel, id) | |||||
| { | { | ||||
| } | } | ||||
| internal static RestInviteMetadata Create(BaseDiscordClient discord, Model model) | |||||
| internal static RestInviteMetadata Create(BaseDiscordClient discord, IGuild guild, IChannel channel, Model model) | |||||
| { | { | ||||
| var entity = new RestInviteMetadata(discord, model.Code); | |||||
| var entity = new RestInviteMetadata(discord, guild, channel, model.Code); | |||||
| entity.Update(model); | entity.Update(model); | ||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -86,6 +86,17 @@ namespace Discord.Rest | |||||
| return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); | return new ChannelPermissions(Permissions.ResolveChannel(Guild, this, channel, guildPerms.RawValue)); | ||||
| } | } | ||||
| //IGuildUser | |||||
| IGuild IGuildUser.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| if (Guild != null) | |||||
| return Guild; | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| //IVoiceState | //IVoiceState | ||||
| bool IVoiceState.IsSelfDeafened => false; | bool IVoiceState.IsSelfDeafened => false; | ||||
| bool IVoiceState.IsSelfMuted => false; | bool IVoiceState.IsSelfMuted => false; | ||||
| @@ -58,6 +58,15 @@ namespace Discord.Rpc | |||||
| public override string ToString() => Name; | public override string ToString() => Name; | ||||
| //IGuildChannel | //IGuildChannel | ||||
| IGuild IGuildChannel.Guild | |||||
| { | |||||
| get | |||||
| { | |||||
| //Always fails | |||||
| throw new InvalidOperationException("Unable to return this entity's parent unless it was fetched through that object."); | |||||
| } | |||||
| } | |||||
| async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | ||||
| => await GetInvitesAsync(options).ConfigureAwait(false); | => await GetInvitesAsync(options).ConfigureAwait(false); | ||||
| async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, RequestOptions options) | async Task<IInviteMetadata> IGuildChannel.CreateInviteAsync(int? maxAge, int? maxUses, bool isTemporary, RequestOptions options) | ||||
| @@ -126,6 +126,7 @@ namespace Discord.WebSocket | |||||
| internal override SocketUser GetUserInternal(ulong id) => GetUser(id); | internal override SocketUser GetUserInternal(ulong id) => GetUser(id); | ||||
| //IGuildChannel | //IGuildChannel | ||||
| IGuild IGuildChannel.Guild => Guild; | |||||
| ulong IGuildChannel.GuildId => Guild.Id; | ulong IGuildChannel.GuildId => Guild.Id; | ||||
| async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | async Task<IReadOnlyCollection<IInviteMetadata>> IGuildChannel.GetInvitesAsync(RequestOptions options) | ||||
| @@ -93,6 +93,7 @@ namespace Discord.WebSocket | |||||
| internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser; | internal new SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser; | ||||
| //IGuildUser | //IGuildUser | ||||
| IGuild IGuildUser.Guild => Guild; | |||||
| ulong IGuildUser.GuildId => Guild.Id; | ulong IGuildUser.GuildId => Guild.Id; | ||||
| IReadOnlyCollection<ulong> IGuildUser.RoleIds => RoleIds; | IReadOnlyCollection<ulong> IGuildUser.RoleIds => RoleIds; | ||||