You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
3.9 KiB
92 lines
3.9 KiB
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Diagnostics;
|
|
using Model = Discord.API.Presence;
|
|
|
|
namespace Discord.WebSocket
|
|
{
|
|
/// <summary>
|
|
/// Represents the WebSocket user's presence status. This may include their online status and their activity.
|
|
/// </summary>
|
|
[DebuggerDisplay(@"{DebuggerDisplay,nq}")]
|
|
public struct SocketPresence : IPresence
|
|
{
|
|
/// <inheritdoc />
|
|
public UserStatus Status { get; }
|
|
/// <inheritdoc />
|
|
public IActivity Activity { get; }
|
|
/// <inheritdoc />
|
|
public IImmutableSet<ClientType> ActiveClients { get; }
|
|
/// <inheritdoc />
|
|
public IImmutableList<IActivity> Activities { get; }
|
|
internal SocketPresence(UserStatus status, IActivity activity, IImmutableSet<ClientType> activeClients, IImmutableList<IActivity> activities)
|
|
{
|
|
Status = status;
|
|
Activity = activity;
|
|
ActiveClients = activeClients ?? ImmutableHashSet<ClientType>.Empty;
|
|
Activities = activities ?? ImmutableList<IActivity>.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);
|
|
}
|
|
/// <summary>
|
|
/// Creates a new <see cref="IReadOnlyCollection{T}"/> containing all of the client types
|
|
/// where a user is active from the data supplied in the Presence update frame.
|
|
/// </summary>
|
|
/// <param name="clientTypesDict">
|
|
/// A dictionary keyed by the <see cref="ClientType"/>
|
|
/// and where the value is the <see cref="UserStatus"/>.
|
|
/// </param>
|
|
/// <returns>
|
|
/// A collection of all <see cref="ClientType"/>s that this user is active.
|
|
/// </returns>
|
|
private static IImmutableSet<ClientType> ConvertClientTypesDict(IDictionary<string, string> clientTypesDict)
|
|
{
|
|
if (clientTypesDict == null || clientTypesDict.Count == 0)
|
|
return ImmutableHashSet<ClientType>.Empty;
|
|
var set = new HashSet<ClientType>();
|
|
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();
|
|
}
|
|
/// <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.
|
|
/// </summary>
|
|
/// <returns>
|
|
/// A string that resolves to <see cref="Discord.WebSocket.SocketPresence.Status" />.
|
|
/// </returns>
|
|
public override string ToString() => Status.ToString();
|
|
private string DebuggerDisplay => $"{Status}{(Activity != null ? $", {Activity.Name}": "")}";
|
|
|
|
internal SocketPresence Clone() => this;
|
|
}
|
|
}
|