paranoia mode engaged. fixing instability on mono.
This commit is contained in:
		| @@ -66,8 +66,6 @@ namespace NadekoBot.Classes.Music { | ||||
|                     Provider = "Radio Stream"; | ||||
|                 } | ||||
|                 else if (SoundCloud.Default.IsSoundCloudLink(Query)) { | ||||
|                     if (OnResolving != null) | ||||
|                         OnResolving(); | ||||
|                     var svideo = await SoundCloud.Default.GetVideoAsync(Query); | ||||
|                     Title = svideo.FullName; | ||||
|                     Provider = "SoundCloud"; | ||||
| @@ -75,9 +73,6 @@ namespace NadekoBot.Classes.Music { | ||||
|                     Console.WriteLine(uri); | ||||
|                 } | ||||
|                 else { | ||||
|  | ||||
|                     if (OnResolving != null) | ||||
|                         OnResolving(); | ||||
|                     var links = await SearchHelper.FindYoutubeUrlByKeywords(Query); | ||||
|                     if (links == String.Empty) | ||||
|                         throw new OperationCanceledException("Not a valid youtube query."); | ||||
| @@ -105,18 +100,18 @@ namespace NadekoBot.Classes.Music { | ||||
|             } | ||||
|  | ||||
|             musicStreamer = new MusicStreamer(this, uri); | ||||
|             if (OnQueued != null) | ||||
|                 OnQueued(); | ||||
|             musicStreamer.OnCompleted += () => { | ||||
|                 OnCompleted(); | ||||
|             }; | ||||
|             OnQueued(); | ||||
|         } | ||||
|  | ||||
|         internal string PrintStats() => musicStreamer?.Stats(); | ||||
|  | ||||
|         public Action OnQueued = null; | ||||
|         public Action OnBuffering = null; | ||||
|         public Action OnStarted = null; | ||||
|         public Action OnCompleted = null; | ||||
|         public Action OnResolving = null; | ||||
|         public Action<string> OnResolvingFailed = null; | ||||
|         public event Action OnQueued = delegate { }; | ||||
|         public event Action OnStarted = delegate { }; | ||||
|         public event Action OnCompleted = delegate { }; | ||||
|         public event Action<string> OnResolvingFailed = delegate { }; | ||||
|  | ||||
|         internal void Cancel() { | ||||
|             musicStreamer?.Cancel(); | ||||
| @@ -126,6 +121,10 @@ namespace NadekoBot.Classes.Music { | ||||
|             musicStreamer?.Stop(); | ||||
|         } | ||||
|  | ||||
|         protected void Complete() { | ||||
|             OnCompleted(); | ||||
|         } | ||||
|  | ||||
|         internal async Task Start() { | ||||
|             int attemptsLeft = 4; | ||||
|             //wait for up to 4 seconds to resolve a link | ||||
| @@ -136,6 +135,7 @@ namespace NadekoBot.Classes.Music { | ||||
|                         throw new TimeoutException("Resolving timed out."); | ||||
|                     } | ||||
|                 } | ||||
|                 OnStarted(); | ||||
|                 await musicStreamer.StartPlayback(); | ||||
|             } | ||||
|             catch (TimeoutException) { | ||||
| @@ -157,6 +157,8 @@ namespace NadekoBot.Classes.Music { | ||||
|         private bool IsCanceled { get; set; } | ||||
|         public bool IsPaused => parent.IsPaused; | ||||
|  | ||||
|         public event Action OnCompleted = delegate { }; | ||||
|  | ||||
|         StreamRequest parent; | ||||
|         private readonly object _bufferLock = new object(); | ||||
|         private bool prebufferingComplete = false; | ||||
| @@ -196,8 +198,15 @@ namespace NadekoBot.Classes.Music { | ||||
|  | ||||
|                         if (State == StreamState.Completed) { | ||||
|                             Console.WriteLine("Buffering canceled, stream is completed."); | ||||
|                             p.CancelOutputRead(); | ||||
|                             p.Close(); | ||||
|                             try { | ||||
|                                 p.CancelOutputRead(); | ||||
|                             } | ||||
|                             catch { } | ||||
|                             try { | ||||
|                                 p.Close(); | ||||
|                             } | ||||
|                             catch { } | ||||
|                             p.Dispose(); | ||||
|                             return; | ||||
|                         } | ||||
|                         if (buffer.readPos > 5.MiB() && buffer.writePos > 5.MiB()) { | ||||
| @@ -221,8 +230,15 @@ namespace NadekoBot.Classes.Music { | ||||
|                         if (read == 0) { | ||||
|                             if (attempt == 5) { | ||||
|                                 Console.WriteLine($"Didn't read anything from the stream for {attempt} attempts. {buffer.Length / 1.MB()}MB length"); | ||||
|                                 p.CancelOutputRead(); | ||||
|                                 p.Close(); | ||||
|                                 try { | ||||
|                                     p.CancelOutputRead(); | ||||
|                                 } | ||||
|                                 catch { } | ||||
|                                 try { | ||||
|                                     p.Close(); | ||||
|                                 } | ||||
|                                 catch { } | ||||
|                                 p.Dispose(); | ||||
|                                 return; | ||||
|                             } | ||||
|                             else { | ||||
| @@ -242,8 +258,6 @@ namespace NadekoBot.Classes.Music { | ||||
|             catch { } | ||||
|             finally { | ||||
|                 if (p != null) { | ||||
|                     p.CancelOutputRead(); | ||||
|                     p.Close(); | ||||
|                     p.Dispose(); | ||||
|                     p = null; | ||||
|                 } | ||||
| @@ -254,8 +268,6 @@ namespace NadekoBot.Classes.Music { | ||||
|             Console.WriteLine("Starting playback."); | ||||
|             if (State == StreamState.Playing) return; | ||||
|             State = StreamState.Playing; | ||||
|             if (parent.OnBuffering != null) | ||||
|                 parent.OnBuffering(); | ||||
|  | ||||
|             Task.Factory.StartNew(async () => { | ||||
|                 await BufferSong(); | ||||
| @@ -283,9 +295,6 @@ namespace NadekoBot.Classes.Music { | ||||
|             int blockSize = 1920 * NadekoBot.client.GetService<AudioService>()?.Config?.Channels ?? 3840; | ||||
|             byte[] voiceBuffer = new byte[blockSize]; | ||||
|  | ||||
|             if (parent.OnStarted != null) | ||||
|                 parent.OnStarted(); | ||||
|  | ||||
|             int attempt = 0; | ||||
|             while (!IsCanceled) { | ||||
|                 int readCount = 0; | ||||
| @@ -319,7 +328,6 @@ namespace NadekoBot.Classes.Music { | ||||
|                     await Task.Delay(100); | ||||
|                 } | ||||
|             } | ||||
|             parent.MusicControls.VoiceClient.Wait(); | ||||
|             Stop(); | ||||
|         } | ||||
|  | ||||
| @@ -332,8 +340,7 @@ namespace NadekoBot.Classes.Music { | ||||
|             var oldState = State; | ||||
|             State = StreamState.Completed; | ||||
|             if (oldState == StreamState.Playing) | ||||
|                 if (parent.OnCompleted != null) | ||||
|                     parent.OnCompleted(); | ||||
|                 OnCompleted(); | ||||
|         } | ||||
|         //stackoverflow ftw | ||||
|         private byte[] adjustVolume(byte[] audioSamples, float volume) { | ||||
|   | ||||
| @@ -35,7 +35,7 @@ namespace NadekoBot.Classes.Permissions { | ||||
|                     var data = Newtonsoft.Json.JsonConvert.DeserializeObject<ServerPermissions>(File.ReadAllText(file)); | ||||
|                     _permissionsDict.TryAdd(server, data); | ||||
|                 } catch (Exception ex) { | ||||
|                     Console.WriteLine($"Failed getting server with id: {file}\nReason: {ex.Message}"); | ||||
|                     //Console.WriteLine($"Failed getting server with id: {file}\nReason: {ex.Message}"); | ||||
|                 } | ||||
|             } | ||||
|             Console.WriteLine("Permission initialization complete."); | ||||
|   | ||||
| @@ -86,34 +86,37 @@ namespace NadekoBot.Classes.Trivia { | ||||
|             Commands.Trivia.runningTrivias.TryRemove(_server, out throwAwayValue); | ||||
|         } | ||||
|  | ||||
|         public async void StopGame() { | ||||
|         public async Task StopGame() { | ||||
|             if (!ShouldStopGame) | ||||
|                 await _channel.SendMessage(":exclamation: Trivia will stop after this question."); | ||||
|             ShouldStopGame = true; | ||||
|         } | ||||
|  | ||||
|         private async void PotentialGuess(object sender, MessageEventArgs e) { | ||||
|             if (e.Channel.IsPrivate) return; | ||||
|             if (e.Server != _server) return; | ||||
|             try { | ||||
|                 if (e.Channel.IsPrivate) return; | ||||
|                 if (e.Server != _server) return; | ||||
|  | ||||
|             bool guess = false; | ||||
|             lock (_guessLock) { | ||||
|                 if (GameActive && CurrentQuestion.IsAnswerCorrect(e.Message.Text) && !triviaCancelSource.IsCancellationRequested) { | ||||
|                     users.TryAdd(e.User, 0); //add if not exists | ||||
|                     users[e.User]++; //add 1 point to the winner | ||||
|                     guess = true; | ||||
|                     triviaCancelSource.Cancel(); | ||||
|                 } | ||||
|             } | ||||
|             if (guess) { | ||||
|                 await _channel.SendMessage($"☑️ {e.User.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**"); | ||||
|                 if (users[e.User] == WinRequirement) { | ||||
|                     ShouldStopGame = true; | ||||
|                     await _channel.Send($":exclamation: We have a winner! Its {e.User.Mention}."); | ||||
|                     // add points to the winner | ||||
|                     await FlowersHandler.AddFlowersAsync(e.User, "Won Trivia", 2); | ||||
|                 bool guess = false; | ||||
|                 lock (_guessLock) { | ||||
|                     if (GameActive && CurrentQuestion.IsAnswerCorrect(e.Message.Text) && !triviaCancelSource.IsCancellationRequested) { | ||||
|                         users.TryAdd(e.User, 0); //add if not exists | ||||
|                         users[e.User]++; //add 1 point to the winner | ||||
|                         guess = true; | ||||
|                         triviaCancelSource.Cancel(); | ||||
|                     } | ||||
|                 } | ||||
|                 if (guess) { | ||||
|                     await _channel.SendMessage($"☑️ {e.User.Mention} guessed it! The answer was: **{CurrentQuestion.Answer}**"); | ||||
|                     if (users[e.User] == WinRequirement) { | ||||
|                         ShouldStopGame = true; | ||||
|                         await _channel.Send($":exclamation: We have a winner! Its {e.User.Mention}."); | ||||
|                         // add points to the winner | ||||
|                         await FlowersHandler.AddFlowersAsync(e.User, "Won Trivia", 2); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch { } | ||||
|         } | ||||
|  | ||||
|         public string GetLeaderboard() { | ||||
|   | ||||
| @@ -327,7 +327,7 @@ namespace NadekoBot.Commands { | ||||
|             bases[baseNumber] = new Caller { CallUser = u.Trim(), TimeAdded = DateTime.Now, BaseDestroyed = false }; | ||||
|         } | ||||
|  | ||||
|         internal async void Start() { | ||||
|         internal async Task Start() { | ||||
|             if (Started) | ||||
|                 throw new InvalidOperationException(); | ||||
|             try { | ||||
|   | ||||
| @@ -18,11 +18,14 @@ namespace NadekoBot | ||||
|  | ||||
|         private async void Client_MessageReceived(object sender, Discord.MessageEventArgs e) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(e.Message.Text)) | ||||
|                 return; | ||||
|             if (CopiedUsers.Contains(e.User.Id)) { | ||||
|                 await e.Channel.SendMessage( e.Message.Text.Replace("@everyone","@everryone")); | ||||
|             try { | ||||
|                 if (string.IsNullOrWhiteSpace(e.Message.Text)) | ||||
|                     return; | ||||
|                 if (CopiedUsers.Contains(e.User.Id)) { | ||||
|                     await e.Channel.SendMessage(e.Message.Text); | ||||
|                 } | ||||
|             } | ||||
|             catch { } | ||||
|         } | ||||
|  | ||||
|         public override Func<CommandEventArgs, Task> DoFunc() => async e => | ||||
|   | ||||
| @@ -34,24 +34,26 @@ namespace NadekoBot.Commands { | ||||
|         public PlayingRotate() { | ||||
|             int i = -1; | ||||
|             timer.Elapsed += (s, e) => { | ||||
|                 i++; | ||||
|                 Console.WriteLine("elapsed"); | ||||
|                 string status = ""; | ||||
|                 lock (playingPlaceholderLock) { | ||||
|                     if (playingPlaceholders.Count == 0) | ||||
|                         return; | ||||
|                     if (i >= playingPlaceholders.Count) { | ||||
|                         i = -1; | ||||
|                         return; | ||||
|                     } | ||||
|                     status = rotatingStatuses[i]; | ||||
|                     foreach (var kvp in playingPlaceholders) { | ||||
|                         status = status.Replace(kvp.Key, kvp.Value()); | ||||
|                 try { | ||||
|                     i++; | ||||
|                     string status = ""; | ||||
|                     lock (playingPlaceholderLock) { | ||||
|                         if (playingPlaceholders.Count == 0) | ||||
|                             return; | ||||
|                         if (i >= playingPlaceholders.Count) { | ||||
|                             i = -1; | ||||
|                             return; | ||||
|                         } | ||||
|                         status = rotatingStatuses[i]; | ||||
|                         foreach (var kvp in playingPlaceholders) { | ||||
|                             status = status.Replace(kvp.Key, kvp.Value()); | ||||
|                         } | ||||
|                     } | ||||
|                     if (string.IsNullOrWhiteSpace(status)) | ||||
|                         return; | ||||
|                     Task.Run(() => { try { NadekoBot.client.SetGame(status); } catch { } }); | ||||
|                 } | ||||
|                 if (string.IsNullOrWhiteSpace(status)) | ||||
|                     return; | ||||
|                 NadekoBot.client.SetGame(status); | ||||
|                 catch { } | ||||
|             }; | ||||
|         } | ||||
|  | ||||
| @@ -74,6 +76,7 @@ namespace NadekoBot.Commands { | ||||
|                 .Alias(".adpl") | ||||
|                 .Description("Adds a specified string to the list of playing strings to rotate. Supported placeholders: " + string.Join(", ", playingPlaceholders.Keys)) | ||||
|                 .Parameter("text", ParameterType.Unparsed) | ||||
|                 .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) | ||||
|                 .Do(async e => { | ||||
|                     var arg = e.GetArg("text"); | ||||
|                     if (string.IsNullOrWhiteSpace(arg)) | ||||
| @@ -110,7 +113,7 @@ namespace NadekoBot.Commands { | ||||
|                       lock (playingPlaceholderLock) { | ||||
|                           if (!int.TryParse(arg.Trim(), out num) || num <= 0 || num > rotatingStatuses.Count) | ||||
|                               return; | ||||
|                           str = rotatingStatuses[num]; | ||||
|                           str = rotatingStatuses[num - 1]; | ||||
|                           rotatingStatuses.RemoveAt(num - 1); | ||||
|                       } | ||||
|                       await e.Channel.SendMessage($"🆗 `Removed playing string #{num}`({str})"); | ||||
|   | ||||
| @@ -105,19 +105,22 @@ namespace NadekoBot.Modules { | ||||
|         } | ||||
|  | ||||
|         private async void Vote(object sender, MessageEventArgs e) { | ||||
|             if (!e.Channel.IsPrivate) | ||||
|                 return; | ||||
|             if (participants.ContainsKey(e.User)) | ||||
|                 return; | ||||
|  | ||||
|             int vote; | ||||
|             if (int.TryParse(e.Message.Text, out vote)) { | ||||
|                 if (vote < 1 || vote > answers.Length) | ||||
|             try { | ||||
|                 if (!e.Channel.IsPrivate) | ||||
|                     return; | ||||
|                 if (participants.TryAdd(e.User, vote)) { | ||||
|                     await e.User.SendMessage($"Thanks for voting **{e.User.Name}**."); | ||||
|                 if (participants.ContainsKey(e.User)) | ||||
|                     return; | ||||
|  | ||||
|                 int vote; | ||||
|                 if (int.TryParse(e.Message.Text, out vote)) { | ||||
|                     if (vote < 1 || vote > answers.Length) | ||||
|                         return; | ||||
|                     if (participants.TryAdd(e.User, vote)) { | ||||
|                         await e.User.SendMessage($"Thanks for voting **{e.User.Name}**."); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             catch { } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @@ -41,46 +41,54 @@ namespace NadekoBot.Commands { | ||||
|         } | ||||
|  | ||||
|         private async void UserLeft(object sender, UserEventArgs e) { | ||||
|             if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) || | ||||
|                 !AnnouncementsDictionary[e.Server.Id].Bye) return; | ||||
|             try { | ||||
|                 if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) || | ||||
|                     !AnnouncementsDictionary[e.Server.Id].Bye) return; | ||||
|  | ||||
|             var controls = AnnouncementsDictionary[e.Server.Id]; | ||||
|             var channel = NadekoBot.client.GetChannel(controls.ByeChannel); | ||||
|             var msg = controls.ByeText.Replace("%user%", "**" + e.User.Name + "**").Trim(); | ||||
|             if (string.IsNullOrEmpty(msg)) | ||||
|                 return; | ||||
|                 var controls = AnnouncementsDictionary[e.Server.Id]; | ||||
|                 var channel = NadekoBot.client.GetChannel(controls.ByeChannel); | ||||
|                 var msg = controls.ByeText.Replace("%user%", "**" + e.User.Name + "**").Trim(); | ||||
|                 if (string.IsNullOrEmpty(msg)) | ||||
|                     return; | ||||
|  | ||||
|             if (controls.ByePM) { | ||||
|                 Greeted++; | ||||
|                 try { | ||||
|                     await e.User.SendMessage($"`Farewell Message From {e.Server?.Name}`\n" + msg); | ||||
|                 if (controls.ByePM) { | ||||
|                     Greeted++; | ||||
|                     try { | ||||
|                         await e.User.SendMessage($"`Farewell Message From {e.Server?.Name}`\n" + msg); | ||||
|                     } | ||||
|                     catch { } | ||||
|                 } | ||||
|                 else { | ||||
|                     if (channel == null) return; | ||||
|                     Greeted++; | ||||
|                     await channel.Send(msg); | ||||
|                 } | ||||
|                 catch { } | ||||
|             } else { | ||||
|                 if (channel == null) return; | ||||
|                 Greeted++; | ||||
|                 await channel.Send(msg); | ||||
|             } | ||||
|             catch { } | ||||
|         } | ||||
|  | ||||
|         private async void UserJoined(object sender, Discord.UserEventArgs e) { | ||||
|             if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) || | ||||
|                 !AnnouncementsDictionary[e.Server.Id].Greet) return; | ||||
|             try { | ||||
|                 if (!AnnouncementsDictionary.ContainsKey(e.Server.Id) || | ||||
|                     !AnnouncementsDictionary[e.Server.Id].Greet) return; | ||||
|  | ||||
|             var controls = AnnouncementsDictionary[e.Server.Id]; | ||||
|             var channel = NadekoBot.client.GetChannel(controls.GreetChannel); | ||||
|                 var controls = AnnouncementsDictionary[e.Server.Id]; | ||||
|                 var channel = NadekoBot.client.GetChannel(controls.GreetChannel); | ||||
|  | ||||
|             var msg = controls.GreetText.Replace("%user%", e.User.Mention).Trim(); | ||||
|             if (string.IsNullOrEmpty(msg)) | ||||
|                 return; | ||||
|             if (controls.GreetPM) { | ||||
|                 Greeted++; | ||||
|                 await e.User.SendMessage($"`Welcome Message From {e.Server.Name}`\n" + msg); | ||||
|             } else { | ||||
|                 if (channel == null) return; | ||||
|                 Greeted++; | ||||
|                 await channel.Send(msg); | ||||
|                 var msg = controls.GreetText.Replace("%user%", e.User.Mention).Trim(); | ||||
|                 if (string.IsNullOrEmpty(msg)) | ||||
|                     return; | ||||
|                 if (controls.GreetPM) { | ||||
|                     Greeted++; | ||||
|                     await e.User.SendMessage($"`Welcome Message From {e.Server.Name}`\n" + msg); | ||||
|                 } | ||||
|                 else { | ||||
|                     if (channel == null) return; | ||||
|                     Greeted++; | ||||
|                     await channel.Send(msg); | ||||
|                 } | ||||
|             } | ||||
|             catch { } | ||||
|         } | ||||
|  | ||||
|         public class AnnounceControls { | ||||
|   | ||||
| @@ -82,20 +82,23 @@ namespace NadekoBot.Commands { | ||||
|         } | ||||
|  | ||||
|         private async void AnswerReceived(object sender, MessageEventArgs e) { | ||||
|             if (e.Channel == null || e.Channel.Id != channel.Id) return; | ||||
|             try { | ||||
|                 if (e.Channel == null || e.Channel.Id != channel.Id) return; | ||||
|  | ||||
|             var guess = e.Message.RawText; | ||||
|                 var guess = e.Message.RawText; | ||||
|  | ||||
|                 var distance = currentSentence.LevenshteinDistance(guess); | ||||
|                 var decision = Judge(distance, guess.Length); | ||||
|                 if (decision && !finishedUserIds.Contains(e.User.Id)) { | ||||
|                     finishedUserIds.Add(e.User.Id); | ||||
|                     await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ currentSentence.Length / TypingGame.WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!"); | ||||
|                     if (finishedUserIds.Count % 2 == 0) { | ||||
|                         await e.Channel.SendMessage($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{currentSentence}**:book:"); | ||||
|                     } | ||||
|  | ||||
|             var distance = currentSentence.LevenshteinDistance(guess); | ||||
|             var decision = Judge(distance, guess.Length); | ||||
|             if (decision && !finishedUserIds.Contains(e.User.Id)) { | ||||
|                 finishedUserIds.Add(e.User.Id); | ||||
|                 await channel.Send($"{e.User.Mention} finished in **{sw.Elapsed.Seconds}** seconds with { distance } errors, **{ currentSentence.Length / TypingGame.WORD_VALUE / sw.Elapsed.Seconds * 60 }** WPM!"); | ||||
|                 if (finishedUserIds.Count % 2 == 0) { | ||||
|                     await e.Channel.SendMessage($":exclamation: `A lot of people finished, here is the text for those still typing:`\n\n:book:**{currentSentence}**:book:"); | ||||
|                 } | ||||
|  | ||||
|             } | ||||
|             catch { } | ||||
|         } | ||||
|  | ||||
|         private bool Judge(int errors, int textLength) => errors <= textLength / 25; | ||||
|   | ||||
| @@ -153,11 +153,11 @@ namespace NadekoBot.Modules { | ||||
|                       if (!string.IsNullOrWhiteSpace(e.GetArg("user"))) { | ||||
|                           var usr = e.Server.FindUsers(e.GetArg("user")).FirstOrDefault(); | ||||
|                           if (usr != null) { | ||||
|                               await e.Channel.SendMessage($"`List of roles for **{usr.Name}**:` \n• " + string.Join("\n• ", usr.Roles).Replace("@everyone", "මeveryone")); | ||||
|                               await e.Channel.SendMessage($"`List of roles for **{usr.Name}**:` \n• " + string.Join("\n• ", usr.Roles)); | ||||
|                               return; | ||||
|                           } | ||||
|                       } | ||||
|                       await e.Channel.SendMessage("`List of roles:` \n• " + string.Join("\n• ", e.Server.Roles).Replace("@everyone", "මeveryone")); | ||||
|                       await e.Channel.SendMessage("`List of roles:` \n• " + string.Join("\n• ", e.Server.Roles)); | ||||
|                   }); | ||||
|  | ||||
|                 cgb.CreateCommand(".b").Alias(".ban") | ||||
|   | ||||
| @@ -341,7 +341,7 @@ namespace NadekoBot.Modules { | ||||
|                             } | ||||
|                         } | ||||
|                         if (msg != null) | ||||
|                             await e.Channel.SendMessage($"Last message mentioning you was at {msg.Timestamp}\n**Message from {msg.User.Name}:** {msg.RawText.Replace("@everyone", "@everryone")}"); | ||||
|                             await e.Channel.SendMessage($"Last message mentioning you was at {msg.Timestamp}\n**Message from {msg.User.Name}:** {msg.RawText}"); | ||||
|                         else | ||||
|                             await e.Channel.SendMessage("I can't find a message mentioning you."); | ||||
|                     }); | ||||
| @@ -362,7 +362,7 @@ namespace NadekoBot.Modules { | ||||
|                     .Description("Useless. Writes calling @X to chat.\n**Usage**: @NadekoBot call @X ") | ||||
|                     .Parameter("who", ParameterType.Required) | ||||
|                     .Do(async e => { | ||||
|                         await e.Channel.SendMessage("Calling " + e.Args[0].Replace("@everyone", "[everyone]") + "..."); | ||||
|                         await e.Channel.SendMessage("Calling " + e.Args[0] + "..."); | ||||
|                     }); | ||||
|                 cgb.CreateCommand("hide") | ||||
|                     .Description("Hides Nadeko in plain sight!11!!") | ||||
|   | ||||
| @@ -48,11 +48,14 @@ namespace NadekoBot.Modules | ||||
|                     .Description("Ask the 8ball a yes/no question.") | ||||
|                     .Parameter("question",Discord.Commands.ParameterType.Unparsed) | ||||
|                     .Do(async e => { | ||||
|                         string question = e.GetArg("question").Replace("@everyone","[everyone]"); | ||||
|                         string question = e.GetArg("question"); | ||||
|                         if (string.IsNullOrWhiteSpace(question)) | ||||
|                             return;                                                 | ||||
|                         await e.Channel.SendMessage( | ||||
|                             $":question: **Question**: `{question}` \n:crystal_ball: **8Ball Answers**: `{_8BallAnswers[_r.Next(0, _8BallAnswers.Length)]}`"); | ||||
|                             return; | ||||
|                         try { | ||||
|                             await e.Channel.SendMessage( | ||||
|                                 $":question: **Question**: `{question}` \n:crystal_ball: **8Ball Answers**: `{_8BallAnswers[new Random().Next(0, _8BallAnswers.Length)]}`"); | ||||
|                         } | ||||
|                         catch { } | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand(">") | ||||
|   | ||||
| @@ -1,16 +1,16 @@ | ||||
| using System; | ||||
| using System.Linq; | ||||
| using Discord.Modules; | ||||
| using Discord.Commands; | ||||
| using Discord; | ||||
| using NadekoBot.Extensions; | ||||
| using System.Collections.Concurrent; | ||||
| using NadekoBot.Classes.Music; | ||||
| using Timer = System.Timers.Timer; | ||||
| using System.Threading.Tasks; | ||||
| using NadekoBot.Classes; | ||||
| using Discord; | ||||
| using Discord.Audio; | ||||
| using Discord.Commands; | ||||
| using Discord.Modules; | ||||
| using NadekoBot.Classes; | ||||
| using NadekoBot.Classes.Music; | ||||
| using NadekoBot.Extensions; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Linq; | ||||
| using System.Text.RegularExpressions; | ||||
| using System.Threading.Tasks; | ||||
| using Timer = System.Timers.Timer; | ||||
|  | ||||
| namespace NadekoBot.Modules { | ||||
|     class Music : DiscordModule { | ||||
| @@ -40,7 +40,7 @@ namespace NadekoBot.Modules { | ||||
|                     .Alias("next") | ||||
|                     .Description("Goes to the next song in the queue.") | ||||
|                     .Do(async e => { | ||||
|                         if (musicPlayers.ContainsKey(e.Server) == false) return; | ||||
|                         if (!musicPlayers.ContainsKey(e.Server)) return; | ||||
|                         await musicPlayers[e.Server].LoadNextSong(); | ||||
|                     }); | ||||
|  | ||||
| @@ -48,7 +48,7 @@ namespace NadekoBot.Modules { | ||||
|                     .Alias("stop") | ||||
|                     .Description("Completely stops the music, unbinds the bot from the channel, and cleans up files.") | ||||
|                     .Do(e => { | ||||
|                         if (musicPlayers.ContainsKey(e.Server) == false) return; | ||||
|                         if (!musicPlayers.ContainsKey(e.Server)) return; | ||||
|                         musicPlayers[e.Server].Stop(true); | ||||
|                     }); | ||||
|  | ||||
| @@ -56,7 +56,7 @@ namespace NadekoBot.Modules { | ||||
|                     .Alias("pause") | ||||
|                     .Description("Pauses or Unpauses the song.") | ||||
|                     .Do(async e => { | ||||
|                         if (musicPlayers.ContainsKey(e.Server) == false) return; | ||||
|                         if (!musicPlayers.ContainsKey(e.Server)) return; | ||||
|                         if (musicPlayers[e.Server].TogglePause()) | ||||
|                             await e.Channel.SendMessage("🎵`Music player paused.`"); | ||||
|                         else | ||||
| @@ -67,11 +67,13 @@ namespace NadekoBot.Modules { | ||||
|                     .Alias("yq") | ||||
|                     .Description("Queue a song using keywords or a link. Bot will join your voice channel. **You must be in a voice channel**.\n**Usage**: `!m q Dream Of Venice`") | ||||
|                     .Parameter("query", ParameterType.Unparsed) | ||||
|                     .Do(async e => await QueueSong(e,e.GetArg("query"))); | ||||
|                     .Do(async e => { | ||||
|                         await QueueSong(e, e.GetArg("query")); | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand("lq") | ||||
|                     .Alias("ls").Alias("lp") | ||||
|                     .Description("Lists up to 10 currently queued songs.") | ||||
|                     .Description("Lists up to 15 currently queued songs.") | ||||
|                     .Do(async e => { | ||||
|                         if (musicPlayers.ContainsKey(e.Server) == false) { | ||||
|                             await e.Channel.SendMessage("🎵 No active music player."); | ||||
| @@ -81,19 +83,18 @@ namespace NadekoBot.Modules { | ||||
|                         string toSend = "🎵 **" + player.SongQueue.Count + "** `videos currently queued.` "; | ||||
|                         if (player.SongQueue.Count >= 50) | ||||
|                             toSend += "**Song queue is full!**\n"; | ||||
|                         await e.Channel.SendMessage(toSend); | ||||
|                         int number = 1; | ||||
|                         await e.Channel.SendMessage(string.Join("\n", player.SongQueue.Take(10).Select(v => $"`{number++}.` {v.FullPrettyName}"))); | ||||
|                         await e.Channel.SendMessage(toSend + string.Join("\n", player.SongQueue.Take(15).Select(v => $"`{number++}.` {v.FullPrettyName}"))); | ||||
|                     }); | ||||
|  | ||||
|                 cgb.CreateCommand("np") | ||||
|                  .Alias("playing") | ||||
|                  .Description("Shows the song currently playing.") | ||||
|                  .Do(async e => { | ||||
|                      if (musicPlayers.ContainsKey(e.Server) == false) return; | ||||
|                      var player = musicPlayers[e.Server]; | ||||
|                      await e.Channel.SendMessage($"🎵`Now Playing` {player.CurrentSong.FullPrettyName}"); | ||||
|                  }); | ||||
|                      .Alias("playing") | ||||
|                      .Description("Shows the song currently playing.") | ||||
|                      .Do(async e => { | ||||
|                          if (musicPlayers.ContainsKey(e.Server) == false) return; | ||||
|                          var player = musicPlayers[e.Server]; | ||||
|                          await e.Channel.SendMessage($"🎵`Now Playing` {player.CurrentSong.FullPrettyName}"); | ||||
|                      }); | ||||
|  | ||||
|                 cgb.CreateCommand("vol") | ||||
|                   .Description("Sets the music volume 0-150%") | ||||
| @@ -168,8 +169,11 @@ namespace NadekoBot.Modules { | ||||
|                 Timer setgameTimer = new Timer(); | ||||
|                 setgameTimer.Interval = 20000; | ||||
|                 setgameTimer.Elapsed += (s, e) => { | ||||
|                     int num = musicPlayers.Where(kvp => kvp.Value.CurrentSong != null).Count(); | ||||
|                     NadekoBot.client.SetGame($"{num} songs".SnPl(num) + $", {musicPlayers.Sum(kvp => kvp.Value.SongQueue.Count())} queued"); | ||||
|                     try { | ||||
|                         int num = musicPlayers.Where(kvp => kvp.Value.CurrentSong != null).Count(); | ||||
|                         NadekoBot.client.SetGame($"{num} songs".SnPl(num) + $", {musicPlayers.Sum(kvp => kvp.Value.SongQueue.Count())} queued"); | ||||
|                     } | ||||
|                     catch { } | ||||
|                 }; | ||||
|                 cgb.CreateCommand("setgame") | ||||
|                     .Description("Sets the game of the bot to the number of songs playing.**Owner only**") | ||||
| @@ -195,7 +199,7 @@ namespace NadekoBot.Modules { | ||||
|                         } | ||||
|                         var ids = await SearchHelper.GetVideoIDs(await SearchHelper.GetPlaylistIdByKeyword(e.GetArg("playlist"))); | ||||
|                         //todo TEMPORARY SOLUTION, USE RESOLVE QUEUE IN THE FUTURE | ||||
|                         var msg = await e.Channel.SendMessage($"🎵 `Attempting to queue {ids.Count} songs".SnPl(ids.Count)+"...`"); | ||||
|                         var msg = await e.Channel.SendMessage($"🎵 `Attempting to queue {ids.Count} songs".SnPl(ids.Count) + "...`"); | ||||
|                         foreach (var id in ids) { | ||||
|                             Task.Run(async () => await QueueSong(e, id, true)).ConfigureAwait(false); | ||||
|                             await Task.Delay(150); | ||||
| @@ -209,12 +213,12 @@ namespace NadekoBot.Modules { | ||||
|                   .AddCheck(Classes.Permissions.SimpleCheckers.OwnerOnly()) | ||||
|                   .Do(async e => { | ||||
|                       var arg = e.GetArg("directory"); | ||||
|                       if(string.IsNullOrWhiteSpace(e.GetArg("directory"))) | ||||
|                         return; | ||||
|                       if (string.IsNullOrWhiteSpace(e.GetArg("directory"))) | ||||
|                           return; | ||||
|                       try { | ||||
|                           var fileEnum = System.IO.Directory.EnumerateFiles(e.GetArg("directory")).Take(50); | ||||
|                           foreach (var file in fileEnum) { | ||||
|                               await Task.Run(async() => await QueueSong(e, file, true, MusicType.Local)).ConfigureAwait(false); | ||||
|                               await Task.Run(async () => await QueueSong(e, file, true, MusicType.Local)).ConfigureAwait(false); | ||||
|                           } | ||||
|                           await e.Channel.SendMessage("🎵 `Directory queue complete.`"); | ||||
|                       } | ||||
| @@ -247,7 +251,7 @@ namespace NadekoBot.Modules { | ||||
|                   .Description("Moves the bot to your voice channel. (works only if music is already playing)") | ||||
|                   .Do(async e => { | ||||
|                       MusicControls mc; | ||||
|                       if (e.User.VoiceChannel == null || e.User.VoiceChannel.Server != e.Server || !musicPlayers.TryGetValue(e.Server,out mc)) | ||||
|                       if (e.User.VoiceChannel == null || e.User.VoiceChannel.Server != e.Server || !musicPlayers.TryGetValue(e.Server, out mc)) | ||||
|                           return; | ||||
|                       mc.VoiceChannel = e.User.VoiceChannel; | ||||
|                       mc.VoiceClient = await mc.VoiceChannel.JoinAudio(); | ||||
| @@ -255,7 +259,7 @@ namespace NadekoBot.Modules { | ||||
|  | ||||
|                 cgb.CreateCommand("rm") | ||||
|                     .Description("Remove a song by its # in the queue, or 'all' to remove whole queue.") | ||||
|                     .Parameter("num",ParameterType.Required) | ||||
|                     .Parameter("num", ParameterType.Required) | ||||
|                     .Do(async e => { | ||||
|                         var arg = e.GetArg("num"); | ||||
|                         MusicControls mc; | ||||
| @@ -292,11 +296,11 @@ namespace NadekoBot.Modules { | ||||
|  | ||||
|         private async Task QueueSong(CommandEventArgs e, string query, bool silent = false, MusicType musicType = MusicType.Normal) { | ||||
|             if (e.User.VoiceChannel?.Server != e.Server) { | ||||
|                 if(!silent) | ||||
|                 if (!silent) | ||||
|                     await e.Channel.SendMessage("💢 You need to be in a voice channel on this server.\n If you are already in a voice channel, try rejoining."); | ||||
|                 return; | ||||
|             } | ||||
|              | ||||
|  | ||||
|             if (string.IsNullOrWhiteSpace(query) || query.Length < 3) | ||||
|                 return; | ||||
|  | ||||
| @@ -331,36 +335,48 @@ namespace NadekoBot.Modules { | ||||
|                 Message qmsg = null; | ||||
|                 Message msg = null; | ||||
|                 if (!silent) { | ||||
|                     qmsg = await e.Channel.SendMessage("🎵 `Searching / Resolving...`"); | ||||
|                     sr.OnResolvingFailed += async (err) => { | ||||
|                         await qmsg?.Edit($"💢 🎵 `Resolving failed` for **{query}**"); | ||||
|                     }; | ||||
|                     sr.OnQueued += async () => { | ||||
|                         await qmsg?.Edit($"🎵`Queued`{sr.FullPrettyName}"); | ||||
|                     }; | ||||
|                     try { | ||||
|                         qmsg = await e.Channel.SendMessage("🎵 `Searching / Resolving...`"); | ||||
|                         sr.OnResolvingFailed += async (err) => { | ||||
|                             try { | ||||
|                                 await qmsg.Edit($"💢 🎵 `Resolving failed` for **{query}**"); | ||||
|                             } | ||||
|                             catch { } | ||||
|                         }; | ||||
|                         sr.OnQueued += async () => { | ||||
|                             try { | ||||
|                                 await qmsg.Edit($"🎵`Queued`{sr.FullPrettyName}"); | ||||
|                             } | ||||
|                             catch { } | ||||
|                         }; | ||||
|                     } | ||||
|                     catch { } | ||||
|                 } | ||||
|                 sr.OnCompleted += async () => { | ||||
|                     MusicControls mc; | ||||
|                     if (musicPlayers.TryGetValue(e.Server, out mc)) { | ||||
|                         if (mc.SongQueue.Count == 0) | ||||
|                             mc.Stop(); | ||||
|                     try { | ||||
|                         MusicControls mc; | ||||
|                         if (musicPlayers.TryGetValue(e.Server, out mc)) { | ||||
|                             if (mc.SongQueue.Count == 0) | ||||
|                                 mc.Stop(); | ||||
|                         } | ||||
|                         await e.Channel.SendMessage($"🎵`Finished`{sr.FullPrettyName}"); | ||||
|                     } | ||||
|                     await e.Channel.SendMessage($"🎵`Finished`{sr.FullPrettyName}"); | ||||
|                     catch { } | ||||
|                 }; | ||||
|                 sr.OnStarted += async () => { | ||||
|                     var msgTxt = $"🎵`Playing`{sr.FullPrettyName} `Vol: {(int)(player.Volume * 100)}%`"; | ||||
|                     if (msg == null) | ||||
|                         await e.Channel.SendMessage(msgTxt); | ||||
|                     else | ||||
|                         await msg.Edit(msgTxt); | ||||
|                     qmsg?.Delete(); | ||||
|                 }; | ||||
|                 sr.OnBuffering += async () => { | ||||
|                     msg = await e.Channel.SendMessage($"🎵`Buffering...`{sr.FullPrettyName}"); | ||||
|                     try { | ||||
|                         var msgTxt = $"🎵`Playing`{sr.FullPrettyName} `Vol: {(int)(player.Volume * 100)}%`"; | ||||
|                         if (qmsg != null) | ||||
|                             await qmsg.Edit(msgTxt); | ||||
|                         else | ||||
|                             await e.Channel.SendMessage(msgTxt); | ||||
|                     } | ||||
|                     catch { } | ||||
|                 }; | ||||
|  | ||||
|                 await sr.Resolve(); | ||||
|             } catch (Exception ex) { | ||||
|                 Console.WriteLine(); | ||||
|             } | ||||
|             catch (Exception ex) { | ||||
|                 await e.Channel.SendMessage($"💢 {ex.Message}"); | ||||
|                 return; | ||||
|             } | ||||
| @@ -368,7 +384,7 @@ namespace NadekoBot.Modules { | ||||
|  | ||||
|         private bool IsRadioLink(string query) => | ||||
|             (query.StartsWith("http") || | ||||
|             query.StartsWith("ww"))  | ||||
|             query.StartsWith("ww")) | ||||
|             && | ||||
|             (query.Contains(".pls") || | ||||
|             query.Contains(".m3u") || | ||||
| @@ -378,7 +394,7 @@ namespace NadekoBot.Modules { | ||||
|         private async Task<string> HandleStreamContainers(string query) { | ||||
|             string file = null; | ||||
|             try { | ||||
|                  file = await SearchHelper.GetResponseAsync(query); | ||||
|                 file = await SearchHelper.GetResponseAsync(query); | ||||
|             } | ||||
|             catch { | ||||
|                 return query; | ||||
|   | ||||
| @@ -66,7 +66,6 @@ namespace NadekoBot { | ||||
|             //create new discord client | ||||
|             client = new DiscordClient(new DiscordConfigBuilder() { | ||||
|                 MessageCacheSize = 20, | ||||
|                 ConnectionTimeout = 60000, | ||||
|             }); | ||||
|  | ||||
|             //create a command service | ||||
| @@ -110,7 +109,7 @@ namespace NadekoBot { | ||||
|             modules.Add(new Conversations(), "Conversations", ModuleFilter.None); | ||||
|             modules.Add(new Gambling(), "Gambling", ModuleFilter.None); | ||||
|             modules.Add(new Games(), "Games", ModuleFilter.None); | ||||
|             modules.Add(new Music(), "Music", ModuleFilter.None); | ||||
|             //modules.Add(new Music(), "Music", ModuleFilter.None); | ||||
|             modules.Add(new Searches(), "Searches", ModuleFilter.None); | ||||
|             if (loadTrello) | ||||
|                 modules.Add(new Trello(), "Trello", ModuleFilter.None); | ||||
| @@ -142,22 +141,30 @@ namespace NadekoBot { | ||||
|                 Classes.Permissions.PermissionsHandler.Initialize(); | ||||
|  | ||||
|                 client.ClientAPI.SendingRequest += (s, e) => { | ||||
|                     var request = e.Request as Discord.API.Client.Rest.SendMessageRequest; | ||||
|                     if (request != null) { | ||||
|                         if (string.IsNullOrWhiteSpace(request.Content)) | ||||
|                             e.Cancel = true; | ||||
|                         //else | ||||
|                         //    Console.WriteLine("Sending request."); | ||||
|                         request.Content = request.Content.Replace("@everyone", "@everyοne"); | ||||
|                     try { | ||||
|                         var request = e.Request as Discord.API.Client.Rest.SendMessageRequest; | ||||
|                         if (request != null) { | ||||
|                             if (string.IsNullOrWhiteSpace(request.Content)) | ||||
|                                 e.Cancel = true; | ||||
|                             else | ||||
|                                 Console.WriteLine("Sending request."); | ||||
|                             request.Content = request.Content.Replace("@everyone", "@everyοne"); | ||||
|                         } | ||||
|                     } | ||||
|                     catch { | ||||
|                         Console.WriteLine("SENDING REQUEST ERRORED!!!!"); | ||||
|                     } | ||||
|                 }; | ||||
|  | ||||
|                 //client.ClientAPI.SentRequest += (s, e) => { | ||||
|                 //    var request = e.Request as Discord.API.Client.Rest.SendMessageRequest; | ||||
|                 //    if (request != null) { | ||||
|                 //        Console.WriteLine("Sent."); | ||||
|                 //    } | ||||
|                 //}; | ||||
|                 client.ClientAPI.SentRequest += (s, e) => { | ||||
|                     try { | ||||
|                         var request = e.Request as Discord.API.Client.Rest.SendMessageRequest; | ||||
|                         if (request != null) { | ||||
|                             Console.WriteLine("Sent."); | ||||
|                         } | ||||
|                     } | ||||
|                     catch { Console.WriteLine("SENT REQUEST ERRORED!!!"); } | ||||
|                 }; | ||||
|             }); | ||||
|             Console.WriteLine("Exiting..."); | ||||
|             Console.ReadKey(); | ||||
| @@ -200,9 +207,12 @@ namespace NadekoBot { | ||||
|                     t.Interval = 2000; | ||||
|                     t.Start(); | ||||
|                     t.Elapsed += (s, ev) => { | ||||
|                         repliedRecently = false; | ||||
|                         t.Stop(); | ||||
|                         t.Dispose(); | ||||
|                         try { | ||||
|                             repliedRecently = false; | ||||
|                             t.Stop(); | ||||
|                             t.Dispose(); | ||||
|                         } | ||||
|                         catch { } | ||||
|                     }; | ||||
|                 } | ||||
|             } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user