@@ -8,7 +8,7 @@ namespace Discord | |||||
{ | { | ||||
internal static class CacheableEntityExtensions | internal static class CacheableEntityExtensions | ||||
{ | { | ||||
public static IActivityModel ToModel<TModel>(this RichGame richGame) where TModel : WritableActivityModel, new() | |||||
public static IActivityModel ToModel<TModel>(this RichGame richGame) where TModel : IActivityModel, new() | |||||
{ | { | ||||
return new TModel() | return new TModel() | ||||
{ | { | ||||
@@ -34,7 +34,7 @@ namespace Discord | |||||
}; | }; | ||||
} | } | ||||
public static IActivityModel ToModel<TModel>(this SpotifyGame spotify) where TModel : WritableActivityModel, new() | |||||
public static IActivityModel ToModel<TModel>(this SpotifyGame spotify) where TModel : IActivityModel, new() | |||||
{ | { | ||||
return new TModel() | return new TModel() | ||||
{ | { | ||||
@@ -53,11 +53,12 @@ namespace Discord | |||||
} | } | ||||
public static IActivityModel ToModel<TModel, TEmoteModel>(this CustomStatusGame custom) | public static IActivityModel ToModel<TModel, TEmoteModel>(this CustomStatusGame custom) | ||||
where TModel : WritableActivityModel, new() | |||||
where TEmoteModel : WritableEmojiModel, new() | |||||
where TModel : IActivityModel, new() | |||||
where TEmoteModel : IEmojiModel, new() | |||||
{ | { | ||||
return new TModel | return new TModel | ||||
{ | { | ||||
Id = "custom", | |||||
Type = ActivityType.CustomStatus, | Type = ActivityType.CustomStatus, | ||||
Name = custom.Name, | Name = custom.Name, | ||||
State = custom.State, | State = custom.State, | ||||
@@ -66,7 +67,7 @@ namespace Discord | |||||
}; | }; | ||||
} | } | ||||
public static IActivityModel ToModel<TModel>(this StreamingGame stream) where TModel : WritableActivityModel, new() | |||||
public static IActivityModel ToModel<TModel>(this StreamingGame stream) where TModel : IActivityModel, new() | |||||
{ | { | ||||
return new TModel | return new TModel | ||||
{ | { | ||||
@@ -77,8 +78,11 @@ namespace Discord | |||||
}; | }; | ||||
} | } | ||||
public static IEmojiModel ToModel<TModel>(this IEmote emote) where TModel : WritableEmojiModel, new() | |||||
public static IEmojiModel ToModel<TModel>(this IEmote emote) where TModel : IEmojiModel, new() | |||||
{ | { | ||||
if (emote == null) | |||||
return null; | |||||
var model = new TModel() | var model = new TModel() | ||||
{ | { | ||||
Name = emote.Name | Name = emote.Name | ||||
@@ -8,27 +8,14 @@ namespace Discord | |||||
{ | { | ||||
public interface IEmojiModel | 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; } | |||||
} | } | ||||
} | } |
@@ -8,81 +8,41 @@ namespace Discord | |||||
{ | { | ||||
public interface IActivityModel | 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 | #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 | #endregion | ||||
#region Party | #region Party | ||||
string PartyId { get; } | |||||
long[] PartySize { get; } | |||||
string PartyId { get; set; } | |||||
long[] PartySize { get; set; } | |||||
#endregion | #endregion | ||||
#region Secrets | #region Secrets | ||||
string JoinSecret { get; } | |||||
string SpectateSecret { get; } | |||||
string MatchSecret { get; } | |||||
string JoinSecret { get; set; } | |||||
string SpectateSecret { get; set; } | |||||
string MatchSecret { get; set; } | |||||
#endregion | #endregion | ||||
#region Timestamps | #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 | #endregion | ||||
} | } | ||||
} | } |
@@ -8,10 +8,10 @@ namespace Discord | |||||
{ | { | ||||
public interface IPresenceModel | 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; } | |||||
} | } | ||||
} | } |
@@ -8,12 +8,12 @@ namespace Discord | |||||
{ | { | ||||
public interface ICurrentUserModel : IUserModel | 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; } | |||||
} | } | ||||
} | } |
@@ -8,16 +8,16 @@ namespace Discord | |||||
{ | { | ||||
public interface IMemberModel | 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; } | |||||
} | } | ||||
} | } |
@@ -6,11 +6,12 @@ using System.Threading.Tasks; | |||||
namespace Discord | namespace Discord | ||||
{ | { | ||||
public interface IUserModel : IEntity<ulong> | |||||
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; } | |||||
} | } | ||||
} | } |
@@ -25,18 +25,46 @@ namespace Discord.API | |||||
public Optional<UserProperties> PublicFlags { get; set; } | public Optional<UserProperties> PublicFlags { get; set; } | ||||
// ICurrentUserModel | // 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(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,4 +1,5 @@ | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using System; | |||||
namespace Discord.API | namespace Discord.API | ||||
{ | { | ||||
@@ -21,20 +22,52 @@ namespace Discord.API | |||||
[JsonProperty("user")] | [JsonProperty("user")] | ||||
public Optional<User> User { get; set; } | public Optional<User> 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(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -42,50 +42,96 @@ namespace Discord.API | |||||
[JsonProperty("created_at")] | [JsonProperty("created_at")] | ||||
public Optional<long> CreatedAt { get; set; } | public Optional<long> 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(); | |||||
} | |||||
@@ -27,24 +27,44 @@ namespace Discord.API | |||||
public Optional<DateTimeOffset?> TimedOutUntil { get; set; } | public Optional<DateTimeOffset?> TimedOutUntil { get; set; } | ||||
// IMemberModel | // 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>()); | |||||
ulong[] IMemberModel.Roles { | |||||
get => Roles.GetValueOrDefault(Array.Empty<ulong>()); 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(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -30,16 +30,24 @@ namespace Discord.API | |||||
[JsonProperty("premium_since")] | [JsonProperty("premium_since")] | ||||
public Optional<DateTimeOffset?> PremiumSince { get; set; } | public Optional<DateTimeOffset?> 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>(); | |||||
ClientType[] IPresenceModel.ActiveClients { | |||||
get => ClientStatus.IsSpecified ? ClientStatus.Value.Select(x => (ClientType)Enum.Parse(typeof(ClientType), x.Key, true)).ToArray() : Array.Empty<ClientType>(); set => throw new NotSupportedException(); | |||||
} | |||||
IActivityModel[] IPresenceModel.Activities => Activities.ToArray(); | |||||
IActivityModel[] IPresenceModel.Activities { | |||||
get => Activities.ToArray(); set => throw new NotSupportedException(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -1,4 +1,5 @@ | |||||
using Newtonsoft.Json; | using Newtonsoft.Json; | ||||
using System; | |||||
namespace Discord.API | namespace Discord.API | ||||
{ | { | ||||
@@ -21,14 +22,31 @@ namespace Discord.API | |||||
// IUserModel | // 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<ulong>.Id => Id; | |||||
ulong IUserModel.Id | |||||
{ | |||||
get => Id; | |||||
set => throw new NotSupportedException(); | |||||
} | |||||
} | } | ||||
} | } |
@@ -29,7 +29,7 @@ namespace Discord.WebSocket | |||||
#region Presence | #region Presence | ||||
ValueTask<IPresenceModel> GetPresenceAsync(ulong userId, CacheRunMode runmode); | ValueTask<IPresenceModel> 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); | ValueTask RemovePresenseAsync(ulong userId, CacheRunMode runmode); | ||||
#endregion | #endregion | ||||
@@ -41,7 +41,10 @@ namespace Discord.WebSocket | |||||
#region Global users | #region Global users | ||||
internal void RemoveReferencedGlobalUser(ulong id) | 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) | private void TrackGlobalUser(ulong id, SocketGlobalUser user) | ||||
{ | { | ||||
@@ -116,6 +116,45 @@ namespace Discord.WebSocket | |||||
public ulong? GuildId { get; set; } | 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() | internal Model ToModel() | ||||
{ | { | ||||
return new CacheModel | return new CacheModel | ||||
@@ -132,18 +171,18 @@ namespace Discord.WebSocket | |||||
switch (game) | switch (game) | ||||
{ | { | ||||
case RichGame richGame: | case RichGame richGame: | ||||
return richGame.ToModel<WritableActivityModel>(); | |||||
return richGame.ToModel<ActivityCacheModel>(); | |||||
case SpotifyGame spotify: | case SpotifyGame spotify: | ||||
return spotify.ToModel<WritableActivityModel>(); | |||||
return spotify.ToModel<ActivityCacheModel>(); | |||||
case CustomStatusGame custom: | case CustomStatusGame custom: | ||||
return custom.ToModel<WritableActivityModel, WritableEmojiModel>(); | |||||
return custom.ToModel<ActivityCacheModel, EmojiCacheModel>(); | |||||
case StreamingGame stream: | case StreamingGame stream: | ||||
return stream.ToModel<WritableActivityModel>(); | |||||
return stream.ToModel<ActivityCacheModel>(); | |||||
} | } | ||||
break; | break; | ||||
} | } | ||||
return new WritableActivityModel | |||||
return new ActivityCacheModel | |||||
{ | { | ||||
Name = x.Name, | Name = x.Name, | ||||
Details = x.Details, | Details = x.Details, | ||||
@@ -15,7 +15,7 @@ namespace Discord.WebSocket | |||||
/// Represents a WebSocket-based user. | /// Represents a WebSocket-based user. | ||||
/// </summary> | /// </summary> | ||||
[DebuggerDisplay(@"{DebuggerDisplay,nq}")] | [DebuggerDisplay(@"{DebuggerDisplay,nq}")] | ||||
public abstract class SocketUser : SocketEntity<ulong>, IUser, ICached<Model> | |||||
public abstract class SocketUser : SocketEntity<ulong>, IUser, ICached<Model>, IDisposable | |||||
{ | { | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public abstract bool IsBot { get; internal set; } | public abstract bool IsBot { get; internal set; } | ||||
@@ -41,9 +41,9 @@ namespace Discord.WebSocket | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public UserStatus Status => Presence.Value.Status; | public UserStatus Status => Presence.Value.Status; | ||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public IReadOnlyCollection<ClientType> ActiveClients => Presence.Value.ActiveClients ?? ImmutableHashSet<ClientType>.Empty; | |||||
public IReadOnlyCollection<ClientType> ActiveClients => Presence.Value?.ActiveClients ?? ImmutableHashSet<ClientType>.Empty; | |||||
/// <inheritdoc /> | /// <inheritdoc /> | ||||
public IReadOnlyCollection<IActivity> Activities => Presence.Value.Activities ?? ImmutableList<IActivity>.Empty; | |||||
public IReadOnlyCollection<IActivity> Activities => Presence.Value?.Activities ?? ImmutableList<IActivity>.Empty; | |||||
/// <summary> | /// <summary> | ||||
/// Gets mutual guilds shared with this user. | /// Gets mutual guilds shared with this user. | ||||
/// </summary> | /// </summary> | ||||
@@ -59,7 +59,7 @@ namespace Discord.WebSocket | |||||
} | } | ||||
internal virtual bool Update(ClientStateManager state, Model model) | internal virtual bool Update(ClientStateManager state, Model model) | ||||
{ | { | ||||
Presence ??= new Lazy<SocketPresence>(() => state.GetPresence(Id), System.Threading.LazyThreadSafetyMode.ExecutionAndPublication); | |||||
Presence ??= new Lazy<SocketPresence>(() => state.GetPresence(Id), System.Threading.LazyThreadSafetyMode.PublicationOnly); | |||||
bool hasChanges = false; | bool hasChanges = false; | ||||
if (model.Avatar != AvatarId) | if (model.Avatar != AvatarId) | ||||
{ | { | ||||
@@ -117,6 +117,8 @@ namespace Discord.WebSocket | |||||
/// The full name of the user. | /// The full name of the user. | ||||
/// </returns> | /// </returns> | ||||
public override string ToString() => Format.UsernameAndDiscriminator(this, Discord.FormatUsersInBidirectionalUnicode); | 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" : "")})"; | private string DebuggerDisplay => $"{Format.UsernameAndDiscriminator(this, Discord.FormatUsersInBidirectionalUnicode)} ({Id}{(IsBot ? ", Bot" : "")})"; | ||||
internal SocketUser Clone() => MemberwiseClone() as SocketUser; | internal SocketUser Clone() => MemberwiseClone() as SocketUser; | ||||