diff options
| author | Ionut Andrei Oanca <oancaionutandrei@gmail.com> | 2020-11-15 17:03:27 +0100 |
|---|---|---|
| committer | Ionut Andrei Oanca <oancaionutandrei@gmail.com> | 2020-11-15 17:30:28 +0100 |
| commit | c7e53bce2fa43ad38807a0589e1bc020237e49c6 (patch) | |
| tree | af484c31dc4b762aba404a28462a3cae8c23f5b5 /Emby.Server.Implementations/SyncPlay | |
| parent | 5d77f422f0e4998130f1defebd08e053188a1a25 (diff) | |
Patch data-races and minor changes in SyncPlay
Diffstat (limited to 'Emby.Server.Implementations/SyncPlay')
| -rw-r--r-- | Emby.Server.Implementations/SyncPlay/GroupController.cs | 96 | ||||
| -rw-r--r-- | Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs | 312 |
2 files changed, 184 insertions, 224 deletions
diff --git a/Emby.Server.Implementations/SyncPlay/GroupController.cs b/Emby.Server.Implementations/SyncPlay/GroupController.cs index a0d951b3e..48596bb42 100644 --- a/Emby.Server.Implementations/SyncPlay/GroupController.cs +++ b/Emby.Server.Implementations/SyncPlay/GroupController.cs @@ -46,11 +46,6 @@ namespace Emby.Server.Implementations.SyncPlay private readonly ILibraryManager _libraryManager; /// <summary> - /// The SyncPlay manager. - /// </summary> - private readonly ISyncPlayManager _syncPlayManager; - - /// <summary> /// Internal group state. /// </summary> /// <value>The group's state.</value> @@ -63,19 +58,16 @@ namespace Emby.Server.Implementations.SyncPlay /// <param name="userManager">The user manager.</param> /// <param name="sessionManager">The session manager.</param> /// <param name="libraryManager">The library manager.</param> - /// <param name="syncPlayManager">The SyncPlay manager.</param> public GroupController( ILogger logger, IUserManager userManager, ISessionManager sessionManager, - ILibraryManager libraryManager, - ISyncPlayManager syncPlayManager) + ILibraryManager libraryManager) { _logger = logger; _userManager = userManager; _sessionManager = sessionManager; _libraryManager = libraryManager; - _syncPlayManager = syncPlayManager; _state = new IdleGroupState(_logger); } @@ -168,7 +160,7 @@ namespace Emby.Server.Implementations.SyncPlay /// </summary> /// <param name="from">The current session.</param> /// <param name="type">The filtering type.</param> - /// <returns>The array of sessions matching the filter.</returns> + /// <returns>The list of sessions matching the filter.</returns> private IEnumerable<SessionInfo> FilterSessions(SessionInfo from, SyncPlayBroadcastType type) { return type switch @@ -209,7 +201,7 @@ namespace Emby.Server.Implementations.SyncPlay /// <param name="user">The user.</param> /// <param name="queue">The queue.</param> /// <returns><c>true</c> if the user can access all the items in the queue, <c>false</c> otherwise.</returns> - private bool HasAccessToQueue(User user, IEnumerable<Guid> queue) + private bool HasAccessToQueue(User user, IReadOnlyList<Guid> queue) { // Check if queue is empty. if (!queue?.Any() ?? true) @@ -234,7 +226,7 @@ namespace Emby.Server.Implementations.SyncPlay return true; } - private bool AllUsersHaveAccessToQueue(IEnumerable<Guid> queue) + private bool AllUsersHaveAccessToQueue(IReadOnlyList<Guid> queue) { // Check if queue is empty. if (!queue?.Any() ?? true) @@ -262,7 +254,6 @@ namespace Emby.Server.Implementations.SyncPlay { GroupName = request.GroupName; AddSession(session); - _syncPlayManager.AddSessionToGroup(session, this); var sessionIsPlayingAnItem = session.FullNowPlayingItem != null; @@ -270,7 +261,7 @@ namespace Emby.Server.Implementations.SyncPlay if (sessionIsPlayingAnItem) { - var playlist = session.NowPlayingQueue.Select(item => item.Id); + var playlist = session.NowPlayingQueue.Select(item => item.Id).ToList(); PlayQueue.Reset(); PlayQueue.SetPlaylist(playlist); PlayQueue.SetPlayingItemById(session.FullNowPlayingItem.Id); @@ -290,14 +281,13 @@ namespace Emby.Server.Implementations.SyncPlay _state.SessionJoined(this, _state.Type, session, cancellationToken); - _logger.LogInformation("InitGroup: {0} created group {1}.", session.Id, GroupId.ToString()); + _logger.LogInformation("InitGroup: {SessionId} created group {GroupId}.", session.Id, GroupId.ToString()); } /// <inheritdoc /> public void SessionJoin(SessionInfo session, JoinGroupRequest request, CancellationToken cancellationToken) { AddSession(session); - _syncPlayManager.AddSessionToGroup(session, this); var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, GetInfo()); SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, updateSession, cancellationToken); @@ -307,7 +297,7 @@ namespace Emby.Server.Implementations.SyncPlay _state.SessionJoined(this, _state.Type, session, cancellationToken); - _logger.LogInformation("SessionJoin: {0} joined group {1}.", session.Id, GroupId.ToString()); + _logger.LogInformation("SessionJoin: {SessionId} joined group {GroupId}.", session.Id, GroupId.ToString()); } /// <inheritdoc /> @@ -321,7 +311,7 @@ namespace Emby.Server.Implementations.SyncPlay _state.SessionJoined(this, _state.Type, session, cancellationToken); - _logger.LogInformation("SessionRestore: {0} re-joined group {1}.", session.Id, GroupId.ToString()); + _logger.LogInformation("SessionRestore: {SessionId} re-joined group {GroupId}.", session.Id, GroupId.ToString()); } /// <inheritdoc /> @@ -330,7 +320,6 @@ namespace Emby.Server.Implementations.SyncPlay _state.SessionLeaving(this, _state.Type, session, cancellationToken); RemoveSession(session); - _syncPlayManager.RemoveSessionFromGroup(session, this); var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupLeft, GroupId.ToString()); SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, updateSession, cancellationToken); @@ -338,7 +327,7 @@ namespace Emby.Server.Implementations.SyncPlay var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserLeft, session.UserName); SendGroupUpdate(session, SyncPlayBroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); - _logger.LogInformation("SessionLeave: {0} left group {1}.", session.Id, GroupId.ToString()); + _logger.LogInformation("SessionLeave: {SessionId} left group {GroupId}.", session.Id, GroupId.ToString()); } /// <inheritdoc /> @@ -347,27 +336,21 @@ namespace Emby.Server.Implementations.SyncPlay // The server's job is to maintain a consistent state for clients to reference // and notify clients of state changes. The actual syncing of media playback // happens client side. Clients are aware of the server's time and use it to sync. - _logger.LogInformation("HandleRequest: {0} requested {1}, group {2} in {3} state.", session.Id, request.Type, GroupId.ToString(), _state.Type); + _logger.LogInformation("HandleRequest: {SessionId} requested {RequestType}, group {GroupId} is {StateType}.", session.Id, request.Type, GroupId.ToString(), _state.Type); request.Apply(this, _state, session, cancellationToken); } /// <inheritdoc /> public GroupInfoDto GetInfo() { - return new GroupInfoDto() - { - GroupId = GroupId.ToString(), - GroupName = GroupName, - State = _state.Type, - Participants = Participants.Values.Select(session => session.Session.UserName).Distinct().ToList(), - LastUpdatedAt = DateTime.UtcNow - }; + var participants = Participants.Values.Select(session => session.Session.UserName).Distinct().ToList(); + return new GroupInfoDto(GroupId, GroupName, _state.Type, participants, DateTime.UtcNow); } /// <inheritdoc /> public bool HasAccessToPlayQueue(User user) { - var items = PlayQueue.GetPlaylist().Select(item => item.ItemId); + var items = PlayQueue.GetPlaylist().Select(item => item.ItemId).ToList(); return HasAccessToQueue(user, items); } @@ -383,7 +366,7 @@ namespace Emby.Server.Implementations.SyncPlay /// <inheritdoc /> public void SetState(IGroupState state) { - _logger.LogInformation("SetState: {0} switching from {1} to {2}.", GroupId.ToString(), _state.Type, state.Type); + _logger.LogInformation("SetState: {GroupId} switching from {FromStateType} to {ToStateType}.", GroupId.ToString(), _state.Type, state.Type); this._state = state; } @@ -418,26 +401,19 @@ namespace Emby.Server.Implementations.SyncPlay /// <inheritdoc /> public SendCommand NewSyncPlayCommand(SendCommandType type) { - return new SendCommand() - { - GroupId = GroupId.ToString(), - PlaylistItemId = PlayQueue.GetPlayingItemPlaylistId(), - PositionTicks = PositionTicks, - Command = type, - When = LastActivity, - EmittedAt = DateTime.UtcNow - }; + return new SendCommand( + GroupId, + PlayQueue.GetPlayingItemPlaylistId(), + LastActivity, + type, + PositionTicks, + DateTime.UtcNow); } /// <inheritdoc /> public GroupUpdate<T> NewSyncPlayGroupUpdate<T>(GroupUpdateType type, T data) { - return new GroupUpdate<T>() - { - GroupId = GroupId.ToString(), - Type = type, - Data = data - }; + return new GroupUpdate<T>(GroupId, type, data); } /// <inheritdoc /> @@ -501,10 +477,10 @@ namespace Emby.Server.Implementations.SyncPlay } /// <inheritdoc /> - public bool SetPlayQueue(IEnumerable<Guid> playQueue, int playingItemPosition, long startPositionTicks) + public bool SetPlayQueue(IReadOnlyList<Guid> playQueue, int playingItemPosition, long startPositionTicks) { // Ignore on empty queue or invalid item position. - if (!playQueue.Any() || playingItemPosition >= playQueue.Count() || playingItemPosition < 0) + if (playQueue.Count == 0 || playingItemPosition >= playQueue.Count || playingItemPosition < 0) { return false; } @@ -547,7 +523,7 @@ namespace Emby.Server.Implementations.SyncPlay } /// <inheritdoc /> - public bool RemoveFromPlayQueue(IEnumerable<string> playlistItemIds) + public bool RemoveFromPlayQueue(IReadOnlyList<string> playlistItemIds) { var playingItemRemoved = PlayQueue.RemoveFromPlaylist(playlistItemIds); if (playingItemRemoved) @@ -576,10 +552,10 @@ namespace Emby.Server.Implementations.SyncPlay } /// <inheritdoc /> - public bool AddToPlayQueue(IEnumerable<Guid> newItems, GroupQueueMode mode) + public bool AddToPlayQueue(IReadOnlyList<Guid> newItems, GroupQueueMode mode) { // Ignore on empty list. - if (!newItems.Any()) + if (newItems.Count == 0) { return false; } @@ -673,16 +649,14 @@ namespace Emby.Server.Implementations.SyncPlay startPositionTicks += Math.Max(elapsedTime.Ticks, 0); } - return new PlayQueueUpdate() - { - Reason = reason, - LastUpdate = PlayQueue.LastChange, - Playlist = PlayQueue.GetPlaylist(), - PlayingItemIndex = PlayQueue.PlayingItemIndex, - StartPositionTicks = startPositionTicks, - ShuffleMode = PlayQueue.ShuffleMode, - RepeatMode = PlayQueue.RepeatMode - }; + return new PlayQueueUpdate( + reason, + PlayQueue.LastChange, + PlayQueue.GetPlaylist(), + PlayQueue.PlayingItemIndex, + startPositionTicks, + PlayQueue.ShuffleMode, + PlayQueue.RepeatMode); } } } diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs index 178536631..ee75580cc 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs @@ -72,19 +72,9 @@ namespace Emby.Server.Implementations.SyncPlay _userManager = userManager; _sessionManager = sessionManager; _libraryManager = libraryManager; - _sessionManager.SessionStarted += OnSessionManagerSessionStarted; - _sessionManager.SessionEnded += OnSessionManagerSessionEnded; - _sessionManager.PlaybackStart += OnSessionManagerPlaybackStart; - _sessionManager.PlaybackStopped += OnSessionManagerPlaybackStopped; } - /// <summary> - /// Gets all groups. - /// </summary> - /// <value>All groups.</value> - public IEnumerable<IGroupController> Groups => _groups.Values; - /// <inheritdoc /> public void Dispose() { @@ -92,127 +82,6 @@ namespace Emby.Server.Implementations.SyncPlay GC.SuppressFinalize(this); } - /// <summary> - /// Releases unmanaged and optionally managed resources. - /// </summary> - /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> - protected virtual void Dispose(bool disposing) - { - if (_disposed) - { - return; - } - - _sessionManager.SessionStarted -= OnSessionManagerSessionStarted; - _sessionManager.SessionEnded -= OnSessionManagerSessionEnded; - _sessionManager.PlaybackStart -= OnSessionManagerPlaybackStart; - _sessionManager.PlaybackStopped -= OnSessionManagerPlaybackStopped; - - _disposed = true; - } - - private void OnSessionManagerSessionStarted(object sender, SessionEventArgs e) - { - var session = e.SessionInfo; - if (!IsSessionInGroup(session)) - { - return; - } - - var groupId = GetSessionGroup(session) ?? Guid.Empty; - var request = new JoinGroupRequest() - { - GroupId = groupId - }; - JoinGroup(session, groupId, request, CancellationToken.None); - } - - private void OnSessionManagerSessionEnded(object sender, SessionEventArgs e) - { - var session = e.SessionInfo; - if (!IsSessionInGroup(session)) - { - return; - } - - // TODO: probably remove this event, not used at the moment. - } - - private void OnSessionManagerPlaybackStart(object sender, PlaybackProgressEventArgs e) - { - var session = e.Session; - if (!IsSessionInGroup(session)) - { - return; - } - - // TODO: probably remove this event, not used at the moment. - } - - private void OnSessionManagerPlaybackStopped(object sender, PlaybackStopEventArgs e) - { - var session = e.Session; - if (!IsSessionInGroup(session)) - { - return; - } - - // TODO: probably remove this event, not used at the moment. - } - - private bool IsRequestValid<T>(SessionInfo session, GroupRequestType requestType, T request, bool checkRequest = true) - { - if (session == null || (request == null && checkRequest)) - { - return false; - } - - var user = _userManager.GetUserById(session.UserId); - - if (user.SyncPlayAccess == SyncPlayAccess.None) - { - _logger.LogWarning("IsRequestValid: {0} does not have access to SyncPlay. Requested {1}.", session.Id, requestType); - - var error = new GroupUpdate<string>() - { - // TODO: rename to a more generic error. Next PR will fix this. - Type = GroupUpdateType.JoinGroupDenied - }; - _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); - return false; - } - - if (requestType.Equals(GroupRequestType.NewGroup) && user.SyncPlayAccess != SyncPlayAccess.CreateAndJoinGroups) - { - _logger.LogWarning("IsRequestValid: {0} does not have permission to create groups.", session.Id); - - var error = new GroupUpdate<string> - { - Type = GroupUpdateType.CreateGroupDenied - }; - _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); - return false; - } - - return true; - } - - private bool IsRequestValid(SessionInfo session, GroupRequestType requestType) - { - return IsRequestValid(session, requestType, session, false); - } - - private bool IsSessionInGroup(SessionInfo session) - { - return _sessionToGroupMap.ContainsKey(session.Id); - } - - private Guid? GetSessionGroup(SessionInfo session) - { - _sessionToGroupMap.TryGetValue(session.Id, out var group); - return group?.GroupId; - } - /// <inheritdoc /> public void NewGroup(SessionInfo session, NewGroupRequest request, CancellationToken cancellationToken) { @@ -229,9 +98,10 @@ namespace Emby.Server.Implementations.SyncPlay LeaveGroup(session, cancellationToken); } - var group = new GroupController(_logger, _userManager, _sessionManager, _libraryManager, this); + var group = new GroupController(_logger, _userManager, _sessionManager, _libraryManager); _groups[group.GroupId] = group; + AddSessionToGroup(session, group); group.CreateGroup(session, request, cancellationToken); } } @@ -253,25 +123,18 @@ namespace Emby.Server.Implementations.SyncPlay if (group == null) { - _logger.LogWarning("JoinGroup: {0} tried to join group {0} that does not exist.", session.Id, groupId); + _logger.LogWarning("JoinGroup: {SessionId} tried to join group {GroupId} that does not exist.", session.Id, groupId); - var error = new GroupUpdate<string>() - { - Type = GroupUpdateType.GroupDoesNotExist - }; + var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.GroupDoesNotExist, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); return; } if (!group.HasAccessToPlayQueue(user)) { - _logger.LogWarning("JoinGroup: {0} does not have access to some content from the playing queue of group {1}.", session.Id, group.GroupId.ToString()); + _logger.LogWarning("JoinGroup: {SessionId} does not have access to some content from the playing queue of group {GroupId}.", session.Id, group.GroupId.ToString()); - var error = new GroupUpdate<string>() - { - GroupId = group.GroupId.ToString(), - Type = GroupUpdateType.LibraryAccessDenied - }; + var error = new GroupUpdate<string>(group.GroupId, GroupUpdateType.LibraryAccessDenied, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); return; } @@ -287,6 +150,7 @@ namespace Emby.Server.Implementations.SyncPlay LeaveGroup(session, cancellationToken); } + AddSessionToGroup(session, group); group.SessionJoin(session, request, cancellationToken); } } @@ -307,21 +171,19 @@ namespace Emby.Server.Implementations.SyncPlay if (group == null) { - _logger.LogWarning("LeaveGroup: {0} does not belong to any group.", session.Id); + _logger.LogWarning("LeaveGroup: {SessionId} does not belong to any group.", session.Id); - var error = new GroupUpdate<string>() - { - Type = GroupUpdateType.NotInGroup - }; + var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); return; } + RemoveSessionFromGroup(session, group); group.SessionLeave(session, cancellationToken); if (group.IsGroupEmpty()) { - _logger.LogInformation("LeaveGroup: removing empty group {0}.", group.GroupId); + _logger.LogInformation("LeaveGroup: removing empty group {GroupId}.", group.GroupId); _groups.Remove(group.GroupId, out _); } } @@ -338,11 +200,14 @@ namespace Emby.Server.Implementations.SyncPlay var user = _userManager.GetUserById(session.UserId); - return _groups - .Values - .Where(group => group.HasAccessToPlayQueue(user)) - .Select(group => group.GetInfo()) - .ToList(); + lock (_groupsLock) + { + return _groups + .Values + .Where(group => group.HasAccessToPlayQueue(user)) + .Select(group => group.GetInfo()) + .ToList(); + } } /// <inheritdoc /> @@ -360,12 +225,9 @@ namespace Emby.Server.Implementations.SyncPlay if (group == null) { - _logger.LogWarning("HandleRequest: {0} does not belong to any group.", session.Id); + _logger.LogWarning("HandleRequest: {SessionId} does not belong to any group.", session.Id); - var error = new GroupUpdate<string>() - { - Type = GroupUpdateType.NotInGroup - }; + var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); return; } @@ -374,8 +236,74 @@ namespace Emby.Server.Implementations.SyncPlay } } - /// <inheritdoc /> - public void AddSessionToGroup(SessionInfo session, IGroupController group) + /// <summary> + /// Releases unmanaged and optionally managed resources. + /// </summary> + /// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param> + protected virtual void Dispose(bool disposing) + { + if (_disposed) + { + return; + } + + _sessionManager.SessionStarted -= OnSessionManagerSessionStarted; + _disposed = true; + } + + private void OnSessionManagerSessionStarted(object sender, SessionEventArgs e) + { + var session = e.SessionInfo; + lock (_groupsLock) + { + if (!IsSessionInGroup(session)) + { + return; + } + + var groupId = GetSessionGroup(session); + var request = new JoinGroupRequest(groupId); + JoinGroup(session, groupId, request, CancellationToken.None); + } + } + + /// <summary> + /// Checks if a given session has joined a group. + /// </summary> + /// <remarks> + /// Not thread-safe, call only under groups-lock. + /// </remarks> + /// <param name="session">The session.</param> + /// <returns><c>true</c> if the session has joined a group, <c>false</c> otherwise.</returns> + private bool IsSessionInGroup(SessionInfo session) + { + return _sessionToGroupMap.ContainsKey(session.Id); + } + + /// <summary> + /// Gets the group joined by the given session, if any. + /// </summary> + /// <remarks> + /// Not thread-safe, call only under groups-lock. + /// </remarks> + /// <param name="session">The session.</param> + /// <returns>The group identifier if the session has joined a group, an empty identifier otherwise.</returns> + private Guid GetSessionGroup(SessionInfo session) + { + _sessionToGroupMap.TryGetValue(session.Id, out var group); + return group?.GroupId ?? Guid.Empty; + } + + /// <summary> + /// Maps a session to a group. + /// </summary> + /// <remarks> + /// Not thread-safe, call only under groups-lock. + /// </remarks> + /// <param name="session">The session.</param> + /// <param name="group">The group.</param> + /// <exception cref="InvalidOperationException">Thrown when the user is in another group already.</exception> + private void AddSessionToGroup(SessionInfo session, IGroupController group) { if (session == null) { @@ -390,8 +318,16 @@ namespace Emby.Server.Implementations.SyncPlay _sessionToGroupMap[session.Id] = group ?? throw new InvalidOperationException("Group is null!"); } - /// <inheritdoc /> - public void RemoveSessionFromGroup(SessionInfo session, IGroupController group) + /// <summary> + /// Unmaps a session from a group. + /// </summary> + /// <remarks> + /// Not thread-safe, call only under groups-lock. + /// </remarks> + /// <param name="session">The session.</param> + /// <param name="group">The group.</param> + /// <exception cref="InvalidOperationException">Thrown when the user is not found in the specified group.</exception> + private void RemoveSessionFromGroup(SessionInfo session, IGroupController group) { if (session == null) { @@ -414,5 +350,55 @@ namespace Emby.Server.Implementations.SyncPlay throw new InvalidOperationException("Session was in wrong group!"); } } + + /// <summary> + /// Checks if a given session is allowed to make a given request. + /// </summary> + /// <param name="session">The session.</param> + /// <param name="requestType">The request type.</param> + /// <param name="request">The request.</param> + /// <param name="checkRequest">Whether to check if request is null.</param> + /// <returns><c>true</c> if the request is valid, <c>false</c> otherwise. Will return <c>false</c> also when session is null.</returns> + private bool IsRequestValid<T>(SessionInfo session, GroupRequestType requestType, T request, bool checkRequest = true) + { + if (session == null || (request == null && checkRequest)) + { + return false; + } + + var user = _userManager.GetUserById(session.UserId); + + if (user.SyncPlayAccess == SyncPlayAccess.None) + { + _logger.LogWarning("IsRequestValid: {SessionId} does not have access to SyncPlay. Requested {RequestType}.", session.Id, requestType); + + // TODO: rename to a more generic error. Next PR will fix this. + var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.JoinGroupDenied, string.Empty); + _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); + return false; + } + + if (requestType.Equals(GroupRequestType.NewGroup) && user.SyncPlayAccess != SyncPlayAccess.CreateAndJoinGroups) + { + _logger.LogWarning("IsRequestValid: {SessionId} does not have permission to create groups.", session.Id); + + var error = new GroupUpdate<string>(Guid.Empty, GroupUpdateType.CreateGroupDenied, string.Empty); + _sessionManager.SendSyncPlayGroupUpdate(session, error, CancellationToken.None); + return false; + } + + return true; + } + + /// <summary> + /// Checks if a given session is allowed to make a given type of request. + /// </summary> + /// <param name="session">The session.</param> + /// <param name="requestType">The request type.</param> + /// <returns><c>true</c> if the request is valid, <c>false</c> otherwise. Will return <c>false</c> also when session is null.</returns> + private bool IsRequestValid(SessionInfo session, GroupRequestType requestType) + { + return IsRequestValid(session, requestType, session, false); + } } } |
