Skip to content

Commit

Permalink
feature: support reading multiple activities (#1520)
Browse files Browse the repository at this point in the history
  • Loading branch information
SubZero0 authored Aug 1, 2020
1 parent 2d80037 commit 421a0c1
Show file tree
Hide file tree
Showing 9 changed files with 46 additions and 8 deletions.
4 changes: 4 additions & 0 deletions src/Discord.Net.Core/Entities/Users/IPresence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,5 +19,9 @@ public interface IPresence
/// Gets the set of clients where this user is currently active.
/// </summary>
IImmutableSet<ClientType> ActiveClients { get; }
/// <summary>
/// Gets the list of activities that this user currently has available.
/// </summary>
IImmutableList<IActivity> Activities { get; }
}
}
5 changes: 5 additions & 0 deletions src/Discord.Net.Rest/API/Common/Presence.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma warning disable CS1591
using Newtonsoft.Json;
using System;
using System.Collections.Generic;

namespace Discord.API
Expand All @@ -26,5 +27,9 @@ internal class Presence
// "client_status": { "desktop": "dnd", "mobile": "dnd" }
[JsonProperty("client_status")]
public Optional<Dictionary<string, string>> ClientStatus { get; set; }
[JsonProperty("activities")]
public List<Game> Activities { get; set; }
[JsonProperty("premium_since")]
public Optional<DateTimeOffset?> PremiumSince { get; set; }
}
}
2 changes: 2 additions & 0 deletions src/Discord.Net.Rest/Entities/Users/RestUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ public class RestUser : RestEntity<ulong>, IUser, IUpdateable
/// <inheritdoc />
public virtual IImmutableSet<ClientType> ActiveClients => ImmutableHashSet<ClientType>.Empty;
/// <inheritdoc />
public virtual IImmutableList<IActivity> Activities => ImmutableList<IActivity>.Empty;
/// <inheritdoc />
public virtual bool IsWebhook => false;

internal RestUser(BaseDiscordClient discord, ulong id)
Expand Down
4 changes: 2 additions & 2 deletions src/Discord.Net.WebSocket/DiscordSocketClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ internal SocketGlobalUser GetOrCreateSelfUser(ClientState state, Discord.API.Use
{
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;
});
}
Expand Down Expand Up @@ -450,7 +450,7 @@ private async Task SendStatusAsync()
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
Expand Down
2 changes: 2 additions & 0 deletions src/Discord.Net.WebSocket/Entities/Users/SocketGuildUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,8 @@ internal void Update(ClientState state, PresenceModel model, bool updatePresence
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)
{
Expand Down
31 changes: 27 additions & 4 deletions src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@ public struct SocketPresence : IPresence
public IActivity Activity { get; }
/// <inheritdoc />
public IImmutableSet<ClientType> ActiveClients { get; }
internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet<ClientType> activeClients)
/// <inheritdoc />
public IImmutableList<IActivity> Activities { get; }
internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet<ClientType> activeClients, IImmutableList<IActivity> activities)
{
Status = status;
Activity= activity;
ActiveClients = activeClients;
Activity = activity;
ActiveClients = activeClients ?? ImmutableHashSet<ClientType>.Empty;
Activities = activities ?? ImmutableList<IActivity>.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);
}
/// <summary>
/// Creates a new <see cref="IReadOnlyCollection{T}"/> containing all of the client types
Expand All @@ -53,6 +57,25 @@ private static IImmutableSet<ClientType> ConvertClientTypesDict(IDictionary<stri
}
return set.ToImmutableHashSet();
}
/// <summary>
/// Creates a new <see cref="IReadOnlyCollection{T}"/> containing all the activities
/// that a user has from the data supplied in the Presence update frame.
/// </summary>
/// <param name="activities">
/// A list of <see cref="API.Game"/>.
/// </param>
/// <returns>
/// A list of all <see cref="IActivity"/> that this user currently has available.
/// </returns>
private static IImmutableList<IActivity> ConvertActivitiesList(IList<API.Game> activities)
{
if (activities == null || activities.Count == 0)
return ImmutableList<IActivity>.Empty;
var list = new List<IActivity>();
foreach (var activity in activities)
list.Add(activity.ToEntity());
return list.ToImmutableList();
}

/// <summary>
/// Gets the status of the user.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class SocketUnknownUser : SocketUser
/// <inheritdoc />
public override bool IsWebhook => false;
/// <inheritdoc />
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 { } }
/// <inheritdoc />
/// <exception cref="NotSupportedException">This field is not supported for an unknown user.</exception>
internal override SocketGlobalUser GlobalUser =>
Expand Down
2 changes: 2 additions & 0 deletions src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ public abstract class SocketUser : SocketEntity<ulong>, IUser
public UserStatus Status => Presence.Status;
/// <inheritdoc />
public IImmutableSet<ClientType> ActiveClients => Presence.ActiveClients ?? ImmutableHashSet<ClientType>.Empty;
/// <inheritdoc />
public IImmutableList<IActivity> Activities => Presence.Activities ?? ImmutableList<IActivity>.Empty;
/// <summary>
/// Gets mutual guilds shared with this user.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class SocketWebhookUser : SocketUser, IWebhookUser
/// <inheritdoc />
public override bool IsWebhook => true;
/// <inheritdoc />
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();

Expand Down

0 comments on commit 421a0c1

Please sign in to comment.