From 8d38b2617412e39730bce0b1b99b8d9a0ee79545 Mon Sep 17 00:00:00 2001
From: Joe Rayhawk <jrayhawk@action.fairlystable.org>
Date: Mon, 4 Sep 2017 22:22:39 -0700
Subject: ircobsbridge.rb: extensive changes

---
 ircobsbridge.rb | 133 ++++++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 111 insertions(+), 22 deletions(-)

diff --git a/ircobsbridge.rb b/ircobsbridge.rb
index aa89577..124f540 100644
--- a/ircobsbridge.rb
+++ b/ircobsbridge.rb
@@ -8,19 +8,23 @@ require 'openssl'
 require 'websocket'
 require 'net/http'
 require 'pp'
+require 'uri'
 
 confdir = Dir.home + '/.config/twitch/'
 ENV['APPDATA'] && confdir = ENV['APPDATA'] + "\\twitch\\"
 ENV['XDG_CONFIG_HOME'] && confdir = ENV['XDG_CONFIG_HOME'] + '/twitch/'
 
-access_token = IO.read( confdir + 'access_token' ).chomp
-channel      = IO.read( confdir + 'channel'      ).chomp
-client_id    = IO.read( confdir + 'client_id'    ).chomp
-unix_socket_path =      confdir + 'chat_socket'
-obs_password = IO.read( confdir + 'obs_password' ).chomp
+# returning 'true' on each line to conceal results when sourcing in irb
 
-def ircsocketwrite( unix_socket_path, text )
-  unix_socket = UNIXSocket.new( unix_socket_path )
+( $ACCESS_TOKEN = IO.read( confdir + 'access_token' ).chomp ) && true
+( $CHANNEL      = IO.read( confdir + 'channel'      ).chomp ) && true
+( $CLIENT_ID    = IO.read( confdir + 'client_id'    ).chomp ) && true
+( $UNIX_SOCKET_PATH =      confdir + 'chat_socket'  )         && true
+( $OBS_PASSWORD = IO.read( confdir + 'obs_password' ).chomp ) && true
+( $TRN_API_KEY  = IO.read( confdir + '../trn-api-key' ).chomp ) && true
+
+def ircsocketwrite( text )
+  unix_socket = UNIXSocket.new( $UNIX_SOCKET_PATH )
   unix_socket.print( text )
 rescue
 ensure
@@ -57,6 +61,84 @@ def GetStreamingStatus( id = '1' )
   websocketwrite( '{ "request-type": "GetStreamingStatus", "message-id" : "' + id.to_s + '" }' )
 end
 
+def pubgstats( name )
+  tries = 2
+  http = Net::HTTP.new( 'pubgtracker.com', 443 )
+  http.use_ssl = true
+  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
+  http.read_timeout = 500
+
+  req = Net::HTTP::Get.new( "/api/profile/pc/#{name}" )
+  ( req["TRN-Api-Key"] = $TRN_API_KEY ) && true
+  
+  begin
+    response = JSON.parse( http.request( req ).body )
+  rescue
+    sleep 2
+    retry unless( tries-=1 ).zero?
+  end
+
+  if response['error'] then
+    ircsocketwrite( "| pubgstats: #{response['message']} (maybe bad name?)\n" )
+    return
+  end
+
+  totalwins = 0
+  totallosses = 0
+  totalkills = 0
+  totaldeaths = 0
+  totalrounds = 0
+  bestrank = 9999999
+  bestrating = 0
+  bestroundkills = 0
+  bestrangekill = 0
+ 
+#response['Stats'].each { |matchstats| matchstats['Stats'].each { |stats| printf( "%9s %3s %5s %25s %10s\n", matchstats['Season'], matchstats['Region'], matchstats['Match'], stats['field'], stats['value'] ) } } && true# debug
+#response['Stats'].each { |matchstats| matchstats['Stats'].each { |stats| printf( "%9s %3s %5s %23s %20s %12s %10s %10s %10s %10s\n", matchstats['Season'], matchstats['Region'], matchstats['Match'], stats['label'], stats['field'], stats['category'], stats['value'], stats['rank'], stats['percentile'], stats['displayValue'] ) } } && true # debug
+  
+response['Stats'].each do |matchstats|
+  kdr = 0.0
+  matchstats['Stats'].each do |stats|
+    if stats['field'] == 'KillDeathRatio' then
+      kdr = stats['value'].to_f
+    end
+    stats['field'] == 'Wins'         && totalwins   += stats['value'].to_i
+    stats['field'] == 'Losses'       && totallosses += stats['value'].to_i
+    stats['field'] == 'RoundsPlayed' && totalrounds += stats['value'].to_i
+    if stats['field'] == 'Kills' && kdr != 0 then
+      totalkills  += stats['value'].to_i
+      totaldeaths += stats['value'].to_i / kdr
+    end
+    ( stats['field'] == 'BestRating'                          && stats['value'].to_i > bestrating )     && bestrating     = stats['value'].to_i
+    ( stats['field'] == 'RoundMostKills'                      && stats['value'].to_i > bestroundkills ) && bestroundkills = stats['value'].to_i
+    ( stats['field'] == 'LongestKill'                         && stats['value'].to_i > bestrangekill )  && bestrangekill  = stats['value'].to_i
+    ( stats['field'] == 'BestRank' && 0 < stats['value'].to_i && stats['value'].to_i < bestrank )       && bestrank       = stats['value'].to_i
+  end
+  
+end && true
+
+
+#bestrank
+#bestrating
+#bestroundkills
+totalkills /= 2
+totaldeaths /= 2
+totalwins /= 2
+totallosses /= 2
+#bestrangekill
+winratio = totalwins.to_f/totallosses.to_f
+killratio = totalkills.to_f/totaldeaths.to_f
+
+ircsocketwrite( sprintf( "| %s  BEST: rating: %i, rank: %i, roundkills: %i, rangekill: %i;  TOTAL: kills/deaths: %i / %i = %02.03f, wins/losses: %i / %i = %01.03f ", response['PlayerName'], bestrating, bestrank, bestroundkills, bestrangekill, totalkills, totaldeaths, killratio, totalwins, totallosses, winratio ) )
+#ircsocketwrite( "| #{response['PlayerName']} PUBG Stats: BestRating: #{bestrating}, BestRank: #{bestrank}, HighestRoundKills: #{bestroundkills}, TotalKills: #{totalkills}, TotalWins/Losses #{totalwins}/#{totallosses} = #{winratio}, HighestRange: #{bestrangekill}\n" )
+
+#	optimally:
+# highest 'Kills' 'KillDeathRatio' & percentile 'Wins'/'WinPoints'/'WinRatio'/percentile 'RoundMostKills' 'RoundsPlayed' 'BestRating' 'BestRank' 'LongestKill'
+# realistically:
+# BestRank BestRating RoundsPlayed Wins/Losses WinRatio Kills RoundMostKills LongestKill
+	
+end
+
 def transientsource( source )
   Thread.new {
     SetSourceRender( 'media-' + source , false )
@@ -77,9 +159,9 @@ def websocket_create()
     print $tcp_socket.read_nonblock( 4096 )
     websocketwrite( '{ "request-type": "GetAuthRequired", "message-id" : "1" }' )
     # Let the obsreader thread do the actual authentication.
-  rescue IOError, EOFError
-    $tcp_socket.close
-    sleep 1
+  rescue IOError, EOFError, Errno::ECONNREFUSED, Errno::ECONNRESET
+    $tcp_socket && $tcp_socket.close
+    sleep 5
     retry
   end
 end
@@ -93,7 +175,7 @@ $globallastused = 0
 
 def command_dispatch( mode, user, command, arg1 )
   # arg1 may be empty String
-  safe = /^[-0-9a-zA-Z]+$/
+  safe = /^[-0-9a-zA-Z_]+$/
   if mode == '@' && command == 'scene'
     if arg1 =~ safe
       SetCurrentScene( arg1 )
@@ -113,10 +195,17 @@ def command_dispatch( mode, user, command, arg1 )
       return
     end
   elsif mode == '@' && command == 'commands'
-    ircsocketwrite( unix_socket_path, "!source !scene !metaminute !nopgl1 !nopgl2\n" )
+    ircsocketwrite( "| !source !scene !pubg !metaminute !nopgl1 !nopgl2\n" )
     return
   end 
   # ratelimited commands after +o commands
+  if command =~ /^(pubg)$/
+    if ( ! $lastused[ command ] || $lastused[ command ] <= ( Time.now.to_i - 5 ) ) # || mode == '@'
+      $lastused[ command ] = Time.now.to_i
+      pubgstats( arg1 )
+      return
+    end
+  end
   if ( ! $lastused[ command ] || $lastused[ command ] <= ( Time.now.to_i - 120 ) ) && $globallastused <= ( Time.now.to_i - 60 ) # || mode == '@'
     $globallastused = Time.now.to_i
     $lastused[ command ] = Time.now.to_i
@@ -124,7 +213,7 @@ def command_dispatch( mode, user, command, arg1 )
       transientsource( command )
       return
     elsif command == 'commands'
-      ircsocketwrite( unix_socket_path, "!metaminute !nopgl1 !nopgl2\n" )
+      ircsocketwrite( "| !pubg !metaminute !nopgl1 !nopgl2\n" )
       return
     end
   end
@@ -133,9 +222,9 @@ end
 # irclog read loop event thread
 ircreader = Thread.new {
 begin
-  irclog = IO.popen('/usr/bin/tail -n0 -F ' + ENV['HOME'] + '/irclogs/twitch/#' + channel + '.log' )
+  irclog = IO.popen('/usr/bin/tail -n0 -F ' + ENV['HOME'] + '/irclogs/twitch/#' + $CHANNEL + '.log' )
   irclog.each_line do |line|
-    if ( match = line.match(/^\d\d:\d\d <([@ +])(.+)?> *!([-0-9a-zA-Z]+) *([-0-9a-zA-Z]*)/) )
+    if ( match = line.match(/^\d\d:\d\d <([@ +])(.+)?> *!([-0-9a-zA-Z]+) *([-0-9a-zA-Z_]*)/) )
       command_dispatch( *match.to_a[1..4] )
     end
   end
@@ -157,32 +246,32 @@ obsreader = Thread.new {
 	elsif frame_parsed['current-scene'] && frame_parsed['scenes'] # GetSceneList
           text = '| Current scene: ' + frame_parsed['current-scene'] + ' | Available: ' + frame_parsed['scenes'].map{|v| v['name'] }.sort.join(' ') + "\n" 
 	  print text
-          ircsocketwrite( unix_socket_path, text )
+          ircsocketwrite( text )
 	elsif frame_parsed['name'] && frame_parsed['sources']         # GetCurrentScene
 	  pp frame_parsed
           text = '| Sources: ' + frame_parsed['sources'].map{|v| v['name'] }.sort.join(' ') + "\n"
 	  print text
           if frame_parsed['message-id'] == '1' 
-            ircsocketwrite( unix_socket_path, text )
+            ircsocketwrite( text )
           else # other message-ids are a source we want to toggle
             frame_parsed['sources'].each do |v|
               if v['name'] == frame_parsed['message-id']
                 if    v['render'] == true
                   SetSourceRender( v['name'], 'false', '2' )
-                  ircsocketwrite( unix_socket_path, '| Source ' + v['name'] + " is now unrendered\n" )
+                  ircsocketwrite( '| Source ' + v['name'] + " is now unrendered\n" )
                 elsif v['render'] == false
                   SetSourceRender( v['name'], 'true',  '2' )
-                  ircsocketwrite( unix_socket_path, '| Source ' + v['name'] + " is now visible\n" )
+                  ircsocketwrite( '| Source ' + v['name'] + " is now visible\n" )
                 end
               end
             end
           end
         elsif frame_parsed['update-type'] == 'SwitchScenes'
-          ircsocketwrite( unix_socket_path, '| Scene is now ' + frame_parsed['scene-name'] + "\n" )
+          ircsocketwrite( '| Scene is now ' + frame_parsed['scene-name'] + "\n" )
         #elsif frame_parsed['update-type'] == 'SceneItemVisibilityChanged'
-        #  ircsocketwrite( unix_socket_path, '| Source ' + frame_parsed['item-name'] + ' visibility is now ' + frame_parsed['item-visible'].to_s + "\n" )
+        #  ircsocketwrite( '| Source ' + frame_parsed['item-name'] + ' visibility is now ' + frame_parsed['item-visible'].to_s + "\n" )
 	elsif frame_parsed['authRequired'] == true                    # GetAuthRequired
-          websocketwrite( '{ "request-type": "Authenticate", "message-id" : "2", "auth" : "' + Digest::SHA256.base64digest(Digest::SHA256.base64digest(obs_password + frame_parsed['salt'])+frame_parsed['challenge']) + '" }' )
+          websocketwrite( '{ "request-type": "Authenticate", "message-id" : "2", "auth" : "' + Digest::SHA256.base64digest(Digest::SHA256.base64digest($OBS_PASSWORD + frame_parsed['salt'])+frame_parsed['challenge']) + '" }' )
 	else
           print frame_decoded
         end
-- 
cgit v1.2.3