using Pulsar.Client.Helper; using Pulsar.Client.Networking; using Pulsar.Common.Enums; using Pulsar.Common.Messages; using System; using System.Threading; namespace Pulsar.Client.User { /// /// Provides user activity detection and sends messages on change. /// public class ActivityDetection : IDisposable { /// /// Stores the last user status to detect changes. /// private UserStatus _lastUserStatus; /// /// The client to use for communication with the server. /// private readonly PulsarClient _client; /// /// Create a and signals cancellation. /// private readonly CancellationTokenSource _tokenSource; /// /// The token to check for cancellation. /// private readonly CancellationToken _token; /// /// Initializes a new instance of using the given client. /// /// The name of the mutex. public ActivityDetection(PulsarClient client) { _client = client; _tokenSource = new CancellationTokenSource(); _token = _tokenSource.Token; client.ClientState += OnClientStateChange; } private void OnClientStateChange(Networking.Client s, bool connected) { // reset user status if (connected) _lastUserStatus = UserStatus.Active; } /// /// Starts the user activity detection. /// public void Start() { new Thread(UserActivityThread).Start(); } /// /// Checks for user activity changes sends to the on change. /// private void UserActivityThread() { try { if (IsUserIdle()) { if (_lastUserStatus != UserStatus.Idle) { _lastUserStatus = UserStatus.Idle; _client.Send(new SetUserStatus { Message = _lastUserStatus }); } } else { if (_lastUserStatus != UserStatus.Active) { _lastUserStatus = UserStatus.Active; _client.Send(new SetUserStatus { Message = _lastUserStatus }); } } } catch (Exception e) when (e is NullReferenceException || e is ObjectDisposedException) { } } /// /// Determines whether the user is idle if the last user input was more than 10 minutes ago. /// /// True if the user is idle, else false. private bool IsUserIdle() { var ticks = Environment.TickCount; var idleTime = ticks - NativeMethodsHelper.GetLastInputInfoTickCount(); idleTime = ((idleTime > 0) ? (idleTime / 1000) : 0); return (idleTime > 600); // idle for 10 minutes } public static string UserIdleTime() { var ticks = Environment.TickCount; var idleTime = ticks - NativeMethodsHelper.GetLastInputInfoTickCount(); idleTime = ((idleTime > 0) ? (idleTime / 1000) : 0); return TimeSpan.FromSeconds(idleTime).ToString(@"hh\:mm\:ss"); } /// /// Disposes all managed and unmanaged resources associated with this activity detection service. /// public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (disposing) { _client.ClientState -= OnClientStateChange; _tokenSource.Cancel(); _tokenSource.Dispose(); } } } }