|
@@ -6,6 +6,7 @@ require 'fileutils'
|
|
|
require 'securerandom'
|
|
|
require 'net/http'
|
|
|
require 'json'
|
|
|
+require 'youtube-dl.rb'
|
|
|
|
|
|
settings = YAML.load(File.read "config.yaml")['settings']
|
|
|
bot = Discordrb::Commands::CommandBot.new token: settings['token'], prefix: settings['prefix']
|
|
@@ -95,4 +96,116 @@ bot.command(:copypasta, description: "Cites the holy texts.") do |_event, keywor
|
|
|
end
|
|
|
|
|
|
|
|
|
+class UserQueue
|
|
|
+ def initialize(user)
|
|
|
+ @user = user
|
|
|
+ @songs = []
|
|
|
+ end
|
|
|
+
|
|
|
+ attr_accessor :user
|
|
|
+ attr_accessor :songs
|
|
|
+end
|
|
|
+
|
|
|
+class FairQueue
|
|
|
+ def initialize(voice_bot)
|
|
|
+ @voice_bot = voice_bot
|
|
|
+ @queues = []
|
|
|
+ @now_playing = nil
|
|
|
+ end
|
|
|
+
|
|
|
+ def append(user, video)
|
|
|
+ @queues.append UserQueue.new user unless @queues.any? { |queue| queue.user == user }
|
|
|
+ @queues.select{ |queue| queue.user == user }.first.songs.append(video)
|
|
|
+ end
|
|
|
+
|
|
|
+ def queue
|
|
|
+ queues = @queues.map{ |queue| queue.songs }
|
|
|
+ target_length = queues.map{ |queue| queue.length }.max
|
|
|
+ queues.map{ |queue| queue + (target_length - queue.length).times.collect{nil} }.transpose.flatten.compact
|
|
|
+ end
|
|
|
+
|
|
|
+ def play
|
|
|
+ until @queues.empty?
|
|
|
+ queue = @queues.shift
|
|
|
+ @now_playing = queue.songs.shift
|
|
|
+ # Rotate user to last place
|
|
|
+ @queues.append queue unless queue.songs.empty?
|
|
|
+ # Play song
|
|
|
+ # song_log("Playing *#{video.title}*...")
|
|
|
+ @voice_bot.play_file(@now_playing.filename)
|
|
|
+ end
|
|
|
+ @voice_bot.destroy
|
|
|
+ end
|
|
|
+
|
|
|
+ attr_accessor :now_playing
|
|
|
+end
|
|
|
+
|
|
|
+def format_title(video)
|
|
|
+ total_seconds = video.information[:duration]
|
|
|
+ seconds = total_seconds % 60
|
|
|
+ minutes = (total_seconds / 60) % 60
|
|
|
+ hours = total_seconds / (60 * 60)
|
|
|
+ timestamp = format("%02d:%02d", minutes, seconds)
|
|
|
+ timestamp = format("%02d:%s", hours, timestamp) if hours > 0
|
|
|
+ "**#{video.information[:fulltitle]}** `[#{timestamp}]`"
|
|
|
+end
|
|
|
+
|
|
|
+fairqueues = Hash.new
|
|
|
+
|
|
|
+youtube_dl_options = {
|
|
|
+ default_search: 'ytsearch',
|
|
|
+ format: 'bestaudio',
|
|
|
+ output: 'cache/%(title)s-%(id)s.%(ext)s'
|
|
|
+}
|
|
|
+
|
|
|
+bot.command(:play, description: "Plays 'music' of your choosing in your voice channel.") do |_event, *query|
|
|
|
+ voice_bot = _event.voice
|
|
|
+ unless voice_bot then
|
|
|
+ channel = _event.user.voice_channel
|
|
|
+ next "You're not in any voice channel!" unless channel
|
|
|
+ voice_bot = bot.voice_connect(channel)
|
|
|
+ fairqueues[_event.server] = FairQueue.new(voice_bot)
|
|
|
+ end
|
|
|
+
|
|
|
+ video = YoutubeDL.download query.join(' '), youtube_dl_options
|
|
|
+
|
|
|
+ fairqueue = fairqueues[_event.server]
|
|
|
+ fairqueue.append(_event.user, video)
|
|
|
+
|
|
|
+ if voice_bot.playing? then
|
|
|
+ "Added #{format_title(video)} to the queue."
|
|
|
+ else
|
|
|
+ Thread.new{fairqueue.play}
|
|
|
+ "Started playing #{format_title(video)}"
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+bot.command(:skip, description: "Expresses your dislike of the currently playing 'music'.") do |_event|
|
|
|
+ _event.voice.stop_playing
|
|
|
+end
|
|
|
+
|
|
|
+bot.command(:np, description: "Shows what 'music' is currently playing.") do |_event|
|
|
|
+ queue = fairqueues[_event.server]
|
|
|
+ next "Nothing is playing." unless _event.voice
|
|
|
+ format_title(queue.now_playing)
|
|
|
+end
|
|
|
+
|
|
|
+bot.command(:stop, description: "Puts an end to your misery.") do |_event|
|
|
|
+ if _event.voice
|
|
|
+ _event.voice.destroy
|
|
|
+ "Stopped playing."
|
|
|
+ else
|
|
|
+ "Nothing is playing."
|
|
|
+ end
|
|
|
+end
|
|
|
+
|
|
|
+bot.command(:queue, description: "Lists the impending torture.") do |_event|
|
|
|
+ queue = fairqueues[_event.server]
|
|
|
+ next "Nothing is playing." unless queue
|
|
|
+ next "The queue is empty." if queue.queue.empty?
|
|
|
+
|
|
|
+ queue.queue.each_with_index.map{|video, i| "#{i + 1}. #{format_title(video)}"}.join("\n")
|
|
|
+end
|
|
|
+
|
|
|
+
|
|
|
bot.run
|