From 71fa23de2e0b45c3333a87ff18a95c0f28869108 Mon Sep 17 00:00:00 2001 From: Joe Rayhawk Date: Sun, 31 Jul 2022 04:16:08 -0700 Subject: bungmobott: fix OBS scene, source, and filter handling. Filters no longer toggle due to limitations in the obs-websocket protocol and my willingness to implement an entire object system to mirror OBS's. --- crystal/bungmobott.cr | 100 ++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 57 deletions(-) (limited to 'crystal/bungmobott.cr') diff --git a/crystal/bungmobott.cr b/crystal/bungmobott.cr index d2b2cd9..671ca3c 100755 --- a/crystal/bungmobott.cr +++ b/crystal/bungmobott.cr @@ -459,7 +459,7 @@ spawn do spawn do while msg = obsipc.receive pp msg - if ( match = msg.match( /^\x10source-toggle ([a-z0-9-_]+)/ ) ) + if ( match = msg.match( /^\x10source ([a-z0-9-_]+)/ ) ) source = match[1] sources = reversesource( scenes, currentscene ) pp sources @@ -467,18 +467,22 @@ spawn do request["request-type"] = "SetSceneItemProperties" request["message-id"] = "SetSceneItemProperties" #request["request-type"] = "GetSceneItemProperties" - request["message-id"] = "toggle-source" scene = sources[source] request["scene-name"] = sources[source] request["item"] = source - if scenes[scene][source]["render"] == true - request["visible"] = false - else - request["visible"] = true + if ( match = msg.match( /^\x10source ([a-z0-9-_]+) (true|false)/ ) ) + request["visible"] = ( match[2] == "true" ) + obs_pubsub.send( request.to_json ) + elsif ( match = msg.match( /^\x10source ([a-z0-9-_]+)/ ) ) + request["visible"] = ( scenes[scene][source]["render"]? == true ) + obs_pubsub.send( request.to_json ) end + elsif ( match = msg.match( /^\x10source/ ) ) + request = Hash( String, String ){ + "request-type" => "GetCurrentScene", + "message-id" => "GetCurrentScene", + } obs_pubsub.send( request.to_json ) - elsif ( match = msg.match( /^\x10source ([a-z0-9-_]+)/ ) ) - # FIXME else obs_pubsub.send( msg ) end @@ -520,21 +524,26 @@ spawn do obsipc.send( request.to_json ) end when "SourceFilterVisibilityChanged" - ircipc.send( { "##{settings["channel"]}", "| obs: source #{json["sourceName"]} filter #{json["filterName"]} visibility is now #{json["filterEnabled"]}" } ) + ircipc.send( { "##{settings["channel"]}", "| obs: source #{json["sourceName"]} filter #{json["filterName"]} visibility is currently #{json["filterEnabled"]}" } ) when "SceneItemVisibilityChanged" + scenes[json["scene-name"].as_s][json["item-name"].as_s]["render"] = json["item-visible"].as_bool ircipc.send( { "##{settings["channel"]}", "| obs: source #{json["item-name"]} visibility is now #{json["item-visible"].as_bool}" } ) end print( "RECEIVED: ") print( json.to_pretty_json ) print( "\n") - case json["message-id"]? - when "GetCurrentScene" + case json["message-id"]?.as_s? + when /^GetCurrentScene/ currentscene = json["name"].as_s - ircipc.send( { "#" + settings["channel"], "| obs: " + json["sources"].as_a.map{ |source| source["name"] }.join(", ") } ) + if json["message-id"].as_s? !~ /Quietly/ + ircipc.send( { "#" + settings["channel"], "| obs: " + json["sources"].as_a.map{ |source| source["name"] }.join(", ") } ) + end when "GetSourceFilters" - ircipc.send( { "#" + settings["channel"], "| obs: " + json["filters"].as_a.map{ |filter| filter["name"] }.join(", ") } ) - when "GetSceneList" - ircipc.send( { "#" + settings["channel"], "| obs: " + json["scenes"].as_a.map{ |scene| scene["name"] }.join(", ") } ) + ircipc.send( { "#" + settings["channel"], "| obs: " + json["filters"].as_a.map{ |filter| "#{filter["name"].as_s}: #{filter["enabled"].as_bool}" }.join(", ") } ) + when /^GetSceneList/ + if json["message-id"].as_s? !~ /Quietly/ + ircipc.send( { "#" + settings["channel"], "| obs: " + json["scenes"].as_a.map{ |scene| scene["name"] }.join(", ") } ) + end json["scenes"].as_a.each{ |scene| scenes[scene["name"].as_s]? || ( scenes[scene["name"].as_s] = Hash( String, Hash( String, Int64 | Float64 | Bool | String ) ).new ) scene["sources"].as_a.each{ |source| @@ -550,25 +559,22 @@ spawn do } } pp scenes - when "toggle-filter" - name = json["filters"][0]["name"].as_s - visible = ( json["filters"][0]["enabled"].as_bool == false ) - ircipc.send( { "#" + settings["channel"], "| obs: Setting visibility of filter #{name} to #{visible}" } ) - obsipc.send( "{ \"request-type\": \"SetSourceFilterVisibility\", \"message-id\": \"SetSourceFilterVisibility\", \"sourceName\": \"#{name}\", \"visible\": #{visible} }" ) - #This is a dumb hack to toggle SetSceneItemProperty visibility - when "toggle-source" - name = json["name"].as_s - visible = ( json["visible"].as_bool == false ) - ircipc.send( { "#" + settings["channel"], "| obs: Setting visibility of source #{name} to #{visible}" } ) - obsipc.send( "{ \"request-type\": \"SetSceneItemProperties\", \"message-id\": \"SetSceneItemProperties\", \"item\": \"#{name}\", \"visible\": #{visible} }" ) end end - request = Hash( String, String ){ - "request-type" => "GetCurrentScene", - "message-id" => "GetCurrentScene", - } - obsipc.send( request.to_json ) + spawn do + sleep 1 + request = Hash( String, String ){ + "request-type" => "GetCurrentScene", + "message-id" => "GetCurrentScene Quietly", + } + obsipc.send( request.to_json ) + request = Hash( String, String ){ + "request-type" => "GetSceneList", + "message-id" => "GetSceneList Quietly", + } + obsipc.send( request.to_json) + end obs_pubsub.run rescue ex : Socket::ConnectError # these are a bit noisy @@ -600,7 +606,7 @@ loop do # PRIVMSG #channel message\r\n spawn do while msgtuple = ircipc.receive # why does this need to be a tuple? - sizelimit=( 512 - ( msgtuple[0].size + 11 ) ) + sizelimit=( 512 - ( msgtuple[0].size + 12 ) ) bot.message( msgtuple[0], msgtuple[1][0..sizelimit] ) # limit size end end @@ -702,29 +708,12 @@ loop do end elsif ( ( cmd =~ /^source$/ ) && ( mod || own ) ) request = Hash( String, String | Bool ).new - if ( match[2]? ) && ( sourceargs = match[2].match( /^([a-zA-Z0-9-_]+) +(true|false)/ ) ) -# request["request-type"] = "SetSceneItemProperties" -# request["message-id"] = "SetSceneItemProperties" -# request["item"] = sourceargs[1] -# sourceargs[2] == "true" && ( request["visible"] = true ) -# sourceargs[2] == "false" && ( request["visible"] = false ) -# -# ircipc.send( { "##{settings["channel"]}", "Setting source #{sourceargs[1]} visibility to #{sourceargs[2]}" } ) + if ( match[2]? ) && ( sourceargs = match[2].match( /^([a-zA-Z0-9-_]+) +(true|false)$/ ) ) obsipc.send( "\x10source #{match[2]}" ) elsif ( match[2]? && match[2] =~ /^[a-zA-Z0-9-_]+$/ ) - #sources = reversesource( scenes, currentscene ) - #request["request-type"] = "SetSceneItemProperties" - #request["message-id"] = "SetSceneItemProperties" - #request["request-type"] = "GetSceneItemProperties" - #request["message-id"] = "toggle-source" - #request["item"] = match[2] - #obsipc.send( request.to_json ) - obsipc.send( "\x10source-toggle #{match[2]}" ) - else -# request["request-type"] = "GetCurrentScene" -# request["message-id"] = "GetCurrentScene" -# obsipc.send( request.to_json ) obsipc.send( "\x10source #{match[2]}" ) + else + obsipc.send( "\x10source" ) end elsif ( ( cmd =~ /^filter$/ ) && ( mod || own ) ) request = Hash( String, String | Bool ){ @@ -740,16 +729,13 @@ loop do filterargs[3] == "false" && ( request["filterEnabled"] = false ) obsipc.send( request.to_json ) elsif ( match[2]? ) && ( filterargs = match[2].match( /^([a-zA-Z0-9-_]+) +([a-zA-Z0-9-_]+)/ ) ) - request["message-id"] = "toggle-filter" - request["sourceName"] = filterargs[1] - request["filterName"] = filterargs[2] - obsipc.send( request.to_json ) + ircipc.send( { "##{settings["channel"]}", "Must provide provide a value of true or false as the third argument." } ) elsif ( match[2]? && match[2] =~ /^[a-zA-Z0-9-_]+$/ ) request["sourceName"] = match[2] request["message-id"] = "GetSourceFilters" obsipc.send( request.to_json ) else - ircipc.send( { "##{settings["channel"]}", "Must provide at least one source name as argument, and optionally one filter name." } ) + ircipc.send( { "##{settings["channel"]}", "Must provide at least one source name as argument, and optionally one filter name and a value of true or false." } ) end elsif ( cmd == "duplicate" && ( mod || own || vip ) ) if ( match[2]? ) && ( filterargs = match[2].match( /^([a-zA-Z0-9-_]+)/ ) ) -- cgit v1.2.3