From 0b8caf568c85f8c0b2698c7b8591e5a98c1b25eb Mon Sep 17 00:00:00 2001 From: Master Kwoth Date: Fri, 22 Jan 2016 06:35:44 +0100 Subject: [PATCH] multiserver music almost done --- NadekoBot/Classes/_JSONModels.cs | 2 +- NadekoBot/Modules/Music.cs | 103 +++++++++++++++++++------------ NadekoBot/NadekoBot.cs | 25 +++++++- 3 files changed, 89 insertions(+), 41 deletions(-) diff --git a/NadekoBot/Classes/_JSONModels.cs b/NadekoBot/Classes/_JSONModels.cs index 53b9881c..62c3dc59 100644 --- a/NadekoBot/Classes/_JSONModels.cs +++ b/NadekoBot/Classes/_JSONModels.cs @@ -7,10 +7,10 @@ public string BotMention; public string GoogleAPIKey; public ulong OwnerID; - public bool Crawl; public string ParseID; public string ParseKey; public string TrelloAppKey; + public bool? ForwardMessages; } public class AnimeResult { diff --git a/NadekoBot/Modules/Music.cs b/NadekoBot/Modules/Music.cs index aec33ba6..ae02b5c8 100644 --- a/NadekoBot/Modules/Music.cs +++ b/NadekoBot/Modules/Music.cs @@ -15,23 +15,22 @@ using System.Diagnostics; using NadekoBot.Extensions; using System.Net; using System.Globalization; +using System.Collections.Concurrent; namespace NadekoBot.Modules { class Music : DiscordModule { - private static bool exit = true; - public static bool NextSong = false; - public static IAudioClient Voice; - public static Channel VoiceChannel; - public static bool Pause = false; - public static List SongQueue = new List(); - - public static StreamRequest CurrentSong; - - public static bool Exit { - get { return exit; } - set { exit = value; } // if i set this to true, break the song and exit the main loop + public class MusicControls { + public bool NextSong = false; + public IAudioClient Voice; + public Channel VoiceChannel; + public bool Pause = false; + public List SongQueue = new List(); + public StreamRequest CurrentSong; } + + public static ConcurrentDictionary musicPlayers = new ConcurrentDictionary(); + public Music() : base() { //commands.Add(new PlayMusic()); @@ -49,11 +48,19 @@ namespace NadekoBot.Modules { var client = NadekoBot.client; Task.Run(async () => { + while (true) { - if (CurrentSong == null || CurrentSong.State == StreamTaskState.Completed) { - await LoadNextSong(); - } else - await Task.Delay(200); + try { + foreach (var kvp in musicPlayers) { + var player = kvp.Value; + if (player.CurrentSong == null || player.CurrentSong.State == StreamTaskState.Completed) { + LoadNextSong(player); + await Task.Delay(200); + } + } + } catch (Exception e) { + Console.WriteLine(e); + } } }); @@ -65,9 +72,10 @@ namespace NadekoBot.Modules { .Alias("next") .Description("Goes to the next song in the queue.") .Do(e => { - if (CurrentSong == null) return; + if (musicPlayers.ContainsKey(e.Server) == false || (musicPlayers[e.Server]?.CurrentSong) == null) return; + var CurrentSong = musicPlayers[e.Server].CurrentSong; CurrentSong.Cancel(); - CurrentSong = SongQueue.Take(1).FirstOrDefault(); + CurrentSong = musicPlayers[e.Server].SongQueue.Take(1).FirstOrDefault(); if (CurrentSong != null) { CurrentSong.Start(); } @@ -77,60 +85,79 @@ namespace NadekoBot.Modules { .Alias("stop") .Description("Completely stops the music and unbinds the bot from the channel and cleanes up files.") .Do(e => { - SongQueue.Clear(); - if (CurrentSong != null) { - CurrentSong.Cancel(); - CurrentSong = null; + if (musicPlayers.ContainsKey(e.Server) == false) return; + var player = musicPlayers[e.Server]; + player.SongQueue.Clear(); + if (player.CurrentSong != null) { + player.CurrentSong.Cancel(); + player.CurrentSong = null; } - Directory.Delete("StreamBuffers", true); }); + cgb.CreateCommand("p") .Alias("pause") .Description("Pauses the song") .Do(async e => { + if (musicPlayers.ContainsKey(e.Server) == false) return; await e.Send("Not yet implemented."); }); + cgb.CreateCommand("q") .Alias("yq") - .Description("Queue a song using a multi/single word name.\n**Usage**: `!m q Dream Of Venice`") + .Description("Queue a song using keywords or link. **You must be in a voice channel**.\n**Usage**: `!m q Dream Of Venice`") .Parameter("Query", ParameterType.Unparsed) .Do(e => { - SongQueue.Add(new StreamRequest(NadekoBot.client, e, e.GetArg("Query"))); + if (musicPlayers.ContainsKey(e.Server) == false) + musicPlayers.TryAdd(e.Server, new MusicControls()); + var player = musicPlayers[e.Server]; + player.SongQueue.Add(new StreamRequest(NadekoBot.client, e, e.GetArg("Query"))); }); cgb.CreateCommand("lq") .Alias("ls").Alias("lp") .Description("Lists up to 10 currently queued songs.") .Do(async e => { - await e.Send(":musical_note: " + SongQueue.Count + " videos currently queued."); - await e.Send(string.Join("\n", SongQueue.Select(v => v.Title).Take(10))); + if (musicPlayers.ContainsKey(e.Server) == false) await e.Send(":musical_note: No active music player."); + var player = musicPlayers[e.Server]; + + await e.Send(":musical_note: " + player.SongQueue.Count + " videos currently queued."); + await e.Send(string.Join("\n", player.SongQueue.Select(v => v.Title).Take(10))); + }); + + cgb.CreateCommand("clrbfr") + .Alias("clearbuffers") + .Description("Clears the music buffer across all servers. **Owner only.**") + .Do(e => { + if (NadekoBot.OwnerID != e.User.Id) return; + Directory.Delete("StreamBuffers", true); }); cgb.CreateCommand("sh") .Description("Shuffles the current playlist.") .Do(async e => { - if (SongQueue.Count < 2) { + if (musicPlayers.ContainsKey(e.Server) == false) return; + var player = musicPlayers[e.Server]; + if (player.SongQueue.Count < 2) { await e.Send("Not enough songs in order to perform the shuffle."); return; } - SongQueue.Shuffle(); + player.SongQueue.Shuffle(); await e.Send(":musical_note: Songs shuffled!"); }); }); } - private async Task LoadNextSong() { - if (SongQueue.Count == 0 || !SongQueue[0].LinkResolved) { - if (CurrentSong != null) - CurrentSong.Cancel(); - CurrentSong = null; - await Task.Delay(200); + private void LoadNextSong(MusicControls player) { + if (player.SongQueue.Count == 0 || !player.SongQueue[0].LinkResolved) { + if (player.CurrentSong != null) + player.CurrentSong.Cancel(); + player.CurrentSong = null; return; } - CurrentSong = SongQueue[0]; - SongQueue.RemoveAt(0); - CurrentSong.Start(); + player.CurrentSong = player.SongQueue[0]; + player.SongQueue.RemoveAt(0); + player.CurrentSong.Start(); return; } } diff --git a/NadekoBot/NadekoBot.cs b/NadekoBot/NadekoBot.cs index ab57d866..d98fb3d3 100644 --- a/NadekoBot/NadekoBot.cs +++ b/NadekoBot/NadekoBot.cs @@ -20,8 +20,10 @@ namespace NadekoBot public static string botMention; public static string GoogleAPIKey = null; public static ulong OwnerID; + public static User OwnerUser = null; public static string password; public static string TrelloAppKey; + public static bool ForwardMessages = false; static void Main() { @@ -45,6 +47,13 @@ namespace NadekoBot TrelloAppKey = c.TrelloAppKey; trelloLoaded = true; } + if (c.ForwardMessages != true) + Console.WriteLine("Not forwarding messages."); + else { + ForwardMessages = true; + Console.WriteLine("Forwarding messages."); + } + OwnerID = c.OwnerID; password = c.Password; } @@ -75,7 +84,7 @@ namespace NadekoBot Console.WriteLine("Parse key and/or ID not found. Logging disabled."); } - //reply to personal messages + //reply to personal messages and forward if enabled. client.MessageReceived += Client_MessageReceived; //add command service @@ -87,7 +96,9 @@ namespace NadekoBot //add audio service var audio = client.Services.Add(new AudioService(new AudioServiceConfig() { Channels = 2, - EnableEncryption = false + EnableEncryption = false, + EnableMultiserver = true, + Mode = AudioMode.Outgoing })); //install modules @@ -116,6 +127,12 @@ namespace NadekoBot Console.WriteLine("Heap: "+ Math.Round(GC.GetTotalMemory(true) / (1024.0 * 1024.0), 2).ToString() + "MB"); Console.WriteLine("-------------------------"); + + foreach (var serv in client.Servers) { + if ((OwnerUser = serv.GetUser(OwnerID)) != null) + return; + } + }); Console.WriteLine("Exiting..."); Console.ReadKey(); @@ -126,8 +143,12 @@ namespace NadekoBot if (e.Server != null) return; try { (await client.GetInvite(e.Message.Text))?.Accept(); + await e.User.Send("I got in, thanks. <3"); } catch (Exception) { } + if (NadekoBot.ForwardMessages && OwnerUser != null) + await OwnerUser.Send(e.Message.Text); + if (repliedRecently = !repliedRecently) { await e.Send("You can type `-h` or `-help` or `@MyName help` in any of the channels I am in and I will send you a message with my commands.\n Or you can find out what i do here: https://github.com/Kwoth/NadekoBot\nYou can also just send me an invite link to a server and I will join it.\nIf you don't want me on your server, you can simply ban me ;("); Timer t = new Timer();