From 42bdb22bfb690a6af37d70f12844881d884927b1 Mon Sep 17 00:00:00 2001 From: JPVenson Date: Tue, 25 Mar 2025 16:45:00 +0100 Subject: Fixed namespaces --- MediaBrowser.Controller/Session/ISessionManager.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'MediaBrowser.Controller/Session') diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 5dd0413b4d..21131e6b5e 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -6,7 +6,8 @@ using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; -using Jellyfin.Data.Entities.Security; +using Jellyfin.Database.Implementations.Entities; +using Jellyfin.Database.Implementations.Entities.Security; using MediaBrowser.Controller.Authentication; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Dto; @@ -73,7 +74,7 @@ namespace MediaBrowser.Controller.Session /// The remote end point. /// The user. /// A task containing the session information. - Task LogSessionActivity(string appName, string appVersion, string deviceId, string deviceName, string remoteEndPoint, Jellyfin.Data.Entities.User user); + Task LogSessionActivity(string appName, string appVersion, string deviceId, string deviceName, string remoteEndPoint, User user); /// /// Used to report that a session controller has connected. -- cgit v1.2.3 From 181a37a8cd512a46dfc5af55c43ef1468d206d75 Mon Sep 17 00:00:00 2001 From: timminator <150205162+timminator@users.noreply.github.com> Date: Fri, 28 Mar 2025 00:59:08 +0100 Subject: Fix consumer count off by one when closing a browser tab with a livestream that is transcoding (#13220) Rework Implementation Fix review issues Add missing nullorempty check Fix closely related #13721 --- .../Session/SessionManager.cs | 87 +++++++++++++++++++--- MediaBrowser.Controller/Session/ISessionManager.cs | 8 ++ .../Transcoding/TranscodeManager.cs | 9 +-- 3 files changed, 87 insertions(+), 17 deletions(-) (limited to 'MediaBrowser.Controller/Session') diff --git a/Emby.Server.Implementations/Session/SessionManager.cs b/Emby.Server.Implementations/Session/SessionManager.cs index 42f7deca15..ac3e105940 100644 --- a/Emby.Server.Implementations/Session/SessionManager.cs +++ b/Emby.Server.Implementations/Session/SessionManager.cs @@ -64,6 +64,9 @@ namespace Emby.Server.Implementations.Session private readonly ConcurrentDictionary _activeConnections = new(StringComparer.OrdinalIgnoreCase); + private readonly ConcurrentDictionary> _activeLiveStreamSessions + = new(StringComparer.OrdinalIgnoreCase); + private Timer _idleTimer; private Timer _inactiveTimer; @@ -311,13 +314,49 @@ namespace Emby.Server.Implementations.Session _activeConnections.TryRemove(key, out _); if (!string.IsNullOrEmpty(session.PlayState?.LiveStreamId)) { - await _mediaSourceManager.CloseLiveStream(session.PlayState.LiveStreamId).ConfigureAwait(false); + await CloseLiveStreamIfNeededAsync(session.PlayState.LiveStreamId, session.Id).ConfigureAwait(false); } await OnSessionEnded(session).ConfigureAwait(false); } } + /// + public async Task CloseLiveStreamIfNeededAsync(string liveStreamId, string sessionIdOrPlaySessionId) + { + bool liveStreamNeedsToBeClosed = false; + + if (_activeLiveStreamSessions.TryGetValue(liveStreamId, out var activeSessionMappings)) + { + if (activeSessionMappings.TryRemove(sessionIdOrPlaySessionId, out var correspondingId)) + { + if (!string.IsNullOrEmpty(correspondingId)) + { + activeSessionMappings.TryRemove(correspondingId, out _); + } + + liveStreamNeedsToBeClosed = true; + } + + if (activeSessionMappings.IsEmpty) + { + _activeLiveStreamSessions.TryRemove(liveStreamId, out _); + } + } + + if (liveStreamNeedsToBeClosed) + { + try + { + await _mediaSourceManager.CloseLiveStream(liveStreamId).ConfigureAwait(false); + } + catch (Exception ex) + { + _logger.LogError(ex, "Error closing live stream"); + } + } + } + /// public async ValueTask ReportSessionEnded(string sessionId) { @@ -737,6 +776,11 @@ namespace Emby.Server.Implementations.Session } } + if (!string.IsNullOrEmpty(info.LiveStreamId)) + { + UpdateLiveStreamActiveSessionMappings(info.LiveStreamId, info.SessionId, info.PlaySessionId); + } + var eventArgs = new PlaybackStartEventArgs { Item = libraryItem, @@ -794,6 +838,32 @@ namespace Emby.Server.Implementations.Session return OnPlaybackProgress(info, false); } + private void UpdateLiveStreamActiveSessionMappings(string liveStreamId, string sessionId, string playSessionId) + { + var activeSessionMappings = _activeLiveStreamSessions.GetOrAdd(liveStreamId, _ => new ConcurrentDictionary()); + + if (!string.IsNullOrEmpty(playSessionId)) + { + if (!activeSessionMappings.TryGetValue(sessionId, out var currentPlaySessionId) || currentPlaySessionId != playSessionId) + { + if (!string.IsNullOrEmpty(currentPlaySessionId)) + { + activeSessionMappings.TryRemove(currentPlaySessionId, out _); + } + + activeSessionMappings[sessionId] = playSessionId; + activeSessionMappings[playSessionId] = sessionId; + } + } + else + { + if (!activeSessionMappings.TryGetValue(sessionId, out _)) + { + activeSessionMappings[sessionId] = string.Empty; + } + } + } + /// /// Used to report playback progress for an item. /// @@ -834,6 +904,11 @@ namespace Emby.Server.Implementations.Session } } + if (!string.IsNullOrEmpty(info.LiveStreamId)) + { + UpdateLiveStreamActiveSessionMappings(info.LiveStreamId, info.SessionId, info.PlaySessionId); + } + var eventArgs = new PlaybackProgressEventArgs { Item = libraryItem, @@ -1016,14 +1091,7 @@ namespace Emby.Server.Implementations.Session if (!string.IsNullOrEmpty(info.LiveStreamId)) { - try - { - await _mediaSourceManager.CloseLiveStream(info.LiveStreamId).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error closing live stream"); - } + await CloseLiveStreamIfNeededAsync(info.LiveStreamId, session.Id).ConfigureAwait(false); } var eventArgs = new PlaybackStopEventArgs @@ -2071,6 +2139,7 @@ namespace Emby.Server.Implementations.Session } _activeConnections.Clear(); + _activeLiveStreamSessions.Clear(); } } } diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 21131e6b5e..47bcfdb6ef 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -342,5 +342,13 @@ namespace MediaBrowser.Controller.Session Task RevokeUserTokens(Guid userId, string currentAccessToken); Task CloseIfNeededAsync(SessionInfo session); + + /// + /// Used to close the livestream if needed. + /// + /// The livestream id. + /// The session id or playsession id. + /// Task. + Task CloseLiveStreamIfNeededAsync(string liveStreamId, string sessionIdOrPlaySessionId); } } diff --git a/MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs b/MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs index 85bb862c77..c7f9cf2ccf 100644 --- a/MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs +++ b/MediaBrowser.MediaEncoding/Transcoding/TranscodeManager.cs @@ -242,14 +242,7 @@ public sealed class TranscodeManager : ITranscodeManager, IDisposable if (closeLiveStream && !string.IsNullOrWhiteSpace(job.LiveStreamId)) { - try - { - await _mediaSourceManager.CloseLiveStream(job.LiveStreamId).ConfigureAwait(false); - } - catch (Exception ex) - { - _logger.LogError(ex, "Error closing live stream for {Path}", job.Path); - } + await _sessionManager.CloseLiveStreamIfNeededAsync(job.LiveStreamId, job.PlaySessionId).ConfigureAwait(false); } } -- cgit v1.2.3 From 269508be9f78901b3a3b2bea88392aeef88359e4 Mon Sep 17 00:00:00 2001 From: Niels van Velzen Date: Sat, 19 Apr 2025 21:08:15 +0200 Subject: Fix SyncPlay WebSocket OpenAPI schemas (#13946) --- Emby.Server.Implementations/SyncPlay/Group.cs | 16 +--- .../SyncPlay/SyncPlayManager.cs | 8 +- Jellyfin.Server/Filters/AdditionalModelFilter.cs | 105 ++++++++++++++------- .../Outbound/SyncPlayGroupUpdateCommandMessage.cs | 24 ----- ...SyncPlayGroupUpdateCommandOfGroupInfoMessage.cs | 25 ----- ...yGroupUpdateCommandOfGroupStateUpdateMessage.cs | 25 ----- ...ayGroupUpdateCommandOfPlayQueueUpdateMessage.cs | 25 ----- .../SyncPlayGroupUpdateCommandOfStringMessage.cs | 25 ----- MediaBrowser.Controller/Session/ISessionManager.cs | 2 +- .../SyncPlay/GroupStates/AbstractGroupState.cs | 12 +-- .../SyncPlay/GroupStates/WaitingGroupState.cs | 16 ++-- .../SyncPlay/IGroupStateContext.cs | 11 +-- MediaBrowser.Model/SyncPlay/GroupUpdate.cs | 17 +++- MediaBrowser.Model/SyncPlay/GroupUpdateOfT.cs | 31 ------ MediaBrowser.Model/SyncPlay/GroupUpdateType.cs | 10 -- .../SyncPlay/SyncPlayGroupDoesNotExistUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayGroupJoinedUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayGroupLeftUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayLibraryAccessDeniedUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayNotInGroupUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayPlayQueueUpdate.cs | 21 +++++ MediaBrowser.Model/SyncPlay/SyncPlayStateUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayUserJoinedUpdate.cs | 21 +++++ .../SyncPlay/SyncPlayUserLeftUpdate.cs | 21 +++++ 24 files changed, 299 insertions(+), 242 deletions(-) delete mode 100644 MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandMessage.cs delete mode 100644 MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupInfoMessage.cs delete mode 100644 MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupStateUpdateMessage.cs delete mode 100644 MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfPlayQueueUpdateMessage.cs delete mode 100644 MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfStringMessage.cs delete mode 100644 MediaBrowser.Model/SyncPlay/GroupUpdateOfT.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayGroupDoesNotExistUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayGroupJoinedUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayGroupLeftUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayLibraryAccessDeniedUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayNotInGroupUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayPlayQueueUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayStateUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayUserJoinedUpdate.cs create mode 100644 MediaBrowser.Model/SyncPlay/SyncPlayUserLeftUpdate.cs (limited to 'MediaBrowser.Controller/Session') diff --git a/Emby.Server.Implementations/SyncPlay/Group.cs b/Emby.Server.Implementations/SyncPlay/Group.cs index d47e477938..c2e834ad58 100644 --- a/Emby.Server.Implementations/SyncPlay/Group.cs +++ b/Emby.Server.Implementations/SyncPlay/Group.cs @@ -273,7 +273,7 @@ namespace Emby.Server.Implementations.SyncPlay SetState(waitingState); } - var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, GetInfo()); + var updateSession = new SyncPlayGroupJoinedUpdate(GroupId, GetInfo()); SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, updateSession, cancellationToken); _state.SessionJoined(this, _state.Type, session, cancellationToken); @@ -291,10 +291,10 @@ namespace Emby.Server.Implementations.SyncPlay { AddSession(session); - var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupJoined, GetInfo()); + var updateSession = new SyncPlayGroupJoinedUpdate(GroupId, GetInfo()); SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, updateSession, cancellationToken); - var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserJoined, session.UserName); + var updateOthers = new SyncPlayUserJoinedUpdate(GroupId, session.UserName); SendGroupUpdate(session, SyncPlayBroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); _state.SessionJoined(this, _state.Type, session, cancellationToken); @@ -314,10 +314,10 @@ namespace Emby.Server.Implementations.SyncPlay RemoveSession(session); - var updateSession = NewSyncPlayGroupUpdate(GroupUpdateType.GroupLeft, GroupId.ToString()); + var updateSession = new SyncPlayGroupLeftUpdate(GroupId, GroupId.ToString()); SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, updateSession, cancellationToken); - var updateOthers = NewSyncPlayGroupUpdate(GroupUpdateType.UserLeft, session.UserName); + var updateOthers = new SyncPlayUserLeftUpdate(GroupId, session.UserName); SendGroupUpdate(session, SyncPlayBroadcastType.AllExceptCurrentSession, updateOthers, cancellationToken); _logger.LogInformation("Session {SessionId} left group {GroupId}.", session.Id, GroupId.ToString()); @@ -425,12 +425,6 @@ namespace Emby.Server.Implementations.SyncPlay DateTime.UtcNow); } - /// - public GroupUpdate NewSyncPlayGroupUpdate(GroupUpdateType type, T data) - { - return new GroupUpdate(GroupId, type, data); - } - /// public long SanitizePositionTicks(long? positionTicks) { diff --git a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs index fdfff8f3b8..92b80e1029 100644 --- a/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs +++ b/Emby.Server.Implementations/SyncPlay/SyncPlayManager.cs @@ -159,7 +159,7 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("Session {SessionId} tried to join group {GroupId} that does not exist.", session.Id, request.GroupId); - var error = new GroupUpdate(Guid.Empty, GroupUpdateType.GroupDoesNotExist, string.Empty); + var error = new SyncPlayGroupDoesNotExistUpdate(Guid.Empty, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -171,7 +171,7 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("Session {SessionId} tried to join group {GroupId} but does not have access to some content of the playing queue.", session.Id, group.GroupId.ToString()); - var error = new GroupUpdate(group.GroupId, GroupUpdateType.LibraryAccessDenied, string.Empty); + var error = new SyncPlayLibraryAccessDeniedUpdate(group.GroupId, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); return; } @@ -248,7 +248,7 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id); - var error = new GroupUpdate(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty); + var error = new SyncPlayNotInGroupUpdate(Guid.Empty, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); } } @@ -327,7 +327,7 @@ namespace Emby.Server.Implementations.SyncPlay { _logger.LogWarning("Session {SessionId} does not belong to any group.", session.Id); - var error = new GroupUpdate(Guid.Empty, GroupUpdateType.NotInGroup, string.Empty); + var error = new SyncPlayNotInGroupUpdate(Guid.Empty, string.Empty); _sessionManager.SendSyncPlayGroupUpdate(session.Id, error, CancellationToken.None); } } diff --git a/Jellyfin.Server/Filters/AdditionalModelFilter.cs b/Jellyfin.Server/Filters/AdditionalModelFilter.cs index 4cd0fc231e..421eeecda0 100644 --- a/Jellyfin.Server/Filters/AdditionalModelFilter.cs +++ b/Jellyfin.Server/Filters/AdditionalModelFilter.cs @@ -92,17 +92,51 @@ namespace Jellyfin.Server.Filters continue; } - // Additional discriminator needed for GroupUpdate models... - if (messageType == SessionMessageType.SyncPlayGroupUpdate && type != typeof(SyncPlayGroupUpdateCommandMessage)) - { - continue; - } - var schema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository); outboundWebSocketSchemas.Add(schema); outboundWebSocketDiscriminators.Add(messageType.ToString()!, schema.Reference.ReferenceV3); } + // Add custom "SyncPlayGroupUpdateMessage" schema because Swashbuckle cannot generate it for us + var syncPlayGroupUpdateMessageSchema = new OpenApiSchema + { + Type = "object", + Description = "Untyped sync play command.", + Properties = new Dictionary + { + { + "Data", new OpenApiSchema + { + AllOf = + [ + new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = nameof(GroupUpdate) } } + ], + Description = "Group update data", + Nullable = false, + } + }, + { "MessageId", new OpenApiSchema { Type = "string", Format = "uuid", Description = "Gets or sets the message id." } }, + { + "MessageType", new OpenApiSchema + { + Enum = Enum.GetValues().Select(type => new OpenApiString(type.ToString())).ToList(), + AllOf = + [ + new OpenApiSchema { Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = nameof(SessionMessageType) } } + ], + Description = "The different kinds of messages that are used in the WebSocket api.", + Default = new OpenApiString(nameof(SessionMessageType.SyncPlayGroupUpdate)), + ReadOnly = true + } + }, + }, + AdditionalPropertiesAllowed = false, + Reference = new OpenApiReference { Type = ReferenceType.Schema, Id = "SyncPlayGroupUpdateMessage" } + }; + context.SchemaRepository.AddDefinition("SyncPlayGroupUpdateMessage", syncPlayGroupUpdateMessageSchema); + outboundWebSocketSchemas.Add(syncPlayGroupUpdateMessageSchema); + outboundWebSocketDiscriminators[nameof(SessionMessageType.SyncPlayGroupUpdate)] = syncPlayGroupUpdateMessageSchema.Reference.ReferenceV3; + var outboundWebSocketMessageSchema = new OpenApiSchema { Type = "object", @@ -140,41 +174,46 @@ namespace Jellyfin.Server.Filters }); // Manually generate sync play GroupUpdate messages. - if (!context.SchemaRepository.Schemas.TryGetValue(nameof(GroupUpdate), out var groupUpdateSchema)) - { - groupUpdateSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate), context.SchemaRepository); - } - - var groupUpdateOfGroupInfoSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate), context.SchemaRepository); - var groupUpdateOfGroupStateSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate), context.SchemaRepository); - var groupUpdateOfStringSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate), context.SchemaRepository); - var groupUpdateOfPlayQueueSchema = context.SchemaGenerator.GenerateSchema(typeof(GroupUpdate), context.SchemaRepository); + var groupUpdateTypes = typeof(GroupUpdate<>).Assembly.GetTypes() + .Where(t => t.BaseType != null + && t.BaseType.IsGenericType + && t.BaseType.GetGenericTypeDefinition() == typeof(GroupUpdate<>)) + .ToList(); - groupUpdateSchema.OneOf = new List + var groupUpdateSchemas = new List(); + var groupUpdateDiscriminators = new Dictionary(); + foreach (var type in groupUpdateTypes) { - groupUpdateOfGroupInfoSchema, - groupUpdateOfGroupStateSchema, - groupUpdateOfStringSchema, - groupUpdateOfPlayQueueSchema - }; + var groupUpdateType = (GroupUpdateType?)type.GetProperty(nameof(GroupUpdate.Type))?.GetCustomAttribute()?.Value; + if (groupUpdateType is null) + { + continue; + } + + var schema = context.SchemaGenerator.GenerateSchema(type, context.SchemaRepository); + groupUpdateSchemas.Add(schema); + groupUpdateDiscriminators[groupUpdateType.ToString()!] = schema.Reference.ReferenceV3; + } - groupUpdateSchema.Discriminator = new OpenApiDiscriminator + var groupUpdateSchema = new OpenApiSchema { - PropertyName = nameof(GroupUpdate.Type), - Mapping = new Dictionary + Type = "object", + Description = "Represents the list of possible group update types", + Reference = new OpenApiReference + { + Id = nameof(GroupUpdate), + Type = ReferenceType.Schema + }, + OneOf = groupUpdateSchemas, + Discriminator = new OpenApiDiscriminator { - { GroupUpdateType.UserJoined.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 }, - { GroupUpdateType.UserLeft.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 }, - { GroupUpdateType.GroupJoined.ToString(), groupUpdateOfGroupInfoSchema.Reference.ReferenceV3 }, - { GroupUpdateType.GroupLeft.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 }, - { GroupUpdateType.StateUpdate.ToString(), groupUpdateOfGroupStateSchema.Reference.ReferenceV3 }, - { GroupUpdateType.PlayQueue.ToString(), groupUpdateOfPlayQueueSchema.Reference.ReferenceV3 }, - { GroupUpdateType.NotInGroup.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 }, - { GroupUpdateType.GroupDoesNotExist.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 }, - { GroupUpdateType.LibraryAccessDenied.ToString(), groupUpdateOfStringSchema.Reference.ReferenceV3 } + PropertyName = nameof(GroupUpdate.Type), + Mapping = groupUpdateDiscriminators } }; + context.SchemaRepository.Schemas[nameof(GroupUpdate)] = groupUpdateSchema; + context.SchemaGenerator.GenerateSchema(typeof(ServerDiscoveryInfo), context.SchemaRepository); foreach (var configuration in _serverConfigurationManager.GetConfigurationStores()) diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandMessage.cs deleted file mode 100644 index 6a501aa7ea..0000000000 --- a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandMessage.cs +++ /dev/null @@ -1,24 +0,0 @@ -using System.ComponentModel; -using MediaBrowser.Model.Session; -using MediaBrowser.Model.SyncPlay; - -namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound; - -/// -/// Untyped sync play command. -/// -public class SyncPlayGroupUpdateCommandMessage : OutboundWebSocketMessage -{ - /// - /// Initializes a new instance of the class. - /// - /// The send command. - public SyncPlayGroupUpdateCommandMessage(GroupUpdate data) - : base(data) - { - } - - /// - [DefaultValue(SessionMessageType.SyncPlayGroupUpdate)] - public override SessionMessageType MessageType => SessionMessageType.SyncPlayGroupUpdate; -} diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupInfoMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupInfoMessage.cs deleted file mode 100644 index 47f706e2a4..0000000000 --- a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupInfoMessage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel; -using MediaBrowser.Model.Session; -using MediaBrowser.Model.SyncPlay; - -namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound; - -/// -/// Sync play group update command with group info. -/// GroupUpdateTypes: GroupJoined. -/// -public class SyncPlayGroupUpdateCommandOfGroupInfoMessage : OutboundWebSocketMessage> -{ - /// - /// Initializes a new instance of the class. - /// - /// The group info. - public SyncPlayGroupUpdateCommandOfGroupInfoMessage(GroupUpdate data) - : base(data) - { - } - - /// - [DefaultValue(SessionMessageType.SyncPlayGroupUpdate)] - public override SessionMessageType MessageType => SessionMessageType.SyncPlayGroupUpdate; -} diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupStateUpdateMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupStateUpdateMessage.cs deleted file mode 100644 index 11ddb1e250..0000000000 --- a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfGroupStateUpdateMessage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel; -using MediaBrowser.Model.Session; -using MediaBrowser.Model.SyncPlay; - -namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound; - -/// -/// Sync play group update command with group state update. -/// GroupUpdateTypes: StateUpdate. -/// -public class SyncPlayGroupUpdateCommandOfGroupStateUpdateMessage : OutboundWebSocketMessage> -{ - /// - /// Initializes a new instance of the class. - /// - /// The group info. - public SyncPlayGroupUpdateCommandOfGroupStateUpdateMessage(GroupUpdate data) - : base(data) - { - } - - /// - [DefaultValue(SessionMessageType.SyncPlayGroupUpdate)] - public override SessionMessageType MessageType => SessionMessageType.SyncPlayGroupUpdate; -} diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfPlayQueueUpdateMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfPlayQueueUpdateMessage.cs deleted file mode 100644 index 7e73399b1b..0000000000 --- a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfPlayQueueUpdateMessage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel; -using MediaBrowser.Model.Session; -using MediaBrowser.Model.SyncPlay; - -namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound; - -/// -/// Sync play group update command with play queue update. -/// GroupUpdateTypes: PlayQueue. -/// -public class SyncPlayGroupUpdateCommandOfPlayQueueUpdateMessage : OutboundWebSocketMessage> -{ - /// - /// Initializes a new instance of the class. - /// - /// The play queue update. - public SyncPlayGroupUpdateCommandOfPlayQueueUpdateMessage(GroupUpdate data) - : base(data) - { - } - - /// - [DefaultValue(SessionMessageType.SyncPlayGroupUpdate)] - public override SessionMessageType MessageType => SessionMessageType.SyncPlayGroupUpdate; -} diff --git a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfStringMessage.cs b/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfStringMessage.cs deleted file mode 100644 index 5b5ccd3eda..0000000000 --- a/MediaBrowser.Controller/Net/WebSocketMessages/Outbound/SyncPlayGroupUpdateCommandOfStringMessage.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System.ComponentModel; -using MediaBrowser.Model.Session; -using MediaBrowser.Model.SyncPlay; - -namespace MediaBrowser.Controller.Net.WebSocketMessages.Outbound; - -/// -/// Sync play group update command with string. -/// GroupUpdateTypes: GroupDoesNotExist (error), LibraryAccessDenied (error), NotInGroup (error), GroupLeft (groupId), UserJoined (username), UserLeft (username). -/// -public class SyncPlayGroupUpdateCommandOfStringMessage : OutboundWebSocketMessage> -{ - /// - /// Initializes a new instance of the class. - /// - /// The send command. - public SyncPlayGroupUpdateCommandOfStringMessage(GroupUpdate data) - : base(data) - { - } - - /// - [DefaultValue(SessionMessageType.SyncPlayGroupUpdate)] - public override SessionMessageType MessageType => SessionMessageType.SyncPlayGroupUpdate; -} diff --git a/MediaBrowser.Controller/Session/ISessionManager.cs b/MediaBrowser.Controller/Session/ISessionManager.cs index 47bcfdb6ef..2b3afa1174 100644 --- a/MediaBrowser.Controller/Session/ISessionManager.cs +++ b/MediaBrowser.Controller/Session/ISessionManager.cs @@ -161,7 +161,7 @@ namespace MediaBrowser.Controller.Session /// The identifier of the session. /// The group update. /// The cancellation token. - /// Type of group. + /// The group update type. /// Task. Task SendSyncPlayGroupUpdate(string sessionId, GroupUpdate command, CancellationToken cancellationToken); diff --git a/MediaBrowser.Controller/SyncPlay/GroupStates/AbstractGroupState.cs b/MediaBrowser.Controller/SyncPlay/GroupStates/AbstractGroupState.cs index 51c95a1bb2..31890c40ae 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupStates/AbstractGroupState.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupStates/AbstractGroupState.cs @@ -80,7 +80,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates } var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.RemoveItems); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); if (playingItemRemoved && !context.PlayQueue.IsItemPlaying()) @@ -106,7 +106,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates } var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.MoveItem); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); } @@ -127,7 +127,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates _ => PlayQueueUpdateReason.Queue }; var playQueueUpdate = context.GetPlayQueueUpdate(reason); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); } @@ -184,7 +184,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates { context.SetRepeatMode(request.Mode); var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.RepeatMode); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); } @@ -193,7 +193,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates { context.SetShuffleMode(request.Mode); var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.ShuffleMode); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); } @@ -221,7 +221,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates { // Notify relevant state change event. var stateUpdate = new GroupStateUpdate(Type, reason.Action); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.StateUpdate, stateUpdate); + var update = new SyncPlayStateUpdate(context.GroupId, stateUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); } diff --git a/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs b/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs index dcc06db1ed..132765b719 100644 --- a/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs +++ b/MediaBrowser.Controller/SyncPlay/GroupStates/WaitingGroupState.cs @@ -78,7 +78,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates // Prepare new session. var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.NewPlaylist); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, update, cancellationToken); context.SetBuffering(session, true); @@ -152,7 +152,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates } var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.NewPlaylist); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); // Reset status of sessions and await for all Ready events. @@ -177,7 +177,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates if (result) { var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); // Reset status of sessions and await for all Ready events. @@ -215,7 +215,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates context.RestartCurrentItem(); var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.NewPlaylist); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); // Reset status of sessions and await for all Ready events. @@ -336,7 +336,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates _logger.LogDebug("Session {SessionId} reported wrong playlist item in group {GroupId}.", session.Id, context.GroupId.ToString()); var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem); - var updateSession = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var updateSession = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, updateSession, cancellationToken); context.SetBuffering(session, true); @@ -410,7 +410,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates _logger.LogDebug("Session {SessionId} reported wrong playlist item in group {GroupId}.", session.Id, context.GroupId.ToString()); var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.SetCurrentItem); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.CurrentSession, update, cancellationToken); context.SetBuffering(session, true); @@ -583,7 +583,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates { // Send playing-queue update. var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.NextItem); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); // Reset status of sessions and await for all Ready events. @@ -629,7 +629,7 @@ namespace MediaBrowser.Controller.SyncPlay.GroupStates { // Send playing-queue update. var playQueueUpdate = context.GetPlayQueueUpdate(PlayQueueUpdateReason.PreviousItem); - var update = context.NewSyncPlayGroupUpdate(GroupUpdateType.PlayQueue, playQueueUpdate); + var update = new SyncPlayPlayQueueUpdate(context.GroupId, playQueueUpdate); context.SendGroupUpdate(session, SyncPlayBroadcastType.AllGroup, update, cancellationToken); // Reset status of sessions and await for all Ready events. diff --git a/MediaBrowser.Controller/SyncPlay/IGroupStateContext.cs b/MediaBrowser.Controller/SyncPlay/IGroupStateContext.cs index d2de224503..ddf86be71f 100644 --- a/MediaBrowser.Controller/SyncPlay/IGroupStateContext.cs +++ b/MediaBrowser.Controller/SyncPlay/IGroupStateContext.cs @@ -66,11 +66,11 @@ namespace MediaBrowser.Controller.SyncPlay /// /// Sends a GroupUpdate message to the interested sessions. /// - /// The type of the data of the message. /// The current session. /// The filtering type. /// The message to send. /// The cancellation token. + /// The group update type. /// The task. Task SendGroupUpdate(SessionInfo from, SyncPlayBroadcastType type, GroupUpdate message, CancellationToken cancellationToken); @@ -91,15 +91,6 @@ namespace MediaBrowser.Controller.SyncPlay /// The command. SendCommand NewSyncPlayCommand(SendCommandType type); - /// - /// Builds a new group update message. - /// - /// The type of the data of the message. - /// The update type. - /// The data to send. - /// The group update. - GroupUpdate NewSyncPlayGroupUpdate(GroupUpdateType type, T data); - /// /// Sanitizes the PositionTicks, considers the current playing item when available. /// diff --git a/MediaBrowser.Model/SyncPlay/GroupUpdate.cs b/MediaBrowser.Model/SyncPlay/GroupUpdate.cs index ec67d7ea87..7944434999 100644 --- a/MediaBrowser.Model/SyncPlay/GroupUpdate.cs +++ b/MediaBrowser.Model/SyncPlay/GroupUpdate.cs @@ -5,15 +5,18 @@ namespace MediaBrowser.Model.SyncPlay; /// /// Group update without data. /// -public abstract class GroupUpdate +/// The type of the update data. +public abstract class GroupUpdate { /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// The group identifier. - protected GroupUpdate(Guid groupId) + /// The update data. + protected GroupUpdate(Guid groupId, T data) { GroupId = groupId; + Data = data; } /// @@ -22,9 +25,15 @@ public abstract class GroupUpdate /// The group identifier. public Guid GroupId { get; } + /// + /// Gets the update data. + /// + /// The update data. + public T Data { get; } + /// /// Gets the update type. /// /// The update type. - public GroupUpdateType Type { get; init; } + public abstract GroupUpdateType Type { get; } } diff --git a/MediaBrowser.Model/SyncPlay/GroupUpdateOfT.cs b/MediaBrowser.Model/SyncPlay/GroupUpdateOfT.cs deleted file mode 100644 index 25cd444611..0000000000 --- a/MediaBrowser.Model/SyncPlay/GroupUpdateOfT.cs +++ /dev/null @@ -1,31 +0,0 @@ -#pragma warning disable SA1649 - -using System; - -namespace MediaBrowser.Model.SyncPlay; - -/// -/// Class GroupUpdate. -/// -/// The type of the data of the message. -public class GroupUpdate : GroupUpdate -{ - /// - /// Initializes a new instance of the class. - /// - /// The group identifier. - /// The update type. - /// The update data. - public GroupUpdate(Guid groupId, GroupUpdateType type, T data) - : base(groupId) - { - Data = data; - Type = type; - } - - /// - /// Gets the update data. - /// - /// The update data. - public T Data { get; } -} diff --git a/MediaBrowser.Model/SyncPlay/GroupUpdateType.cs b/MediaBrowser.Model/SyncPlay/GroupUpdateType.cs index 907d1defe0..e792229a47 100644 --- a/MediaBrowser.Model/SyncPlay/GroupUpdateType.cs +++ b/MediaBrowser.Model/SyncPlay/GroupUpdateType.cs @@ -45,16 +45,6 @@ namespace MediaBrowser.Model.SyncPlay /// GroupDoesNotExist, - /// - /// The create-group-denied error. Sent when a user tries to create a group without required permissions. - /// - CreateGroupDenied, - - /// - /// The join-group-denied error. Sent when a user tries to join a group without required permissions. - /// - JoinGroupDenied, - /// /// The library-access-denied error. Sent when a user tries to join a group without required access to the library. /// diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayGroupDoesNotExistUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayGroupDoesNotExistUpdate.cs new file mode 100644 index 0000000000..7e2d10c8b8 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayGroupDoesNotExistUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayGroupDoesNotExistUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayGroupDoesNotExistUpdate(Guid groupId, string data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.GroupDoesNotExist)] + public override GroupUpdateType Type => GroupUpdateType.GroupDoesNotExist; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayGroupJoinedUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayGroupJoinedUpdate.cs new file mode 100644 index 0000000000..bfb49152a3 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayGroupJoinedUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayGroupJoinedUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayGroupJoinedUpdate(Guid groupId, GroupInfoDto data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.GroupJoined)] + public override GroupUpdateType Type => GroupUpdateType.GroupJoined; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayGroupLeftUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayGroupLeftUpdate.cs new file mode 100644 index 0000000000..5ff60c5c27 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayGroupLeftUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayGroupLeftUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayGroupLeftUpdate(Guid groupId, string data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.GroupLeft)] + public override GroupUpdateType Type => GroupUpdateType.GroupLeft; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayLibraryAccessDeniedUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayLibraryAccessDeniedUpdate.cs new file mode 100644 index 0000000000..0d9a722f78 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayLibraryAccessDeniedUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayLibraryAccessDeniedUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayLibraryAccessDeniedUpdate(Guid groupId, string data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.LibraryAccessDenied)] + public override GroupUpdateType Type => GroupUpdateType.LibraryAccessDenied; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayNotInGroupUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayNotInGroupUpdate.cs new file mode 100644 index 0000000000..a3b610f619 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayNotInGroupUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayNotInGroupUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayNotInGroupUpdate(Guid groupId, string data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.NotInGroup)] + public override GroupUpdateType Type => GroupUpdateType.NotInGroup; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayPlayQueueUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayPlayQueueUpdate.cs new file mode 100644 index 0000000000..83d9bd40bc --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayPlayQueueUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayPlayQueueUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayPlayQueueUpdate(Guid groupId, PlayQueueUpdate data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.PlayQueue)] + public override GroupUpdateType Type => GroupUpdateType.PlayQueue; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayStateUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayStateUpdate.cs new file mode 100644 index 0000000000..744ca46a0b --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayStateUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayStateUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayStateUpdate(Guid groupId, GroupStateUpdate data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.StateUpdate)] + public override GroupUpdateType Type => GroupUpdateType.StateUpdate; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayUserJoinedUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayUserJoinedUpdate.cs new file mode 100644 index 0000000000..e8c6b4df41 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayUserJoinedUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayUserJoinedUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayUserJoinedUpdate(Guid groupId, string data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.UserJoined)] + public override GroupUpdateType Type => GroupUpdateType.UserJoined; +} diff --git a/MediaBrowser.Model/SyncPlay/SyncPlayUserLeftUpdate.cs b/MediaBrowser.Model/SyncPlay/SyncPlayUserLeftUpdate.cs new file mode 100644 index 0000000000..97be8e63a8 --- /dev/null +++ b/MediaBrowser.Model/SyncPlay/SyncPlayUserLeftUpdate.cs @@ -0,0 +1,21 @@ +using System; +using System.ComponentModel; + +namespace MediaBrowser.Model.SyncPlay; + +/// +public class SyncPlayUserLeftUpdate : GroupUpdate +{ + /// + /// Initializes a new instance of the class. + /// + /// The groupId. + /// The data. + public SyncPlayUserLeftUpdate(Guid groupId, string data) : base(groupId, data) + { + } + + /// + [DefaultValue(GroupUpdateType.UserLeft)] + public override GroupUpdateType Type => GroupUpdateType.UserLeft; +} -- cgit v1.2.3