From 421a0c12ccf97ae01d1467a103db7392c30bef9e Mon Sep 17 00:00:00 2001 From: Paulo Date: Sat, 1 Aug 2020 13:43:56 -0300 Subject: [PATCH] feature: support reading multiple activities (#1520) --- .../Entities/Users/IPresence.cs | 4 +++ src/Discord.Net.Rest/API/Common/Presence.cs | 5 +++ .../Entities/Users/RestUser.cs | 2 ++ .../DiscordSocketClient.cs | 4 +-- .../Entities/Users/SocketGuildUser.cs | 2 ++ .../Entities/Users/SocketPresence.cs | 31 ++++++++++++++++--- .../Entities/Users/SocketUnknownUser.cs | 2 +- .../Entities/Users/SocketUser.cs | 2 ++ .../Entities/Users/SocketWebhookUser.cs | 2 +- 9 files changed, 46 insertions(+), 8 deletions(-) diff --git a/src/Discord.Net.Core/Entities/Users/IPresence.cs b/src/Discord.Net.Core/Entities/Users/IPresence.cs index 620eb907c..a17ac0df2 100644 --- a/src/Discord.Net.Core/Entities/Users/IPresence.cs +++ b/src/Discord.Net.Core/Entities/Users/IPresence.cs @@ -19,5 +19,9 @@ namespace Discord /// Gets the set of clients where this user is currently active. /// IImmutableSet ActiveClients { get; } + /// + /// Gets the list of activities that this user currently has available. + /// + IImmutableList Activities { get; } } } diff --git a/src/Discord.Net.Rest/API/Common/Presence.cs b/src/Discord.Net.Rest/API/Common/Presence.cs index 22526e8ac..b37ad4229 100644 --- a/src/Discord.Net.Rest/API/Common/Presence.cs +++ b/src/Discord.Net.Rest/API/Common/Presence.cs @@ -1,5 +1,6 @@ #pragma warning disable CS1591 using Newtonsoft.Json; +using System; using System.Collections.Generic; namespace Discord.API @@ -26,5 +27,9 @@ namespace Discord.API // "client_status": { "desktop": "dnd", "mobile": "dnd" } [JsonProperty("client_status")] public Optional> ClientStatus { get; set; } + [JsonProperty("activities")] + public List Activities { get; set; } + [JsonProperty("premium_since")] + public Optional PremiumSince { get; set; } } } diff --git a/src/Discord.Net.Rest/Entities/Users/RestUser.cs b/src/Discord.Net.Rest/Entities/Users/RestUser.cs index d5fffca94..f5becd3ff 100644 --- a/src/Discord.Net.Rest/Entities/Users/RestUser.cs +++ b/src/Discord.Net.Rest/Entities/Users/RestUser.cs @@ -35,6 +35,8 @@ namespace Discord.Rest /// public virtual IImmutableSet ActiveClients => ImmutableHashSet.Empty; /// + public virtual IImmutableList Activities => ImmutableList.Empty; + /// public virtual bool IsWebhook => false; internal RestUser(BaseDiscordClient discord, ulong id) diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs index 1bfa467b6..004c6179c 100644 --- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs +++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs @@ -342,7 +342,7 @@ namespace Discord.WebSocket { var user = SocketGlobalUser.Create(this, state, model); user.GlobalUser.AddRef(); - user.Presence = new SocketPresence(UserStatus.Online, null, null); + user.Presence = new SocketPresence(UserStatus.Online, null, null, null); return user; }); } @@ -450,7 +450,7 @@ namespace Discord.WebSocket return; var status = Status; var statusSince = _statusSince; - CurrentUser.Presence = new SocketPresence(status, Activity, null); + CurrentUser.Presence = new SocketPresence(status, Activity, null, null); var gameModel = new GameModel(); // Discord only accepts rich presence over RPC, don't even bother building a payload diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs index e5dbfa01d..a506a5d7f 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs @@ -154,6 +154,8 @@ namespace Discord.WebSocket Nickname = model.Nick.Value; if (model.Roles.IsSpecified) UpdateRoles(model.Roles.Value); + if (model.PremiumSince.IsSpecified) + _premiumSinceTicks = model.PremiumSince.Value?.UtcTicks; } private void UpdateRoles(ulong[] roleIds) { diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs index 52f111303..407e14419 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs @@ -18,16 +18,20 @@ namespace Discord.WebSocket public IActivity Activity { get; } /// public IImmutableSet ActiveClients { get; } - internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet activeClients) + /// + public IImmutableList Activities { get; } + internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet activeClients, IImmutableList activities) { Status = status; - Activity= activity; - ActiveClients = activeClients; + Activity = activity; + ActiveClients = activeClients ?? ImmutableHashSet.Empty; + Activities = activities ?? ImmutableList.Empty; } internal static SocketPresence Create(Model model) { var clients = ConvertClientTypesDict(model.ClientStatus.GetValueOrDefault()); - return new SocketPresence(model.Status, model.Game?.ToEntity(), clients); + var activities = ConvertActivitiesList(model.Activities); + return new SocketPresence(model.Status, model.Game?.ToEntity(), clients, activities); } /// /// Creates a new containing all of the client types @@ -53,6 +57,25 @@ namespace Discord.WebSocket } return set.ToImmutableHashSet(); } + /// + /// Creates a new containing all the activities + /// that a user has from the data supplied in the Presence update frame. + /// + /// + /// A list of . + /// + /// + /// A list of all that this user currently has available. + /// + private static IImmutableList ConvertActivitiesList(IList activities) + { + if (activities == null || activities.Count == 0) + return ImmutableList.Empty; + var list = new List(); + foreach (var activity in activities) + list.Add(activity.ToEntity()); + return list.ToImmutableList(); + } /// /// Gets the status of the user. diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs index 840a1c30b..dd2e747b4 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUnknownUser.cs @@ -25,7 +25,7 @@ namespace Discord.WebSocket /// public override bool IsWebhook => false; /// - internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null); } set { } } + internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null, null); } set { } } /// /// This field is not supported for an unknown user. internal override SocketGlobalUser GlobalUser => diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs index b830ce79c..7d3c2d23b 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs @@ -41,6 +41,8 @@ namespace Discord.WebSocket public UserStatus Status => Presence.Status; /// public IImmutableSet ActiveClients => Presence.ActiveClients ?? ImmutableHashSet.Empty; + /// + public IImmutableList Activities => Presence.Activities ?? ImmutableList.Empty; /// /// Gets mutual guilds shared with this user. /// diff --git a/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs b/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs index 8819fe1b4..d400e1ae7 100644 --- a/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs +++ b/src/Discord.Net.WebSocket/Entities/Users/SocketWebhookUser.cs @@ -30,7 +30,7 @@ namespace Discord.WebSocket /// public override bool IsWebhook => true; /// - internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null); } set { } } + internal override SocketPresence Presence { get { return new SocketPresence(UserStatus.Offline, null, null, null); } set { } } internal override SocketGlobalUser GlobalUser => throw new NotSupportedException();