| @@ -113,7 +113,7 @@ namespace Discord.Rest | |||||
| /// A <see cref="RestInteraction"/> that represents the incoming http interaction. | /// A <see cref="RestInteraction"/> that represents the incoming http interaction. | ||||
| /// </returns> | /// </returns> | ||||
| /// <exception cref="BadSignatureException">Thrown when the signature doesn't match the public key.</exception> | /// <exception cref="BadSignatureException">Thrown when the signature doesn't match the public key.</exception> | ||||
| public Task<RestInteraction> ParseHttpInteractionAsync(string publicKey, string signature, string timestamp, string body) | |||||
| public RestInteraction ParseHttpInteractionAsync(string publicKey, string signature, string timestamp, string body) | |||||
| => ParseHttpInteractionAsync(publicKey, signature, timestamp, Encoding.UTF8.GetBytes(body)); | => ParseHttpInteractionAsync(publicKey, signature, timestamp, Encoding.UTF8.GetBytes(body)); | ||||
| /// <summary> | /// <summary> | ||||
| @@ -127,7 +127,7 @@ namespace Discord.Rest | |||||
| /// A <see cref="RestInteraction"/> that represents the incoming http interaction. | /// A <see cref="RestInteraction"/> that represents the incoming http interaction. | ||||
| /// </returns> | /// </returns> | ||||
| /// <exception cref="BadSignatureException">Thrown when the signature doesn't match the public key.</exception> | /// <exception cref="BadSignatureException">Thrown when the signature doesn't match the public key.</exception> | ||||
| public async Task<RestInteraction> ParseHttpInteractionAsync(string publicKey, string signature, string timestamp, byte[] body) | |||||
| public RestInteraction ParseHttpInteractionAsync(string publicKey, string signature, string timestamp, byte[] body) | |||||
| { | { | ||||
| if (!IsValidHttpInteraction(publicKey, signature, timestamp, body)) | if (!IsValidHttpInteraction(publicKey, signature, timestamp, body)) | ||||
| { | { | ||||
| @@ -138,7 +138,7 @@ namespace Discord.Rest | |||||
| using (var jsonReader = new JsonTextReader(textReader)) | using (var jsonReader = new JsonTextReader(textReader)) | ||||
| { | { | ||||
| var model = Serializer.Deserialize<API.Interaction>(jsonReader); | var model = Serializer.Deserialize<API.Interaction>(jsonReader); | ||||
| return await RestInteraction.CreateAsync(this, model); | |||||
| return RestInteraction.Create(this, model); | |||||
| } | } | ||||
| } | } | ||||
| @@ -39,16 +39,16 @@ namespace Discord.Rest | |||||
| { | { | ||||
| } | } | ||||
| internal new static async Task<RestCommandBase> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal new static RestCommandBase Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestCommandBase(client, model); | var entity = new RestCommandBase(client, model); | ||||
| await entity.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal override async Task UpdateAsync(DiscordRestClient client, Model model) | |||||
| internal override void Update(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| await base.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| base.Update(client, model); | |||||
| } | } | ||||
| /// <summary> | /// <summary> | ||||
| @@ -27,20 +27,20 @@ namespace Discord.Rest | |||||
| { | { | ||||
| } | } | ||||
| internal static async Task<RestCommandBaseData> CreateAsync(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| internal static RestCommandBaseData Create(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| { | { | ||||
| var entity = new RestCommandBaseData(client, model); | var entity = new RestCommandBaseData(client, model); | ||||
| await entity.UpdateAsync(client, model, guild, channel).ConfigureAwait(false); | |||||
| entity.Update(client, model, guild, channel); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal virtual async Task UpdateAsync(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| internal virtual void Update(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| { | { | ||||
| Name = model.Name; | Name = model.Name; | ||||
| if (model.Resolved.IsSpecified && ResolvableData == null) | if (model.Resolved.IsSpecified && ResolvableData == null) | ||||
| { | { | ||||
| ResolvableData = new RestResolvableData<Model>(); | ResolvableData = new RestResolvableData<Model>(); | ||||
| await ResolvableData.PopulateAsync(client, guild, channel, model).ConfigureAwait(false); | |||||
| ResolvableData.PopulateAsync(client, guild, channel, model).ConfigureAwait(false); | |||||
| } | } | ||||
| } | } | ||||
| @@ -20,22 +20,22 @@ namespace Discord.Rest | |||||
| } | } | ||||
| internal new static async Task<RestMessageCommand> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal new static RestMessageCommand Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestMessageCommand(client, model); | var entity = new RestMessageCommand(client, model); | ||||
| await entity.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal override async Task UpdateAsync(DiscordRestClient client, Model model) | |||||
| internal override void Update(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| await base.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| base.Update(client, model); | |||||
| var dataModel = model.Data.IsSpecified | var dataModel = model.Data.IsSpecified | ||||
| ? (DataModel)model.Data.Value | ? (DataModel)model.Data.Value | ||||
| : null; | : null; | ||||
| Data = await RestMessageCommandData.CreateAsync(client, dataModel, Guild, Channel).ConfigureAwait(false); | |||||
| Data = RestMessageCommandData.Create(client, dataModel, Guild, Channel); | |||||
| } | } | ||||
| //IMessageCommandInteraction | //IMessageCommandInteraction | ||||
| @@ -28,10 +28,10 @@ namespace Discord.Rest | |||||
| internal RestMessageCommandData(DiscordRestClient client, Model model) | internal RestMessageCommandData(DiscordRestClient client, Model model) | ||||
| : base(client, model) { } | : base(client, model) { } | ||||
| internal new static async Task<RestMessageCommandData> CreateAsync(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| internal new static RestMessageCommandData Create(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| { | { | ||||
| var entity = new RestMessageCommandData(client, model); | var entity = new RestMessageCommandData(client, model); | ||||
| await entity.UpdateAsync(client, model, guild, channel).ConfigureAwait(false); | |||||
| entity.Update(client, model, guild, channel); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -23,22 +23,22 @@ namespace Discord.Rest | |||||
| { | { | ||||
| } | } | ||||
| internal new static async Task<RestUserCommand> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal new static RestUserCommand Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestUserCommand(client, model); | var entity = new RestUserCommand(client, model); | ||||
| await entity.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal override async Task UpdateAsync(DiscordRestClient client, Model model) | |||||
| internal override void Update(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| await base.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| base.Update(client, model); | |||||
| var dataModel = model.Data.IsSpecified | var dataModel = model.Data.IsSpecified | ||||
| ? (DataModel)model.Data.Value | ? (DataModel)model.Data.Value | ||||
| : null; | : null; | ||||
| Data = await RestUserCommandData.CreateAsync(client, dataModel, Guild, Channel).ConfigureAwait(false); | |||||
| Data = RestUserCommandData.Create(client, dataModel, Guild, Channel); | |||||
| } | } | ||||
| //IUserCommandInteractionData | //IUserCommandInteractionData | ||||
| @@ -26,10 +26,10 @@ namespace Discord.Rest | |||||
| internal RestUserCommandData(DiscordRestClient client, Model model) | internal RestUserCommandData(DiscordRestClient client, Model model) | ||||
| : base(client, model) { } | : base(client, model) { } | ||||
| internal new static async Task<RestUserCommandData> CreateAsync(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| internal new static RestUserCommandData Create(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| { | { | ||||
| var entity = new RestUserCommandData(client, model); | var entity = new RestUserCommandData(client, model); | ||||
| await entity.UpdateAsync(client, model, guild, channel).ConfigureAwait(false); | |||||
| entity.Update(client, model, guild, channel); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -37,15 +37,15 @@ namespace Discord.Rest | |||||
| Data = new RestMessageComponentData(dataModel); | Data = new RestMessageComponentData(dataModel); | ||||
| } | } | ||||
| internal new static async Task<RestMessageComponent> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal new static RestMessageComponent Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestMessageComponent(client, model); | var entity = new RestMessageComponent(client, model); | ||||
| await entity.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal override async Task UpdateAsync(DiscordRestClient discord, Model model) | |||||
| internal override void Update(DiscordRestClient discord, Model model) | |||||
| { | { | ||||
| await base.UpdateAsync(discord, model).ConfigureAwait(false); | |||||
| base.Update(discord, model); | |||||
| if (model.Message.IsSpecified && model.ChannelId.IsSpecified) | if (model.Message.IsSpecified && model.ChannelId.IsSpecified) | ||||
| { | { | ||||
| @@ -26,10 +26,10 @@ namespace Discord.Rest | |||||
| Data = new RestModalData(dataModel); | Data = new RestModalData(dataModel); | ||||
| } | } | ||||
| internal new static async Task<RestModal> CreateAsync(DiscordRestClient client, ModelBase model) | |||||
| internal new static RestModal Create(DiscordRestClient client, ModelBase model) | |||||
| { | { | ||||
| var entity = new RestModal(client, model); | var entity = new RestModal(client, model); | ||||
| await entity.UpdateAsync(client, model); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -28,10 +28,16 @@ namespace Discord.Rest | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public int Version { get; private set; } | public int Version { get; private set; } | ||||
| private Lazy<RestUser> _user; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the user who invoked the interaction. | /// Gets the user who invoked the interaction. | ||||
| /// </summary> | /// </summary> | ||||
| public RestUser User { get; private set; } | |||||
| public RestUser User | |||||
| { | |||||
| get | |||||
| => _user.Value; | |||||
| } | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public string UserLocale { get; private set; } | public string UserLocale { get; private set; } | ||||
| @@ -48,15 +54,27 @@ namespace Discord.Rest | |||||
| public bool IsValidToken | public bool IsValidToken | ||||
| => InteractionHelper.CanRespondOrFollowup(this); | => InteractionHelper.CanRespondOrFollowup(this); | ||||
| private Lazy<IRestMessageChannel> _channel; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the channel that this interaction was executed in. | /// Gets the channel that this interaction was executed in. | ||||
| /// </summary> | /// </summary> | ||||
| public IRestMessageChannel Channel { get; private set; } | |||||
| public IRestMessageChannel Channel | |||||
| { | |||||
| get | |||||
| => _channel.Value; | |||||
| } | |||||
| private Lazy<RestGuild> _guild; | |||||
| /// <summary> | /// <summary> | ||||
| /// Gets the guild this interaction was executed in. | /// Gets the guild this interaction was executed in. | ||||
| /// </summary> | /// </summary> | ||||
| public RestGuild Guild { get; private set; } | |||||
| public RestGuild Guild | |||||
| { | |||||
| get | |||||
| => _guild.Value; | |||||
| } | |||||
| /// <inheritdoc/> | /// <inheritdoc/> | ||||
| public bool HasResponded { get; protected set; } | public bool HasResponded { get; protected set; } | ||||
| @@ -72,11 +90,11 @@ namespace Discord.Rest | |||||
| : DateTime.UtcNow; | : DateTime.UtcNow; | ||||
| } | } | ||||
| internal static async Task<RestInteraction> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal static RestInteraction Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| if(model.Type == InteractionType.Ping) | if(model.Type == InteractionType.Ping) | ||||
| { | { | ||||
| return await RestPingInteraction.CreateAsync(client, model); | |||||
| return RestPingInteraction.Create(client, model); | |||||
| } | } | ||||
| if (model.Type == InteractionType.ApplicationCommand) | if (model.Type == InteractionType.ApplicationCommand) | ||||
| @@ -90,26 +108,26 @@ namespace Discord.Rest | |||||
| return dataModel.Type switch | return dataModel.Type switch | ||||
| { | { | ||||
| ApplicationCommandType.Slash => await RestSlashCommand.CreateAsync(client, model).ConfigureAwait(false), | |||||
| ApplicationCommandType.Message => await RestMessageCommand.CreateAsync(client, model).ConfigureAwait(false), | |||||
| ApplicationCommandType.User => await RestUserCommand.CreateAsync(client, model).ConfigureAwait(false), | |||||
| ApplicationCommandType.Slash => RestSlashCommand.Create(client, model), | |||||
| ApplicationCommandType.Message => RestMessageCommand.Create(client, model), | |||||
| ApplicationCommandType.User => RestUserCommand.Create(client, model), | |||||
| _ => null | _ => null | ||||
| }; | }; | ||||
| } | } | ||||
| if (model.Type == InteractionType.MessageComponent) | if (model.Type == InteractionType.MessageComponent) | ||||
| return await RestMessageComponent.CreateAsync(client, model).ConfigureAwait(false); | |||||
| return RestMessageComponent.Create(client, model); | |||||
| if (model.Type == InteractionType.ApplicationCommandAutocomplete) | if (model.Type == InteractionType.ApplicationCommandAutocomplete) | ||||
| return await RestAutocompleteInteraction.CreateAsync(client, model).ConfigureAwait(false); | |||||
| return RestAutocompleteInteraction.Create(client, model); | |||||
| if (model.Type == InteractionType.ModalSubmit) | if (model.Type == InteractionType.ModalSubmit) | ||||
| return await RestModal.CreateAsync(client, model).ConfigureAwait(false); | |||||
| return RestModal.Create(client, model); | |||||
| return null; | return null; | ||||
| } | } | ||||
| internal virtual async Task UpdateAsync(DiscordRestClient discord, Model model) | |||||
| internal virtual void Update(DiscordRestClient discord, Model model) | |||||
| { | { | ||||
| IsDMInteraction = !model.GuildId.IsSpecified; | IsDMInteraction = !model.GuildId.IsSpecified; | ||||
| @@ -122,18 +140,18 @@ namespace Discord.Rest | |||||
| if(Guild == null && model.GuildId.IsSpecified) | if(Guild == null && model.GuildId.IsSpecified) | ||||
| { | { | ||||
| Guild = await discord.GetGuildAsync(model.GuildId.Value); | |||||
| _guild = new(() => discord.GetGuildAsync(model.GuildId.Value).GetAwaiter().GetResult()); // tbd | |||||
| } | } | ||||
| if (User == null) | if (User == null) | ||||
| { | { | ||||
| if (model.Member.IsSpecified && model.GuildId.IsSpecified) | if (model.Member.IsSpecified && model.GuildId.IsSpecified) | ||||
| { | { | ||||
| User = RestGuildUser.Create(Discord, Guild, model.Member.Value); | |||||
| _user = new(() => RestGuildUser.Create(Discord, Guild, model.Member.Value)); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| User = RestUser.Create(Discord, model.User.Value); | |||||
| _user = new(() => RestUser.Create(Discord, model.User.Value)); | |||||
| } | } | ||||
| } | } | ||||
| @@ -141,7 +159,7 @@ namespace Discord.Rest | |||||
| { | { | ||||
| try | try | ||||
| { | { | ||||
| Channel = (IRestMessageChannel)await discord.GetChannelAsync(model.ChannelId.Value); | |||||
| _channel = new(() => (IRestMessageChannel)discord.GetChannelAsync(model.ChannelId.Value).GetAwaiter().GetResult()); // tbd | |||||
| } | } | ||||
| catch(HttpException x) when(x.DiscordCode == DiscordErrorCode.MissingPermissions) { } // ignore | catch(HttpException x) when(x.DiscordCode == DiscordErrorCode.MissingPermissions) { } // ignore | ||||
| } | } | ||||
| @@ -18,10 +18,10 @@ namespace Discord.Rest | |||||
| { | { | ||||
| } | } | ||||
| internal static new async Task<RestPingInteraction> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal static new RestPingInteraction Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestPingInteraction(client, model.Id); | var entity = new RestPingInteraction(client, model.Id); | ||||
| await entity.UpdateAsync(client, model); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -32,10 +32,10 @@ namespace Discord.Rest | |||||
| Data = new RestAutocompleteInteractionData(dataModel); | Data = new RestAutocompleteInteractionData(dataModel); | ||||
| } | } | ||||
| internal new static async Task<RestAutocompleteInteraction> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal new static RestAutocompleteInteraction Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestAutocompleteInteraction(client, model); | var entity = new RestAutocompleteInteraction(client, model); | ||||
| await entity.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| @@ -23,22 +23,22 @@ namespace Discord.Rest | |||||
| { | { | ||||
| } | } | ||||
| internal new static async Task<RestSlashCommand> CreateAsync(DiscordRestClient client, Model model) | |||||
| internal new static RestSlashCommand Create(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| var entity = new RestSlashCommand(client, model); | var entity = new RestSlashCommand(client, model); | ||||
| await entity.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| entity.Update(client, model); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal override async Task UpdateAsync(DiscordRestClient client, Model model) | |||||
| internal override void Update(DiscordRestClient client, Model model) | |||||
| { | { | ||||
| await base.UpdateAsync(client, model).ConfigureAwait(false); | |||||
| base.Update(client, model); | |||||
| var dataModel = model.Data.IsSpecified | var dataModel = model.Data.IsSpecified | ||||
| ? (DataModel)model.Data.Value | ? (DataModel)model.Data.Value | ||||
| : null; | : null; | ||||
| Data = await RestSlashCommandData.CreateAsync(client, dataModel, Guild, Channel).ConfigureAwait(false); | |||||
| Data = RestSlashCommandData.Create(client, dataModel, Guild, Channel); | |||||
| } | } | ||||
| //ISlashCommandInteraction | //ISlashCommandInteraction | ||||
| @@ -14,15 +14,15 @@ namespace Discord.Rest | |||||
| internal RestSlashCommandData(DiscordRestClient client, Model model) | internal RestSlashCommandData(DiscordRestClient client, Model model) | ||||
| : base(client, model) { } | : base(client, model) { } | ||||
| internal static new async Task<RestSlashCommandData> CreateAsync(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| internal static new RestSlashCommandData Create(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| { | { | ||||
| var entity = new RestSlashCommandData(client, model); | var entity = new RestSlashCommandData(client, model); | ||||
| await entity.UpdateAsync(client, model, guild, channel).ConfigureAwait(false); | |||||
| entity.Update(client, model, guild, channel); | |||||
| return entity; | return entity; | ||||
| } | } | ||||
| internal override async Task UpdateAsync(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| internal override void Update(DiscordRestClient client, Model model, RestGuild guild, IRestMessageChannel channel) | |||||
| { | { | ||||
| await base.UpdateAsync(client, model, guild, channel).ConfigureAwait(false); | |||||
| base.Update(client, model, guild, channel); | |||||
| Options = model.Options.IsSpecified | Options = model.Options.IsSpecified | ||||
| ? model.Options.Value.Select(x => new RestSlashCommandDataOption(this, x)).ToImmutableArray() | ? model.Options.Value.Select(x => new RestSlashCommandDataOption(this, x)).ToImmutableArray() | ||||