using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using System.Globalization; using System.Threading.Tasks; using EventUserModel = Discord.API.GuildScheduledEventUser; using Model = Discord.API.User; namespace Discord.Rest { /// /// Represents a REST-based user. /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public class RestUser : RestEntity, IUser, IUpdateable { #region RestUser /// public bool IsBot { get; private set; } /// public string Username { get; private set; } /// public ushort DiscriminatorValue { get; private set; } /// public string AvatarId { get; private set; } /// /// Gets the hash of the banner. /// /// /// if the user has no banner set. /// public string BannerId { get; private set; } /// /// Gets the color of the banner. /// /// /// if the user has no banner set. /// public Color? BannerColor { get; private set; } /// public Color? AccentColor { get; private set; } /// public UserProperties? PublicFlags { get; private set; } /// public string GlobalName { get; internal set; } /// public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id); /// public string Discriminator => DiscriminatorValue.ToString("D4"); /// public string Mention => MentionUtils.MentionUser(Id); /// public virtual IActivity Activity => null; /// public virtual UserStatus Status => UserStatus.Offline; /// public virtual IReadOnlyCollection ActiveClients => ImmutableHashSet.Empty; /// public virtual IReadOnlyCollection Activities => ImmutableList.Empty; /// public virtual bool IsWebhook => false; /// public string AvatarDecorationHash { get; private set; } /// public ulong? AvatarDecorationSkuId { get; private set; } /// public PrimaryGuild? PrimaryGuild { get; private set; } internal RestUser(BaseDiscordClient discord, ulong id) : base(discord, id) { } internal static RestUser Create(BaseDiscordClient discord, Model model) => Create(discord, null, model, null); internal static RestUser Create(BaseDiscordClient discord, IGuild guild, Model model, ulong? webhookId) { RestUser entity; if (webhookId.HasValue) entity = new RestWebhookUser(discord, guild, model.Id, webhookId.Value); else entity = new RestUser(discord, model.Id); entity.Update(model); return entity; } internal static RestUser Create(BaseDiscordClient discord, IGuild guild, EventUserModel model) { if (model.Member.IsSpecified) { var member = model.Member.Value; member.User = model.User; return RestGuildUser.Create(discord, guild, member); } else return RestUser.Create(discord, model.User); } internal virtual void Update(Model model) { if (model.Avatar.IsSpecified) AvatarId = model.Avatar.Value; if (model.Banner.IsSpecified) BannerId = model.Banner.Value; if (model.BannerColor.IsSpecified) BannerColor = model.BannerColor.Value; if (model.AccentColor.IsSpecified) AccentColor = model.AccentColor.Value; if (model.Discriminator.IsSpecified) DiscriminatorValue = ushort.Parse(model.Discriminator.GetValueOrDefault(null) ?? "0", NumberStyles.None, CultureInfo.InvariantCulture); if (model.Bot.IsSpecified) IsBot = model.Bot.Value; if (model.Username.IsSpecified) Username = model.Username.Value; if (model.PublicFlags.IsSpecified) PublicFlags = model.PublicFlags.Value; if (model.GlobalName.IsSpecified) GlobalName = model.GlobalName.Value; if (model.AvatarDecoration is { IsSpecified: true, Value: not null }) { AvatarDecorationHash = model.AvatarDecoration.Value?.Asset; AvatarDecorationSkuId = model.AvatarDecoration.Value?.SkuId; } if (model.PrimaryGuild.IsSpecified) { if (model.PrimaryGuild.Value is null) PrimaryGuild = null; else PrimaryGuild = new( model.PrimaryGuild.Value.GuildId, model.PrimaryGuild.Value.IdentityEnabled, model.PrimaryGuild.Value.Tag, model.PrimaryGuild.Value.BadgeHash); } } /// public virtual async Task UpdateAsync(RequestOptions options = null) { var model = await Discord.ApiClient.GetUserAsync(Id, options).ConfigureAwait(false); Update(model); } /// /// Creates a direct message channel to this user. /// /// The options to be used when sending the request. /// /// A task that represents the asynchronous get operation. The task result contains a rest DM channel where the user is the recipient. /// public Task CreateDMChannelAsync(RequestOptions options = null) => UserHelper.CreateDMChannelAsync(this, Discord, options); /// public string GetAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) => CDN.GetUserAvatarUrl(Id, AvatarId, size, format); /// public string GetBannerUrl(ImageFormat format = ImageFormat.Auto, ushort size = 256) => CDN.GetUserBannerUrl(Id, BannerId, size, format); /// public string GetDefaultAvatarUrl() => DiscriminatorValue != 0 ? CDN.GetDefaultUserAvatarUrl(DiscriminatorValue) : CDN.GetDefaultUserAvatarUrl(Id); public virtual string GetDisplayAvatarUrl(ImageFormat format = ImageFormat.Auto, ushort size = 128) => GetAvatarUrl(format, size) ?? GetDefaultAvatarUrl(); /// public string GetAvatarDecorationUrl() => AvatarDecorationHash is not null ? CDN.GetAvatarDecorationUrl(AvatarDecorationHash) : null; /// /// Gets the Username#Discriminator of the user. /// /// /// A string that resolves to Username#Discriminator of the user. /// public override string ToString() => Format.UsernameAndDiscriminator(this, Discord.FormatUsersInBidirectionalUnicode); private string DebuggerDisplay => $"{Format.UsernameAndDiscriminator(this, Discord.FormatUsersInBidirectionalUnicode)} ({Id}{(IsBot ? ", Bot" : "")})"; #endregion #region IUser /// async Task IUser.CreateDMChannelAsync(RequestOptions options) => await CreateDMChannelAsync(options).ConfigureAwait(false); #endregion } }