using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Diagnostics; using Model = Discord.API.Presence; namespace Discord.WebSocket { /// /// Represents the WebSocket user's presence status. This may include their online status and their activity. /// [DebuggerDisplay(@"{DebuggerDisplay,nq}")] public struct SocketPresence : IPresence { /// public UserStatus Status { get; } /// public IActivity Activity { get; } /// public IImmutableSet ActiveClients { get; } /// public IImmutableList Activities { get; } internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet activeClients, IImmutableList activities) { Status = status; Activity = activity; ActiveClients = activeClients ?? ImmutableHashSet.Empty; Activities = activities ?? ImmutableList.Empty; } internal static SocketPresence Create(Model model) { var clients = ConvertClientTypesDict(model.ClientStatus.GetValueOrDefault()); var activities = ConvertActivitiesList(model.Activities); return new SocketPresence(model.Status, model.Game?.ToEntity(), clients, activities); } /// /// Creates a new containing all of the client types /// where a user is active from the data supplied in the Presence update frame. /// /// /// A dictionary keyed by the /// and where the value is the . /// /// /// A collection of all s that this user is active. /// private static IImmutableSet ConvertClientTypesDict(IDictionary clientTypesDict) { if (clientTypesDict == null || clientTypesDict.Count == 0) return ImmutableHashSet.Empty; var set = new HashSet(); foreach (var key in clientTypesDict.Keys) { if (Enum.TryParse(key, true, out ClientType type)) set.Add(type); // quietly discard ClientTypes that do not match } 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. /// /// /// A string that resolves to . /// public override string ToString() => Status.ToString(); private string DebuggerDisplay => $"{Status}{(Activity != null ? $", {Activity.Name}": "")}"; internal SocketPresence Clone() => this; } }