diff --git a/DisCatSharp/Entities/Guild/ScheduledEvent/DiscordScheduledEvent.cs b/DisCatSharp/Entities/Guild/ScheduledEvent/DiscordScheduledEvent.cs index b91b3f3f0..c2feb1d88 100644 --- a/DisCatSharp/Entities/Guild/ScheduledEvent/DiscordScheduledEvent.cs +++ b/DisCatSharp/Entities/Guild/ScheduledEvent/DiscordScheduledEvent.cs @@ -1,344 +1,344 @@ // This file is part of the DisCatSharp project, based off DSharpPlus. // // Copyright (c) 2021-2022 AITSYS // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. using System; using System.Collections.Generic; using System.Globalization; using System.Threading.Tasks; using DisCatSharp.Enums; using DisCatSharp.Net; using DisCatSharp.Net.Models; using Newtonsoft.Json; namespace DisCatSharp.Entities { /// /// Represents an scheduled event. /// public class DiscordScheduledEvent : SnowflakeObject, IEquatable { /// /// Gets the guild id of the associated scheduled event. /// [JsonProperty("guild_id", NullValueHandling = NullValueHandling.Ignore)] public ulong GuildId { get; internal set; } /// /// Gets the guild to which this scheduled event belongs. /// [JsonIgnore] public DiscordGuild Guild => this.Discord.Guilds.TryGetValue(this.GuildId, out var guild) ? guild : null; /// /// Gets the associated channel. /// [JsonIgnore] public Task Channel => this.ChannelId.HasValue ? this.Discord.ApiClient.GetChannelAsync(this.ChannelId.Value) : null; /// /// Gets id of the associated channel id. /// [JsonProperty("channel_id", NullValueHandling = NullValueHandling.Ignore)] public ulong? ChannelId { get; internal set; } /// /// Gets the ID of the user that created the scheduled event. /// [JsonProperty("creator_id")] public ulong CreatorId { get; internal set; } /// /// Gets the user that created the scheduled event. /// [JsonProperty("creator")] public DiscordUser Creator { get; internal set; } /// /// Gets the member that created the scheduled event. /// [JsonIgnore] public DiscordMember CreatorMember => this.Guild.MembersInternal.TryGetValue(this.CreatorId, out var owner) ? owner : this.Discord.ApiClient.GetGuildMemberAsync(this.GuildId, this.CreatorId).Result; /// /// Gets the name of the scheduled event. /// [JsonProperty("name", NullValueHandling = NullValueHandling.Ignore)] public string Name { get; internal set; } /// /// Gets the description of the scheduled event. /// [JsonProperty("description", NullValueHandling = NullValueHandling.Ignore)] public string Description { get; internal set; } /// /// Gets this event's cover hash, when applicable. /// [JsonProperty("image", NullValueHandling = NullValueHandling.Ignore)] public string CoverImageHash { get; internal set; } /// /// Gets this event's cover in url form. /// [JsonIgnore] public string CoverImageUrl - => !string.IsNullOrWhiteSpace(this.CoverImageHash) ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Uri}{Endpoints.GUILD_EVENTS}/{this.Id.ToString(CultureInfo.InvariantCulture)}/{this.CoverImageHash}" : null; + => !string.IsNullOrWhiteSpace(this.CoverImageHash) ? $"{DiscordDomain.GetDomain(CoreDomain.DiscordCdn).Uri}{Endpoints.GUILD_EVENTS}/{this.Id.ToString(CultureInfo.InvariantCulture)}/{this.CoverImageHash}.png" : null; // Somehow they does not include a extension. .{(this.CoverImageHash.StartsWith("a_") ? "gif" : "png")} /// /// Gets the scheduled start time of the scheduled event. /// [JsonIgnore] public DateTimeOffset? ScheduledStartTime => !string.IsNullOrWhiteSpace(this.ScheduledStartTimeRaw) && DateTimeOffset.TryParse(this.ScheduledStartTimeRaw, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dto) ? dto : null; /// /// Gets the scheduled start time of the scheduled event as raw string. /// [JsonProperty("scheduled_start_time", NullValueHandling = NullValueHandling.Ignore)] internal string ScheduledStartTimeRaw { get; set; } /// /// Gets the scheduled end time of the scheduled event. /// [JsonIgnore] public DateTimeOffset? ScheduledEndTime => !string.IsNullOrWhiteSpace(this.ScheduledEndTimeRaw) && DateTimeOffset.TryParse(this.ScheduledEndTimeRaw, CultureInfo.InvariantCulture, DateTimeStyles.None, out var dto) ? dto : null; /// /// Gets the scheduled end time of the scheduled event as raw string. /// [JsonProperty("scheduled_end_time", NullValueHandling = NullValueHandling.Ignore)] internal string ScheduledEndTimeRaw { get; set; } /// /// Gets the privacy level of the scheduled event. /// [JsonProperty("privacy_level", NullValueHandling = NullValueHandling.Ignore)] internal ScheduledEventPrivacyLevel PrivacyLevel { get; set; } /// /// Gets the status of the scheduled event. /// [JsonProperty("status", NullValueHandling = NullValueHandling.Ignore)] public ScheduledEventStatus Status { get; internal set; } /// /// Gets the entity type. /// [JsonProperty("entity_type", NullValueHandling = NullValueHandling.Ignore)] public ScheduledEventEntityType EntityType { get; internal set; } /// /// Gets id of the entity. /// [JsonProperty("entity_id", NullValueHandling = NullValueHandling.Ignore)] public ulong? EntityId { get; internal set; } /// /// Gets metadata of the entity. /// [JsonProperty("entity_metadata", NullValueHandling = NullValueHandling.Ignore)] public DiscordScheduledEventEntityMetadata EntityMetadata { get; internal set; } /* This isn't used. * See https://github.com/discord/discord-api-docs/pull/3586#issuecomment-969066061. * Was originally for paid stages. /// /// Gets the sku ids of the scheduled event. /// [JsonProperty("sku_ids", NullValueHandling = NullValueHandling.Ignore)] public IReadOnlyList SkuIds { get; internal set; }*/ /// /// Gets the total number of users subscribed to the scheduled event. /// [JsonProperty("user_count", NullValueHandling = NullValueHandling.Ignore)] public int UserCount { get; internal set; } /// /// Initializes a new instance of the class. /// internal DiscordScheduledEvent() { } #region Methods /// /// Modifies the current scheduled event. /// /// Action to perform on this thread /// Thrown when the client does not have the permission. /// Thrown when the event does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public async Task ModifyAsync(Action action) { var mdl = new ScheduledEventEditModel(); action(mdl); var channelId = Optional.FromNoValue(); if (mdl.Channel.HasValue && (mdl.Channel.Value.Type != ChannelType.Voice || mdl.Channel.Value.Type != ChannelType.Stage) && mdl.Channel.Value != null) throw new ArgumentException("Channel needs to be a voice or stage channel."); else if (mdl.Channel.HasValue && mdl.Channel.Value != null) channelId = mdl.Channel.Value.Id; if (this.EntityType != ScheduledEventEntityType.External && mdl.EntityType == ScheduledEventEntityType.External) channelId = null; var description = Optional.FromNoValue(); if (mdl.Description.HasValue && mdl.Description.Value != null) description = mdl.Description; else if (mdl.Description.HasValue) description = null; var coverb64 = Optional.FromNoValue(); if (mdl.CoverImage.HasValue && mdl.CoverImage.Value != null) using (var imgtool = new ImageTool(mdl.CoverImage.Value)) coverb64 = imgtool.GetBase64(); else if (mdl.CoverImage.HasValue) coverb64 = null; var scheduledEndTime = Optional.FromNoValue(); if (mdl.ScheduledEndTime.HasValue && mdl.ScheduledEndTime.Value != null && mdl.EntityType.HasValue ? mdl.EntityType == ScheduledEventEntityType.External : this.EntityType == ScheduledEventEntityType.External) scheduledEndTime = mdl.ScheduledEndTime.Value; await this.Discord.ApiClient.ModifyGuildScheduledEventAsync(this.GuildId, this.Id, channelId, this.EntityType == ScheduledEventEntityType.External ? new DiscordScheduledEventEntityMetadata(mdl.Location.Value) : null, mdl.Name, mdl.ScheduledStartTime, scheduledEndTime, description, mdl.EntityType, mdl.Status, coverb64, mdl.AuditLogReason); } /// /// Starts the current scheduled event. /// /// Thrown when the client does not have the permission. /// Thrown when the event does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public async Task StartAsync(string reason = null) => this.Status == ScheduledEventStatus.Scheduled ? await this.Discord.ApiClient.ModifyGuildScheduledEventStatusAsync(this.GuildId, this.Id, ScheduledEventStatus.Active, reason) : throw new InvalidOperationException("You can only start scheduled events"); /// /// Cancels the current scheduled event. /// /// The audit log reason. /// Thrown when the client does not have the permission. /// Thrown when the event does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public async Task CancelAsync(string reason = null) => this.Status == ScheduledEventStatus.Scheduled ? await this.Discord.ApiClient.ModifyGuildScheduledEventStatusAsync(this.GuildId, this.Id, ScheduledEventStatus.Canceled, reason) : throw new InvalidOperationException("You can only cancel scheduled events"); /// /// Ends the current scheduled event. /// /// The audit log reason. /// Thrown when the client does not have the permission. /// Thrown when the event does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public async Task EndAsync(string reason = null) => this.Status == ScheduledEventStatus.Active ? await this.Discord.ApiClient.ModifyGuildScheduledEventStatusAsync(this.GuildId, this.Id, ScheduledEventStatus.Completed, reason) : throw new InvalidOperationException("You can only stop active events"); /// /// Gets a list of users RSVP'd to the scheduled event. /// /// The limit how many users to receive from the event. Defaults to 100. Max 100. /// Get results of before the given snowflake. /// Get results of after the given snowflake. /// Wether to include guild member data. /// Thrown when the client does not have the correct permissions. /// Thrown when the event does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public async Task> GetUsersAsync(int? limit = null, ulong? before = null, ulong? after = null, bool? withMember = null) => await this.Discord.ApiClient.GetGuildScheduledEventRspvUsersAsync(this.GuildId, this.Id, limit, before, after, withMember); /// /// Deletes a scheduled event. /// /// The audit log reason. /// Thrown when the client does not have the permission. /// Thrown when the event does not exist. /// Thrown when an invalid parameter was provided. /// Thrown when Discord is unable to process the request. public async Task DeleteAsync(string reason = null) => await this.Discord.ApiClient.DeleteGuildScheduledEventAsync(this.GuildId, this.Id, reason); #endregion /// /// Checks whether this is equal to another object. /// /// Object to compare to. /// Whether the object is equal to this . public override bool Equals(object obj) => this.Equals(obj as DiscordScheduledEvent); /// /// Checks whether this is equal to another . /// /// to compare to. /// Whether the is equal to this . public bool Equals(DiscordScheduledEvent e) => e is not null && (ReferenceEquals(this, e) || this.Id == e.Id); /// /// Gets the hash code for this . /// /// The hash code for this . public override int GetHashCode() => this.Id.GetHashCode(); /// /// Gets whether the two objects are equal. /// /// First event to compare. /// Second ecent to compare. /// Whether the two events are equal. public static bool operator ==(DiscordScheduledEvent e1, DiscordScheduledEvent e2) { var o1 = e1 as object; var o2 = e2 as object; return (o1 != null || o2 == null) && (o1 == null || o2 != null) && ((o1 == null && o2 == null) || e1.Id == e2.Id); } /// /// Gets whether the two objects are not equal. /// /// First event to compare. /// Second event to compare. /// Whether the two events are not equal. public static bool operator !=(DiscordScheduledEvent e1, DiscordScheduledEvent e2) => !(e1 == e2); } }