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; } internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet activeClients) { Status = status; Activity= activity; ActiveClients = activeClients; } internal static SocketPresence Create(Model model) { var clients = ConvertClientTypesDict(model.ClientStatus.GetValueOrDefault()); return new SocketPresence(model.Status, model.Game?.ToEntity(), clients); } /// /// 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(); } /// /// 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; } }