Shuffle will now show in .lq at the top, and instead of shuffling playlist, it will randomly jump to a song in the playlist. "

This commit is contained in:
Master Kwoth 2017-07-02 08:03:24 +02:00
parent 3731994061
commit 9bb72d9976
4 changed files with 47 additions and 46 deletions

View File

@ -1,18 +1,14 @@
using Discord.Commands; using Discord.Commands;
using Discord.WebSocket; using Discord.WebSocket;
using NadekoBot.Services; using NadekoBot.Services;
using System.IO;
using Discord; using Discord;
using System.Threading.Tasks; using System.Threading.Tasks;
using NadekoBot.Attributes; using NadekoBot.Attributes;
using System; using System;
using System.Linq; using System.Linq;
using NadekoBot.Extensions; using NadekoBot.Extensions;
using System.Net.Http;
using Newtonsoft.Json.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using NadekoBot.Services.Database.Models; using NadekoBot.Services.Database.Models;
using System.Threading;
using NadekoBot.Services.Music; using NadekoBot.Services.Music;
using NadekoBot.DataStructures; using NadekoBot.DataStructures;
using System.Collections.Concurrent; using System.Collections.Concurrent;
@ -102,24 +98,26 @@ namespace NadekoBot.Modules.Music
.WithThumbnailUrl(songInfo.Thumbnail) .WithThumbnailUrl(songInfo.Thumbnail)
.WithFooter(ef => ef.WithText(songInfo.PrettyProvider))) .WithFooter(ef => ef.WithText(songInfo.PrettyProvider)))
.ConfigureAwait(false); .ConfigureAwait(false);
if (mp.Stopped)
{
(await ReplyErrorLocalized("music_queue_stopped", Format.Code(Prefix + "play")).ConfigureAwait(false)).DeleteAfter(10);
}
queuedMessage?.DeleteAfter(10); queuedMessage?.DeleteAfter(10);
} }
catch catch
{ {
// ignored // ignored
} // if queued message sending fails, don't attempt to delete it }
} }
} }
} }
//todo add play command. .play = .n, .play whatever = .q whatever //todo add play command. .play = .n, .play whatever = .q whatever
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Queue([Remainder] string query) public async Task Queue([Remainder] string query)
{ {
//todo add a notice that player is stopped if user queues a song while it is
var mp = await _music.GetOrCreatePlayer(Context); var mp = await _music.GetOrCreatePlayer(Context);
var songInfo = await _music.ResolveSong(query, Context.User.ToString()); var songInfo = await _music.ResolveSong(query, Context.User.ToString());
await InternalQueue(mp, songInfo, false); await InternalQueue(mp, songInfo, false);
@ -207,7 +205,7 @@ namespace NadekoBot.Modules.Music
return $"**⇒**`{number}.` {v.PrettyFullName}"; return $"**⇒**`{number}.` {v.PrettyFullName}";
else else
return $"`{number}.` {v.PrettyFullName}"; return $"`{number}.` {v.PrettyFullName}";
})); //todo v.prettyfullname instead of title }));
desc = $"`🔊` {songs[current].PrettyFullName}\n\n" + desc; desc = $"`🔊` {songs[current].PrettyFullName}\n\n" + desc;
@ -687,7 +685,7 @@ namespace NadekoBot.Modules.Music
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task Move() public void Move()
{ {
var vch = ((IGuildUser)Context.User).VoiceChannel; var vch = ((IGuildUser)Context.User).VoiceChannel;
@ -748,6 +746,7 @@ namespace NadekoBot.Modules.Music
//} //}
//todo test smq
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task SetMaxQueue(uint size = 0) public async Task SetMaxQueue(uint size = 0)
@ -782,6 +781,7 @@ namespace NadekoBot.Modules.Music
// await ReplyConfirmLocalized("max_playtime_set", seconds).ConfigureAwait(false); // await ReplyConfirmLocalized("max_playtime_set", seconds).ConfigureAwait(false);
//} //}
//todo test rcs
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task ReptCurSong() public async Task ReptCurSong()
@ -803,6 +803,7 @@ namespace NadekoBot.Modules.Music
.ConfigureAwait(false); .ConfigureAwait(false);
} }
//todo test rpl
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
public async Task RepeatPl() public async Task RepeatPl()
@ -862,6 +863,7 @@ namespace NadekoBot.Modules.Music
await ReplyConfirmLocalized("autoplay_enabled").ConfigureAwait(false); await ReplyConfirmLocalized("autoplay_enabled").ConfigureAwait(false);
} }
//todo test output text channel
[NadekoCommand, Usage, Description, Aliases] [NadekoCommand, Usage, Description, Aliases]
[RequireContext(ContextType.Guild)] [RequireContext(ContextType.Guild)]
[RequireUserPermission(GuildPermission.ManageMessages)] [RequireUserPermission(GuildPermission.ManageMessages)]

View File

@ -96,48 +96,46 @@ namespace NadekoBot.Services.Music
var ac = await GetAudioClient(); var ac = await GetAudioClient();
if (ac == null) if (ac == null)
{ {
await Task.Delay(900); await Task.Delay(900, cancelToken);
// just wait some time, maybe bot doesn't even have perms to join that voice channel, // just wait some time, maybe bot doesn't even have perms to join that voice channel,
// i don't want to spam connection attempts // i don't want to spam connection attempts
continue; continue;
} }
using (var pcm = ac.CreatePCMStream(AudioApplication.Music)) var pcm = ac.CreatePCMStream(AudioApplication.Music, bufferMillis: 250);
OnStarted?.Invoke(this, data.Song);
byte[] buffer = new byte[3840];
int bytesRead = 0;
try
{ {
OnStarted?.Invoke(this, data.Song); while ((bytesRead = await b.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false)) > 0)
{
var vol = Volume;
if (vol != 1)
AdjustVolume(buffer, vol);
await Task.WhenAll(Task.Delay(10), pcm.WriteAsync(buffer, 0, bytesRead, cancelToken)).ConfigureAwait(false);
byte[] buffer = new byte[3840]; await (pauseTaskSource?.Task ?? Task.CompletedTask);
int bytesRead = 0; }
try }
{ catch (OperationCanceledException)
while ((bytesRead = await b.ReadAsync(buffer, 0, buffer.Length, cancelToken).ConfigureAwait(false)) > 0) {
{ _log.Info("Song Canceled");
var vol = Volume; }
if (vol != 1) catch (Exception ex)
AdjustVolume(buffer, vol); {
await Task.WhenAll(Task.Delay(10), pcm.WriteAsync(buffer, 0, bytesRead, cancelToken)).ConfigureAwait(false); _log.Warn(ex);
}
finally
{
//flush is known to get stuck from time to time, just cancel it if it takes more than 1 second
var flushCancel = new CancellationTokenSource();
var flushToken = flushCancel.Token;
var flushDelay = Task.Delay(1000, flushToken);
await Task.WhenAny(flushDelay, pcm.FlushAsync(flushToken));
flushCancel.Cancel();
await (pauseTaskSource?.Task ?? Task.CompletedTask); OnCompleted?.Invoke(this, data.Song);
}
}
catch (OperationCanceledException)
{
_log.Info("Song Canceled");
}
catch (Exception ex)
{
_log.Warn(ex);
}
finally
{
//flush is known to get stuck from time to time, just cancel it if it takes more than 1 second
var flushCancel = new CancellationTokenSource();
var flushToken = flushCancel.Token;
var flushDelay = Task.Delay(1000, flushToken);
await Task.WhenAny(flushDelay, pcm.FlushAsync(flushToken));
flushCancel.Cancel();
OnCompleted?.Invoke(this, data.Song);
}
} }
} }
} }

View File

@ -57,7 +57,7 @@ namespace NadekoBot.Services.Music
song.ThrowIfNull(nameof(song)); song.ThrowIfNull(nameof(song));
lock (locker) lock (locker)
{ {
if(CurrentIndex >= maxQueueSize) if(maxQueueSize !=0 && CurrentIndex >= maxQueueSize)
throw new PlaylistFullException(); throw new PlaylistFullException();
Songs.AddLast(song); Songs.AddLast(song);
} }

View File

@ -437,6 +437,7 @@
"music_queued_song": "Queued song", "music_queued_song": "Queued song",
"music_queue_cleared": "Music queue cleared.", "music_queue_cleared": "Music queue cleared.",
"music_queue_full": "Queue is full at {0}/{0}.", "music_queue_full": "Queue is full at {0}/{0}.",
"music_queue_stopped": "Player is stopped. Use {0} command to start playing.",
"music_removed_song": "Removed song", "music_removed_song": "Removed song",
"music_repeating_cur_song": "Repeating current song", "music_repeating_cur_song": "Repeating current song",
"music_repeating_playlist": "Repeating playlist", "music_repeating_playlist": "Repeating playlist",