From f0195cf97aab6b1d28ac76c39c7c4ce63da78ae9 Mon Sep 17 00:00:00 2001 From: Joe Rayhawk Date: Mon, 14 Mar 2022 08:13:03 -0700 Subject: crystal/irc.cr: irresponsible omnibus commit --- crystal/irc.cr | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 166 insertions(+), 19 deletions(-) (limited to 'crystal') diff --git a/crystal/irc.cr b/crystal/irc.cr index 96d4090..ceddd56 100644 --- a/crystal/irc.cr +++ b/crystal/irc.cr @@ -3,6 +3,7 @@ require "http" require "uri" require "twitcr" require "json" +require "crystal_mpd" STDOUT.sync = true @@ -17,8 +18,19 @@ settings["home"] = Path.home.to_s end end +snifflast = Int64.new(0) + client = Twitcr::Client.new( settings ) +def urbandef( term : String ) + #http://api.urbandictionary.com/v0/define?term=waifu + client = HTTP::Client.new( "api.urbandictionary.com" ) + response = client.exec( "GET", "/v0/define?term=" + URI.encode_www_form( term ) ) + puts response.status_code + json = JSON.parse( response.body ) + return json["list"][0]["definition"].to_s.gsub( /[\[\]]/, "" ).gsub( /\n/, "" ) +end + def ircmsg( home : String, channel : String, msg : String) if msg !~ /(\r|\n)/ sock = Socket.unix @@ -43,7 +55,6 @@ def effectsmsg( msg : String ) sock.connect Socket::UNIXAddress.new( ENV["HOME"] + "/.effects.sock" ) sock.puts( msg ) sock.close - puts "attempted to use glmatrix" rescue ex puts ex end @@ -115,7 +126,7 @@ def t2s( settings : Hash(String, String), userdir : String, chatuser : String, t end voices = Hash(String, String).new -File.each_line( settings["home"] + "/voicelist" ) do |line| +File.each_line( settings["home"] + "/voicelist.txt" ) do |line| voices[ line.downcase ] = line end @@ -124,21 +135,28 @@ lastvoice = Array(String).new bot = Twitch::IRC::Client.new( nick: "bungmonkey", token: "oauth:" + settings["access_token"], log_mode: true ) bot.tags = [ "membership", "tags", "commands" ] +# Reconnect on IO::Error? + # Create a handler to process incoming messages bot.on_message do |message| + spawn do next unless ( userlogreturn = userlog( settings, message ) ) chatuser, uid, userdir = userlogreturn + if ( chatuser == "pipne" ) && ( ( Time.utc.to_unix - snifflast ) >= 14400 ) + snifflast = Time.utc.to_unix + t2smsg( chatuser + " sniff null" ) + end if ( t2sreturn = t2s( settings, userdir, chatuser, message.params[1] ) ) lastvoice.insert( 0, t2sreturn ) lastvoice = lastvoice[0..4] end - next unless ( ( match = message.params[1].match(/^ *!([A-Za-z]+) (([a-zA-Z0-9 _\:,.&'\/-]|!)+)/) || message.params[1].match(/^ *!([A-Za-z]+)/) ) ) + next unless ( ( match = message.params[1].match(/^ *!([A-Za-z]+) (([a-zA-Z0-9= _\:,.&'\/?;\\\(\)\[\]+\-]|!)+)/) || message.params[1].match(/^ *!([A-Za-z]+)/) ) ) cmd = match[1] own = ( message.tags["room-id"] == message.tags["user-id"] ) vip = ( message.tags["badges"].to_s.matches?( /(^|,)vip\// ) ) mod = ( message.tags["mod"] == "1" ) sub = ( message.tags["subscriber"] == "1" ) - if ( ( cmd == "substitute" ) && ( mod || sub ) ) + if ( ( cmd =~ /^(substitute|voicesub)$/ ) && ( mod || sub ) ) case message.params[1].split( " " ).size when 1 if File.exists?( userdir + "/voicesub" ) @@ -163,6 +181,8 @@ bot.on_message do |message| end end end + elsif ( cmd =~ /^(commands|help)$/ ) + bot.message( "#bungmonkey", "| https://bungmonkey.omgwallhack.org/txt/commands.txt" ) elsif ( ( cmd == "lastvoice" ) && ( mod || sub ) ) unless lastvoice.empty? bot.message( "#bungmonkey", "| Last voices were " + lastvoice.join( ", " ) ) @@ -171,7 +191,7 @@ bot.on_message do |message| end elsif ( ( cmd =~ /^(voices|voicelist)$/ ) && ( mod || sub ) ) bot.message( "#bungmonkey", "| https://bungmonkey.omgwallhack.org/voicelist.txt" ) - elsif ( ( cmd == "voice" ) && ( mod || sub ) ) + elsif ( ( cmd =~ /^(setvoice|voice)$/ ) && ( mod || sub ) ) case message.params[1].split( " " ).size when 1 namesub, voice_setting, voice_output = getvoice( settings, userdir, chatuser ) @@ -194,6 +214,7 @@ bot.on_message do |message| bot.message( "#bungmonkey", "| Voice for #{chatuser} is now #{File.read( userdir + "/voice" )}." ) # TODO: make separate script to print streamelements URLs to client machine else + pp ( match ) bot.message( "#bungmonkey", "| Invalid voice. To see list, use !voices" ) end end @@ -203,13 +224,12 @@ bot.on_message do |message| elsif ( ( cmd =~ /^(status|title)$/ ) && ( mod || own ) ) begin if match[2]? - puts "2 matches" - json = JSON.parse( client.put_channel!( settings["channel_id"].to_u64, status: match[2] ) ) - ircmsg( settings["home"], settings["channel"], "Status is now \"#{ json["status"] }\"") + client.put_channel!( settings["channel_id"].to_u64, title: match[2] ) + json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) ) + ircmsg( settings["home"], settings["channel"], "Title is now \"#{ json["data"][0]["title"] }\"") else - puts "1 matches" json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) ) - ircmsg( settings["home"], settings["channel"], "| Status is currently \"#{ json["status"] }\"") + ircmsg( settings["home"], settings["channel"], "| Title is currently \"#{ json["data"][0]["title"] }\"") end rescue ex ircmsg( settings["home"], settings["channel"], "| An error occurred! " + ex.message.to_s ) @@ -218,20 +238,137 @@ bot.on_message do |message| begin if match[2]? puts "2 matches" - json = JSON.parse( client.put_channel!( settings["channel_id"].to_u64, game: match[2] ) ) - ircmsg( settings["home"], settings["channel"], "Game is now \"#{ json["game"] }\"") + client.put_channel!( settings["channel_id"].to_u64, game: match[2] ) + json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) ) + ircmsg( settings["home"], settings["channel"], "Game is now \"#{ json["data"][0]["game_name"] }\"") else puts "1 matches" json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) ) - ircmsg( settings["home"], settings["channel"], "| Game is currently \"#{ json["game"] }\"") + ircmsg( settings["home"], settings["channel"], "| Game is currently \"#{ json["data"][0]["game_name"] }\"") end rescue ex ircmsg( settings["home"], settings["channel"], "| An error occurred! " + ex.message.to_s ) end elsif ( ( cmd == "urban" ) && ( mod || own || sub || vip ) ) - - elsif ( cmd == "glmatrix" ) + if match[2]? && match[2] =~ /^([a-zA-Z0-9 -])+$/ + definition = urbandef( match[2] ) + ircmsg( settings["home"], settings["channel"], definition[0,400] ) + else + ircmsg( settings["home"], settings["channel"], "| Urban Dictionary search term should consist of letters, numbers, spaces, and/or hyphens." ) + end + elsif ( cmd == "matrix" ) effectsmsg( "overlay glmatrix" ) + elsif ( cmd =~ /juggle|juggler/ ) + effectsmsg( "overlay juggler3d" ) + elsif ( cmd =~ /fireworks|firework/ ) + effectsmsg( "overlay fireworkx" ) + elsif ( cmd == "pipes" ) + if match[2]? && match[2] =~ /^(fast|faster)$/ + effectsmsg( "overlay pipes " + match[2] ) + else + effectsmsg( "overlay pipes" ) + end + elsif ( cmd == "jellyfish" ) + effectsmsg( "overlay hydrostat" ) + elsif ( cmd == "gluten" ) + effectsmsg( "overlay flyingtoasters" ) + elsif ( cmd =~ /^(glsnake|glmatrix|gibson|xmatrix|flyingtoasters|moebiusgears|fireworkx|hydrostat|hypertorus|jigsaw|juggler3d|kaleidocycle|kumppa|molecule|noof|polyhedra)$/ ) + effectsmsg( "overlay " + cmd ) + elsif ( cmd =~ /gltext|cowsay|xcowsay/ ) + if ( match[2]? ) && ( gltextargs = match[2].match( /^([0-9]+) +(.+)$/ ) ) + seconds=UInt64.new( 1 ) + seconds=gltextargs[1].to_u64 + if ( own || mod || vip ) + effectsmsg( "overlay #{cmd} #{match[2]}" ) + puts "matched #{cmd} #{match[2]}" + elsif ( sub ) + if ( seconds > 20 ) + seconds=20 + end + effectsmsg( "overlay #{cmd} #{seconds} #{gltextargs[2]}" ) + puts "matched #{cmd} #{seconds} #{gltextargs[2]}" + else + if ( seconds > 5 ) + seconds=5 + end + effectsmsg( "overlay #{cmd} #{seconds} #{gltextargs[2]}" ) + puts "matched #{cmd} #{seconds} #{gltextargs[2]}" + end + elsif match[2]? && match[2] =~ /^.+$/ + effectsmsg( "overlay #{cmd} #{match[2]}" ) + puts "matched #{cmd} #{match[2]}" + else + effectsmsg( "overlay #{cmd}" ) + puts "failed to match gltext" + end + elsif ( cmd =~ /cow|cowabunga|holycow/ ) + if match[2]? && match[2] =~ /^([0-9])+$/ + effectsmsg( "overlay bouncingcow #{match[2]}" ) + else + effectsmsg( "overlay bouncingcow" ) + end + elsif ( cmd == "overlay" ) + if match[2]? && match[2] =~ /^[a-z]+$/ + ircmsg( settings["home"], settings["channel"], "| overlay requires an argument consisting wholly of lower case characters.") + effectsmsg( "overlay #{match[2]}" ) + else + end + elsif ( cmd == "hackerman" ) + ircmsg( settings["home"], settings["channel"], "| https://bungmonkey.omgwallhack.org/img/hackerman.jpg" ) + elsif ( cmd =~ /^(songrequest|sr)$/ ) && match[2]? + puts ("song detected: #{match[2]}") + if ( ( match[2] =~ /list=/ ) && ( match[2] !~ /v=/ ) ) + ircmsg( settings["home"], settings["channel"], "| Lists are not accepted.\n" ) + elsif Process.run( "sraddsong.sh", {match[2]} ) + m = MPD::Client.new + currentsong = m.currentsong + if ( currentsong ) && ( currentsong["file"].to_s == "http://music/music.ogg" ) + m.next + end + if ( status = m.status ) && ( playlistinfo = m.playlistinfo ) + ircmsg( settings["home"], settings["channel"], "| " + playlistinfo[ status["playlistlength"].to_i - 1 ]["file"].to_s + " added in position " + status["playlistlength"].to_s ) + else + ircmsg( settings["home"], settings["channel"], "| A failure occured." ) + end + m.disconnect + else + end + elsif ( cmd =~ /^current(|song)$/ ) + m = MPD::Client.new + if ( currentsong = m.currentsong ) + ircmsg( settings["home"], settings["channel"], "| Currently playing: " + currentsong["file"].to_s ) + else + ircmsg( settings["home"], settings["channel"], "| A failure occured." ) + end + m.disconnect + elsif ( cmd =~ /^seek$/ ) + if ( ( match[2] ) && ( match[2] =~ /([+-]|)[0-9]/ ) ) + m = MPD::Client.new + m.seekcur( match[2] ) + if ( ( musicstatus = m.status ) && ( pos = musicstatus["elapsed"].to_f.to_u64 ) ) + min=( pos / 60 ).to_u64 + sec=( pos % 60 ).to_u64 + ircmsg( settings["home"], settings["channel"], "| " + sprintf( "2%d:2%d", min, sec ) ) + else + ircmsg( settings["home"], settings["channel"], "| An error occurred. " ) + end + m.disconnect + else + ircmsg( settings["home"], settings["channel"], "| Seek requires an argument of an absolute position in integer number of seconds, or a relative position in in signed integer number of seconds such as +60" ) + end + elsif ( cmd =~ /^next(|song)$/ ) + m = MPD::Client.new + m.next + if ( status = m.status ) && ( status["playlistlength"].to_i > 0 ) + if ( currentsong = m.nextsong ) + ircmsg( settings["home"], settings["channel"], "| Currently playing: " + currentsong["file"].to_s ) + else + ircmsg( settings["home"], settings["channel"], "| A failure occured." ) + end + else + ircmsg( settings["home"], settings["channel"], "| Playlist is now empty." ) + end + m.disconnect elsif ( cmd == "followage" ) begin if match[2]? @@ -257,16 +394,26 @@ bot.on_message do |message| ircmsg( settings["home"], settings["channel"], "An error occurred! " + ex.message.to_s ) end end - -rescue ex - pp ex + end end + rooms = Array( String ).new rooms = [ "#bungmonkey", "kr3wzz" ] +while true + begin # Connect to Twitch -bot.run( rooms.map{ | room | room.sub( /^#/, "") } ) + bot.run( rooms.map{ | room | room.sub( /^#/, "") } ) + rescue ex : IO::Error + pp ex + # loop to reconnect + rescue ex + pp ex + exit 1 + end +end + # FastIRC::Message.to_s # @badge-info=;badges=;color=;display-name=BungMonkey;emotes=;flags=;id=20fcc358-4fc3-4919-8229-f1034743d18f;mod=0;room-id=46694819;subscriber=0;tmi-sent-ts=1587876383907;turbo=0;user-id=59895482;user-type= :bungmonkey!bungmonkey@bungmonkey.tmi.twitch.tv PRIVMSG #kr3wzz test -- cgit v1.2.3