123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227 |
- require 'yaml'
- require 'discordrb'
- require 'icunicode'
- require 'open-uri'
- 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']
- def save_settings
- File.open("config.yaml", 'w') do |file|
- file.write(YAML.dump({'settings' => $settings}))
- end
- end
- bot.command(:translit) do |_event, script, *text|
- _event.message.mentions.each do |user|
- member = user.on(_event.channel.server)
- original_name = member.nick
- original_name ||= member.username
- transliterated = original_name.transliterate(script).force_encoding("UTF-8")
- member.nick = transliterated
- _event.send_message("Congratulations on your new nickname, #{member.mention}")
- end
- _event.send_message("Translitterated: #{text.join(' ').transliterate(script).force_encoding("UTF-8")}")
- "Finished translitting"
- end
- bot.command(:reset) do |_event|
- _event.message.mentions.each do |user|
- user.on(_event.channel.server).nickname = nil
- end
- "Finished resetting"
- end
- bot.command(:loli, description: "Calls for the lolice.") do |_event|
- "https://tankernn.eu/~frans/files/loli_police_#{rand(1..3)}.png"
- end
- bot.command(:reap, description: "Reaps images posted by the caller in the current channel.") do |_event, stop_id|
- next "No stop_id supplied" if stop_id == nil
- FileUtils::mkdir_p("/tmp/tankbot_images/")
- stop = false
- earliest_message_id = nil
- control_message = _event.send_message("Reaping images sent by #{_event.author.mention}. React to this message to stop.")
- until stop
- messages = _event.channel.history(100, earliest_message_id)
- messages.select{ |message| message.author === _event.author }.each do |message|
- puts "#{message.id}, #{stop_id}"
- if control_message.reactions? or message.id == stop_id
- stop = true
- break
- end
- message.attachments.select{ |attachment| attachment.image? }.each do |attachment|
- control_message.edit(control_message.content + "\nDownloading **#{attachment.filename}**... (#{message.timestamp.strftime("%F")})")
- open("/tmp/tankbot_images/#{attachment.id}-#{attachment.filename}", 'wb') do |file|
- file << open(attachment.url).read
- end
- end
- end
- stop = messages.length < 100
- earliest_message_id = messages.last.id
- end
- filename = "#{SecureRandom.uuid}.tar.gz"
- `tar -czf /var/www/scr/#{filename} /tmp/tankbot_images`
- FileUtils::rm_rf("/tmp/tankbot_images")
- control_message.edit("https://scr.tankernn.eu/#{filename}")
- end
- bot.command(:neko, description: "Requests (sometimes lewd) nekos.") do |_event, keyword|
- url = "https://nekos.life/api/v2/img/"
- options = ["cum", "les", "meow", "tickle", "lewd", "feed", "bj",
- "nsfw_neko_gif", "poke", "anal", "slap", "avatar", "pussy",
- "lizard", "classic", "kuni", "pat", "kiss", "neko", "cuddle",
- "fox_girl", "boobs", "random_hentai_gif", "hug"]
- if options.include? keyword then
- response = JSON.parse(Net::HTTP.get(URI("#{url}#{keyword}")))
- "Here's your lewds! °˖✧◝(⁰▿⁰)◜✧˖°\n#{response['url']}"
- else
- "No such tag. Please specify one of `#{options.join(", ")}`"
- end
- end
- bot.command(:lmgtfy, description: "Helps tech-illiterate people to enlightenment.") do |_event, *args|
- "http://lmgtfy.com/?s=d&q=#{args.join('+')}"
- end
- bot.command(:copypasta, description: "Cites the holy texts.") do |_event, keyword|
- pastafile = "copypastas.json"
- file = File.read pastafile
- pastas = JSON.parse file
- if pastas.include? keyword then
- pastas[keyword]
- else
- "No such pasta. Available pastas include `#{pastas.keys.join(", ")}`"
- end
- 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)
- voice_bot.volume = $settings['volume']
- 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.command(:volume, description: "Sets the severity of currently playing 'music'.") do |_event, volume|
- next "Nothing is playing." unless _event.voice
- $settings['volume'] = _event.voice.volume = [volume.to_f, 1.5].min
- save_settings
- ""
- end
- bot.run
|