diff --git a/src/Discord.Net.Core/Cache/CacheableEntityExtensions.cs b/src/Discord.Net.Core/Cache/CacheableEntityExtensions.cs index fb265f94a..6e6b0945f 100644 --- a/src/Discord.Net.Core/Cache/CacheableEntityExtensions.cs +++ b/src/Discord.Net.Core/Cache/CacheableEntityExtensions.cs @@ -8,7 +8,7 @@ namespace Discord { internal static class CacheableEntityExtensions { - public static IActivityModel ToModel(this RichGame richGame) where TModel : WritableActivityModel, new() + public static IActivityModel ToModel(this RichGame richGame) where TModel : IActivityModel, new() { return new TModel() { @@ -34,7 +34,7 @@ namespace Discord }; } - public static IActivityModel ToModel(this SpotifyGame spotify) where TModel : WritableActivityModel, new() + public static IActivityModel ToModel(this SpotifyGame spotify) where TModel : IActivityModel, new() { return new TModel() { @@ -53,11 +53,12 @@ namespace Discord } public static IActivityModel ToModel(this CustomStatusGame custom) - where TModel : WritableActivityModel, new() - where TEmoteModel : WritableEmojiModel, new() + where TModel : IActivityModel, new() + where TEmoteModel : IEmojiModel, new() { return new TModel { + Id = "custom", Type = ActivityType.CustomStatus, Name = custom.Name, State = custom.State, @@ -66,7 +67,7 @@ namespace Discord }; } - public static IActivityModel ToModel(this StreamingGame stream) where TModel : WritableActivityModel, new() + public static IActivityModel ToModel(this StreamingGame stream) where TModel : IActivityModel, new() { return new TModel { @@ -77,8 +78,11 @@ namespace Discord }; } - public static IEmojiModel ToModel(this IEmote emote) where TModel : WritableEmojiModel, new() + public static IEmojiModel ToModel(this IEmote emote) where TModel : IEmojiModel, new() { + if (emote == null) + return null; + var model = new TModel() { Name = emote.Name diff --git a/src/Discord.Net.Core/Cache/Models/Emoji/IEmojiModel.cs b/src/Discord.Net.Core/Cache/Models/Emoji/IEmojiModel.cs index bc5b43e2a..4a1270ba7 100644 --- a/src/Discord.Net.Core/Cache/Models/Emoji/IEmojiModel.cs +++ b/src/Discord.Net.Core/Cache/Models/Emoji/IEmojiModel.cs @@ -8,27 +8,14 @@ namespace Discord { public interface IEmojiModel { - ulong? Id { get; } - string Name { get; } - ulong[] Roles { get; } - bool RequireColons { get; } - bool IsManaged { get; } - bool IsAnimated { get; } - bool IsAvailable { get; } + ulong? Id { get; set; } + string Name { get; set; } + ulong[] Roles { get; set; } + bool RequireColons { get; set; } + bool IsManaged { get; set; } + bool IsAnimated { get; set; } + bool IsAvailable { get; set; } - ulong? CreatorId { get; } - } - - internal class WritableEmojiModel : IEmojiModel - { - public ulong? Id { get; set; } - public string Name { get; set; } - public ulong[] Roles { get; set; } - public bool RequireColons { get; set; } - public bool IsManaged { get; set; } - public bool IsAnimated { get; set; } - public bool IsAvailable { get; set; } - - public ulong? CreatorId { get; set; } + ulong? CreatorId { get; set; } } } diff --git a/src/Discord.Net.Core/Cache/Models/Presense/IActivityModel.cs b/src/Discord.Net.Core/Cache/Models/Presense/IActivityModel.cs index a66e88754..64633e604 100644 --- a/src/Discord.Net.Core/Cache/Models/Presense/IActivityModel.cs +++ b/src/Discord.Net.Core/Cache/Models/Presense/IActivityModel.cs @@ -8,81 +8,41 @@ namespace Discord { public interface IActivityModel { - string Id { get; } - string Url { get; } - string Name { get; } - ActivityType Type { get; } - string Details { get; } - string State { get; } - ActivityProperties Flags { get; } - DateTimeOffset CreatedAt { get; } - IEmojiModel Emoji { get; } - ulong? ApplicationId { get; } - string SyncId { get; } - string SessionId { get; } + string Id { get; set; } + string Url { get; set; } + string Name { get; set; } + ActivityType Type { get; set; } + string Details { get; set; } + string State { get; set; } + ActivityProperties Flags { get; set; } + DateTimeOffset CreatedAt { get; set; } + IEmojiModel Emoji { get; set; } + ulong? ApplicationId { get; set; } + string SyncId { get; set; } + string SessionId { get; set; } #region Assets - string LargeImage { get; } - string LargeText { get; } - string SmallImage { get; } - string SmallText { get; } + string LargeImage { get; set; } + string LargeText { get; set; } + string SmallImage { get; set; } + string SmallText { get; set; } #endregion #region Party - string PartyId { get; } - long[] PartySize { get; } + string PartyId { get; set; } + long[] PartySize { get; set; } #endregion #region Secrets - string JoinSecret { get; } - string SpectateSecret { get; } - string MatchSecret { get; } + string JoinSecret { get; set; } + string SpectateSecret { get; set; } + string MatchSecret { get; set; } #endregion #region Timestamps - DateTimeOffset? TimestampStart { get; } - DateTimeOffset? TimestampEnd { get; } - #endregion - } - - internal class WritableActivityModel : IActivityModel - { - public string Id { get; set; } - public string Url { get; set; } - public string Name { get; set; } - public ActivityType Type { get; set; } - public string Details { get; set; } - public string State { get; set; } - public ActivityProperties Flags { get; set; } - public DateTimeOffset CreatedAt { get; set; } - public IEmojiModel Emoji { get; set; } - public ulong? ApplicationId { get; set; } - public string SyncId { get; set; } - public string SessionId { get; set; } - - - #region Assets - public string LargeImage { get; set; } - public string LargeText { get; set; } - public string SmallImage { get; set; } - public string SmallText { get; set; } - #endregion - - #region Party - public string PartyId { get; set; } - public long[] PartySize { get; set; } - #endregion - - #region Secrets - public string JoinSecret { get; set; } - public string SpectateSecret { get; set; } - public string MatchSecret { get; set; } - #endregion - - #region Timestamps - public DateTimeOffset? TimestampStart { get; set; } - public DateTimeOffset? TimestampEnd { get; set; } + DateTimeOffset? TimestampStart { get; set; } + DateTimeOffset? TimestampEnd { get; set; } #endregion } } diff --git a/src/Discord.Net.Core/Cache/Models/Presense/IPresenceModel.cs b/src/Discord.Net.Core/Cache/Models/Presense/IPresenceModel.cs index c58a1fad5..887aa858b 100644 --- a/src/Discord.Net.Core/Cache/Models/Presense/IPresenceModel.cs +++ b/src/Discord.Net.Core/Cache/Models/Presense/IPresenceModel.cs @@ -8,10 +8,10 @@ namespace Discord { public interface IPresenceModel { - ulong UserId { get; } - ulong? GuildId { get; } - UserStatus Status { get; } - ClientType[] ActiveClients { get; } - IActivityModel[] Activities { get; } + ulong UserId { get; set; } + ulong? GuildId { get; set; } + UserStatus Status { get; set; } + ClientType[] ActiveClients { get; set; } + IActivityModel[] Activities { get; set; } } } diff --git a/src/Discord.Net.Core/Cache/Models/Users/ICurrentUserModel.cs b/src/Discord.Net.Core/Cache/Models/Users/ICurrentUserModel.cs index 80b832cf8..7d7b28995 100644 --- a/src/Discord.Net.Core/Cache/Models/Users/ICurrentUserModel.cs +++ b/src/Discord.Net.Core/Cache/Models/Users/ICurrentUserModel.cs @@ -8,12 +8,12 @@ namespace Discord { public interface ICurrentUserModel : IUserModel { - bool? IsVerified { get; } - string Email { get; } - bool? IsMfaEnabled { get; } - UserProperties Flags { get; } - PremiumType PremiumType { get; } - string Locale { get; } - UserProperties PublicFlags { get; } + bool? IsVerified { get; set; } + string Email { get; set; } + bool? IsMfaEnabled { get; set; } + UserProperties Flags { get; set; } + PremiumType PremiumType { get; set; } + string Locale { get; set; } + UserProperties PublicFlags { get; set; } } } diff --git a/src/Discord.Net.Core/Cache/Models/Users/IMemberModel.cs b/src/Discord.Net.Core/Cache/Models/Users/IMemberModel.cs index 3c3a67d5e..972fa7354 100644 --- a/src/Discord.Net.Core/Cache/Models/Users/IMemberModel.cs +++ b/src/Discord.Net.Core/Cache/Models/Users/IMemberModel.cs @@ -8,16 +8,16 @@ namespace Discord { public interface IMemberModel { - IUserModel User { get; } + IUserModel User { get; set; } - string Nickname { get; } - string GuildAvatar { get; } - ulong[] Roles { get; } - DateTimeOffset JoinedAt { get; } - DateTimeOffset? PremiumSince { get; } - bool IsDeaf { get; } - bool IsMute { get; } - bool? IsPending { get; } - DateTimeOffset? CommunicationsDisabledUntil { get; } + string Nickname { get; set; } + string GuildAvatar { get; set; } + ulong[] Roles { get; set; } + DateTimeOffset JoinedAt { get; set; } + DateTimeOffset? PremiumSince { get; set; } + bool IsDeaf { get; set; } + bool IsMute { get; set; } + bool? IsPending { get; set; } + DateTimeOffset? CommunicationsDisabledUntil { get; set; } } } diff --git a/src/Discord.Net.Core/Cache/Models/Users/IUserModel.cs b/src/Discord.Net.Core/Cache/Models/Users/IUserModel.cs index 24d05d0fc..6dcf1d9a7 100644 --- a/src/Discord.Net.Core/Cache/Models/Users/IUserModel.cs +++ b/src/Discord.Net.Core/Cache/Models/Users/IUserModel.cs @@ -6,11 +6,12 @@ using System.Threading.Tasks; namespace Discord { - public interface IUserModel : IEntity + public interface IUserModel { - string Username { get; } - string Discriminator { get; } - bool? IsBot { get; } - string Avatar { get; } + ulong Id { get; set; } + string Username { get; set; } + string Discriminator { get; set; } + bool? IsBot { get; set; } + string Avatar { get; set; } } } diff --git a/src/Discord.Net.Rest/API/Common/CurrentUser.cs b/src/Discord.Net.Rest/API/Common/CurrentUser.cs index 4a19056b2..626256ae1 100644 --- a/src/Discord.Net.Rest/API/Common/CurrentUser.cs +++ b/src/Discord.Net.Rest/API/Common/CurrentUser.cs @@ -25,18 +25,46 @@ namespace Discord.API public Optional PublicFlags { get; set; } // ICurrentUserModel - bool? ICurrentUserModel.IsVerified => Verified.ToNullable(); + bool? ICurrentUserModel.IsVerified + { + get => Verified.ToNullable(); + set => throw new NotSupportedException(); + } - string ICurrentUserModel.Email => Email.GetValueOrDefault(); + string ICurrentUserModel.Email + { + get => Email.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - bool? ICurrentUserModel.IsMfaEnabled => MfaEnabled.ToNullable(); + bool? ICurrentUserModel.IsMfaEnabled + { + get => MfaEnabled.ToNullable(); + set => throw new NotSupportedException(); + } - UserProperties ICurrentUserModel.Flags => Flags.GetValueOrDefault(); + UserProperties ICurrentUserModel.Flags + { + get => Flags.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - PremiumType ICurrentUserModel.PremiumType => PremiumType.GetValueOrDefault(); + PremiumType ICurrentUserModel.PremiumType + { + get => PremiumType.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - string ICurrentUserModel.Locale => Locale.GetValueOrDefault(); + string ICurrentUserModel.Locale + { + get => Locale.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - UserProperties ICurrentUserModel.PublicFlags => PublicFlags.GetValueOrDefault(); + UserProperties ICurrentUserModel.PublicFlags + { + get => PublicFlags.GetValueOrDefault(); + set => throw new NotSupportedException(); + } } } diff --git a/src/Discord.Net.Rest/API/Common/Emoji.cs b/src/Discord.Net.Rest/API/Common/Emoji.cs index af1a25532..2bc381fdb 100644 --- a/src/Discord.Net.Rest/API/Common/Emoji.cs +++ b/src/Discord.Net.Rest/API/Common/Emoji.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System; namespace Discord.API { @@ -21,20 +22,52 @@ namespace Discord.API [JsonProperty("user")] public Optional User { get; set; } - ulong? IEmojiModel.Id => Id; + ulong? IEmojiModel.Id + { + get => Id; + set => throw new NotSupportedException(); + } - string IEmojiModel.Name => Name; + string IEmojiModel.Name + { + get => Name; + set => throw new NotSupportedException(); + } - ulong[] IEmojiModel.Roles => Roles; + ulong[] IEmojiModel.Roles + { + get => Roles; + set => throw new NotSupportedException(); + } - bool IEmojiModel.RequireColons => RequireColons; + bool IEmojiModel.RequireColons + { + get => RequireColons; + set => throw new NotSupportedException(); + } - bool IEmojiModel.IsManaged => Managed; + bool IEmojiModel.IsManaged + { + get => Managed; + set => throw new NotSupportedException(); + } - bool IEmojiModel.IsAnimated => Animated.GetValueOrDefault(); + bool IEmojiModel.IsAnimated + { + get => Animated.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - bool IEmojiModel.IsAvailable => Available.GetValueOrDefault(); + bool IEmojiModel.IsAvailable + { + get => Available.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - ulong? IEmojiModel.CreatorId => User.GetValueOrDefault()?.Id; + ulong? IEmojiModel.CreatorId + { + get => User.GetValueOrDefault()?.Id; + set => throw new NotSupportedException(); + } } } diff --git a/src/Discord.Net.Rest/API/Common/Game.cs b/src/Discord.Net.Rest/API/Common/Game.cs index 32e0d5c51..133943d3e 100644 --- a/src/Discord.Net.Rest/API/Common/Game.cs +++ b/src/Discord.Net.Rest/API/Common/Game.cs @@ -42,50 +42,96 @@ namespace Discord.API [JsonProperty("created_at")] public Optional CreatedAt { get; set; } - string IActivityModel.Id => Id.GetValueOrDefault(); + string IActivityModel.Id { + get => Id.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.Url => StreamUrl.GetValueOrDefault(); + string IActivityModel.Url { + get => StreamUrl.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.State => State.GetValueOrDefault(); + string IActivityModel.State { + get => State.GetValueOrDefault(); set => throw new NotSupportedException(); + } - IEmojiModel IActivityModel.Emoji => Emoji.GetValueOrDefault(); + IEmojiModel IActivityModel.Emoji { + get => Emoji.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.Name => Name; + string IActivityModel.Name { + get => Name; set => throw new NotSupportedException(); + } - ActivityType IActivityModel.Type => Type.GetValueOrDefault().GetValueOrDefault(); + ActivityType IActivityModel.Type { + get => Type.GetValueOrDefault().GetValueOrDefault(); set => throw new NotSupportedException(); + } - ActivityProperties IActivityModel.Flags => Flags.GetValueOrDefault(); + ActivityProperties IActivityModel.Flags { + get => Flags.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.Details => Details.GetValueOrDefault(); - DateTimeOffset IActivityModel.CreatedAt => DateTimeOffset.FromUnixTimeMilliseconds(CreatedAt.GetValueOrDefault()); + string IActivityModel.Details { + get => Details.GetValueOrDefault(); set => throw new NotSupportedException(); + } + DateTimeOffset IActivityModel.CreatedAt { + get => DateTimeOffset.FromUnixTimeMilliseconds(CreatedAt.GetValueOrDefault()); set => throw new NotSupportedException(); + } - ulong? IActivityModel.ApplicationId => ApplicationId.ToNullable(); + ulong? IActivityModel.ApplicationId { + get => ApplicationId.ToNullable(); set => throw new NotSupportedException(); + } - string IActivityModel.SyncId => SyncId.GetValueOrDefault(); + string IActivityModel.SyncId { + get => SyncId.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.SessionId => SessionId.GetValueOrDefault(); + string IActivityModel.SessionId { + get => SessionId.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.LargeImage => Assets.GetValueOrDefault()?.LargeImage.GetValueOrDefault(); + string IActivityModel.LargeImage { + get => Assets.GetValueOrDefault()?.LargeImage.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.LargeText => Assets.GetValueOrDefault()?.LargeText.GetValueOrDefault(); + string IActivityModel.LargeText { + get => Assets.GetValueOrDefault()?.LargeText.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.SmallImage => Assets.GetValueOrDefault()?.SmallImage.GetValueOrDefault(); + string IActivityModel.SmallImage { + get => Assets.GetValueOrDefault()?.SmallImage.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.SmallText => Assets.GetValueOrDefault()?.SmallText.GetValueOrDefault(); + string IActivityModel.SmallText { + get => Assets.GetValueOrDefault()?.SmallText.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IActivityModel.PartyId => Party.GetValueOrDefault()?.Id; + string IActivityModel.PartyId { + get => Party.GetValueOrDefault()?.Id; set => throw new NotSupportedException(); + } - long[] IActivityModel.PartySize => Party.GetValueOrDefault()?.Size; + long[] IActivityModel.PartySize { + get => Party.GetValueOrDefault()?.Size; set => throw new NotSupportedException(); + } - string IActivityModel.JoinSecret => Secrets.GetValueOrDefault()?.Join; + string IActivityModel.JoinSecret { + get => Secrets.GetValueOrDefault()?.Join; set => throw new NotSupportedException(); + } - string IActivityModel.SpectateSecret => Secrets.GetValueOrDefault()?.Spectate; + string IActivityModel.SpectateSecret { + get => Secrets.GetValueOrDefault()?.Spectate; set => throw new NotSupportedException(); + } - string IActivityModel.MatchSecret => Secrets.GetValueOrDefault()?.Match; + string IActivityModel.MatchSecret { + get => Secrets.GetValueOrDefault()?.Match; set => throw new NotSupportedException(); + } - DateTimeOffset? IActivityModel.TimestampStart => Timestamps.GetValueOrDefault()?.Start.ToNullable(); + DateTimeOffset? IActivityModel.TimestampStart { + get => Timestamps.GetValueOrDefault()?.Start.ToNullable(); set => throw new NotSupportedException(); + } - DateTimeOffset? IActivityModel.TimestampEnd => Timestamps.GetValueOrDefault()?.End.ToNullable(); + DateTimeOffset? IActivityModel.TimestampEnd { + get => Timestamps.GetValueOrDefault()?.End.ToNullable(); set => throw new NotSupportedException(); + } diff --git a/src/Discord.Net.Rest/API/Common/GuildMember.cs b/src/Discord.Net.Rest/API/Common/GuildMember.cs index cfe4e652e..18aac3822 100644 --- a/src/Discord.Net.Rest/API/Common/GuildMember.cs +++ b/src/Discord.Net.Rest/API/Common/GuildMember.cs @@ -27,24 +27,44 @@ namespace Discord.API public Optional TimedOutUntil { get; set; } // IMemberModel - string IMemberModel.Nickname => Nick.GetValueOrDefault(); + string IMemberModel.Nickname { + get => Nick.GetValueOrDefault(); set => throw new NotSupportedException(); + } - string IMemberModel.GuildAvatar => Avatar.GetValueOrDefault(); + string IMemberModel.GuildAvatar { + get => Avatar.GetValueOrDefault(); set => throw new NotSupportedException(); + } - ulong[] IMemberModel.Roles => Roles.GetValueOrDefault(Array.Empty()); + ulong[] IMemberModel.Roles { + get => Roles.GetValueOrDefault(Array.Empty()); set => throw new NotSupportedException(); + } - DateTimeOffset IMemberModel.JoinedAt => JoinedAt.GetValueOrDefault(); + DateTimeOffset IMemberModel.JoinedAt { + get => JoinedAt.GetValueOrDefault(); set => throw new NotSupportedException(); + } - DateTimeOffset? IMemberModel.PremiumSince => PremiumSince.GetValueOrDefault(); + DateTimeOffset? IMemberModel.PremiumSince { + get => PremiumSince.GetValueOrDefault(); set => throw new NotSupportedException(); + } - bool IMemberModel.IsDeaf => Deaf.GetValueOrDefault(false); + bool IMemberModel.IsDeaf { + get => Deaf.GetValueOrDefault(false); set => throw new NotSupportedException(); + } - bool IMemberModel.IsMute => Mute.GetValueOrDefault(false); + bool IMemberModel.IsMute { + get => Mute.GetValueOrDefault(false); set => throw new NotSupportedException(); + } - bool? IMemberModel.IsPending => Pending.ToNullable(); + bool? IMemberModel.IsPending { + get => Pending.ToNullable(); set => throw new NotSupportedException(); + } - DateTimeOffset? IMemberModel.CommunicationsDisabledUntil => TimedOutUntil.GetValueOrDefault(); + DateTimeOffset? IMemberModel.CommunicationsDisabledUntil { + get => TimedOutUntil.GetValueOrDefault(); set => throw new NotSupportedException(); + } - IUserModel IMemberModel.User => User; + IUserModel IMemberModel.User { + get => User; set => throw new NotSupportedException(); + } } } diff --git a/src/Discord.Net.Rest/API/Common/Presence.cs b/src/Discord.Net.Rest/API/Common/Presence.cs index 173460242..4269074c0 100644 --- a/src/Discord.Net.Rest/API/Common/Presence.cs +++ b/src/Discord.Net.Rest/API/Common/Presence.cs @@ -30,16 +30,24 @@ namespace Discord.API [JsonProperty("premium_since")] public Optional PremiumSince { get; set; } - ulong IPresenceModel.UserId => User.Id; + ulong IPresenceModel.UserId { + get => User.Id; set => throw new NotSupportedException(); + } - ulong? IPresenceModel.GuildId => GuildId.ToNullable(); + ulong? IPresenceModel.GuildId { + get => GuildId.ToNullable(); set => throw new NotSupportedException(); + } - UserStatus IPresenceModel.Status => Status; + UserStatus IPresenceModel.Status { + get => Status; set => throw new NotSupportedException(); + } - ClientType[] IPresenceModel.ActiveClients => ClientStatus.IsSpecified - ? ClientStatus.Value.Select(x => (ClientType)Enum.Parse(typeof(ClientType), x.Key, true)).ToArray() - : Array.Empty(); + ClientType[] IPresenceModel.ActiveClients { + get => ClientStatus.IsSpecified ? ClientStatus.Value.Select(x => (ClientType)Enum.Parse(typeof(ClientType), x.Key, true)).ToArray() : Array.Empty(); set => throw new NotSupportedException(); + } - IActivityModel[] IPresenceModel.Activities => Activities.ToArray(); + IActivityModel[] IPresenceModel.Activities { + get => Activities.ToArray(); set => throw new NotSupportedException(); + } } } diff --git a/src/Discord.Net.Rest/API/Common/User.cs b/src/Discord.Net.Rest/API/Common/User.cs index 26e5deafd..03d23374f 100644 --- a/src/Discord.Net.Rest/API/Common/User.cs +++ b/src/Discord.Net.Rest/API/Common/User.cs @@ -1,4 +1,5 @@ using Newtonsoft.Json; +using System; namespace Discord.API { @@ -21,14 +22,31 @@ namespace Discord.API // IUserModel - string IUserModel.Username => Username.GetValueOrDefault(); + string IUserModel.Username + { + get => Username.GetValueOrDefault(); + set => throw new NotSupportedException(); + } - string IUserModel.Discriminator => Discriminator.GetValueOrDefault(); + string IUserModel.Discriminator { + get => Discriminator.GetValueOrDefault(); set => throw new NotSupportedException(); + } - bool? IUserModel.IsBot => Bot.ToNullable(); + bool? IUserModel.IsBot + { + get => Bot.ToNullable(); + set => throw new NotSupportedException(); + } - string IUserModel.Avatar => Avatar.GetValueOrDefault(); + string IUserModel.Avatar + { + get => Avatar.GetValueOrDefault(); set => throw new NotSupportedException(); + } - ulong IEntity.Id => Id; + ulong IUserModel.Id + { + get => Id; + set => throw new NotSupportedException(); + } } } diff --git a/src/Discord.Net.WebSocket/Cache/ICacheProvider.cs b/src/Discord.Net.WebSocket/Cache/ICacheProvider.cs index 265580193..5d67b892e 100644 --- a/src/Discord.Net.WebSocket/Cache/ICacheProvider.cs +++ b/src/Discord.Net.WebSocket/Cache/ICacheProvider.cs @@ -29,7 +29,7 @@ namespace Discord.WebSocket #region Presence ValueTask GetPresenceAsync(ulong userId, CacheRunMode runmode); - ValueTask AddOrUpdatePresenseAsync(ulong userId, IPresenceModel presense, CacheRunMode runmode); + ValueTask AddOrUpdatePresenseAsync(ulong userId, IPresenceModel model, CacheRunMode runmode); ValueTask RemovePresenseAsync(ulong userId, CacheRunMode runmode); #endregion diff --git a/src/Discord.Net.WebSocket/ClientStateManager.Experiment.cs b/src/Discord.Net.WebSocket/ClientStateManager.Experiment.cs index cc59c57aa..4ad2460a3 100644 --- a/src/Discord.Net.WebSocket/ClientStateManager.Experiment.cs +++ b/src/Discord.Net.WebSocket/ClientStateManager.Experiment.cs @@ -41,7 +41,10 @@ namespace Discord.WebSocket #region Global users internal void RemoveReferencedGlobalUser(ulong id) - => _userReferences.TryRemove(id, out _); + { + Console.WriteLine("Global user untracked"); + _userReferences.TryRemove(id, out _); + } private void TrackGlobalUser(ulong id, SocketGlobalUser user) { diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs index e6cd61bcc..9e64bc2bb 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs @@ -116,6 +116,45 @@ namespace Discord.WebSocket public ulong? GuildId { get; set; } } + private struct ActivityCacheModel : IActivityModel + { + public string Id { get; set; } + public string Url { get; set; } + public string Name { get; set; } + public ActivityType Type { get; set; } + public string Details { get; set; } + public string State { get; set; } + public ActivityProperties Flags { get; set; } + public DateTimeOffset CreatedAt { get; set; } + public IEmojiModel Emoji { get; set; } + public ulong? ApplicationId { get; set; } + public string SyncId { get; set; } + public string SessionId { get; set; } + public string LargeImage { get; set; } + public string LargeText { get; set; } + public string SmallImage { get; set; } + public string SmallText { get; set; } + public string PartyId { get; set; } + public long[] PartySize { get; set; } + public string JoinSecret { get; set; } + public string SpectateSecret { get; set; } + public string MatchSecret { get; set; } + public DateTimeOffset? TimestampStart { get; set; } + public DateTimeOffset? TimestampEnd { get; set; } + } + + private struct EmojiCacheModel : IEmojiModel + { + public ulong? Id { get; set; } + public string Name { get; set; } + public ulong[] Roles { get; set; } + public bool RequireColons { get; set; } + public bool IsManaged { get; set; } + public bool IsAnimated { get; set; } + public bool IsAvailable { get; set; } + public ulong? CreatorId { get; set; } + } + internal Model ToModel() { return new CacheModel @@ -132,18 +171,18 @@ namespace Discord.WebSocket switch (game) { case RichGame richGame: - return richGame.ToModel(); + return richGame.ToModel(); case SpotifyGame spotify: - return spotify.ToModel(); + return spotify.ToModel(); case CustomStatusGame custom: - return custom.ToModel(); + return custom.ToModel(); case StreamingGame stream: - return stream.ToModel(); + return stream.ToModel(); } break; } - return new WritableActivityModel + return new ActivityCacheModel { Name = x.Name, Details = x.Details, diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs index fca36184b..d61fe8ea7 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs @@ -15,7 +15,7 @@ namespace Discord.WebSocket /// Represents a WebSocket-based user. /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] - public abstract class SocketUser : SocketEntity, IUser, ICached + public abstract class SocketUser : SocketEntity, IUser, ICached, IDisposable { /// public abstract bool IsBot { get; internal set; } @@ -41,9 +41,9 @@ namespace Discord.WebSocket /// public UserStatus Status => Presence.Value.Status; /// - public IReadOnlyCollection ActiveClients => Presence.Value.ActiveClients ?? ImmutableHashSet.Empty; + public IReadOnlyCollection ActiveClients => Presence.Value?.ActiveClients ?? ImmutableHashSet.Empty; /// - public IReadOnlyCollection Activities => Presence.Value.Activities ?? ImmutableList.Empty; + public IReadOnlyCollection Activities => Presence.Value?.Activities ?? ImmutableList.Empty; /// /// Gets mutual guilds shared with this user. /// @@ -59,7 +59,7 @@ namespace Discord.WebSocket } internal virtual bool Update(ClientStateManager state, Model model) { - Presence ??= new Lazy(() => state.GetPresence(Id), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication); + Presence ??= new Lazy(() => state.GetPresence(Id), System.Threading.LazyThreadSafetyMode.PublicationOnly); bool hasChanges = false; if (model.Avatar != AvatarId) { @@ -117,6 +117,8 @@ namespace Discord.WebSocket /// The full name of the user. /// public override string ToString() => Format.UsernameAndDiscriminator(this, Discord.FormatUsersInBidirectionalUnicode); + ~SocketUser() => GlobalUser?.Dispose(); + public void Dispose() => GlobalUser?.Dispose(); private string DebuggerDisplay => $"{Format.UsernameAndDiscriminator(this, Discord.FormatUsersInBidirectionalUnicode)} ({Id}{(IsBot ? ", Bot" : "")})"; internal SocketUser Clone() => MemberwiseClone() as SocketUser;