diff --git a/download.go b/download.go index 3162e27..ef8c23d 100644 --- a/download.go +++ b/download.go @@ -22,6 +22,7 @@ func downloadAndPlay(s *discordgo.Session, guildID, channelID, link, user, txtCh info, err := os.Stat("./audio_cache/" + el.id + ".dca") if err == nil && info.Size() > 0 { el.user = user + el.channel = channelID server[guildID].queue = append(server[guildID].queue, el) go playSound(s, guildID, channelID, el.id+".dca", txtChannel) return @@ -63,9 +64,9 @@ func downloadAndPlay(s *discordgo.Session, guildID, channelID, link, user, txtCh var el Queue if ytdl.Extractor == "youtube" { - el = Queue{ytdl.Title, formatDuration(ytdl.Duration), fileName, ytdl.WebpageURL, user, nil, ytdl.Thumbnail, 0, getSegments(ytdl.ID)} + el = Queue{ytdl.Title, formatDuration(ytdl.Duration), fileName, ytdl.WebpageURL, user, nil, ytdl.Thumbnail, 0, getSegments(ytdl.ID), channelID} } else { - el = Queue{ytdl.Title, formatDuration(ytdl.Duration), fileName, ytdl.WebpageURL, user, nil, ytdl.Thumbnail, 0, nil} + el = Queue{ytdl.Title, formatDuration(ytdl.Duration), fileName, ytdl.WebpageURL, user, nil, ytdl.Thumbnail, 0, nil, channelID} } // Checks if video is already downloaded diff --git a/go.mod b/go.mod index 9938cde..43443d0 100644 --- a/go.mod +++ b/go.mod @@ -19,9 +19,9 @@ require ( github.com/spf13/viper v1.7.2-0.20201203004352-bba82cfc61da github.com/zmb3/spotify v0.0.0-20201231194903-e2d01d9b8bd2 golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect - golang.org/x/net v0.0.0-20201224014010-6772e930b67b // indirect + golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3 - golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 // indirect + golang.org/x/sys v0.0.0-20210122235752-a8b976e07c7b // indirect golang.org/x/text v0.3.5 // indirect google.golang.org/appengine v1.6.7 // indirect gopkg.in/ini.v1 v1.62.0 // indirect diff --git a/go.sum b/go.sum index bad54cf..ade2eb5 100644 --- a/go.sum +++ b/go.sum @@ -370,14 +370,14 @@ golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210112200429-01de73cf58bd h1:0n2rzLq6xLtV9OFaT0BF2syUkjOwRrJ1zvXY5hH7Kkc= -golang.org/x/oauth2 v0.0.0-20210112200429-01de73cf58bd/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3 h1:BaN3BAqnopnKjvl+15DYP6LLrbBHfbfmlFYzmFj/Q9Q= golang.org/x/oauth2 v0.0.0-20210113205817-d3ed898aa8a3/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -423,10 +423,10 @@ golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc h1:y0Og6AYdwus7SIAnKnDxjc4gJetRiYEWOx4AKbOeyEI= -golang.org/x/sys v0.0.0-20210112091331-59c308dcf3cc/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78 h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY= golang.org/x/sys v0.0.0-20210113181707-4bcb84eeeb78/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210122235752-a8b976e07c7b h1:HSSdksA3iHk8fuZz7C7+A6tDgtIRF+7FSXu5TgK09I8= +golang.org/x/sys v0.0.0-20210122235752-a8b976e07c7b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/main.go b/main.go index ca424ca..0e7ec6f 100644 --- a/main.go +++ b/main.go @@ -335,35 +335,47 @@ func messageCreate(s *discordgo.Session, m *discordgo.MessageCreate) { case "summon": go deleteMessage(s, m) + vs := findUserVoiceState(s, m) + // Check if user is not in a voice channel - if findUserVoiceState(s, m) == nil { + if vs == nil { sendAndDeleteEmbed(s, NewEmbed().SetTitle(s.State.User.Username).AddField("Error", "You're not in a voice channel in this guild!").SetColor(0x7289DA).MessageEmbed, m.ChannelID, time.Second*5) - return + break } - // Check if the queue is empty - if len(server[m.GuildID].queue) == 0 { - var err error + var err error - vs := findUserVoiceState(s, m) + // If we are playing something, we lock the pause mutex + if len(server[m.GuildID].queue) > 0 { + server[m.GuildID].pause.Lock() - // Check if user is not in a voice channel - if vs == nil { - sendAndDeleteEmbed(s, NewEmbed().SetTitle(s.State.User.Username).AddField("Error", "You're not in a voice channel in this guild!").SetColor(0x7289DA).MessageEmbed, m.ChannelID, time.Second*5) - return + // Disconnect the bot + if server[m.GuildID].vc != nil { + _ = server[m.GuildID].vc.Disconnect() } - server[m.GuildID].server.Lock() + // And reconnect the bot to the new voice channel + server[m.GuildID].queue[0].channel = vs.ChannelID + server[m.GuildID].vc, err = s.ChannelVoiceJoin(m.GuildID, vs.ChannelID, false, true) - server[m.GuildID].vc, err = s.ChannelVoiceJoin(m.GuildID, vs.ChannelID, false, false) - if err != nil { - lit.Error("%s", err) - } + server[m.GuildID].pause.Unlock() + } else { + // Else we just join the channel and wait + server[m.GuildID].server.Unlock() + + server[m.GuildID].vc, err = s.ChannelVoiceJoin(m.GuildID, vs.ChannelID, false, true) + + // We also start the quitVC routine to disconnect the bot after a minute of inactivity + go quitVC(m.GuildID) server[m.GuildID].server.Unlock() - } else { - sendAndDeleteEmbed(s, NewEmbed().SetTitle(s.State.User.Username).AddField("Error", "Can't summon the bot!\nAlready playing in a voice channel.").SetColor(0x7289DA).MessageEmbed, m.ChannelID, time.Second*5) } + + if err != nil { + sendAndDeleteEmbed(s, NewEmbed().SetTitle(s.State.User.Username).AddField("Error", "Can't join voice channel!\n"+err.Error()).SetColor(0x7289DA).MessageEmbed, m.ChannelID, time.Second*5) + break + } + break // Prints out supported commands diff --git a/sound.go b/sound.go index bf8f44e..5eeeb9d 100644 --- a/sound.go +++ b/sound.go @@ -101,7 +101,7 @@ func playSound(s *discordgo.Session, guildID, channelID, fileName, txtChannel st case server[guildID].vc.OpusSend <- InBuf: break case <-time.After(time.Second / 3): - server[guildID].vc, _ = s.ChannelVoiceJoin(guildID, channelID, false, true) + server[guildID].vc, _ = s.ChannelVoiceJoin(guildID, server[guildID].queue[0].channel, false, true) } } else { @@ -227,7 +227,7 @@ func soundStream(s *discordgo.Session, guildID, channelID, fileName, txtChannel case server[guildID].vc.OpusSend <- InBuf: break case <-time.After(time.Second / 3): - server[guildID].vc, _ = s.ChannelVoiceJoin(guildID, channelID, false, true) + server[guildID].vc, _ = s.ChannelVoiceJoin(guildID, server[guildID].queue[0].channel, false, true) } } else { diff --git a/structures.go b/structures.go index bbf03c8..b38d53d 100644 --- a/structures.go +++ b/structures.go @@ -45,6 +45,8 @@ type Queue struct { frame int // Segments of the song to skip. Uses SponsorBlock API segments map[int]bool + // Channel where we are supposed to play the song. Used for moving the bot around + channel string } // YoutubeDL structure for holding youtube-dl data diff --git a/utilities.go b/utilities.go index c5191dd..b86784b 100644 --- a/utilities.go +++ b/utilities.go @@ -55,7 +55,7 @@ func removeFromQueue(id string, guild string) { for i, q := range server[guild].queue { if q.id == id { copy(server[guild].queue[i:], server[guild].queue[i+1:]) - server[guild].queue[len(server[guild].queue)-1] = Queue{"", "", "", "", "", nil, "", 0, nil} + server[guild].queue[len(server[guild].queue)-1] = Queue{"", "", "", "", "", nil, "", 0, nil, ""} server[guild].queue = server[guild].queue[:len(server[guild].queue)-1] return }