require 'cinch' require 'json' require 'time' require 'chronic' require 'open-uri' require 'nokogiri/class_resolver' require 'nokogiri' require 'uri' require 'net/http' require 'json' require 'htmlentities' def fix_nick(n) return n[0] + "\uFEFF" + n[1,n.length] end def human_time(time) out_str = "" if time > (60*60*24) then #days out_str = (time/(60*60*24)).to_i.to_s + " days" elsif time > (60*60) then #hours out_str = (time/(60*60)).to_i.to_s + " hours" elsif time > (60) then #minutes out_str = (time/(60)).to_i.to_s + " minutes" else #seconds out_str = time.to_s + " seconds" end return out_str end def get_data(f) data = JSON.parse(File.read("data.bd")) if data[f] == nil then return {} else return data[f] end end def set_data(f, v) data = JSON.parse(File.read("data.bd")) data[f] = v File.write("data.bd", JSON.generate(data)) end bot = Cinch::Bot.new do pounces = [] seens = {} who = "" sentence = "" who_working = false last_saids = {} trev_running = false trev_answers_running = false trev_guesses = {} real_answer = "" countdown_running = false configure do |c| c.server = "irc.libera.chat" c.user = "Monqui" c.password = "tbmsn" c.nick = "botqu9001" c.delay_joins = 15 c.channels = ["#sconesandcream fatjoints", "#sconetv", "#bakedbeans"] c.timeouts.connect = 30 end on :message, ".bots" do |m| m.reply "RePoRTiNg iN 🐵! [ruby] Lmao!" end on :message, /^!thank.*/ do |m| links = [ "https://i.imgur.com/P2jEPy7.png", "https://i.imgur.com/q1IzteE.jpg", "https://i.imgur.com/BM1V3Um.png", "https://i.imgur.com/RuLveTf.jpg", "https://i.imgur.com/ramcAYX.png" ] m.reply links.sample end on :message, "!nonce" do |m| m.reply "French people." end on :message, "!nipples" do |m| m.reply "(.)(.) ooooo" end on :message, "!rub" do |m| m.reply "/me mmmmmmmmmmmmmmmm's" end on :message, "!quote" do |m| q = Quoter.new() m.reply(q.get_quote) end on :message, /^!quote (.+)$/ do |m, quote| q = Quoter.new() q.save_quote(quote) m.reply "K." end on :message, /^!delquote (.*)$/ do |m, id| q = Quoter.new() m.reply(q.del_quote(id)) end on :channel, /^!apod$/ do |m| doc = Nokogiri::HTML.parse(URI.open('https://apod.nasa.gov/apod/astropix.html')) img = doc.xpath("/html/body/center[1]/p[2]/a/img") uri = "https://apod.nasa.gov/" + img.attr("src") name = "\u0002" + doc.xpath("/html/body/center[2]/b[1]").inner_html.strip + "\u000F" m.reply name + ": " + uri end on :channel, /^!moon$/ do |m| doc = Nokogiri::HTML.parse(URI.open('https://www.timeanddate.com/moon/phases/')) img = doc.xpath("//*[@id='cur-moon-percent']") m.reply img.inner_html.to_s end on :channel, /^!google (.*)$/ do |m, terms| google_url = "https://www.google.com/search?q=" + terms.gsub(' ', '%20') m.reply google_url end on :message, /([\.\d]+)lb/i do |m, val| if m.user.nick.to_s != " Ballbag" then m.reply val.to_s + "lb = " + (val.to_f * 0.454).round(2).to_s + "kg" end end on :message, /([\.\d]+)kg/i do |m, val| if m.user.nick.to_s != "Ballbag" then m.reply val.to_s + "kg = " + (val.to_f * 2.2046).round(2).to_s + "lb" end end on :message, /^!roll ([0-9]+)d([0-9]+)$/ do |m, num, max| if num.to_i > 30 or max.to_i > 100 then m.reply "bro be real." return end count = 0 value = 0 vals = [] while count < num.to_i do roll = rand(1..max.to_i) vals.push(roll) value = value + roll count = count + 1 end m.reply "#{m.user.nick} rolled " + vals.join('+') + " = " + value.to_s end on :message, /.* bear .*/ do |m| m.reply "https://33.media.tumblr.com/fe1446dc5f065b3685fe63c51121fc4f/tumblr_mhhadl964P1rgfo8qo1_r2_400.gif" end on :message, /.*trinity.*/i do |m| m.reply "https://tenor.com/view/trinity-taylor-drag-race-sip-cocktail-drama-gif-9086550" end on :message, "hello" do |m| m.reply "Hello, #{m.user.nick}" end on :channel, /^!pounce (\S*) (.*)$/ do |m, t, message| save_msg = {"source" => m.user.nick, "target" => t, "message" => '', 'time' => ''} if message.index("|") != nil then msg_parts = message.split(' | ') save_msg["message"] = msg_parts[1] triggerTime = Chronic.parse(msg_parts[0]) if triggerTime == nil then save_msg["time"] = Time.now else save_msg["time"] = triggerTime end else save_msg["time"] = Time.now save_msg["message"] = message end # m.reply save_msg.inspect pounces.push save_msg # if !pounces[t.downcase].key?(m.user.nick) then # pounces[t.downcase][m.user.nick] = save_msg # else # pounces[t.downcase][m.user.nick] = pounces[t.downcase][m.user.nick] + " | " + message # end m.reply "Will pounce " + t + " next time I see 'em." end on :channel, /^(.*)$/ do |m, val| nick = m.user.nick now = Time.now remaining_pounces = [] out_msgs = {} pounces.each do |p| if nick == p["target"] and now > p["time"] then out_msgs[nick] = p["source"] + " says " + p["message"] + "| " + out_msgs[nick].to_s else remaining_pounces.push p end end out_msgs.each do |key, val| m.reply "Hey " + key + ", " + val end # m.reply out_msgs.inspect pounces = remaining_pounces # if pounces.key?(nick.downcase) then # pounces[nick.downcase].each_key{|i| # m.reply "Hey " + nick + ", " + i.to_s + " says " + pounces[nick.downcase][i] # } # pounces.delete(nick.downcase) end on :message, /^!print (.*)$/ do |m, cmd| m.reply cmd end on :channel, /^.*$/ do |m| if m.message.slice(0, 2) != "s/" and m.message.slice(0, 1) != "!" and m.user.nick.to_s != "Ballbag" then last_saids[m.user.nick] = m.message end end on :channel, /^!britify(.*)$/ do |m, msg| britese = ['oi', 'u wot', 'm8', 'mate', 'innit', 'bruv', 'fam', "ya kna wha 'm sayin"] msg = msg.strip orig = '?' if msg == '' then orig = last_saids[m.user.nick] else orig = msg end m.reply britese.sample + " " + orig.gsub(/(o)/i, 'ou'). gsub(/(z)/i, 's'). gsub(/(ck)/i, 'que'). gsub(/( of)/i, 'o\''). gsub(/(au)/i, 'o'). gsub(/(and)/i, 'an\''). gsub(/(the)/i, 'tha'). gsub(/(he)/i, '\'e') + " " + britese.sample end # on :channel, /^s\/(.*)\/(.*)\/? ?(.*) ?$/ do |m, f, r, n| on :channel, /^s\/(.*)\/(.*)(\/[^\s]*)?(\s+([^\s]+))?\s*$/ do |m, f, r, o, n, x| nick = m.user.nick if n != nil and n.strip != "" then nick = n.strip end ls = last_saids[nick] re = /#{f}/ sedres = ls.gsub(re, r) m.reply nick + " meant to say: " + sedres #s.try(last_saids[nick]) end on :channel, /^!fc (.*)$/ do |m, val| if m.user.nick.to_s != "Ballbag" then m.reply ((val.to_f-32).to_f/1.8).to_s + "C" end end on :channel, /^!cf (.*)$/ do |m, val| if m.user.nick.to_s != "Ballbag" then m.reply ((val.to_f * 1.8)+32).to_s + "F" end end on :message, /(^|\s)(-?\d+)f($|\s)/i do |m, junk, val, other| if m.user.nick.to_s != "Ballbag" then m.reply val.to_s + "F = " + ((val.to_i-32).to_f/1.8).round(2).to_s + "C" end end on :message, /(^|\s)(-?\d+)c($|\s)/i do |m, junk, val, other| if m.user.nick.to_s != "Ballbag" then m.reply val.to_s + "c = " + ((val.to_i * 1.8)+32).round(2).to_s + "F" end end on :channel, /^!imgur (.*)$/ do |m, tag| m.reply "http://i.imgur.com/" + tag end on :channel, /^(.*)$/ do |m, last_said| seens[m.user.nick.downcase] = {"message": last_said, "time": Time.now().to_i} end on :channel, /^!seen (.*$)/ do |m, nick_long| nick = nick_long.strip if !seens.key?(nick.downcase) then m.reply "Haven't seen " + nick + " since last reboot..." else ht = human_time(Time.now().to_i - seens[nick.downcase][:time]) m.reply nick + " said \"" + seens[nick.downcase][:message] + "\" " + ht + " ago." end end on :channel, /^!remind (.*)[\|:](.*)$/ do |m, time, event| event = event.strip triggerTime = Chronic.parse(time) if triggerTime == nil then m.reply "Iunno wtf time that is." return else timeOut = triggerTime.to_i - Time.now().to_i if timeOut <= 0 then m.reply "YOU CAN'T CHANGE THE PAST, MAN!" else m.reply 'Will remind you to ' + event + ' in about ' + (timeOut).to_s + " secondsish." sleep(timeOut) m.reply m.user.nick.to_s + ": " + event end end end on :channel, /^!countdown$/ do |m| if countdown_running == false then countdown_running = true start = 5 while start > 0 do m.reply start start = start - 1 sleep(1) end countdown_running = false m.reply "GO!" else return end end on :channel, /^!cd$/ do |m| if countdown_running == false then countdown_running = true start = 5 while start > 0 do m.reply start start = start - 1 sleep(1) end countdown_running = false m.reply "GO!" end end on :channel, /^!trev$/ do |m| if trev_running == true then m.reply "PLAY THE GAME!" else trev_running = true res = Net::HTTP.get_response(URI('https://opentdb.com/api.php?amount=1')) if res.is_a?(Net::HTTPSuccess) question = JSON.parse(res.body) question_text = HTMLEntities.new.decode(question["results"][0]["question"]) answer = question["results"][0]["correct_answer"] category = question["results"][0]["category"] difficulty = question["results"][0]["difficulty"] multiplier = 1 difficulty_tag = "H" case difficulty when "easy" multiplier = 0.33 difficulty_tag = "E" when "medium" multiplier = 0.66 difficulty_tag = "M" when "hard" multiplier = 1.0 difficulty_tag = "H" else m.reply "wtf does " + difficulty + " mean??" end answers = question["results"][0]["incorrect_answers"] answers.push(answer) answers.shuffle! m.reply "🖕👁️👄👁️🖕" m.reply "[" + category + "] (\x02" + difficulty_tag + "\x02) " + question_text out_str = "" current_answer = "A" max_answer = answers.max{|c1, c2| HTMLEntities.new.decode(c1).length <=> HTMLEntities.new.decode(c2).length} max_length = max_answer.length + 2 # 2 for padding a bit... padded_answers = answers.map{|v| v.ljust(max_length.to_i) } answers_shown = 0 padded_answers.each do |a| answers_shown = answers_shown + 1 if a.strip == answer.strip then real_answer = current_answer.clone end out_str = out_str + "\x02" + current_answer + "\x0F) " + HTMLEntities.new.decode(a) + " " if answers_shown % 2 == 0 then out_str.strip! out_str = out_str + "\n" end current_answer.next! end m.reply out_str.strip m.reply "TRIVIA STARTING IN 5 SECONDS!" sleep(5) trev_answers_running = true m.reply "You have 30 seconds! GO!" start_time = Time.now.to_i sleep(30) m.reply "The answer was \x02" + real_answer + "\x0F) " + HTMLEntities.new.decode(answer) + "!" someone_won = false data = get_data('trevias') trev_guesses.each do |g| puts g.inspect puts trev_guesses.inspect if g[1] > 0 then someone_won = true nick = g[0] time_took = g[1] - start_time points = ((((30-time_took).to_f/30.0) * 100)*multiplier).floor.to_i if !data.key?(nick) then data[nick] = 0 end data[nick] = data[nick] + points m.reply nick + " got it and took " + time_took.to_s + "s! Wins " + points.to_s + " points! They have " + data[nick].to_s + " total points now!" end end if someone_won == false then m.reply "Looks like no one got it! Better luck next time!" end set_data('trevias', data) trev_guesses = {} trev_running = false trev_answers_running = false else trev_running = false trev_answers_running = false #just in case m.reply "idk I failed to work I am sorry :(" end end end on :channel, /^([abcd])$/i do |m, a| if trev_answers_running == true then nick = m.user.nick # check if nick exists in hash... if not add it. if trev_guesses.has_key? nick then # m.reply "lmao u already guessed!" else if real_answer.downcase == a.downcase then trev_guesses[nick] = Time.now.to_i else trev_guesses[nick] = 0 end m.reply nick + " is locked in with " + a + "!" end end end on :channel, /^!trevscores$/ do |m| scores = get_data('trevias') scores = scores.sort_by { |name, s| s} scores_str = "" real_scores = [] scores.each do |e| real_scores.unshift e end real_scores.each do |e| scores_str = scores_str + "(" + fix_nick(e[0]) + ": " + e[1].to_s + ") " end m.reply scores_str end on :channel, /^!smoke$/ do |m| m.reply " ( )/" m.reply " )(/" m.reply "_________________ ( /)" m.reply "()__)____________)))))" end end bot.start