summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Rayhawk <jrayhawk+git@omgwallhack.org>2024-02-26 18:34:17 -0800
committerJoe Rayhawk <jrayhawk@fairlystable.org>2024-02-27 03:14:39 -0800
commit545d60e306e29b39a58f4467b799d55f1b82b854 (patch)
tree244c2629a8863a2473b446eb355f281c386da9f7
parente04324d824a2e427c7229bd6b58006a26e16202f (diff)
downloadtwitchtools-545d60e306e29b39a58f4467b799d55f1b82b854.tar.gz
twitchtools-545d60e306e29b39a58f4467b799d55f1b82b854.zip
crystal/tcpsocket.cr: add OptionsParser
-rw-r--r--crystal/tcpsocket.cr467
1 files changed, 274 insertions, 193 deletions
diff --git a/crystal/tcpsocket.cr b/crystal/tcpsocket.cr
index c9cdf84..8194eb6 100644
--- a/crystal/tcpsocket.cr
+++ b/crystal/tcpsocket.cr
@@ -10,10 +10,13 @@ require "crystal_mpd"
require "obswebsocket"
require "yaml"
require "bungmobott"
+require "file_utils"
+require "option_parser"
STDOUT.sync = true
STDOUT.flush_on_newline = true
+# Convenience mixins
struct Nil
def as_s?
self
@@ -40,6 +43,25 @@ class OpenSSL::SSL::Socket::Client
end
end
+macro send_and_log( ifc, value )
+ puts( "#{Fiber.current.name} tx {{ifc}}: #{{{value}}}" )
+ {{ifc}}.send( {{value}} )
+end
+
+# IRC say
+macro say( service, channel, text )
+ case {{service}}
+ when "twitch"
+ send_and_log( twitchircifc, { "#" + {{channel}}, {{text}} } )
+ when "gamesurge"
+ send_and_log( gamesurgeircifc, { "#" + {{channel}}, {{text}} } )
+ when "twitch_remote"
+ send_and_log( bbscliifc, "say twitch " + {{text}} )
+ when "gamesurge_remote"
+ send_and_log( bbscliifc, "say gamesurge " + {{text}} )
+ end
+end
+
# Say() in all available primary channels
macro say_all_self_chan( text )
if fibers["Twitch::IRC"]?
@@ -55,21 +77,6 @@ macro say_all_self_chan( text )
end
end
-# IRC say
-macro say( service, channel, text )
-#def say( ipc : Channel( Tuple( String, String ) ), channel : String, text : String )
- case {{service}}
- when "twitch"
- twitchircipc.send( { "#" + {{channel}}, {{text}} } )
- when "gamesurge"
- ircipc.send( { "#" + {{channel}}, {{text}} } )
- when "twitch_remote"
- bbscliipc.send( "say twitch " + {{text}} )
- when "gamesurge_remote"
- bbscliipc.send( "say gamesurge " + {{text}} )
- end
-end
-
macro testrefuser2uid( path )
{% if flag?(:windows) %}
File.exists?( {{path}} ) && ( File.read( {{ path }} ) =~ /^[0-9]+$/ )
@@ -113,9 +120,34 @@ rescue exio : IO::Error
end
configfile = Path[configdir + "config.txt"].normalize
-if ARGV.size >= 1
- configfile = Path[ ARGV[0] ].normalize
+if File.exists?( File.expand_path( "config.txt" ) )
+ configfile = Path[File.expand_path( "config.txt" )].normalize
+end
+
+secretsfile = Path[ configdir + "secrets.txt" ].normalize
+if File.exists?( File.expand_path( "secrets.txt" ) )
+ secretsfile = Path[File.expand_path( "secrets.txt" )].normalize
end
+
+OptionParser.parse do |parser|
+ parser.banner = "Usage: #{PROGRAM_NAME} (arguments...)"
+ parser.on("-c FILE", "--config=FILE", "YAML configuration file") { |file| configfile = Path[file].normalize }
+ parser.on("-s FILE", "--secrets=FILE", "YAML secrets file") { |file| secretsfile = Path[file].normalize }
+ {% if flag?(:windows) %}
+ parser.on("--install-mss-voices", "Download and install Microsoft Speech Services voices") do
+ t2s_mss_voice_install()
+ end
+ {% end %}
+ parser.on("-h", "--help", "Show help") do
+ puts( parser )
+ exit
+ end
+ parser.invalid_option do |flag|
+ STDERR.puts "ERROR: #{flag} is not a valid option."
+ STDERR.puts parser
+ end
+end
+
puts configfile
if File.exists?( configfile )
@@ -144,10 +176,6 @@ if ( config.join_channels && ! config.join_channels.not_nil!.yaml_unmapped.empty
ppe config.join_channels.not_nil!.yaml_unmapped
end
-secretsfile = Path[ configdir + "secrets.txt" ].normalize
-if ARGV.size >= 2
- secretsfile = Path[ ARGV[1] ].normalize
-end
if File.exists?( secretsfile )
secrets = BungmoBott::Secrets.from_yaml( File.read( secretsfile ) )
@@ -260,7 +288,7 @@ if ( mss || gcloud || aws ) && config.voice_list
text2speech = true
if File.exists?( config.voice_list.not_nil! )
File.read( config.voice_list.not_nil! ).strip.split( "\n" ).each do |voice|
- voices[voice.downcase] = voice.strip
+ voices[voice.strip.downcase] = voice.strip
end
#else
#regeneratevoicelist()
@@ -271,36 +299,34 @@ end
lastvoice = Array(String).new
-# channel message subscriptions: { service, chan } => [ client, client ]
-#channelsubs = Hash( Tuple( String, String ), Array( OpenSSL::SSL::Socket::Server | Channel( Tuple( String, FastIRC::Message ) ) ) ).new
+# Inter-Fiber Communication Channels
+# BungmoBott::Socket IRC channel subscriptions: { { service, chan } => [ client, client ] }
channelsubs = Hash( Tuple( String, String ), Array( OpenSSL::SSL::Socket::Server) ).new
# Unencrypted
#connections = Hash(TCPSocket, Hash(String, String)).new
# Encrypted
connections = Hash(OpenSSL::SSL::Socket::Server, Hash(String, String)).new
-ircipc = Channel( Tuple( String, String ) ).new
-# commandircipc: serv, chan, user, msg
-commandircipc = Channel( Tuple( String, FastIRC::Message ) ).new
-commandipc = Channel( String ).new
-# t2sipc: voice, text
-t2sipc = Channel( Tuple( String, String ) ).new
-gamesurgeircipc = Channel( Tuple( String, String ) ).new
-twitchircipc = Channel( Tuple( String, String ) ).new
-twitchapiipc = Channel( Tuple( String, String | UInt64 ) ).new
-bbscliipc = Channel( String ).new
-bbssrvipc = Channel( String ).new
+gamesurgeircifc = Channel( Tuple( String, String ) ).new
+# commandifc: serv, chan, user, msg
+commandifc = Channel( Tuple( String, FastIRC::Message ) ).new
+# t2sifc: voice, text
+t2sifc = Channel( Tuple( String, String ) ).new
+twitchircifc = Channel( Tuple( String, String ) ).new
+twitchapiifc = Channel( Tuple( String, String | UInt64 ) ).new
+bbscliifc = Channel( String ).new
+# currently unused
+#bbssrvifc = Channel( String ).new
waitgroup = Channel( String ).new
-
-fiberipc = Channel( Fiber ).new
+fiberifc = Channel( Fiber ).new
fibers = Hash( String, Fiber ).new
evchan = Channel( JSON::Any ).new
obs : Nil | OBS::WebSocket = nil
if config.obs_connect
obs = OBS::WebSocket.new( "ws://#{config.obs_connect}/", secrets.obs_password )
- # OBS event thread
- spawn name: "obs_event_thread" do
- fiberipc.send( Fiber.current )
+ # OBS event fiber
+ spawn name: "OBS::WebSocket" do
+ fiberifc.send( Fiber.current )
obs.scenes["meta-foreground"].to_h.each_key do | key |
if key =~ /^media-temporary-/
obs.inputs[key].delete!
@@ -309,7 +335,7 @@ if config.obs_connect
obs.eventsub_add( evchan )
while json = evchan.receive
# A Fiber.yield occurs after this to make sure "json" doesn't get overwritten before we can use it.
- spawn do
+ spawn name: "OBS::WebSocket event" do
d = json # Copy *immediately*
case d["eventType"].as_s
when "CurrentProgramSceneChanged"
@@ -355,8 +381,9 @@ if config.obs_connect
pp ex
ensure
waitgroup.send( Fiber.current.name.not_nil! )
+ puts( "#{Fiber.current.name} tx waitgroup: #{Fiber.current.name}" )
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
@@ -398,16 +425,18 @@ def urbandef( term : String )
end
# FIXME: maybe break this out into separate functions later
-def getvoice( voicelist : String, userdir : String, chatuser : String )
- if File.exists?( userdir + "/voice" )
- voice_output = File.read( userdir + "/voice" ).strip
+def getvoice( voicelist : String, userdir : Path, chatuser : String )
+ voicefile = Path.new( userdir, "voice" ).normalize
+ voicenamesubfile = Path.new( userdir, "voicesub" ).normalize
+ if File.exists?( voicefile )
+ voice_output = File.read( voicefile ).strip
voice_setting = voice_output
else
voice_output = File.read( voicelist ).strip.split( "\n" ).sample( 1 )[0].strip
voice_setting = "random"
end
- if File.exists?( userdir + "/voicesub" )
- namesub = File.read( userdir + "/voicesub" ).strip
+ if File.exists?( voicenamesubfile )
+ namesub = File.read( voicenamesubfile ).strip
else
namesub = chatuser
end
@@ -417,7 +446,7 @@ end
def generatevoicelistaws( )
voices = Array(String).new
JSON.parse( `aws polly describe-voices` )["Voices"].as_a.each do | v |
- voices.push( v["Id"].as_s )
+ voices.push( v["Id"].as_s.strip )
end
return voices
end
@@ -430,7 +459,7 @@ def generatevoicelistgcs( gcloud_token : String )
response = HTTP::Client.exec( "GET", "https://texttospeech.googleapis.com/v1/voices?key=#{gcloud_token}", headers, nil, tls: ssl_context )
JSON.parse( response.body )["voices"].as_a.each do | v |
STDERR.puts( "#{v["naturalSampleRateHertz"]} #{v["languageCodes"]} #{v["name"]}" )
- voices.push( v["name"].as_s )
+ voices.push( v["name"].as_s.strip )
end
return voices
end
@@ -452,9 +481,13 @@ def generatevoicelistwin()
v = v.gsub(/ Desktop$/, "")
v = v.gsub( " ", "-" )
if v =~ /[A-Za-z0-9]-[A-Za-z0-9]/
- voices.push( v )
+ voices.push( v.strip )
end
end
+ if ( voices.size < 10 )
+ puts( "WARNING: Microsoft Speech Service voice count is suspiciously low." )
+ puts( "You may want to visit https://www.microsoft.com/en-us/download/details.aspx?id=27224" )
+ end
return voices
end
{% end %}
@@ -467,21 +500,23 @@ end
macro regeneratevoicelist()
if aws
generatevoicelistaws().each do | voice |
- voices[ voice.downcase ] = voice.strip
+ voices[ voice.downcase ] = voice
end
elsif fibers["BungmoBott::Socket client"]?
- bbscliipc.send( "awsvoicelist" )
+ bbscliifc.send( "awsvoicelist" )
+ puts( "#{Fiber.current.name} tx bbscliifc: awsvoicelist" )
end
if secrets.gcloud_token
generatevoicelistgcs( secrets.gcloud_token.not_nil! ).each do | voice |
- voices[ voice.downcase ] = voice.strip
+ voices[ voice.downcase ] = voice
end
elsif fibers["BungmoBott::Socket client"]?
- bbscliipc.send( "gcsvoicelist" )
+ bbscliifc.send( "gcsvoicelist" )
+ puts( "#{Fiber.current.name} tx bbscliifc: gcsvoicelist" )
end
{% if flag?(:windows) %}
generatevoicelistwin().each do | voice |
- voices[ voice.downcase ] = voice.strip
+ voices[ voice.downcase ] = voice
end
{% end %}
writevoices()
@@ -499,14 +534,14 @@ def file_list( path : String ) : Array( String )
end
# TODO: add piping into mpv on POSIX
-def playaudiodata( tempdir, data : Bytes )
- filepath="#{tempdir}#{Time.utc.to_unix_ms}.mp3"
+def playaudiodata( tempdir : Path | String, data : Bytes )
+ filepath=Path.new( tempdir, "#{Time.utc.to_unix_ms}.mp3" ).normalize
File.write( filepath, data )
playaudiofile( filepath )
File.delete( filepath )
end
-def playaudiofile( filepath : String )
+def playaudiofile( filepath : Path )
{% if flag?(:windows) %}
p = Process.new(
"powershell.exe",
@@ -535,36 +570,36 @@ def playaudiofile( filepath : String )
end
# user, uid, userdir,lastseen, oldname
-def userlog( config : BungmoBott::Config, service : String, message : FastIRC::Message ) : Tuple( String, UInt64 | Nil, String, Int32 | Int64, String | Nil ) | Nil
+def userlog( config : BungmoBott::Config, service : String, message : FastIRC::Message ) : Tuple( String, UInt64 | Nil, Path, Int32 | Int64, String | Nil ) | Nil
unless ( ( prefix = message.prefix ) && ( chatuser = prefix.source ) )
return nil
end
if service =~ /^twitch/
if ( uid = message.tags["user-id"]? )
- basedir = config.statedir + "/twitch"
- userdir = basedir + "/uids/" + uid
+ basedir = Path.new( config.statedir, "twitch" ).normalize
+ userdir = Path.new( basedir, "uids", uid ).normalize
if File.directory?( userdir )
lastseen = File.info( userdir ).modification_time.to_unix
else
lastseen = 0
end
- Dir.mkdir_p( basedir + "/names" )
- Dir.mkdir_p( userdir + "/names" )
+ Dir.mkdir_p( Path.new( basedir, "names" ).normalize )
+ Dir.mkdir_p( Path.new( userdir, "names" ).normalize )
File.touch( userdir )
- unless testrefuser2uid( userdir + "/names/" + chatuser )
+ unless testrefuser2uid( Path.new( userdir, "names", chatuser ).normalize )
oldname = nil
datelatest = Time::UNIX_EPOCH
- Dir.each_child( userdir + "/names/" ) do |name|
- namedate = File.info( userdir + "/names/" + name ).modification_time
+ Dir.each_child( Path.new( userdir, "names" ).normalize ) do |name|
+ namedate = File.info( Path.new( userdir, "names", name ).normalize ).modification_time
if namedate > datelatest
oldname = name
datelatest = namedate
end
end
- genrefuser2uid( userdir + "/names/" + chatuser, uid, 3 )
+ genrefuser2uid( Path.new( userdir, "names", chatuser ).normalize, uid, 3 )
end
- unless testrefuser2uid( basedir + "/names/" + chatuser )
- genrefuser2uid( basedir + "/names/" + chatuser, uid, 1 )
+ unless testrefuser2uid( Path.new( basedir, "names", chatuser ).normalize )
+ genrefuser2uid( Path.new( basedir, "names", chatuser ).normalize, uid, 1 )
end
uid = uid.to_u64
else # No uid?
@@ -572,8 +607,8 @@ def userlog( config : BungmoBott::Config, service : String, message : FastIRC::M
return( nil )
end
elsif( service =~ /^gamesurge/ )
- basedir = config.statedir + "/gamesurge"
- userdir = basedir + "/names/" + chatuser
+ basedir = Path.new( config.statedir, "gamesurge" ).normalize
+ userdir = Path.new( basedir, "names", chatuser ).normalize
if File.directory?( userdir )
lastseen = File.info( userdir ).modification_time.to_unix
File.touch( userdir )
@@ -592,6 +627,42 @@ rescue ex
return nil
end
+{% if flag?(:windows) %}
+def t2s_mss_voice_install()
+ puts "Downloading Microsoft Speech Services voice index"
+ puts "https://www.microsoft.com/en-us/download/details.aspx?id=27224"
+ ENV["TEMP"]? || ( STDERR.puts "TEMP environment variable undefined" && exit 2 )
+ ssl_context = OpenSSL::SSL::Context::Client.new
+ response = HTTP::Client.exec( "GET", "https://www.microsoft.com/en-us/download/details.aspx?id=27224", tls: ssl_context )
+ if ( response.status_code == 200 )
+ response.body.split("\"").select(/^https.+MSSpeech.+\.msi$/).each do | msi_url |
+ puts "Downloading: #{msi_url}"
+ ssl_context = OpenSSL::SSL::Context::Client.new
+ response = HTTP::Client.exec( "GET", msi_url, tls: ssl_context )
+ if ( ( response.status_code == 200 ) && ( response.content_type == "application/octet-stream" ) && ( match = /^.+\/(.+msi)$/.match(msi_url) ) )
+ msi_path = Path.new( Path[ENV["LOCALAPPDATA"]].normalize, "Temp", match[1] )
+ puts "Writing : #{msi_path}"
+ File.write( msi_path, response.body )
+ puts "Installing : #{msi_path}"
+ p = Process.new(
+ "msiexec", [ "/i", msi_path.normalize.to_s ], output: STDOUT, error: STDERR,
+ )
+ p.wait
+ puts "Deleting : #{msi_path}"
+ File.delete( msi_path )
+ else
+ end
+ end
+ else
+ puts response.status_code
+ pp response.headers
+ puts response.body
+ exit 1
+ end
+ exit
+end
+{% end %}
+
# Currently only used in flag?(:unix)
def t2smsg( config : BungmoBott::Config, msg : String)
if File.exists?( config.rundir + "/.t2s.sock" )
@@ -604,7 +675,7 @@ rescue ex
pp ex
end
-def t2s( t2sipc : Channel, config : BungmoBott::Config, userdir : String, chatuser : String, text : String )
+def t2s( t2sifc : Channel, config : BungmoBott::Config, userdir : Path, chatuser : String, text : String )
if ( text !~ /^ *(!|\|)/ )
namesub, voice_setting, voice = getvoice( config.voice_list.not_nil!, userdir, chatuser )
subs = Array( Tuple( Regex, String ) ){
@@ -652,7 +723,8 @@ def t2s( t2sipc : Channel, config : BungmoBott::Config, userdir : String, chatus
text = text.gsub( subtuple[0], subtuple[1] )
end
#{% if flag?(:windows) %}
- t2sipc.send( { voice, "#{namesub} #{text}" } )
+ t2sifc.send( { voice, "#{namesub} #{text}" } )
+ puts( "#{Fiber.current.name} tx t2sifc: #{voice}, #{namesub} #{text}" )
#{% else %}
# t2smsg( config, "#{voice} #{namesub} #{text}" )
#{% end %}
@@ -663,12 +735,13 @@ def t2s( t2sipc : Channel, config : BungmoBott::Config, userdir : String, chatus
end
spawn name: "command_dispatch" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
loop do
- while commandmsg : Tuple( String, FastIRC::Message ) = commandircipc.receive
- spawn do
+ while commandmsg : Tuple( String, FastIRC::Message ) = commandifc.receive
+ spawn name: "command_dispatch ifc rx" do
service = String.new
local_commandmsg = commandmsg
+ puts( "#{Fiber.current.name}: #{local_commandmsg}" )
if local_commandmsg.is_a?( Tuple( String, FastIRC::Message ) ) && local_commandmsg[0].is_a?( String )
service = local_commandmsg[0]
message : FastIRC::Message = local_commandmsg[1]
@@ -676,7 +749,8 @@ spawn name: "command_dispatch" do
unless service.empty?
if config.bungmobott_listen && ! ircchannel.empty?
# Do we send to the bungmobott_listen fiber? Probably no need.
- #bbssrvipc.send( "#{message.to_s}" )
+ #bbssrvifc.send( "#{message.to_s}" )
+ #puts( "#{Fiber.current.name} tx bbssrvifc: #{message.to_s}" )
if channelsubs[ { service, ircchannel } ]?
channelsubs[ { service, ircchannel } ].each do |channelsub|
if channelsub.is_a? OpenSSL::SSL::Socket::Server
@@ -688,13 +762,18 @@ spawn name: "command_dispatch" do
next unless ( userlogreturn = userlog( config, service, message ) )
chatuser, uid, userdir, lastseen, oldname = userlogreturn
+ pp userlogreturn
# Have we seen this user lately?
if ( ( Time.utc.to_unix - lastseen ) >= 14400 )
if service =~ /^twitch/ && uid.is_a?( UInt64 )
- twitchapiipc.send( { "get_user", uid.to_s } )
- twitchapiipc.send( { "get_followers", uid.to_s } )
+ if twitchapi
+ puts( "#{Fiber.current.name} tx twitchapiifc: get_user, #{uid}" )
+ twitchapiifc.send( { "get_user", uid.to_s } )
+ puts( "#{Fiber.current.name} tx twitchapiifc: get_followers, #{uid}" )
+ twitchapiifc.send( { "get_followers", uid.to_s } )
+ end
prevnames = Array( String ).new
- if ( prevnames = Dir.children( "#{userdir}/names" ) ) && ( prevnames.size > 1 )
+ if ( prevnames = Dir.children( Path.new( userdir, "names" ).normalize ) ) && ( prevnames.size > 1 )
prevnames.delete( chatuser )
puts "\033[38;5;14m#{chatuser} previous names: #{prevnames.join(", ")}\033[0m"
end
@@ -703,8 +782,8 @@ spawn name: "command_dispatch" do
# This file hierarchy gets manually set up for now.
# Maybe someday let mods do something like:
# !fanfare add pipne https://pip.ne/sniff.mp3
- if File.exists?( userdir + "/fanfare/" )
- playaudiofile( userdir + "/fanfare/" + Dir.children( userdir + "/fanfare/" ).sample )
+ if File.exists?( Path.new( userdir, "fanfare" ).normalize )
+ playaudiofile( Path.new( userdir, "fanfare", Dir.children( Path.new( userdir, "fanfare" ).normalize ).sample ).normalize )
end
end
# FIXME: Generalize this across Twitch/IRC? Mods are +o? vips are +v?
@@ -757,9 +836,8 @@ spawn name: "command_dispatch" do
# As a matter of policy:
# BungmoBott::Socket clients can only say things in their own authenticated channel
# Direct IRC clients can say things whereever.
- # FIXME: this needs to be service-specific
if ( service =~ /^twitch/ && exec.func == "detect_rename" && uid.is_a?( UInt64 ) )
- unless oldname.is_a?( String )
+ if oldname.is_a?( String )
say( service, config.chat_user.not_nil!.twitch.not_nil!, "Rename detected: #{uid}: #{oldname} -> #{chatuser}" )
end
next
@@ -851,9 +929,11 @@ spawn name: "command_dispatch" do
end
end
if text2speech
+ voicenamesubfile = Path.new( userdir, "voicesub" ).normalize
+ voicefile = Path.new( userdir, "voice" ).normalize
if ( exec.func == "text_to_speech" )
puts "Exec-ing text_to_speech"
- if ( t2sreturn = t2s( t2sipc, config, userdir, chatuser, message.params[1] ) )
+ if ( t2sreturn = t2s( t2sifc, config, userdir, chatuser, message.params[1] ) )
lastvoice.insert( 0, t2sreturn.strip )
lastvoice = lastvoice[0..4]
end
@@ -884,8 +964,8 @@ spawn name: "command_dispatch" do
if ( match = / ([a-zA-Z0-9-_]+)/.match( message.params[1] ) )
voice = match[1].downcase
if voice =~ /disabled|null|disable|none|random/
- if File.exists?( userdir + "/voice" )
- File.delete( userdir + "/voice" )
+ if File.exists?( voicefile )
+ File.delete( voicefile )
say( service, ircchannel, "| Voice for #{chatuser} is now random." )
else
say( service, ircchannel, "| Voice for #{chatuser} is already random." )
@@ -893,9 +973,9 @@ spawn name: "command_dispatch" do
elsif voices.has_key?( voice.downcase )
csvoice = voices[voice]
Dir.mkdir_p( userdir )
- File.write( userdir + "/voice", csvoice )
+ File.write( voicefile, csvoice )
pp userdir
- say( service, ircchannel, "| Voice for #{chatuser} is now #{File.read( userdir + "/voice" ).strip}." )
+ say( service, ircchannel, "| Voice for #{chatuser} is now #{File.read( voicefile ).strip}." )
else
pp ( match )
say( service, ircchannel, "| Invalid voice. To see list, use !voices" )
@@ -907,8 +987,8 @@ spawn name: "command_dispatch" do
end
if ( exec.func == "tts_name_get" )
puts "Exec-ing " + exec.func
- if File.exists?( userdir + "/voicesub" )
- say( service, ircchannel, "| Current name substitution is \"#{File.read( userdir + "/voicesub" ).strip}\"." )
+ if File.exists?( voicenamesubfile )
+ say( service, ircchannel, "| Current name substitution is \"#{File.read( voicenamesubfile ).strip}\"." )
else
say( service, ircchannel, "| Current name substitution is disabled." )
end
@@ -919,16 +999,16 @@ spawn name: "command_dispatch" do
pp match[1]
voicesub = match[1].downcase
if voicesub =~ /^(disabled|null|disable|none)$/
- if File.exists?( userdir + "/voicesub" )
- File.delete( userdir + "/voicesub" )
+ if File.exists?( voicenamesubfile )
+ File.delete( voicenamesubfile )
say( service, ircchannel, "| Name substitution for #{chatuser} is now disabled." )
else
say( service, ircchannel, "| Name substitution for #{chatuser} is already disabled." )
end
else
Dir.mkdir_p( userdir )
- File.write( userdir + "/voicesub", voicesub )
- say( service, ircchannel, "| Name substitution for #{chatuser} is now \"#{File.read( userdir + "/voicesub" ).strip}\"." )
+ File.write( voicenamesubfile, voicesub )
+ say( service, ircchannel, "| Name substitution for #{chatuser} is now \"#{File.read( voicenamesubfile ).strip}\"." )
end
end
next
@@ -986,62 +1066,62 @@ spawn name: "command_dispatch" do
# # download url, verify mimetype with libmagic, duplicate existing medialoop source, change "file" SourceSetting
# elsif ( ( cmd =~ /^inputsetting(|s)$/ ) && ( mod || own || vip ) )
# if ( match[2]? && match[2] =~ /^[a-zA-Z0-9-_]+$/ )
-# ircipc.send( { "##{settings["channel"]}", "| #{obs.inputs[match[2]].settings.to_h.to_s} " } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| #{obs.inputs[match[2]].settings.to_h.to_s} " } )
# end
# elsif ( cmd == "create" && ( mod || own || vip ) )
# if ( match[2]? ) && ( match[2] =~ /^([\/a-zA-Z0-9-_]+)/ )
# obstemporarymediacreate( obs, "meta-foreground", match[2], "C:/cygwin64/home/user/effects/#{match[2]}.webm" )
# else
-# ircipc.send( { "##{settings["channel"]}", "Must provide at least one source name as argument." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "Must provide at least one source name as argument." } )
# end
# # FIXME: This is only half-implemented
# elsif ( ( cmd =~ /^(user)$/ ) && ( mod || own ) )
# if match[2]? && match[2] =~ /[a-z][a-z0-9_]+/
-# twitchapiipc.send( { "get_user", match[2] } )
+# twitchapiifc.send( { "get_user", match[2] } )
# elsif match[2]? && match[2] =~ /[0-9]+/
-# twitchapiipc.send( { "get_user", match[2].to_u64 } )
+# twitchapiifc.send( { "get_user", match[2].to_u64 } )
# else
-# twitchapiipc.send( { "get_user", settings["channel_id"].to_u64 } )
+# twitchapiifc.send( { "get_user", settings["channel_id"].to_u64 } )
# end
# elsif ( ( cmd =~ /^(status|title)$/ ) && ( mod || own ) )
# if match[2]?
# client.put_channel!( settings["channel_id"].to_u64, title: match[2] )
# json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) )
-# ircipc.send( { "##{settings["channel"]}", "Title is now \"#{ json["data"][0]["title"] }\""} )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "Title is now \"#{ json["data"][0]["title"] }\""} )
# else
# json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) )
-# ircipc.send( { "##{settings["channel"]}", "| Title is currently \"#{ json["data"][0]["title"] }\""} )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Title is currently \"#{ json["data"][0]["title"] }\""} )
# end
# elsif ( ( cmd =~ /^(game|category)$/ ) && ( mod || own ) )
# if match[2]?
# puts "2 matches"
# client.put_channel!( settings["channel_id"].to_u64, game: match[2] )
# json = JSON.parse( client.get_channel( settings["channel_id"].to_u64 ) )
-# ircipc.send( { "##{settings["channel"]}", "Game is now \"#{ json["data"][0]["game_name"] }\""} )
+# gamesurgeircifc.send( { "##{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 ) )
-# ircipc.send( { "##{settings["channel"]}", "| Game is currently \"#{ json["data"][0]["game_name"] }\""} )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Game is currently \"#{ json["data"][0]["game_name"] }\""} )
# end
# elsif ( ( cmd == "urban" ) && ( mod || own || sub || vip ) )
# if match[2]? && match[2] =~ /^([a-zA-Z0-9 -])+$/
# definition = urbandef( match[2] )
-# ircipc.send( { "##{settings["channel"]}", definition[0,400] } )
-# t2s( t2sipc, settings, userdir, chatuser, definition[0,400] )
+# gamesurgeircifc.send( { "##{settings["channel"]}", definition[0,400] } )
+# t2s( t2sifc, settings, userdir, chatuser, definition[0,400] )
# else
-# ircipc.send( { "##{settings["channel"]}", "| Urban Dictionary search term should consist of letters, numbers, spaces, and/or hyphens." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Urban Dictionary search term should consist of letters, numbers, spaces, and/or hyphens." } )
# end
# elsif ( cmd =~ /^(shout|shoutout)$/ )
# if match[2]? && match[2] =~ /^[a-z]+$/
-# ircipc.send( { "##{settings["channel"]}", "| Go check out twitch.tv/#{match[2]}"} )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Go check out twitch.tv/#{match[2]}"} )
# effectsmsg( settings, "overlay gltext 5 Go follow #{match[2]}" )
# else
-# ircipc.send( { "##{settings["channel"]}", "| Missing argument."} )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Missing argument."} )
# end
# elsif ( cmd =~ /^(songrequest|sr)$/ ) && match[2]?
# puts ("song detected: #{match[2]}")
# if ( ( match[2] =~ /list=/ ) && ( match[2] !~ /v=/ ) )
-# ircipc.send( { "##{settings["channel"]}", "| Lists are not accepted.\n" } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Lists are not accepted.\n" } )
# elsif Process.run( "sraddsong.sh", {match[2]} )
# m = MPD::Client.new
# currentsong = m.currentsong
@@ -1049,9 +1129,9 @@ spawn name: "command_dispatch" do
# m.next
# end
# if ( status = m.status ) && ( playlistinfo = m.playlistinfo )
-# ircipc.send( { "##{settings["channel"]}", "| " + playlistinfo[ status["playlistlength"].to_i - 1 ]["file"].to_s + " added in position " + status["playlistlength"].to_s } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| " + playlistinfo[ status["playlistlength"].to_i - 1 ]["file"].to_s + " added in position " + status["playlistlength"].to_s } )
# else
-# ircipc.send( { "##{settings["channel"]}", "| A failure occured." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| A failure occured." } )
# end
# m.disconnect
# else
@@ -1059,9 +1139,9 @@ spawn name: "command_dispatch" do
# elsif ( cmd =~ /^current(|song)$/ )
# m = MPD::Client.new
# if ( currentsong = m.currentsong )
-# ircipc.send( { "##{settings["channel"]}", "| Currently playing: " + currentsong["file"].to_s } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Currently playing: " + currentsong["file"].to_s } )
# else
-# ircipc.send( { "##{settings["channel"]}", "| A failure occured." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| A failure occured." } )
# end
# m.disconnect
# elsif ( cmd =~ /^seek$/ )
@@ -1071,25 +1151,25 @@ spawn name: "command_dispatch" do
# if ( ( musicstatus = m.status ) && ( pos = musicstatus["elapsed"].to_f.to_u64 ) )
# min=( pos / 60 ).to_u64
# sec=( pos % 60 ).to_u64
-# ircipc.send( { "##{settings["channel"]}", "| " + sprintf( "2%d:2%d", min, sec ) } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| " + sprintf( "2%d:2%d", min, sec ) } )
# else
-# ircipc.send( { "##{settings["channel"]}", "| An error occurred. " } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| An error occurred. " } )
# end
# m.disconnect
# else
-# ircipc.send( { "##{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" } )
+# gamesurgeircifc.send( { "##{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 )
-# ircipc.send( { "##{settings["channel"]}", "| Currently playing: " + currentsong["file"].to_s } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Currently playing: " + currentsong["file"].to_s } )
# else
-# ircipc.send( { "##{settings["channel"]}", "| A failure occured." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| A failure occured." } )
# end
# else
-# ircipc.send( { "##{settings["channel"]}", "| Playlist is now empty." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| Playlist is now empty." } )
# end
# m.disconnect
# elsif ( cmd == "followage" )
@@ -1100,17 +1180,17 @@ spawn name: "command_dispatch" do
# puts client.user_id( args[0] ).to_s
# puts client.user_id( args[1] ).to_s
# puts json
-# ircipc.send( { "##{settings["channel"]}", "| " + json["data"][0]["followed_at"].to_s } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| " + json["data"][0]["followed_at"].to_s } )
# elsif args[0]?
# json = JSON.parse( client.get_user_follows( from: client.user_id( args[0] ).to_u64 , to: settings["channel_id"].to_u64 ) )
# puts client.user_id( args[0] ).to_s
# puts json
-# ircipc.send( { "##{settings["channel"]}", "| " + json["data"][0]["followed_at"].to_s } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| " + json["data"][0]["followed_at"].to_s } )
# end
# else
# json = JSON.parse( client.get_user_follows( from: uid.to_u64 , to: settings["channel_id"].to_u64 ) )
# puts json
-# ircipc.send( { "##{settings["channel"]}", "| " + json["data"][0]["followed_at"].to_s } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| " + json["data"][0]["followed_at"].to_s } )
# end
# end
rescue ex
@@ -1123,7 +1203,7 @@ spawn name: "command_dispatch" do
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
-fiber = fiberipc.receive
+fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
def ttsgcs( languagecode : String, voice : String, text : String, gcskey : String ) : Bytes
@@ -1146,26 +1226,26 @@ def ttsgcs( languagecode : String, voice : String, text : String, gcskey : Strin
return Base64.decode( json["audioContent"].as_s )
end
-def ttsaws( filepath : String, voice : String, text : String )
+def ttsaws( filepath : Path, voice : String, text : String )
p = Process.new(
"aws", [
"polly", "synthesize-speech",
"--output-format", "mp3",
"--voice-id", voice,
"--text", text,
- filepath
+ filepath.to_s
], output: STDOUT, error: STDERR
)
p.wait
end
-
-# Put tts stuff into the same thread so each playback blocks the next
+# Put tts stuff into the same fiber so each playback blocks the next
spawn name: "text2speech" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
loop do
begin
- while t2stuple = t2sipc.receive
+ while t2stuple = t2sifc.receive
+ puts( "#{Fiber.current.name}: #{t2stuple}" )
voice, text = [ *t2stuple ]
if ( match = voice.match( /^Microsoft-([A-Za-z]+)/ ) )
{% if flag?(:windows) %}
@@ -1196,19 +1276,19 @@ spawn name: "text2speech" do
mp3data = ttsgcs( match[1], voice, text, gcloud_token )
playaudiodata( config.tempdir, mp3data )
elsif fibers["BungmoBott::Socket client"]?
- bbscliipc.send( "gcst2s #{voice} #{text}" )
+ bbscliifc.send( "gcst2s #{voice} #{text}" )
# The rest of this is dealt with in the BungmoBott::Socket client
else
STDERR.puts( "ERROR: google cloud voice requested, but no gcloud_token or BungmoBott::Socket client is available" )
end
else
if aws # AWS polly voices
- filepath="#{config.tempdir}#{Time.utc.to_unix_ms}.mp3"
+ filepath=Path.new( config.tempdir, "#{Time.utc.to_unix_ms}.mp3" ).normalize
ttsaws( filepath, voice, text )
playaudiofile( filepath )
File.delete( filepath )
elsif fibers["BungmoBott::Socket client"]?
- bbscliipc.send( "awst2s #{voice} #{text}" )
+ bbscliifc.send( "awst2s #{voice} #{text}" )
# The rest of this is dealt with in the BungmoBott::Socket client
else
STDERR.puts( "ERROR: aws polly voice requested, but no aws CLI executable or BungmoBott::Socket client is available" )
@@ -1224,19 +1304,20 @@ spawn name: "text2speech" do
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
-fiber = fiberipc.receive
+fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
-# Twitch API request handling thread
+# Twitch API request handling fiber
# FIXME: Implement ratelimiting here.
if twitchclient.is_a?( Twitcr::Client )
spawn name: "Twitcr::Client" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
loop do
begin
- while twitchtuple = twitchapiipc.receive
+ while twitchtuple = twitchapiifc.receive
+ puts( "#{Fiber.current.name}: #{twitchtuple}" )
cmd, arg = [ *twitchtuple ]
case cmd
when "get_user"
@@ -1263,24 +1344,25 @@ if twitchclient.is_a?( Twitcr::Client )
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
if ( secrets.twitch_access_token && config.chat_user.not_nil!.twitch && config.join_channels.not_nil!.twitch )
- # Twitch::IRC thread
+ # Twitch::IRC fiber
spawn name: "Twitch::IRC" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
loop do
begin
bot = Twitch::IRC::Client.new( nick: config.chat_user.not_nil!.twitch.not_nil!, token: "oauth:" + secrets.twitch_access_token.not_nil!, log_mode: true )
bot.tags = [ "membership", "tags", "commands" ]
- # Outgoing IRC message thread
+ # Outgoing IRC message fiber
# "Most IRC servers limit messages to 512 bytes in length, including the trailing CR-LF characters."
# PRIVMSG #channel message\r\n
- spawn do
- while tuple = twitchircipc.receive # why does this need to be a tuple?
+ spawn name: "Twitch::IRC ifc rx" do
+ while tuple = twitchircifc.receive # why does this need to be a tuple?
+ puts( "#{Fiber.current.name}: #{tuple}" )
sizelimit=( 512 - ( tuple[0].size + 12 ) )
if ( tuple[0] == "JOIN" )
if ( tuple[0] =~ regextwitchuser )
@@ -1296,7 +1378,7 @@ if ( secrets.twitch_access_token && config.chat_user.not_nil!.twitch && config.j
# Create a handler to process incoming messages
bot.on_message do |message|
- spawn do
+ spawn name: "Twitch::IRC irc rx" do
#FastIRC::Message(
# @tags={
# "badge-info" => "",
@@ -1338,12 +1420,12 @@ if ( secrets.twitch_access_token && config.chat_user.not_nil!.twitch && config.j
# end
# end
- commandircipc.send( { "twitch", message } )
+ commandifc.send( { "twitch", message } )
pp message
pp message.params
rescue ex
pp ex
- #twitchircipc.send( { "##{config.channel}", "An error occurred! " + ex.message.to_s } )
+ #twitchircifc.send( { "##{config.channel}", "An error occurred! " + ex.message.to_s } )
# Maybe send all error messages out through the API? Have to do channel->client mappings, though.
end
end
@@ -1369,25 +1451,25 @@ if ( secrets.twitch_access_token && config.chat_user.not_nil!.twitch && config.j
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
if ( secrets.gamesurge_password && config.chat_user.not_nil!.gamesurge && config.join_channels.not_nil!.gamesurge )
- # GameSurge::IRC thread
+ # GameSurge::IRC fiber
spawn name: "GameSurge::IRC" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
loop do
begin
bot = GameSurge::IRC::Client.new( nick: config.chat_user.not_nil!.gamesurge.not_nil!, token: secrets.gamesurge_password.not_nil!, log_mode: true )
bot.tags = [ "membership", "tags", "commands" ]
- # Outgoing IRC message thread
+ # Outgoing IRC message fiber
# "Most IRC servers limit messages to 512 bytes in length, including the trailing CR-LF characters."
# PRIVMSG #channel message\r\n
- spawn do
- while tuple = ircipc.receive # why does this need to be a tuple?
- STDERR.puts( "#{Fiber.current} irc rx #{tuple}" )
+ spawn name: "GameSurge::IRC ifc rx" do
+ while tuple = gamesurgeircifc.receive # why does this need to be a tuple?
+ puts( "#{Fiber.current.name}: #{tuple}" )
sizelimit=( 512 - ( tuple[0].size + 12 ) )
if ( tuple[0] == "JOIN" )
# FIXME: Do validation on this
@@ -1400,8 +1482,8 @@ if ( secrets.gamesurge_password && config.chat_user.not_nil!.gamesurge && config
# Create a handler to process incoming messages
bot.on_message do |message|
- spawn do
- commandircipc.send( { "gamesurge", message } )
+ spawn name: "GameSurge::IRC irc rx" do
+ commandifc.send( { "gamesurge", message } )
pp message
pp message.params
# elsif ( cmd =~ /^(create|addsource)/ )
@@ -1413,7 +1495,7 @@ if ( secrets.gamesurge_password && config.chat_user.not_nil!.gamesurge && config
# if uri = URI.parse( args.shift )
# newargs.push( uri.to_s )
# else
-# ircipc.send( { "##{settings["channel"]}", "Unable to parse URL." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "Unable to parse URL." } )
# next
# end
# colormask : UInt32 | Nil = nil
@@ -1435,34 +1517,34 @@ if ( secrets.gamesurge_password && config.chat_user.not_nil!.gamesurge && config
# when /^[0-9]+$/
# direction = arg.to_u16%360
# else
-# ircipc.send( { "##{settings["channel"]}", "Unable to parse color argument." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "Unable to parse color argument." } )
# end
# end
# colormask && newargs.push( "colormask=#{colormask}" )
# direction && newargs.push( "direction=#{direction}" )
# t2smsg( settings, "download #{newargs.join(" ")}" )
# else
-# ircipc.send( { "##{settings["channel"]}", "Must provide at least one URL as argument." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "Must provide at least one URL as argument." } )
# end
# elsif ( cmd =~ /^(delete|remove)/ )
# if ( match[2]? ) && ( match[2] =~ /^([\/a-zA-Z0-9-_]+)$/ )
# obs.inputs["medialoop-bullshit-#{match[2]}"].delete!
# else
-# ircipc.send( { "##{settings["channel"]}", "Must provide at least one bullshit source as argument." } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "Must provide at least one bullshit source as argument." } )
# end
# elsif ( cmd == "bullshit" )
# request = Hash( String, String | Bool ).new
# if ( match[2]? && match[2] =~ /^[a-zA-Z0-9-_]+$/ )
# obs.scenes["meta-meta-foreground"]["meta-bullshit"].toggle!
# else
-# ircipc.send( { "##{settings["channel"]}", "| current sources: #{obs.scenes["meta-bullshit"].to_h.keys.map{ | s | s.sub( /^medialoop-bullshit-/, "") } .join(" ")}" } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| current sources: #{obs.scenes["meta-bullshit"].to_h.keys.map{ | s | s.sub( /^medialoop-bullshit-/, "") } .join(" ")}" } )
# end
# elsif ( cmd =~ /^(system|dxdiag|computer)$/ ) && ( Crystal::DESCRIPTION =~ /linux/ )
-# ircipc.send( { "##{settings["channel"]}", "| https://bungmonkey.omgwallhack.org/tmp/DxDiag.txt" } )
+# gamesurgeircifc.send( { "##{settings["channel"]}", "| https://bungmonkey.omgwallhack.org/tmp/DxDiag.txt" } )
# end
rescue ex
pp ex
- ircipc.send( { "##{config.chat_user.not_nil!.gamesurge.not_nil!}", "An error occurred! " + ex.message.to_s } )
+ gamesurgeircifc.send( { "##{config.chat_user.not_nil!.gamesurge.not_nil!}", "An error occurred! " + ex.message.to_s } )
end
end
@@ -1484,33 +1566,32 @@ if ( secrets.gamesurge_password && config.chat_user.not_nil!.gamesurge && config
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
-# BungmoBott::Socket client thread
+# BungmoBott::Socket client fiber
if config.bungmobott_connect
bbscli_host, bbscli_port = config.bungmobott_connect.not_nil!.split(":")
- puts "spawning BungmoBott::Socket client"
spawn name: "BungmoBott::Socket client" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
loop do
- puts "looping BungmoBott::Socket client"
+ puts "#{Fiber.current.name} connecting #{config.bungmobott_connect}"
user = config.chat_user.not_nil!.twitch.not_nil!
bungmobott_key = secrets.bungmobott_key.not_nil!
ssl_socket = OpenSSL::SSL::Socket::Client.new( TCPSocket.new( bbscli_host, bbscli_port.to_u16 ), OpenSSL::SSL::Context::Client.new )
ssl_socket.sync = true
negotiated = false
- spawn do
+ spawn name: "BungmoBott::Socket client ssl rx" do
while message = ssl_socket.gets
- puts "BungmoBott::Socket cli recv: " + message.gsub( bungmobott_key, "CENSORED" )
+ puts "#{Fiber.current.name}: " + message.gsub( bungmobott_key, "CENSORED" )
if message =~ /^error/i
raise Exception.new("BungmoBott::Socket Error: #{message}")
elsif message =~ /^authed/
negotiated = true
#ssl_socket.puts( "say twitch #{user} test" )
elsif ( match = message.match( /^msg (twitch|gamesurge)/ ) )
- commandircipc.send( { "#{match[1]}_remote", FastIRC.parse_line( message.split(" ")[2..].join(" ") ) } )
+ commandifc.send( { "#{match[1]}_remote", FastIRC.parse_line( message.split(" ")[2..].join(" ") ) } )
elsif ( match = message.match( /^awst2s ([0-9]+)/ ) )
datasize = match[1].to_u32
audiodata = Bytes.new( datasize )
@@ -1535,11 +1616,9 @@ if config.bungmobott_connect
end
end
ssl_socket.puts( "auth #{user} #{bungmobott_key}" )
- while input = bbscliipc.receive
+ while input = bbscliifc.receive
+ puts( "#{Fiber.current.name} ssl tx: #{input}" )
# ssl_socket gets redefined in the event of I/O errors, so we deal with it here.
- #if ( climsg = input.match( /^irc +twitch +JOIN \#+([a-zA-Z0-9_]+) *$/ ) )
- #end
- puts( "bbscli tx: " + input )
ssl_socket.puts( input )
end
end
@@ -1549,14 +1628,14 @@ if config.bungmobott_connect
waitgroup.send( Fiber.current.name.not_nil! )
sleep 2
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
-# BungmoBott::Socket thread
+# BungmoBott::Socket fiber
if config.bungmobott_listen
spawn name: "BungmoBott::Socket server" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
ip, port = config.bungmobott_listen.not_nil!.split(":")
tcp_server = TCPServer.new( ip, port.to_i )
ssl_context = OpenSSL::SSL::Context::Server.new
@@ -1573,7 +1652,7 @@ if config.bungmobott_listen
#while tcp_server.accept? do | clientsocket |
while clientsocket = tcp_server.accept?
- spawn do
+ spawn name: "BungmoBott::Socket server tcp rx" do
client = OpenSSL::SSL::Socket::Server.new(clientsocket, ssl_context)
client.flush_on_newline=true
@@ -1596,7 +1675,7 @@ if config.bungmobott_listen
ircchannel = match[3]
if ircservice == "twitch"
client.puts "joining #{ircservice} \##{ircchannel}"
- twitchircipc.send( { "JOIN", ircchannel } )
+ twitchircifc.send( { "JOIN", ircchannel } )
unless channelsubs[ { ircservice, "#" + ircchannel } ]?
channelsubs[ { ircservice, "#" + ircchannel } ] = Array( OpenSSL::SSL::Socket::Server ).new
end
@@ -1604,7 +1683,7 @@ if config.bungmobott_listen
pp channelsubs
elsif ircservice == "gamesurge"
client.puts "joining #{ircservice} \##{ircchannel}"
- ircipc.send( { "JOIN", ircchannel } )
+ gamesurgeircifc.send( { "JOIN", ircchannel } )
unless channelsubs[ { ircservice, "#" + ircchannel } ]?
channelsubs[ { ircservice, "#" + ircchannel } ] = Array( OpenSSL::SSL::Socket::Server ).new
end
@@ -1616,7 +1695,7 @@ if config.bungmobott_listen
if ( match = message.match( /^awsvoicelist$/i ) )
client.puts "awsvoicelist " + generatevoicelistaws().join(" ")
elsif ( match = message.match( /^awst2s ([a-zA-Z-]+) (.+)/i ) )
- filepath="#{config.tempdir}#{Time.utc.to_unix_ms}.mp3"
+ filepath=Path.new( config.tempdir, "#{Time.utc.to_unix_ms}.mp3" ).normalize
ttsaws( filepath, match[1], match[2] )
mp3datasize = File.size( filepath )
mp3data = Bytes.new( mp3datasize )
@@ -1646,7 +1725,7 @@ if config.bungmobott_listen
elsif ( match = message.match( /^say (twitch|gamesurge) (.+)/i ) )
say( match[1], connections[client]["user"], match[2] )
elsif ( message =~ /testchannelsubs/ )
- #commandircipc.send( "testchannelsubs" )
+ #commandifc.send( "testchannelsubs" )
end
else
@@ -1656,7 +1735,6 @@ if config.bungmobott_listen
remotekey = match[2]
if File.exists?( config.statedir + "apikeys/" + remoteuser )
File.each_line( config.statedir + "apikeys/" + remoteuser ) do |localkey|
- puts "comparing #{localkey} to #{remotekey}"
if ( localkey == remotekey )
connections[client]["authed"] = "true"
puts "authed #{ remoteuser }"
@@ -1664,6 +1742,9 @@ if config.bungmobott_listen
connections[client]["user"] = remoteuser
connections[client]["key"] = remotekey
break
+ else
+ puts "WARNING: auth failure: #{localkey} did not match #{remotekey}"
+ # maybe quiet this down once users start using multiple keys
end
end
end
@@ -1694,54 +1775,54 @@ if config.bungmobott_listen
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
if config.join_channels
spawn name: "join_channels" do
- fiberipc.send( Fiber.current )
+ fiberifc.send( Fiber.current )
if fibers["GameSurge::IRC"]? && config.join_channels.not_nil!.gamesurge
ircservice = "gamesurge"
config.join_channels.not_nil!.gamesurge.not_nil!.each do |ircchannel|
- ircipc.send( { "JOIN", ircchannel } )
+ gamesurgeircifc.send( { "JOIN", ircchannel } )
unless channelsubs[ { ircservice, ircchannel } ]?
channelsubs[ { ircservice, "#" + ircchannel } ] = Array( OpenSSL::SSL::Socket::Server ).new
# Do we ever care about this?
#channelsubs[ { ircservice, "#" + ircchannel } ] = Array( OpenSSL::SSL::Socket::Server | Channel( Tuple( String, FastIRC::Message ) ) ).new
end
end
- elsif fibers["BungmoBott::Socket client"]?
+ elsif fibers["BungmoBott::Socket client"]? && config.join_channels.not_nil!.gamesurge
ircservice = "gamesurge"
config.join_channels.not_nil!.gamesurge.not_nil!.each do |ircchannel|
- bbscliipc.send( "irc gamesurge JOIN \#" + ircchannel )
+ bbscliifc.send( "irc gamesurge JOIN \#" + ircchannel )
end
end
if fibers["Twitch::IRC"]? && config.join_channels.not_nil!.twitch
ircservice = "twitch"
config.join_channels.not_nil!.twitch.not_nil!.each do |ircchannel|
- twitchircipc.send( { "JOIN", ircchannel } )
+ twitchircifc.send( { "JOIN", ircchannel } )
unless channelsubs[ { ircservice, ircchannel } ]?
channelsubs[ { ircservice, "#" + ircchannel } ] = Array( OpenSSL::SSL::Socket::Server ).new
# Do we ever care about this?
#channelsubs[ { ircservice, "#" + ircchannel } ] = Array( OpenSSL::SSL::Socket::Server | Channel( Tuple( String, FastIRC::Message ) ) ).new
end
end
- elsif fibers["BungmoBott::Socket client"]?
+ elsif fibers["BungmoBott::Socket client"]? && config.join_channels.not_nil!.twitch
ircservice = "twitch"
config.join_channels.not_nil!.twitch.not_nil!.each do |ircchannel|
- bbscliipc.send( "irc twitch JOIN \#" + ircchannel )
+ bbscliifc.send( "irc twitch JOIN \#" + ircchannel )
end
end
ensure
waitgroup.send( Fiber.current.name.not_nil! )
end
- fiber = fiberipc.receive
+ fiber = fiberifc.receive
fibers[fiber.name.not_nil!] = fiber
end
puts "Spawned fibers:"
-pp fibers
+pp fibers.keys
fibers.size.times do
fiber = waitgroup.receive