2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitmodules
									
									
									
									
										vendored
									
									
								
							| @@ -1,3 +1,3 @@ | |||||||
| [submodule "discord.net"] | [submodule "discord.net"] | ||||||
| 	path = discord.net | 	path = discord.net | ||||||
| 	url = git://github.com/rogueexception/discord.net.git | 	url = git://github.com/kwoth/discord.net.git | ||||||
|   | |||||||
| @@ -46,10 +46,10 @@ namespace NadekoBot.Extensions | |||||||
|             if (num == 0) |             if (num == 0) | ||||||
|                 return string.Empty; |                 return string.Empty; | ||||||
|             if (num <= 3) |             if (num <= 3) | ||||||
|                 return string.Join("", str.Select(c => '.')); |                 return string.Concat(str.Select(c => '.')); | ||||||
|             if (str.Length < num) |             if (str.Length < num) | ||||||
|                 return str; |                 return str; | ||||||
|             return string.Join("", str.Take(num - 3)) + (hideDots ? "" : "..."); |             return string.Concat(str.Take(num - 3)) + (hideDots ? "" : "..."); | ||||||
|         } |         } | ||||||
|         /// <summary> |         /// <summary> | ||||||
|         /// Removes trailing S or ES (if specified) on the given string if the num is 1 |         /// Removes trailing S or ES (if specified) on the given string if the num is 1 | ||||||
| @@ -237,7 +237,7 @@ namespace NadekoBot.Extensions | |||||||
|  |  | ||||||
|         public static string Matrix(this string s) |         public static string Matrix(this string s) | ||||||
|             => |             => | ||||||
|                 string.Join("", s.Select(c => c.ToString() + " ̵̢̬̜͉̞̭̖̰͋̉̎ͬ̔̇̌̀".TrimTo(rng.Next(0, 12), true))); |                 string.Concat(s.Select(c => c.ToString() + " ̵̢̬̜͉̞̭̖̰͋̉̎ͬ̔̇̌̀".TrimTo(rng.Next(0, 12), true))); | ||||||
|         //.Replace("`", ""); |         //.Replace("`", ""); | ||||||
|  |  | ||||||
|         public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) |         public static void ForEach<T>(this IEnumerable<T> source, Action<T> action) | ||||||
|   | |||||||
| @@ -384,7 +384,7 @@ namespace NadekoBot.Classes | |||||||
|         { |         { | ||||||
|             var i = 0; |             var i = 0; | ||||||
|             return "```xl\n" + string.Join("\n", items.GroupBy(item => (i++) / cols) |             return "```xl\n" + string.Join("\n", items.GroupBy(item => (i++) / cols) | ||||||
|                                       .Select(ig => string.Join("", ig.Select(el => howToPrint(el))))) |                                       .Select(ig => string.Concat(ig.Select(el => howToPrint(el))))) | ||||||
|                                       + $"\n```"; |                                       + $"\n```"; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -738,7 +738,7 @@ namespace NadekoBot.Modules.Administration | |||||||
|                         if (string.IsNullOrWhiteSpace(msg)) |                         if (string.IsNullOrWhiteSpace(msg)) | ||||||
|                             return; |                             return; | ||||||
|  |  | ||||||
|                         var ids = e.GetArg("ids").Split('-'); |                         var ids = e.GetArg("ids").Split('|'); | ||||||
|                         if (ids.Length != 2) |                         if (ids.Length != 2) | ||||||
|                             return; |                             return; | ||||||
|                         var sid = ulong.Parse(ids[0]); |                         var sid = ulong.Parse(ids[0]); | ||||||
|   | |||||||
| @@ -1,6 +1,8 @@ | |||||||
| using Discord.Commands; | using Discord.Commands; | ||||||
|  | using Discord.Net; | ||||||
| using NadekoBot.Classes; | using NadekoBot.Classes; | ||||||
| using NadekoBot.Modules.Permissions.Classes; | using NadekoBot.Modules.Permissions.Classes; | ||||||
|  | using System; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Text; | using System.Text; | ||||||
| @@ -144,7 +146,10 @@ namespace NadekoBot.Modules.Administration.Commands | |||||||
|                     { |                     { | ||||||
|                         await e.User.AddRoles(role).ConfigureAwait(false); |                         await e.User.AddRoles(role).ConfigureAwait(false); | ||||||
|                     } |                     } | ||||||
|                     catch |                     catch(HttpException ex) when (ex.StatusCode == System.Net.HttpStatusCode.InternalServerError) | ||||||
|  |                     { | ||||||
|  |                     } | ||||||
|  |                     catch (Exception) | ||||||
|                     { |                     { | ||||||
|                         await e.Channel.SendMessage($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); |                         await e.Channel.SendMessage($":anger:`I am unable to add that role to you. I can't add roles to owners or other roles higher than my role in the role hierarchy.`").ConfigureAwait(false); | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -9,13 +9,14 @@ using System; | |||||||
| using System.Diagnostics; | using System.Diagnostics; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
|  | using System.Text; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
|  |  | ||||||
| namespace NadekoBot.Modules.Conversations | namespace NadekoBot.Modules.Conversations | ||||||
| { | { | ||||||
|     internal class Conversations : DiscordModule |     internal class Conversations : DiscordModule | ||||||
|     { |     { | ||||||
|         private const string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥"; |         private const string firestr = "🔥 ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็ด้้้้้็็็็็้้้้้็็็็็้้้้้้้้็็็็็้้้้้็็็็็้้้้ 🔥"; | ||||||
|         public Conversations() |         public Conversations() | ||||||
|         { |         { | ||||||
|             commands.Add(new RipCommand(this)); |             commands.Add(new RipCommand(this)); | ||||||
| @@ -153,22 +154,23 @@ namespace NadekoBot.Modules.Conversations | |||||||
|                     .Parameter("times", ParameterType.Optional) |                     .Parameter("times", ParameterType.Optional) | ||||||
|                     .Do(async e => |                     .Do(async e => | ||||||
|                     { |                     { | ||||||
|                         var count = 1; |                         int count; | ||||||
|                         int.TryParse(e.Args[0], out count); |                         if (string.IsNullOrWhiteSpace(e.Args[0])) | ||||||
|                         if (count == 0) |  | ||||||
|                             count = 1; |                             count = 1; | ||||||
|  |                         else | ||||||
|  |                             int.TryParse(e.Args[0], out count); | ||||||
|                         if (count < 1 || count > 12) |                         if (count < 1 || count > 12) | ||||||
|                         { |                         { | ||||||
|                             await e.Channel.SendMessage("Number must be between 0 and 12").ConfigureAwait(false); |                             await e.Channel.SendMessage("Number must be between 1 and 12").ConfigureAwait(false); | ||||||
|                             return; |                             return; | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         var str = ""; |                         var str = new StringBuilder(); | ||||||
|                         for (var i = 0; i < count; i++) |                         for (var i = 0; i < count; i++) | ||||||
|                         { |                         { | ||||||
|                             str += firestr; |                             str.Append(firestr); | ||||||
|                         } |                         } | ||||||
|                         await e.Channel.SendMessage(str).ConfigureAwait(false); |                         await e.Channel.SendMessage(str.ToString()).ConfigureAwait(false); | ||||||
|                     }); |                     }); | ||||||
|  |  | ||||||
|                 cgb.CreateCommand("dump") |                 cgb.CreateCommand("dump") | ||||||
|   | |||||||
| @@ -146,7 +146,7 @@ namespace NadekoBot.Modules.Gambling.Helpers | |||||||
|             var orderedPool = cardPool.OrderBy(x => r.Next()); |             var orderedPool = cardPool.OrderBy(x => r.Next()); | ||||||
|             cardPool = cardPool as List<Card> ?? orderedPool.ToList(); |             cardPool = cardPool as List<Card> ?? orderedPool.ToList(); | ||||||
|         } |         } | ||||||
|         public override string ToString() => string.Join("", cardPool.Select(c => c.ToString())) + Environment.NewLine; |         public override string ToString() => string.Concat(cardPool.Select(c => c.ToString())) + Environment.NewLine; | ||||||
|  |  | ||||||
|         private static void InitHandValues() |         private static void InitHandValues() | ||||||
|         { |         { | ||||||
| @@ -226,7 +226,7 @@ namespace NadekoBot.Modules.Gambling.Helpers | |||||||
|             { |             { | ||||||
|                 return kvp.Key; |                 return kvp.Key; | ||||||
|             } |             } | ||||||
|             return "High card " + cards.Max().GetName(); |             return "High card " + (cards.FirstOrDefault(c => c.Number == 1)?.GetName() ?? cards.Max().GetName()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -102,7 +102,6 @@ namespace NadekoBot.Modules.Games.Commands | |||||||
|  |  | ||||||
|                         var file = GetRandomCurrencyImagePath(); |                         var file = GetRandomCurrencyImagePath(); | ||||||
|                         Message msg; |                         Message msg; | ||||||
|                         //todo send message after, not in lock |  | ||||||
|                         if (file == null) |                         if (file == null) | ||||||
|                             msg = e.Channel.SendMessage(NadekoBot.Config.CurrencySign).GetAwaiter().GetResult(); |                             msg = e.Channel.SendMessage(NadekoBot.Config.CurrencySign).GetAwaiter().GetResult(); | ||||||
|                         else |                         else | ||||||
|   | |||||||
| @@ -190,8 +190,6 @@ namespace NadekoBot.Modules.Games.Commands | |||||||
|  |  | ||||||
|                     await e.Channel.SendMessage("Added new article for typing game.").ConfigureAwait(false); |                     await e.Channel.SendMessage("Added new article for typing game.").ConfigureAwait(false); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|             //todo add user submissions |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ using NadekoBot.Modules.Permissions.Classes; | |||||||
| using System; | using System; | ||||||
| using System.IO; | using System.IO; | ||||||
| using System.Linq; | using System.Linq; | ||||||
|  | using System.Text.RegularExpressions; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
|  |  | ||||||
| namespace NadekoBot.Classes.Help.Commands | namespace NadekoBot.Classes.Help.Commands | ||||||
| @@ -24,8 +25,13 @@ namespace NadekoBot.Classes.Help.Commands | |||||||
|                 var com = NadekoBot.Client.GetService<CommandService>().AllCommands |                 var com = NadekoBot.Client.GetService<CommandService>().AllCommands | ||||||
|                     .FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) || |                     .FirstOrDefault(c => c.Text.ToLowerInvariant().Equals(comToFind) || | ||||||
|                                         c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind)); |                                         c.Aliases.Select(a => a.ToLowerInvariant()).Contains(comToFind)); | ||||||
|  |  | ||||||
|  |                 var str = ""; | ||||||
|  |                 var alias = com.Aliases.FirstOrDefault(); | ||||||
|  |                 if (alias != null) | ||||||
|  |                     str = $" / `{ com.Aliases.FirstOrDefault()}`"; | ||||||
|                 if (com != null) |                 if (com != null) | ||||||
|                     await e.Channel.SendMessage($"**__Help for `{com.Text}`__ / __`{("" + com.Aliases.FirstOrDefault() + "" ?? "")}`__**\n**Desc:** {com.Description.Replace("|", "\n**Usage:**")}").ConfigureAwait(false); |                     await e.Channel.SendMessage($@"**__Help for:__ `{com.Text}`**" + str + $"\n**Desc:** {new Regex(@"\|").Replace(com.Description, "\n**Usage:**",1)}").ConfigureAwait(false); | ||||||
|             }).ConfigureAwait(false); |             }).ConfigureAwait(false); | ||||||
|         }; |         }; | ||||||
|         public static string HelpString { |         public static string HelpString { | ||||||
|   | |||||||
| @@ -2,7 +2,9 @@ | |||||||
| using Discord.Audio; | using Discord.Audio; | ||||||
| using NadekoBot.Extensions; | using NadekoBot.Extensions; | ||||||
| using System; | using System; | ||||||
|  | using System.Collections.Concurrent; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
|  | using System.Linq; | ||||||
| using System.Threading; | using System.Threading; | ||||||
| using System.Threading.Tasks; | using System.Threading.Tasks; | ||||||
| namespace NadekoBot.Modules.Music.Classes | namespace NadekoBot.Modules.Music.Classes | ||||||
| @@ -20,22 +22,18 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|     { |     { | ||||||
|         Resolving, |         Resolving, | ||||||
|         Queued, |         Queued, | ||||||
|         Buffering, //not using it atm |  | ||||||
|         Playing, |         Playing, | ||||||
|         Completed |         Completed | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public class MusicPlayer |     public class MusicPlayer | ||||||
|     { |     { | ||||||
|         public static int MaximumPlaylistSize => 50; |  | ||||||
|  |  | ||||||
|         private IAudioClient audioClient { get; set; } |         private IAudioClient audioClient { get; set; } | ||||||
|  |  | ||||||
|         private readonly List<Song> playlist = new List<Song>(); |         private readonly List<Song> playlist = new List<Song>(); | ||||||
|         public IReadOnlyCollection<Song> Playlist => playlist; |         public IReadOnlyCollection<Song> Playlist => playlist; | ||||||
|         private readonly object playlistLock = new object(); |  | ||||||
|  |  | ||||||
|         public Song CurrentSong { get; set; } = default(Song); |         public Song CurrentSong { get; private set; } | ||||||
|         private CancellationTokenSource SongCancelSource { get; set; } |         private CancellationTokenSource SongCancelSource { get; set; } | ||||||
|         private CancellationToken cancelToken { get; set; } |         private CancellationToken cancelToken { get; set; } | ||||||
|  |  | ||||||
| @@ -54,6 +52,8 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|         public bool Autoplay { get; set; } = false; |         public bool Autoplay { get; set; } = false; | ||||||
|         public uint MaxQueueSize { get; set; } = 0; |         public uint MaxQueueSize { get; set; } = 0; | ||||||
|  |  | ||||||
|  |         private ConcurrentQueue<Action> actionQueue { get; set; } = new ConcurrentQueue<Action>(); | ||||||
|  |  | ||||||
|         public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume) |         public MusicPlayer(Channel startingVoiceChannel, float? defaultVolume) | ||||||
|         { |         { | ||||||
|             if (startingVoiceChannel == null) |             if (startingVoiceChannel == null) | ||||||
| @@ -67,86 +67,111 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|             cancelToken = SongCancelSource.Token; |             cancelToken = SongCancelSource.Token; | ||||||
|  |  | ||||||
|             Task.Run(async () => |             Task.Run(async () => | ||||||
|  |             { | ||||||
|  |                 try | ||||||
|  |                 { | ||||||
|  |                     while (!Destroyed) | ||||||
|  |                     { | ||||||
|  |                         try | ||||||
|  |                         { | ||||||
|  |                             Action action; | ||||||
|  |                             if (actionQueue.TryDequeue(out action)) | ||||||
|  |                             { | ||||||
|  |                                 action(); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         finally | ||||||
|  |                         { | ||||||
|  |                             await Task.Delay(100).ConfigureAwait(false); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 catch (Exception ex) | ||||||
|  |                 { | ||||||
|  |                     Console.WriteLine("Action queue crashed"); | ||||||
|  |                     Console.WriteLine(ex); | ||||||
|  |                 } | ||||||
|  |             }).ConfigureAwait(false); | ||||||
|  |  | ||||||
|  |             var t = new Thread(new ThreadStart(async () => | ||||||
|  |             { | ||||||
|  |                 try | ||||||
|                 { |                 { | ||||||
|                     while (!Destroyed) |                     while (!Destroyed) | ||||||
|                     { |                     { | ||||||
|                         try |                         try | ||||||
|                         { |                         { | ||||||
|                             if (audioClient?.State != ConnectionState.Connected) |                             if (audioClient?.State != ConnectionState.Connected) | ||||||
|                             audioClient = await PlaybackVoiceChannel.JoinAudio().ConfigureAwait(false); |  | ||||||
|                     } |  | ||||||
|                     catch |  | ||||||
|                             { |                             { | ||||||
|                         await Task.Delay(1000).ConfigureAwait(false); |                                 audioClient = await PlaybackVoiceChannel.JoinAudio(); | ||||||
|                                 continue; |                                 continue; | ||||||
|                             } |                             } | ||||||
|  |  | ||||||
|                             CurrentSong = GetNextSong(); |                             CurrentSong = GetNextSong(); | ||||||
|                     var curSong = CurrentSong; |                             RemoveSongAt(0); | ||||||
|                     if (curSong != null) |  | ||||||
|                     { |                             if (CurrentSong == null) | ||||||
|  |                                 continue; | ||||||
|  |  | ||||||
|                             try |                             try | ||||||
|                             { |                             { | ||||||
|                             OnStarted(this, curSong); |                                 OnStarted(this, CurrentSong); | ||||||
|                             await curSong.Play(audioClient, cancelToken).ConfigureAwait(false); |                                 await CurrentSong.Play(audioClient, cancelToken); | ||||||
|                             } |                             } | ||||||
|                             catch (OperationCanceledException) |                             catch (OperationCanceledException) | ||||||
|                             { |                             { | ||||||
|                                 Console.WriteLine("Song canceled"); |                                 Console.WriteLine("Song canceled"); | ||||||
|                         } |  | ||||||
|                         catch (Exception ex) |  | ||||||
|                         { |  | ||||||
|                             Console.WriteLine($"Exception in PlaySong: {ex}"); |  | ||||||
|                         } |  | ||||||
|                         OnCompleted(this, curSong); |  | ||||||
|                         curSong = CurrentSong; //to check if its null now |  | ||||||
|                         if (curSong != null) |  | ||||||
|                             if (RepeatSong) |  | ||||||
|                                 playlist.Insert(0, curSong); |  | ||||||
|                             else if (RepeatPlaylist) |  | ||||||
|                                 playlist.Insert(playlist.Count, curSong); |  | ||||||
|                                 SongCancelSource = new CancellationTokenSource(); |                                 SongCancelSource = new CancellationTokenSource(); | ||||||
|                                 cancelToken = SongCancelSource.Token; |                                 cancelToken = SongCancelSource.Token; | ||||||
|                             } |                             } | ||||||
|                     await Task.Delay(1000).ConfigureAwait(false); |                             OnCompleted(this, CurrentSong); | ||||||
|  |  | ||||||
|  |                             if (RepeatPlaylist) | ||||||
|  |                                 AddSong(CurrentSong, CurrentSong.QueuerName); | ||||||
|  |  | ||||||
|  |                             if (RepeatSong) | ||||||
|  |                                 AddSong(CurrentSong, 0); | ||||||
|  |                              | ||||||
|                         } |                         } | ||||||
|             }); |                         finally | ||||||
|  |                         { | ||||||
|  |                             await Task.Delay(300).ConfigureAwait(false); | ||||||
|  |                             CurrentSong = null; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 catch (Exception ex) { | ||||||
|  |                     Console.WriteLine("Music thread crashed."); | ||||||
|  |                     Console.WriteLine(ex); | ||||||
|  |                 } | ||||||
|  |             })); | ||||||
|  |  | ||||||
|  |             t.Start(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void Next() |         public void Next() | ||||||
|         { |         { | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |  | ||||||
|                 if (!SongCancelSource.IsCancellationRequested) |  | ||||||
|             { |             { | ||||||
|                 Paused = false; |                 Paused = false; | ||||||
|                 SongCancelSource.Cancel(); |                 SongCancelSource.Cancel(); | ||||||
|                 } |             }); | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void Stop() |         public void Stop() | ||||||
|         { |         { | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |             { | ||||||
|                 playlist.Clear(); |  | ||||||
|                 CurrentSong = null; |  | ||||||
|                 RepeatPlaylist = false; |                 RepeatPlaylist = false; | ||||||
|                 RepeatSong = false; |                 RepeatSong = false; | ||||||
|  |                 playlist.Clear(); | ||||||
|                 if (!SongCancelSource.IsCancellationRequested) |                 if (!SongCancelSource.IsCancellationRequested) | ||||||
|                     SongCancelSource.Cancel(); |                     SongCancelSource.Cancel(); | ||||||
|             } |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void TogglePause() => Paused = !Paused; |         public void TogglePause() => Paused = !Paused; | ||||||
|  |  | ||||||
|         public void Shuffle() |  | ||||||
|         { |  | ||||||
|             lock (playlistLock) |  | ||||||
|             { |  | ||||||
|                 playlist.Shuffle(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public int SetVolume(int volume) |         public int SetVolume(int volume) | ||||||
|         { |         { | ||||||
|             if (volume < 0) |             if (volume < 0) | ||||||
| @@ -158,16 +183,15 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|             return volume; |             return volume; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         private Song GetNextSong() |         private Song GetNextSong() => | ||||||
|  |             playlist.FirstOrDefault(); | ||||||
|  |  | ||||||
|  |         public void Shuffle() | ||||||
|         { |         { | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |             { | ||||||
|                 if (playlist.Count == 0) |                 playlist.Shuffle(); | ||||||
|                     return null; |             }); | ||||||
|                 var toReturn = playlist[0]; |  | ||||||
|                 playlist.RemoveAt(0); |  | ||||||
|                 return toReturn; |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void AddSong(Song s, string username) |         public void AddSong(Song s, string username) | ||||||
| @@ -175,42 +199,64 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|             if (s == null) |             if (s == null) | ||||||
|                 throw new ArgumentNullException(nameof(s)); |                 throw new ArgumentNullException(nameof(s)); | ||||||
|             ThrowIfQueueFull(); |             ThrowIfQueueFull(); | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |             { | ||||||
|                 s.MusicPlayer = this; |                 s.MusicPlayer = this; | ||||||
|                 s.QueuerName = username.TrimTo(10); |                 s.QueuerName = username.TrimTo(10); | ||||||
|                 playlist.Add(s); |                 playlist.Add(s); | ||||||
|             } |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void AddSong(Song s, int index) |         public void AddSong(Song s, int index) | ||||||
|         { |         { | ||||||
|             if (s == null) |             if (s == null) | ||||||
|                 throw new ArgumentNullException(nameof(s)); |                 throw new ArgumentNullException(nameof(s)); | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |             { | ||||||
|                 playlist.Insert(index, s); |                 playlist.Insert(index, s); | ||||||
|             } |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void RemoveSong(Song s) |         public void RemoveSong(Song s) | ||||||
|         { |         { | ||||||
|             if (s == null) |             if (s == null) | ||||||
|                 throw new ArgumentNullException(nameof(s)); |                 throw new ArgumentNullException(nameof(s)); | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |             { | ||||||
|                 playlist.Remove(s); |                 playlist.Remove(s); | ||||||
|             } |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public void RemoveSongAt(int index) |         public void RemoveSongAt(int index) | ||||||
|         { |         { | ||||||
|             lock (playlistLock) |             actionQueue.Enqueue(() => | ||||||
|             { |             { | ||||||
|                 if (index < 0 || index >= playlist.Count) |                 if (index < 0 || index >= playlist.Count) | ||||||
|                     throw new ArgumentException("Invalid index"); |                     return; | ||||||
|                 playlist.RemoveAt(index); |                 playlist.RemoveAt(index); | ||||||
|  |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         internal void ClearQueue() | ||||||
|  |         { | ||||||
|  |             actionQueue.Enqueue(() => | ||||||
|  |             { | ||||||
|  |                 playlist.Clear(); | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public void Destroy() | ||||||
|  |         { | ||||||
|  |             actionQueue.Enqueue(() => | ||||||
|  |             { | ||||||
|  |                 RepeatPlaylist = false; | ||||||
|  |                 RepeatSong = false; | ||||||
|  |                 Destroyed = true; | ||||||
|  |                 playlist.Clear(); | ||||||
|  |                 if (!SongCancelSource.IsCancellationRequested) | ||||||
|  |                     SongCancelSource.Cancel(); | ||||||
|  |                 audioClient.Disconnect(); | ||||||
|  |             }); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         internal Task MoveToVoiceChannel(Channel voiceChannel) |         internal Task MoveToVoiceChannel(Channel voiceChannel) | ||||||
| @@ -221,27 +267,6 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|             return PlaybackVoiceChannel.JoinAudio(); |             return PlaybackVoiceChannel.JoinAudio(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         internal void ClearQueue() |  | ||||||
|         { |  | ||||||
|             lock (playlistLock) |  | ||||||
|             { |  | ||||||
|                 playlist.Clear(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public void Destroy() |  | ||||||
|         { |  | ||||||
|             lock (playlistLock) |  | ||||||
|             { |  | ||||||
|                 playlist.Clear(); |  | ||||||
|                 Destroyed = true; |  | ||||||
|                 CurrentSong = null; |  | ||||||
|                 if (!SongCancelSource.IsCancellationRequested) |  | ||||||
|                     SongCancelSource.Cancel(); |  | ||||||
|                 audioClient.Disconnect(); |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong; |         internal bool ToggleRepeatSong() => this.RepeatSong = !this.RepeatSong; | ||||||
|  |  | ||||||
|         internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist; |         internal bool ToggleRepeatPlaylist() => this.RepeatPlaylist = !this.RepeatPlaylist; | ||||||
|   | |||||||
| @@ -31,7 +31,7 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|         public SongInfo SongInfo { get; } |         public SongInfo SongInfo { get; } | ||||||
|         public string QueuerName { get; set; } |         public string QueuerName { get; set; } | ||||||
|  |  | ||||||
|         private PoopyBuffer songBuffer { get; } = new PoopyBuffer(NadekoBot.Config.BufferSize); |         private PoopyBuffer songBuffer { get; set; } | ||||||
|  |  | ||||||
|         private bool prebufferingComplete { get; set; } = false; |         private bool prebufferingComplete { get; set; } = false; | ||||||
|         public MusicPlayer MusicPlayer { get; set; } |         public MusicPlayer MusicPlayer { get; set; } | ||||||
| @@ -137,6 +137,9 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|  |  | ||||||
|         internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) |         internal async Task Play(IAudioClient voiceClient, CancellationToken cancelToken) | ||||||
|         { |         { | ||||||
|  |             // initialize the buffer here because if this song was playing before (requeued), we must delete old buffer data | ||||||
|  |             songBuffer = new PoopyBuffer(NadekoBot.Config.BufferSize);  | ||||||
|  |  | ||||||
|             var bufferTask = BufferSong(cancelToken).ConfigureAwait(false); |             var bufferTask = BufferSong(cancelToken).ConfigureAwait(false); | ||||||
|             var bufferAttempts = 0; |             var bufferAttempts = 0; | ||||||
|             const int waitPerAttempt = 500; |             const int waitPerAttempt = 500; | ||||||
| @@ -145,7 +148,6 @@ namespace NadekoBot.Modules.Music.Classes | |||||||
|             { |             { | ||||||
|                 await Task.Delay(waitPerAttempt, cancelToken).ConfigureAwait(false); |                 await Task.Delay(waitPerAttempt, cancelToken).ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|             cancelToken.ThrowIfCancellationRequested(); |  | ||||||
|             Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}"); |             Console.WriteLine($"Prebuffering done? in {waitPerAttempt * bufferAttempts}"); | ||||||
|             const int blockSize = 3840; |             const int blockSize = 3840; | ||||||
|             var attempt = 0; |             var attempt = 0; | ||||||
|   | |||||||
| @@ -151,7 +151,7 @@ namespace NadekoBot.Modules.Music | |||||||
|                         else if (musicPlayer.RepeatPlaylist) |                         else if (musicPlayer.RepeatPlaylist) | ||||||
|                             toSend += "🔁"; |                             toSend += "🔁"; | ||||||
|                         toSend += $" **{musicPlayer.Playlist.Count}** `tracks currently queued. Showing page {page}` "; |                         toSend += $" **{musicPlayer.Playlist.Count}** `tracks currently queued. Showing page {page}` "; | ||||||
|                         if (musicPlayer.Playlist.Count >= MusicPlayer.MaximumPlaylistSize) |                         if (musicPlayer.MaxQueueSize != 0 && musicPlayer.Playlist.Count >= musicPlayer.MaxQueueSize) | ||||||
|                             toSend += "**Song queue is full!**\n"; |                             toSend += "**Song queue is full!**\n"; | ||||||
|                         else |                         else | ||||||
|                             toSend += "\n"; |                             toSend += "\n"; | ||||||
| @@ -300,7 +300,6 @@ namespace NadekoBot.Modules.Music | |||||||
|                             await e.Channel.SendMessage($"🎵 `Failed to find any songs.`").ConfigureAwait(false); |                             await e.Channel.SendMessage($"🎵 `Failed to find any songs.`").ConfigureAwait(false); | ||||||
|                             return; |                             return; | ||||||
|                         } |                         } | ||||||
|                         //todo TEMPORARY SOLUTION, USE RESOLVE QUEUE IN THE FUTURE |  | ||||||
|                         var idArray = ids as string[] ?? ids.ToArray(); |                         var idArray = ids as string[] ?? ids.ToArray(); | ||||||
|                         var count = idArray.Length; |                         var count = idArray.Length; | ||||||
|                         var msg = |                         var msg = | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ namespace NadekoBot.Modules.Permissions.Classes | |||||||
|             { |             { | ||||||
|                 while (true) |                 while (true) | ||||||
|                 { |                 { | ||||||
|                     //blacklist is cleared every 1.75 seconds. That is the most time anyone will be blocked |                     //blacklist is cleared every 1.00 seconds. That is the most time anyone will be blocked | ||||||
|                     await Task.Delay(1750).ConfigureAwait(false); |                     await Task.Delay(1000).ConfigureAwait(false); | ||||||
|                     timeBlackList.Clear(); |                     timeBlackList.Clear(); | ||||||
|                 } |                 } | ||||||
|             }); |             }); | ||||||
|   | |||||||
| @@ -25,7 +25,7 @@ namespace NadekoBot.Modules.Searches.Commands | |||||||
|                                 string.Join("\n", JsonConvert.DeserializeObject<Dictionary<string, string>>(await SearchHelper.GetResponseStringAsync("http://memegen.link/templates/")) |                                 string.Join("\n", JsonConvert.DeserializeObject<Dictionary<string, string>>(await SearchHelper.GetResponseStringAsync("http://memegen.link/templates/")) | ||||||
|                                       .Select(kvp => Path.GetFileName(kvp.Value)) |                                       .Select(kvp => Path.GetFileName(kvp.Value)) | ||||||
|                                       .GroupBy(item => (i++) / 4) |                                       .GroupBy(item => (i++) / 4) | ||||||
|                                       .Select(ig => string.Join("", ig.Select(el => $"{el,-17}")))) |                                       .Select(ig => string.Concat(ig.Select(el => $"{el,-17}")))) | ||||||
|                                       + $"\n```").ConfigureAwait(false); |                                       + $"\n```").ConfigureAwait(false); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -226,10 +226,10 @@ $@"🌍 **Weather for** 【{obj["target"]}】 | |||||||
|                     .Parameter("terms", ParameterType.Unparsed) |                     .Parameter("terms", ParameterType.Unparsed) | ||||||
|                     .Do(async e => |                     .Do(async e => | ||||||
|                     { |                     { | ||||||
|                         var terms = e.GetArg("terms")?.Trim().Replace(' ', '+'); |                         var terms = e.GetArg("terms")?.Trim(); | ||||||
|                         if (string.IsNullOrWhiteSpace(terms)) |                         if (string.IsNullOrWhiteSpace(terms)) | ||||||
|                             return; |                             return; | ||||||
|                         await e.Channel.SendMessage($"https://google.com/search?q={ HttpUtility.UrlEncode(terms) }") |                         await e.Channel.SendMessage($"https://google.com/search?q={ HttpUtility.UrlEncode(terms).Replace(' ', '+') }") | ||||||
|                                        .ConfigureAwait(false); |                                        .ConfigureAwait(false); | ||||||
|                     }); |                     }); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -60,7 +60,7 @@ namespace NadekoBot.Modules.Translator.Helpers | |||||||
|                 text = await http.GetStringAsync(url).ConfigureAwait(false); |                 text = await http.GetStringAsync(url).ConfigureAwait(false); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             return JArray.Parse(text)[0][0][0].ToString(); |             return (string.Concat(JArray.Parse(text)[0].Select(x => x[0]))); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         #endregion |         #endregion | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ namespace NadekoBot.Modules.Utility | |||||||
|                         if (arr.Length == 0) |                         if (arr.Length == 0) | ||||||
|                             await e.Channel.SendMessage("Nobody. (not 100% sure)").ConfigureAwait(false); |                             await e.Channel.SendMessage("Nobody. (not 100% sure)").ConfigureAwait(false); | ||||||
|                         else |                         else | ||||||
|                             await e.Channel.SendMessage("```xl\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Join("", ig.Select(el => $"<22> {el,-35}")))) + "\n```").ConfigureAwait(false); |                             await e.Channel.SendMessage("```xl\n" + string.Join("\n", arr.GroupBy(item => (i++) / 3).Select(ig => string.Concat(ig.Select(el => $"<22> {el,-35}")))) + "\n```").ConfigureAwait(false); | ||||||
|                     }); |                     }); | ||||||
|  |  | ||||||
|                 cgb.CreateCommand(Prefix + "inrole") |                 cgb.CreateCommand(Prefix + "inrole") | ||||||
|   | |||||||
 Submodule discord.net updated: 6bfeaaddf0...3e519b5e0b
									
								
							
		Reference in New Issue
	
	Block a user