public QueuePlayer(IClient client, Session session, Deferrals deferrals) { this.Id = GuidGenerator.GenerateTimeBasedGuid(); this.Client = client; this.Session = session; this.Deferrals = deferrals; }
public void OnSessionCreated(IClient client, Session session, Deferrals deferrals) { // Check if this is a new or reconnecting queuePlayer var queuePlayer = this.queue.Players.SingleOrDefault(p => p.Session.UserId == session.UserId); if (queuePlayer == null) { this.Logger.Debug($"Creating new queuePlayer for {session.User.Name}"); queuePlayer = new QueuePlayer(client, session, deferrals); // Check if the player is in the priorityPlayers list and assign the configured priority var priorityPlayer = this.Configuration.PriorityPlayers.FirstOrDefault(p => p.SteamId == session.User.SteamId); if (priorityPlayer != null) { queuePlayer.Priority = priorityPlayer.Priority; } this.queue.Players.Add(queuePlayer); } else { this.Logger.Debug($"Reassigning queuePlayer to connected player: {session.User.Name}"); queuePlayer.Client = client; queuePlayer.Session = session; queuePlayer.Deferrals = deferrals; var oldThread = this.queue.Threads.SingleOrDefault(t => t.Key.Session.UserId == session.UserId).Key; if (oldThread != null) { this.Logger.Debug($"Disposing of old thread for player: {session.User.Name}"); this.queue.Threads[oldThread].Item2.Cancel(); this.queue.Threads[oldThread].Item1.Wait(); this.queue.Threads[oldThread].Item2.Dispose(); this.queue.Threads[oldThread].Item1.Dispose(); this.queue.Threads.Remove(oldThread); } queuePlayer.Status = QueueStatus.Queued; } this.Logger.Debug($"Adding new thread for player: {session.User.Name}"); var cancellationToken = new CancellationTokenSource(); this.queue.Threads.Add(queuePlayer, new Tuple <Task, CancellationTokenSource>(Task.Factory.StartNew(() => MonitorPlayer(queuePlayer, cancellationToken.Token), cancellationToken.Token), cancellationToken)); }
/// <summary> /// Requests a deferral. When the deferral is disposed, it is considered complete. /// </summary> /// <returns>a deferral.</returns> public IDisposable GetDeferral() { return(Deferrals.GetDeferral()); }
/// <summary> /// Waits until the deferrals are completed. /// </summary> /// <returns>a task that is completed when all deferrals have completed.</returns> internal Task WaitForDeferralsAsync() { return(Deferrals.SignalAndWaitAsync()); }
public ClientDeferralsEventArgs(Client client, Deferrals deferrals) : base(client) { this.Deferrals = deferrals; }
private async void OnConnecting(IClient client, string playerName, CallbackDelegate drop, ExpandoObject callbacks) { var deferrals = new Deferrals(callbacks, drop); Session session = null; User user = null; await this.Events.RaiseAsync(SessionEvents.ClientConnecting, client, deferrals); using (var context = new StorageContext()) using (var transaction = context.Database.BeginTransaction()) { context.Configuration.ProxyCreationEnabled = false; context.Configuration.LazyLoadingEnabled = false; try { user = context.Users.SingleOrDefault(u => u.License == client.License); if (user == default(User)) { await this.Events.RaiseAsync(SessionEvents.UserCreating, client); // Create user user = new User { Id = GuidGenerator.GenerateTimeBasedGuid(), License = client.License, SteamId = client.SteamId, Name = client.Name }; context.Users.Add(user); await context.SaveChangesAsync(); await this.Events.RaiseAsync(SessionEvents.UserCreated, client, user); } else { // Update details user.Name = client.Name; if (client.SteamId.HasValue) { user.SteamId = client.SteamId; } } await this.Events.RaiseAsync(SessionEvents.SessionCreating, client); // Create session session = new Session { Id = GuidGenerator.GenerateTimeBasedGuid(), User = user, IpAddress = client.EndPoint, Created = DateTime.UtcNow, Handle = client.Handle, }; context.Sessions.Add(session); // Save changes await context.SaveChangesAsync(); transaction.Commit(); } catch (DbEntityValidationException ex) { var errorMessages = ex.EntityValidationErrors .SelectMany(x => x.ValidationErrors) .Select(x => x.ErrorMessage); var fullErrorMessage = string.Join("; ", errorMessages); var exceptionMessage = string.Concat(ex.Message, " The Validation errors are: ", fullErrorMessage); transaction.Rollback(); throw new DbEntityValidationException(exceptionMessage, ex.EntityValidationErrors); } catch (Exception ex) { transaction.Rollback(); this.Logger.Error(ex); } } if (user == null || session == null) { throw new Exception($"Failed to create session for {client.Name}"); } this.sessions[session.Id] = session; var threadCancellationToken = new CancellationTokenSource(); lock (this.threads) { this.threads.TryAdd( session, new Tuple <Task, CancellationTokenSource>(Task.Factory.StartNew(() => MonitorSession(session, client), threadCancellationToken.Token), threadCancellationToken) ); } await this.Events.RaiseAsync(SessionEvents.SessionCreated, client, session, deferrals); if (this.sessions.Any(s => s.Value.User.Id == user.Id && s.Key != session.Id)) { Reconnecting(client, session); } await this.Events.RaiseAsync(SessionEvents.ClientConnected, client, session); this.Logger.Debug($"[{session.Id}] Player \"{user.Name}\" connected from {session.IpAddress}"); }
public ClientSessionDeferralsEventArgs(IClient client, Session session, Deferrals deferrals) : base(client, session) { this.Deferrals = deferrals; }