| @@ -4744,8 +4744,11 @@ | |||||
| Builds this builder into a <see cref="T:Discord.ButtonComponent"/> to be used in a <see cref="T:Discord.ComponentBuilder"/>. | Builds this builder into a <see cref="T:Discord.ButtonComponent"/> to be used in a <see cref="T:Discord.ComponentBuilder"/>. | ||||
| </summary> | </summary> | ||||
| <returns>A <see cref="T:Discord.ButtonComponent"/> to be used in a <see cref="T:Discord.ComponentBuilder"/>.</returns> | <returns>A <see cref="T:Discord.ButtonComponent"/> to be used in a <see cref="T:Discord.ComponentBuilder"/>.</returns> | ||||
| <exception cref="T:System.InvalidOperationException">A button cannot contain a <see cref="P:Discord.ButtonBuilder.Url"/> and a <see cref="P:Discord.ButtonBuilder.CustomId"/>.</exception> | |||||
| <exception cref="T:System.InvalidOperationException">A button must contain either a <see cref="P:Discord.ButtonBuilder.Url"/> or a <see cref="P:Discord.ButtonBuilder.CustomId"/>, but not both.</exception> | |||||
| <exception cref="T:System.InvalidOperationException">A button must have an <see cref="P:Discord.ButtonBuilder.Emote"/> or a <see cref="P:Discord.ButtonBuilder.Label"/>.</exception> | <exception cref="T:System.InvalidOperationException">A button must have an <see cref="P:Discord.ButtonBuilder.Emote"/> or a <see cref="P:Discord.ButtonBuilder.Label"/>.</exception> | ||||
| <exception cref="T:System.InvalidOperationException">A link button must contain a URL.</exception> | |||||
| <exception cref="T:System.InvalidOperationException">A link must include a protocol (http or https).</exception> | |||||
| <exception cref="T:System.InvalidOperationException">A non-link button must contain a custom id</exception> | |||||
| </member> | </member> | ||||
| <member name="T:Discord.SelectMenuBuilder"> | <member name="T:Discord.SelectMenuBuilder"> | ||||
| <summary> | <summary> | ||||
| @@ -6038,6 +6041,7 @@ | |||||
| The built embed object. | The built embed object. | ||||
| </returns> | </returns> | ||||
| <exception cref="T:System.InvalidOperationException">Total embed length exceeds <see cref="F:Discord.EmbedBuilder.MaxEmbedLength"/>.</exception> | <exception cref="T:System.InvalidOperationException">Total embed length exceeds <see cref="F:Discord.EmbedBuilder.MaxEmbedLength"/>.</exception> | ||||
| <exception cref="T:System.InvalidOperationException">Any Url must include protocols (i.e http:// or https://).</exception> | |||||
| </member> | </member> | ||||
| <member name="T:Discord.EmbedFieldBuilder"> | <member name="T:Discord.EmbedFieldBuilder"> | ||||
| <summary> | <summary> | ||||
| @@ -520,21 +520,29 @@ namespace Discord | |||||
| /// Builds this builder into a <see cref="ButtonComponent"/> to be used in a <see cref="ComponentBuilder"/>. | /// Builds this builder into a <see cref="ButtonComponent"/> to be used in a <see cref="ComponentBuilder"/>. | ||||
| /// </summary> | /// </summary> | ||||
| /// <returns>A <see cref="ButtonComponent"/> to be used in a <see cref="ComponentBuilder"/>.</returns> | /// <returns>A <see cref="ButtonComponent"/> to be used in a <see cref="ComponentBuilder"/>.</returns> | ||||
| /// <exception cref="InvalidOperationException">A button cannot contain a <see cref="Url"/> and a <see cref="CustomId"/>.</exception> | |||||
| /// <exception cref="InvalidOperationException">A button must contain either a <see cref="Url"/> or a <see cref="CustomId"/>, but not both.</exception> | |||||
| /// <exception cref="InvalidOperationException">A button must have an <see cref="Emote"/> or a <see cref="Label"/>.</exception> | /// <exception cref="InvalidOperationException">A button must have an <see cref="Emote"/> or a <see cref="Label"/>.</exception> | ||||
| /// <exception cref="InvalidOperationException">A link button must contain a URL.</exception> | |||||
| /// <exception cref="InvalidOperationException">A URL must include a protocol (http or https).</exception> | |||||
| /// <exception cref="InvalidOperationException">A non-link button must contain a custom id</exception> | |||||
| public ButtonComponent Build() | public ButtonComponent Build() | ||||
| { | { | ||||
| if (string.IsNullOrEmpty(this.Label) && this.Emote == null) | if (string.IsNullOrEmpty(this.Label) && this.Emote == null) | ||||
| throw new InvalidOperationException("A button must have an Emote or a label!"); | throw new InvalidOperationException("A button must have an Emote or a label!"); | ||||
| if (!string.IsNullOrEmpty(this.Url) && !string.IsNullOrEmpty(this.CustomId)) | |||||
| throw new InvalidOperationException("A button cannot contain a URL and a CustomId!"); | |||||
| if (!(string.IsNullOrEmpty(this.Url) ^ string.IsNullOrEmpty(this.CustomId))) | |||||
| throw new InvalidOperationException("A button must contain either a URL or a CustomId, but not both!"); | |||||
| if (this.Style == ButtonStyle.Link && !string.IsNullOrEmpty(this.CustomId)) | |||||
| this.CustomId = null; | |||||
| else if (this.Style != ButtonStyle.Link && !string.IsNullOrEmpty(this.Url)) // Thanks 𝑴𝒓𝑪𝒂𝒌𝒆𝑺𝒍𝒂𝒚𝒆𝒓 :D | |||||
| this.Url = null; | |||||
| if (this.Style == ButtonStyle.Link) | |||||
| { | |||||
| if (string.IsNullOrEmpty(this.Url)) | |||||
| throw new InvalidOperationException("Link buttons must have a link associated with them"); | |||||
| else if (!Uri.IsWellFormedUriString(this.Url, UriKind.Absolute)) | |||||
| throw new InvalidOperationException("Urls must be well formatted and include their protocol (either HTTP or HTTPS)"); | |||||
| } | |||||
| else if (string.IsNullOrEmpty(this.CustomId)) | |||||
| throw new InvalidOperationException("Non-link buttons must have a custom id associated with them"); | |||||
| return new ButtonComponent(this.Style, this.Label, this.Emote, this.CustomId, this.Url, this.Disabled); | return new ButtonComponent(this.Style, this.Label, this.Emote, this.CustomId, this.Url, this.Disabled); | ||||
| } | } | ||||
| @@ -401,10 +401,24 @@ namespace Discord | |||||
| /// The built embed object. | /// The built embed object. | ||||
| /// </returns> | /// </returns> | ||||
| /// <exception cref="InvalidOperationException">Total embed length exceeds <see cref="MaxEmbedLength"/>.</exception> | /// <exception cref="InvalidOperationException">Total embed length exceeds <see cref="MaxEmbedLength"/>.</exception> | ||||
| /// <exception cref="InvalidOperationException">Any Url must be well formatted include its protocols (i.e http:// or https://).</exception> | |||||
| public Embed Build() | public Embed Build() | ||||
| { | { | ||||
| if (Length > MaxEmbedLength) | if (Length > MaxEmbedLength) | ||||
| throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}."); | throw new InvalidOperationException($"Total embed length must be less than or equal to {MaxEmbedLength}."); | ||||
| if (!string.IsNullOrEmpty(Url) && !Uri.IsWellFormedUriString(Url, UriKind.Absolute)) | |||||
| throw new InvalidOperationException("Url must be well formatted and include its protocol (either HTTP or HTTPS)"); | |||||
| if (!string.IsNullOrEmpty(ThumbnailUrl) && !Uri.IsWellFormedUriString(ThumbnailUrl, UriKind.Absolute)) | |||||
| throw new InvalidOperationException("Thumbnail Url must be well formatted and include its protocol (either HTTP or HTTPS)"); | |||||
| if (!string.IsNullOrEmpty(ImageUrl) && !Uri.IsWellFormedUriString(ImageUrl, UriKind.Absolute)) | |||||
| throw new InvalidOperationException("Image Url must be well formatted and include its protocol (either HTTP or HTTPS)"); | |||||
| if (Author != null) | |||||
| { | |||||
| if(!string.IsNullOrEmpty(Author.Url) && !Uri.IsWellFormedUriString(Author.Url, UriKind.Absolute)) | |||||
| throw new InvalidOperationException("Author Url must be well formatted and include its protocol (either HTTP or HTTPS)"); | |||||
| if (!string.IsNullOrEmpty(Author.IconUrl) && !Uri.IsWellFormedUriString(Author.IconUrl, UriKind.Absolute)) | |||||
| throw new InvalidOperationException("Author Icon Url must be well formatted and include its protocol (either HTTP or HTTPS)"); | |||||
| } | |||||
| var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count); | var fields = ImmutableArray.CreateBuilder<EmbedField>(Fields.Count); | ||||
| for (int i = 0; i < Fields.Count; i++) | for (int i = 0; i < Fields.Count; i++) | ||||