diff --git a/src/Lavalink4NET.Tests/Players/LavalinkPlayerTests.cs b/src/Lavalink4NET.Tests/Players/LavalinkPlayerTests.cs index 641438ab..83dc2ac2 100644 --- a/src/Lavalink4NET.Tests/Players/LavalinkPlayerTests.cs +++ b/src/Lavalink4NET.Tests/Players/LavalinkPlayerTests.cs @@ -10,12 +10,14 @@ using Lavalink4NET.Clients; using Lavalink4NET.Filters; using Lavalink4NET.Players; +using Lavalink4NET.Players.Queued; using Lavalink4NET.Protocol.Models; using Lavalink4NET.Protocol.Models.Filters; using Lavalink4NET.Protocol.Payloads.Events; using Lavalink4NET.Protocol.Requests; using Lavalink4NET.Rest; using Lavalink4NET.Rest.Entities.Tracks; +using Lavalink4NET.Tracks; using Microsoft.Extensions.Internal; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -859,6 +861,9 @@ private static PlayerProperties(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: playerModel.CurrentTrack is null + ? null + : new TrackQueueItem(new TrackReference(RestoreTrack(playerModel.CurrentTrack))), Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -866,6 +871,22 @@ private static PlayerProperties.Instance); } + private static LavalinkTrack RestoreTrack(TrackModel track) => new() + { + Author = track.Information.Author, + Identifier = track.Information.Identifier, + Title = track.Information.Title, + Duration = track.Information.Duration, + IsLiveStream = track.Information.IsLiveStream, + IsSeekable = track.Information.IsSeekable, + Uri = track.Information.Uri, + SourceName = track.Information.SourceName, + StartPosition = track.Information.Position, + ArtworkUri = track.Information.ArtworkUri, + Isrc = track.Information.Isrc, + AdditionalInformation = track.AdditionalInformation, + }; + private static TrackInformationModel CreateDummyTrack() { return new TrackInformationModel( diff --git a/src/Lavalink4NET.Tests/Players/QueuedLavalinkPlayerTests.cs b/src/Lavalink4NET.Tests/Players/QueuedLavalinkPlayerTests.cs index 5ccb721e..9a750695 100644 --- a/src/Lavalink4NET.Tests/Players/QueuedLavalinkPlayerTests.cs +++ b/src/Lavalink4NET.Tests/Players/QueuedLavalinkPlayerTests.cs @@ -13,6 +13,7 @@ using Lavalink4NET.Protocol.Payloads.Events; using Lavalink4NET.Protocol.Requests; using Lavalink4NET.Rest; +using Lavalink4NET.Tracks; using Microsoft.Extensions.Internal; using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Options; @@ -75,6 +76,7 @@ public async Task TestPlayerIsStartedOnSkipAsync() LifecycleNotifier: null), Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, + InitialTrack: null, InitialState: playerModel, Label: "Player", VoiceChannelId: 0, @@ -147,6 +149,7 @@ public async Task TestPlayerStartsSecondTrackIfNoneIsPlayingButCountIsTwoOnSkipA Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: null, Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -215,6 +218,7 @@ public async Task TestPlayerStopsOnSkipIfQueueIsEmptyAsync() Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: null, Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -289,6 +293,7 @@ public async Task TestPlayerPlaysNextAfterTrackEndAsync() Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: new TrackQueueItem(new TrackReference(RestoreTrack(playerModel.CurrentTrack!))), Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -368,6 +373,7 @@ public async Task TestPlayerRepeatsTrackIfRepeatModeIsTrackAsync() Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: new TrackQueueItem(new TrackReference(RestoreTrack(playerModel.CurrentTrack!))), Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -451,6 +457,7 @@ public async Task TestPlayerRepeatsTrackIfRepeatModeIsTrackOnSkipAsync() Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: new TrackQueueItem(new TrackReference(RestoreTrack(playerModel.CurrentTrack!))), Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -525,6 +532,7 @@ public async Task TestPlayerStopsTrackIfRepeatModeIsTrackButNoTrackIsPlayingOnSk Lifecycle: Mock.Of(), ApiClient: apiClientMock.Object, InitialState: playerModel, + InitialTrack: null, Label: "Player", VoiceChannelId: 0, SessionId: sessionId, @@ -543,6 +551,22 @@ await player apiClientMock.Verify(); } + private static LavalinkTrack RestoreTrack(TrackModel track) => new() + { + Author = track.Information.Author, + Identifier = track.Information.Identifier, + Title = track.Information.Title, + Duration = track.Information.Duration, + IsLiveStream = track.Information.IsLiveStream, + IsSeekable = track.Information.IsSeekable, + Uri = track.Information.Uri, + SourceName = track.Information.SourceName, + StartPosition = track.Information.Position, + ArtworkUri = track.Information.ArtworkUri, + Isrc = track.Information.Isrc, + AdditionalInformation = track.AdditionalInformation, + }; + private static TrackInformationModel CreateDummyTrack() { return new TrackInformationModel( diff --git a/src/Lavalink4NET/Players/IPlayerProperties.cs b/src/Lavalink4NET/Players/IPlayerProperties.cs index acaf1943..33d88b78 100644 --- a/src/Lavalink4NET/Players/IPlayerProperties.cs +++ b/src/Lavalink4NET/Players/IPlayerProperties.cs @@ -18,6 +18,8 @@ public interface IPlayerProperties PlayerInformationModel InitialState { get; } + ITrackQueueItem? InitialTrack { get; } + string Label { get; } ILogger Logger { get; } diff --git a/src/Lavalink4NET/Players/LavalinkPlayer.cs b/src/Lavalink4NET/Players/LavalinkPlayer.cs index fe614294..029de55d 100644 --- a/src/Lavalink4NET/Players/LavalinkPlayer.cs +++ b/src/Lavalink4NET/Players/LavalinkPlayer.cs @@ -77,7 +77,7 @@ public LavalinkPlayer(IPlayerProperties p } _currentItem = _nextTrack = properties.InitialState.CurrentTrack is not null - ? new TrackQueueItem(new TrackReference(RestoreTrack(properties.InitialState.CurrentTrack))) + ? properties.Options.Value.InitialTrack ?? new TrackQueueItem(new TrackReference(RestoreTrack(properties.InitialState.CurrentTrack))) : null; Refresh(properties.InitialState); diff --git a/src/Lavalink4NET/Players/LavalinkPlayerHandle.cs b/src/Lavalink4NET/Players/LavalinkPlayerHandle.cs index cd42f5d1..baef5208 100644 --- a/src/Lavalink4NET/Players/LavalinkPlayerHandle.cs +++ b/src/Lavalink4NET/Players/LavalinkPlayerHandle.cs @@ -177,7 +177,7 @@ private async ValueTask CreatePlayerAsync(CancellationToken cancellatio var playerSession = await _playerContext.SessionProvider .GetSessionAsync(_guildId, cancellationToken) .ConfigureAwait(false); - + var playerProperties = new PlayerUpdateProperties { VoiceState = new VoiceStateProperties( @@ -188,12 +188,12 @@ private async ValueTask CreatePlayerAsync(CancellationToken cancellatio if (_options.Value.InitialTrack is not null) { - var initialTrack = _options.Value.InitialTrack.Value; + var initialTrack = _options.Value.InitialTrack; var loadOptions = _options.Value.InitialLoadOptions; - if (initialTrack.IsPresent) + if (initialTrack.Reference.IsPresent) { - playerProperties = playerProperties with { TrackData = initialTrack.Track.ToString(), }; + playerProperties = playerProperties with { TrackData = initialTrack.Track!.ToString(), }; } else { @@ -231,6 +231,7 @@ private async ValueTask CreatePlayerAsync(CancellationToken cancellatio var properties = new PlayerProperties( Context: _playerContext, VoiceChannelId: _voiceState.Value.VoiceChannelId!.Value, + InitialTrack: _options.Value.InitialTrack, InitialState: initialState, Label: label, SessionId: playerSession.SessionId, diff --git a/src/Lavalink4NET/Players/LavalinkPlayerOptions.cs b/src/Lavalink4NET/Players/LavalinkPlayerOptions.cs index 1e810364..86ea56c9 100644 --- a/src/Lavalink4NET/Players/LavalinkPlayerOptions.cs +++ b/src/Lavalink4NET/Players/LavalinkPlayerOptions.cs @@ -10,7 +10,7 @@ public record class LavalinkPlayerOptions public string? Label { get; set; } - public TrackReference? InitialTrack { get; set; } + public ITrackQueueItem? InitialTrack { get; set; } public TrackLoadOptions InitialLoadOptions { get; set; } diff --git a/src/Lavalink4NET/Players/PlayerProperties.cs b/src/Lavalink4NET/Players/PlayerProperties.cs index 3e407939..084d330d 100644 --- a/src/Lavalink4NET/Players/PlayerProperties.cs +++ b/src/Lavalink4NET/Players/PlayerProperties.cs @@ -10,6 +10,7 @@ internal sealed record class PlayerProperties( PlayerContext Context, + ITrackQueueItem? InitialTrack, PlayerInformationModel InitialState, string Label, ulong VoiceChannelId,