Coders-IRC


IRC for Coders

Archive October 2020


[DE] YouTube Announcer (mSL)


image
 #-> Allgemeine Informationen <-#
; Name: YouTube Announcer
; Author: Kylar
; Date: 25.09.2020
; Version: 1.0.0 - Erster Release
; Beschreibung: YouTube Announcer tut genau das, was der Name vermuten/befürchten lässt.
; Das Script sucht aktiv in allen Channels (die nicht ignoriert werden sollen) nach YouTube Links und liefert, über die Google API, Informationen zum Video.
; Dabei kann die Ausgabe für sich selbst (über Echo) oder als MSG im Channel erfolgen.
;
; Voraussetzungen: AdiIRC in der Version 3.8 oder höher oder mIRC in der Version 7.62 oder höher.
;                               Einen Google API-Key für die YouTube Data API v3 (siehe https://developers.google.com/youtube/v3/getting-started)
;
; #-> Installation <-#
; Script entsprechend in AdiIRC/mIRC laden und den Befehl /youtube_announcer aufrufen, um das Script einzustellen.
; Nachdem die Einstellungen vorgenommen wurden, reagiert das Script entsprechend auf Nachrichten.
;
; #-> Deinstallation <-#
; Einfach den Befehl /youtube_announcer deinstall eingeben und das Script entfernt alle globalen Variablen.
; ACHTUNG: Die aktuellen Einstellungen werden in der yta_settings.ini gespeichert und beim erneuten aufrufen von /youtube_announcer geladen.
; Für eine vollständige Deinstallation den Befehl /youtube_announcer deinstall aufrufen, das Script und die yta_settings.ini löschen.

;;   ##############
;;  # Dialog/GUI #
;; ##############
alias youtube_announcer {
  if ( $0 == 0 ) {
    dialog -m yta_d_main yta_d_main
  } 
  else {
    if ( $lower($1) == deinstall || $lower($1) == uninstall || $lower($1) == deinstallation ) {
      yta_uninstall
    }
  }
}

; TODO Unter Nachricht einstellen, dass die Vorschau auch per Echo erfolgen kann (für Farbe usw.)
; Haupt Dialog zum einstellen des Scripts
Dialog yta_d_main {

  ;; Main 
  title "YouTube Announcer"
  ; -1 -1 setzt den Dialog in die Mitte vom Hauptfenster
  size -1 -1 200 150
  option dbu

  menu "About", 100
  ;  menu "Hilfe", 101

  ;; Tab Allgemeine Einstellen
  tab "Allgemeine Einstellungen", 1, 0 0 200 150
  box "Parsing", 10, 5 15 190 70, tab 1
  ; Abstand in der Höhe bei Check muss mindestens 8 sein
  check "Channel Nachrichten Parsen", 11, 10 24 76 8, tab 1
  check "Privat Nachrichten Parsen", 12, 10 32 70 8, tab 1
  check "YT-Infos nur über Echo ausgeben", 22, 95 24 88 8, tab 1
  text "Anbieter die geparst werden sollen", 13, 10 43 180 8, tab 1
  list 14, 10 52 180 28, tab 1 size extsel check multse vsbar

  box "API", 15, 5 90 190 50, tab 1
  text "Damit das Script Informationen über YouTube Videos abrufen kann,", 16, 10 99 180 8, nowrap tab 1
  text "wird ein API-Key von "17, 10 107 50 8, nowrap tab 1
  link "Google", 18, 62 107 18 8, tab 1
  text "benötigt.  Der Key wird auschließlich zum ", 19, 80 107 100 8, tab 1
  text "Abrufen der Videoinformationen verwendet." 20, 10 115 180 12, tab 1
  edit "", 21, 20 125 150 10, tab 1

  ;; Anpassen der Nachricht die ausgegeben wird
  tab "Nachrichten-Formatierung", 3, 0 0 200 150  
  box "Nachricht", 30, 5 15 190 57, tab 3
  edit "", 31, 10 24 180 10, tab 3 autohs
  text "Vorschau", 32, 10 36 100 8, tab 3
  edit "", 33, 10 44 180 10, tab 3 rich read autohs
  check "Vorschau als  Echo ausgeben?", 38, 10 58 80 8, tab 3
  box "Platzhalter", 34, 5 75 190 40 , tab 3
  text "Die folgenden aufgelisteten Zeichenfolgen werden automatisch ersetzt.", 35, 10 84 180 8, tab 3
  text "<duration>, <title>, <channeltitle>, <publishedat>, <favoritecount>", 36, 10 94 180 8, tab 3
  text "<viewcount>, <likecount>, <dislikecount>, <commentcount>", 37, 10 102 180 8, tab 3

  ;; Channels/Nicks die ignoriert werden sollen
  tab "Ignorieren", 4, 0 0 200 150
  text "Server, Channel und Nicknames eintragen, die ignoriert werden sollen.", 40, 5 15 190 12, tab 4

  box "Eingabe", 41, 5 30 190 37, tab 4
  text "Format: [network:][#]Ziel.", 42, 10 40 75 8, tab 4 
  edit "", 43, 10 50 150 10, tab 4
  button "Hinzfügen", 44, 163 50 30 10, tab 4

  box "Liste der zu ignorierenden Objekte", 45, 5 72 190 70, tab 4
  list 46, 10 82 153 55, tab 4 size extsel vsbar
  button "Entfernen", 47, 165 82 27 55, tab 4 multi
}

; About Dialog (zeigt momentan nur Basic-Informationen an)
dialog yta_d_about {
  title "About - YouTube Announcer"
  size -1 -1 100 70
  option dbu

  text "Script Name: YouTube Announcer", 1, 5 5 100 8
  text "Author: Kylar", 2 , 5 13 100 8
  text "Date: September 2020", 3, 5 21 100 8
  text "Kurzbeschreibung: Liefert Informationen zu erkannten YouTube Links", 4, 5 29 190 20
  text "Voraussetzung: YouTube/Goole API-Key", 5, 5 50 100 14
}

;;#
;; Dialog Events
;;#
; Settings laden und die Tabs mit Inhalt befüllen
on *:DIALOG:yta_d_main:init:0: {
  did -a yta_d_main 14 youtube.com
  did -a yta_d_main 14 yu2.be
  did -a yta_d_main 14 youtu.be

  ; Wenn keine Settings vorhanden sind, entsprechend die settings ini laden oder erstellen
  if ( !$var(%yta/settings/*)) {
    yta_load_config   
  }

  var %i = 1
  while ( %i <= $var(%yta/settings/*) ) {
    var %j = 1, %fp = $var(%yta/settings/*, %i) ,%sec = $token(%fp, $calc($numtok(%fp, 47) - 1), 47), %item = $token(%fp, $numtok(%fp, 47), 47)
    var %val = $var(%yta/settings/*, %i).value

    ; Liste der zu ignorierenden Ziele befüllen
    if (%item == list ) { 
      $iif(%val != $chr(7), yta_fill_ignorelist, noop)

    }
    ; Die Nachricht, die ausgegeben werden soll, befüllen 
    elseif ( %item == msg ) {
      $iif(%val != $chr(7), yta_fill_msg, noop ) 

    }
    ; API-Key Feld befüllen   
    elseif ( %item == apikey ) {
      $iif(%val != $chr(7), yta_fill_apikey, noop )

    }
    ; URLS in der Liste markieren
    elseif ( %item == urls ) {
      if ( %val != $chr(7) ) {
        var %j = 1
        while ( %j <= $numtok(%val, 44) ) {
          var %k = 1, %val1 = $token(%val, %j, 44)          
          while ( %k <= $did(14).lines ) {
            if ($did(14, %k).text == %val1) {
              did -s yta_d_main 14 %k
            }
            inc %k
          }
          inc %j
        }
      }
    } 
    ; Checkbox für die Ausgabe der über Echo
    elseif ( %sec == General && %item == echo ) {
      if ( %val == 1 ) {
        did -c $dname 22
      }
    }
    ; Checkbox, ob Channel-Nachrichten geparst werden sollen
    elseif ( %item == cmsg ) {
      if ( %val == 1 ) {
        did -c $dname 11
      }      

    } 
    ; Checkbox, ob Private-Nachrichten geparst werden sollen
    elseif ( %item == pmsg ) {
      if ( %val == 1 ) {
        did -c $dname 12
      }
    }
    ; Einstellung für die Ausgabe der Vorschau    
    elseif ( %sec == Message && %item == echo ) {
      if ( %val == 1 ) {
        did -c $dname 38
      }
    }
    inc %i
  }
}

; Einstellungen beim Verlassen des Dialogs in die ini schreiben
on *:DIALOG:yta_d_main:close:0: {
  yta_save_config
}

; API-Key in Variable speichern
on *:DIALOG:yta_d_main:edit:21: {
  set %yta/settings/General/apikey $did(21).text
}

; Verarbeitung der Click-Events
; Im Tab IgnoreList: Multiselektion kann nicht als ganzes entfernt werden, nur einzelne Ziele können entfernt werden.
on *:DIALOG:yta_d_main:sclick:*: {
  if ( $did == 11 ) {
    ; channel nachricht
    set %yta/settings/General/cmsg $did(11).state
  } 
  elseif ( $did == 12 ) {
    ; private nachricht
    set %yta/settings/General/pmsg $did(12).state
  }
  elseif ( $did == 22 ) {
    set %yta/settings/General/echo $did(22).state
  }
  elseif ( $did == 14 ) {
    ;listbox mit urls
    if ( $did(14, $did(14).sel ).cstate == 1 ) {
      set %yta/settings/General/urls $addtok($did(14, $did(14).sel).text, %yta/settings/General/urls, 44)
    } 
    else {
      set %yta/settings/General/urls $remtok(%yta/settings/General/urls, $did(14, $did(14).sel).text, 0, 44)
    }
  } 
  elseif ($did == 44) { ; Tab Ignorelist 
    ; Hinzufügen
    if ($len($did(43).text) > 0) {
      if ( (, !isin $did(43).text) && $regex($did(43).text, /^(?:\w+:)?#?[a-zA-Z0-9:#\|]+/) ) {
        set %yta/settings/IgnoreList/list $addtok($did(43).text, %yta/settings/IgnoreList/list, 44)
        did -r yta_d_main 43
        yta_fill_ignorelist
      }
    }
  }
  elseif ( $did == 47 ) { ; Tab Ignorelist 
    ; Entfernen
    if ( $len($did(46).seltext) > 0 ) {
      set %yta/settings/IgnoreList/list $remtok(%yta/settings/IgnoreList/list, $did(46).seltext, 0,44)
      did -r yta_d_main 46
      didtok yta_d_main 46 44 %yta/settings/IgnoreList/list
    }
  } 
  elseif ( $did == 38 ) {
    set %yta/settings/Message/echo $did(38).state
  }
  elseif ( $did == 18 ) {
    .url https://developers.google.com/youtube/v3/getting-started
  }
}

; Das Textfeld "Vorschau" mit den Inhalt aus "Nachricht" befüllen und 
; Platzhalter durch Dummy-Daten ersetzen
on *:DIALOG:yta_d_main:edit:31: {
  if ($len($did(31).text) > 0) {
    var %t1 = publishedAt $+ $chr(7) $+ title $+ $chr(7) $+ channelTitle $+ $chr(7) $+ duration $+ $chr(7) $+favoritecount $+ $chr(7) $+ viewcount $+ $chr(7) $+ likecount $+ $chr(7) $+ dislikecount  $+ $chr(7) $+ commentcount
    var %t2 = 2012-10-01T15:27:35Z $+ $chr(7) $+ A very special Title $+ $chr(7) $+ TheChan Nel $+ $chr(7) $+ PT7H3M33S $+ $chr(7) $+ 60 $+ $chr(7) $+ 1250 $+ $chr(7) $+ 1000 $+ $chr(7) $+ 250 $+ $chr(7) $+ 450

    ; Vorschau soll auch per Echo erfolgen
    if ( %yta/settings/Message/echo == 1 ) { 
      echo -ga $yta_replace_placeholder($did(31).text, %t1, %t2)
    } 
    did -ri yta_d_main 33 1 $yta_replace_placeholder($did(31).text, %t1, %t2)
  } 
  else {
    did -r yta_d_main 33
  }
  set %yta/settings/Message/msg $did(31).text
}

; About Dialog öffnen 
on *:DIALOG:yta_d_main:menu:100 {
  ; Diese Operation blockt die UI und das Fenster MUSS geschlossen werden
  noop $dialog(yta_d_about, yta_d_about)
}

;;#
;;  Helfer-Funktionen
;;#

; Liste der zu ignorierenden Ziele füllen
alias yta_fill_ignorelist {
  did -r yta_d_main 46

  var %i = 1 
  while ( %i <= $numtok(%yta/settings/IgnoreList/list, 44) ) {
    var %val = $token(%yta/settings/IgnoreList/list, %i, 44)
    did -a yta_d_main 46 %val
    inc %i
  }
}

; Wird beim Dialog-Start aufgerufen, um "Vorschau" und "Nachricht" zu befüllen
alias yta_fill_msg {
  if ( $len(%yta/settings/Message/msg) > 0 ) {
    did -r yta_d_main 31
    did -a yta_d_main 31 %yta/settings/Message/msg

    var %t1 = publishedAt $+ $chr(7) $+ title $+ $chr(7) $+ channelTitle $+ $chr(7) $+ duration $+ $chr(7) $+favoritecount $+ $chr(7) $+ viewcount $+ $chr(7) $+ likecount $+ $chr(7) $+ dislikecount  $+ $chr(7) $+ commentcount
    var %t2 = 2012-10-01T15:27:35Z $+ $chr(7) $+ A very special Title $+ $chr(7) $+ TheChan Nel $+ $chr(7) $+ PT7H3M33S $+ $chr(7) $+ 60 $+ $chr(7) $+ 1250 $+ $chr(7) $+ 1000 $+ $chr(7) $+ 250 $+ $chr(7) $+ 450

    did -ri yta_d_main 33  1 $yta_replace_placeholder($did(31).text, %t1, %t2)
  }
}

; Wird beim Dialog-Start aufgerufen, um das Feld "APIKEY" zu befüllen
alias yta_fill_apikey {
  if ( $len(%yta/settings/General/apikey) > 0 ) {
    did -r yta_d_main 21
    did -a yta_d_main 21 %yta/settings/General/apikey
  }
}

; Ersetzt im Text ($1) alle Platzhalter ($2) mit den enstprechenden Werten ($3)
; Die Funktion erwartet 3 Token
; $1 = Text in dem ersetzt werden soll
; $2 = Eine Tokenliste (Trennzeichen $chr(7)) mit Wörtern die Ersetzt werden sollen (ohne < und >)
; $3 = Eine Tokenliste (Trennzeichen $chr(7)) mit der gleichen Länge wie $2 und den entrechpenden Werten die eingesetzt werden sollen.
; Rückgabe: Der übergebene Text ($1) mit den ersetzten Platzhaltern oder bei Fehler den gleichen Text
; Beispiel: //echo -ag $yta_replace_placeholder(Der <title> ist von <channeltitle>., title $+ $chr(7) $+ channeltitle, TESTTITLE $+ $chr(7) $+ Channel Title ist Super!)
alias yta_replace_placeholder {
  var %msg = $1

  if ($isid && $0 == 3) {

    if ( $numtok($2, 7) == $numtok($2, 7) ) {
      var %i = 1 
      while ( %i <= $numtok($2, 7) ) {
        var %key = $lower($token($2, %i, 7)), %val = $token($3, %i, 7)

        if ( (%key != title) && (%key != channelTitle) ) {
          var %val $yt_placeholder_format(%val)
        }

        noop $regsub(%msg, /< $+ %key $+ >/gi, %val, %msg)
        inc %i
      }
    }

    return %msg
  }
}

; Helferfunktion die Zahlen (1000 wird zu 1 Tsd), Published-Datum (2012-10-01T15:27:35Z zu 01.10.2012) und Lauflänge (PT3D1H5M30S zu 03:01:05:30) umwandelt
; Zahlen werden nur bis Mrd umgewandelt, alles was größer ist, wird normal ausgegeben
; Zeit wird, bei Fehler und so weiter, als 00:00:00 ausgegeben
; TODO Funktion mathematisch aufarbeiten und nicht so einen Quark nutzen :P aber so lange es funktioniert?
alias yt_placeholder_format {
  if ($isid && $0 == 1) {
    if ( $1 isnum ) {
      var %i = 3, %j = 1, %suff = Tsd.Mio.Mrd

      while ( %i <= 9 ) {
        var %v = $round($calc($1 / (10^%i)), 2)

        if ( $len($int(%v)) <= 3 && $int(%v) > 0  ) {
          return %v $token(%suff, %j, 46)
        }

        inc %i 3
        inc %j
      }

    }
    elseif ( $lower($left($1, 2)) == $lower(PT) ) {
      var %t = $lower($mid($1, 3, $len($1)))
      var %d = 00, %h = 00, %m = 00, %s = 00

      while ( $len(%t) >= 1 ) {
        if ( $left(%t, 1) isnum ) {
          var %tmp = %tmp $+ $left(%t, 1)
        } 
        else {
          var  % $+ $left(%t, 1) $iif($len(%tmp) == 1, 0) $+ %tmp
          unset %tmp
        }
        var %t = $mid(%t, 2, $len(%t))
      }

      return $iif(%d != 00, %d $+ :) $+ $iif(%h != 00, %h $+ :, 00:) $+ $iif(%m != 00, %m $+ :, 00:) $+ %s
    }
    elseif ( $numtok($1, 84) == 2  ) {
      var %date = $token($1, 1, 84)
      return $token(%date, 3, 45) $+ . $+ $token(%date, 2, 45) $+ . $+ $token(%date, 1, 45)
    } 
  }

  return $1
}

; Überprüft, ob eines der angegebenen Argumente in der Ignorelist ist
; Folgende Angaben sind möglich:
; Wenn nur $1: $1 = Channel/Nickname/Server der geprüft wird
; Wenn $1 und $2: $1 = Server, $2 = Nickname/Channel der in Kombination geprüft werden soll
; Wenn $1, $2, und $3: $1 = Server, $2 = Channel und $3 = Nickname
; Rückgabe: $true wenn eins der übergebenen Argumente in der Liste gefunden wird, ansonsten $false
alias yta_is_in_ignorelist {
  if ( $isid ) {
    if ( $0 >= 1 ) {
      var %i = 1, %1 = $lower($1), %2 = $lower($2), %3 = $lower($3)
      while ( %i <=  $numtok(%yta/settings/IgnoreList/list, 44) ) {
        var %target = $lower($token(%yta/settings/IgnoreList/list, %i, 44))

        if ( %1 $+ : == %target || %1 == %target ) { 
          return $true
        } 
        elseif ( %2 != $null && ( %2 == %target || %1 $+ : $+ %2 == %target ) ) {
          return $true

        }
        elseif ( %3 != $null && (%3 == %target || %1 $+ : $+ %3 == %target) ) {
          return $true
        }
        inc %i
      }
    }  
    return $false
  }
}

; Testet, ob in $1 der Text nach möglichen URLS geparst werden soll.
; $1 muss entweder chan oder priv sein
; Rückgabe: $true wenn parsing aktiv sein soll, ansonsten $false
alias yta_is_parsing_active {
  if ( $isid ) {
    if ( ($1 == chan && %yta/settings/General/cmsg == 1) || ($1 == priv && %yta/settings/General/pmsg == 1) ) {
      return $true
    }
    return $false
  }
}

; Testet, ob $1 eine URL ist die aktiv abgefragt werden soll
; Rückgabe: $true wenn sie aktiv ist, ansonsten $false
alias yta_is_active_url {
  if ( $isid ) {
    var %i 1 
    while ( %i <= $numtok(%yta/settings/General/urls, 44) ) {
      if ( $1 == $token(%yta/settings/General/urls, %i, 44) ) {
        return $true
      }
      inc %i
    }
    return $false
  }
}

;; #
;; Konfiguration laden/speichern
;; Nur über das Dialog Event Init aufrufen!
;; #
alias yta_load_config {
  var %settings/General = cmsg pmsg echo urls apikey
  var %settings/Message = msg echo
  var %settings/IgnoreList = list

  var %i = 1
  while (%i <= $var(%settings/*)) {
    var %tmpk = $token($var(%settings/*, %i), 2, 47) 
    var %tmpv =  %settings/ [ $+ [ %tmpk ] ]
    var %j = 1

    while (%j <= $numtok(%tmpv, 32)) {
      var %item = $token(%tmpv, %j, 32)
      var %val = $readini($mircdir $+ yta_settings.ini, n, %tmpk, %item)

      set %yta/settings/ $+ %tmpk $+  / $+ %item $iif(%val == $chr(7), $null, %val)
      inc %j
    }

    inc %i
  }
}

alias yta_save_config {
  var %i = 1

  while ( %i <= $var(%yta/settings/*) ) {
    var %fp = $var(%yta/settings/*, %i)
    var %val = $var(%yta/settings/*, %i).value
    var %key = $token(%fp, $calc($numtok(%fp, 47) - 1), 47)
    var %item = $token(%fp, $numtok(%fp, 47), 47)

    ; Damit kein Fehler geworfen wird, representiert 7 (BEL) keinen Inhalt
    writeini $mircdir $+ yta_settings.ini  %key  %item  $iif(%val == $null, $chr(7), %val)

    inc %i
  }
}

;;   ######################################
;;  # Nachrichtenverarbeitung und Socket #
;; ######################################
;; <# Haupt-Event
; Reagiert auf Texte (Channel/Privat) die 
; https?://(www)?youtu(.be|be.com) oder https?://(www)?yu2.be beinhalten
; Abbruch des Events passiert in mehreren Stufen, weil nicht Daten
; sofort vorhanden sind (z.B. der tatsächliche URL wird erst im Regex ermittelt).
;; #>
on $*:TEXT:$(/https? $+ $chr(58) $+ \/{2}(w{3}\.)?(youtu\.?be(\.com)?|yu2.be)/Si):*: {
  ; Überprüfen, ob überhaupt parsing erlaubt ist
  if ( $chan != $null && !$yta_is_parsing_active(chan) ) {
    return $false
  }
  elseif ( $chan == $null && !$yta_is_parsing_active(priv) ) {
    return $false
  }

  ; Wenn das bearbeiten erlaubt ist, überprüfen dass auch kein Ziel (Server, Chan, Nick) ingoriert werden soll
  if ( !$yta_is_in_ignorelist($network, $iif($chan != $null, $chan, $nick), $iif($chan != $null, $nick)) ) {
    ; Folgendes regex soll die Video-ID suchen und das 1. Ergebnis speichern
    ; Den Regex kann man bestimmt schöner machen, aber er hat in meinen Tests funktioniert
    var %re = https?:\/{2}(?:w{3}\.)?((?:youtu\.?be(?:\.com)?|yu2.be))\/(?=watch\?v\=([a-zA-Z0-9_-]+)|([a-zA-Z0-9_-]+))
    if ( $regex(yta_re_match, $1-, / $+ %re $+ /Si) > 0 ) {
      var %vid = $regml(yta_re_match, 2), %host = $regml(yta_re_match, 1)
      ; Host/URL kann erst ab hier geprüft werden
      ; Ist die URL nicht Aktiv (Checkbox im UI) dann wird das Event hier beendet
      if ( !$yta_is_active_url(%host) ) {
        return $false
      }
      ; Ticks sind ms seit systemstart
      var %tick $ticks

      ; Um Spam zu verhindern, nur alle 30 Sekunden ein Video für Chan/Nick abfragen
      if ( $calc(%tick -  [ % $+ yta/spamprot/ $+ [ $network ]  $+  [ $iif($chan != $null, $chan, $nick) ] $+ /tick ] ) >= 30000 ) {
        set %yta/spamprot/ $+ $network $+ $iif($chan != $null, $chan, $nick) $+ /tick %tick

        ; Spamprot und request Variablen nach 30 Sekunden entfernen
        .timer $+ yta/timers/ $+ $network $+ $iif($chan != $null, $chan, $nick) 1 30  yta_request_cleanup $network $+ $iif($chan != $null, $chan, $nick)

        ; Socket öffnen und Informationen als mark speichern
        sockopen -e yta/sockets/ $+ %tick googleapis.com 443
        sockmark yta/sockets/ $+ %tick $network $+ , $+ $iif($chan != $null, $chan, $nick) $+ , $+ %vid

      }
    } 
  }
}

;; <# Socket Logik
; Im folgendem Abschnitt befindet sich die Logik für den Umgang mit den geöffneten Sockets.
; Dabei gibt es zwei Hauptevents die bearbeitet werden.
; Beim öffnen wird eine HTTP Anfrage an den googleapis Server geschickt und die Markierung vom Socket in die Request-Variable geschrieben.
; Im Lesevorgang werden die erhaltenen Daten verarbeitet, in die Request-Variable geschrieben und die Ticknummer an die Funktion yta_send_message übergeben
;; #>
on *:SOCKOPEN:yta/sockets/*: {
  ; Daten für das GET  Request zusammen tragen
  var %apikey %yta/settings/General/apikey
  var %vid $token($sock($sockname, 1).mark, 3, 44)

  var %tick $token($sockname, $numtok($sockname, 47), 47)

  ; Wenn eines von beiden nicht abgerufen werden kann, socket schließen
  if ( %apikey == $null || %vid == $null) {
    unset %yta/ytrequests/ $+ %tick $+ /*
    sockclose $sockname
    return $false
  }

  ; GET Request zusammensetzen
  var %get /youtube/v3/videos?part=snippet%2CcontentDetails%2Cstatistics $+ &id= $+ %vid $+ &key= $+ %apikey

  ; HTTP Anfrage senden
  sockwrite -n $sockname GET %get HTTP/1.1
  sockwrite -n $sockname Host: www.googleapis.com
  sockwrite -n $sockname User-Agent: mSL YouTube Announcer
  sockwrite -n $sockname Accept: application/json
  sockwrite -n $sockname

  set %yta/ytrequests/ $+ %tick $+ / $+ network $token($sock($sockname, 1).mark, 1, 44)
  set %yta/ytrequests/ $+ %tick $+ / $+ dest $token($sock($sockname, 1).mark, 2, 44)
  set %yta/ytrequests/ $+ %tick $+ / $+ vid  $token($sock($sockname, 1).mark, 3, 44)

}

; TODO Eventlogik umschreiben, so das Hashtables verwendet werde
; Durch filtern von Elementen die ersetzt werden, ensteht ein Chaos aus IF/ELSIF Verzweigungen.
; Deswegen wäre ein Rewrite mit Hashtables vielleicht sinnvoll, um alle Elemente vom JSON zu speichern.
on *:SOCKREAD:yta/sockets/*: {
  var %tick $token($sockname, $numtok($sockname, 47), 47)
  var %line

  sockread %line

  ; HTTP Status-Code abfragen und entsprechend fortfahren oder abbrechen  
  if ( HTTP/1.1 isin %line ) {
    if ( $token(%line, 2, 32) != 200 ) {
      unset %yta/ytrequests/ $+ %tick $+ /*
      sockclose $sockname
      return $false
    }

  }
  elseif ( "publishedAt" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ publishedat %val

  } 
  elseif ( "title" isin %line && %yta/ytrequests/ [ $+ [ %tick ] $+ /title ] == $null ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ title %val

  } 
  elseif ( "channeltitle" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ channeltitle %val

  } 
  elseif ( "duration" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ duration %val    

  } 
  elseif ( "viewcount" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ viewcount %val    

  } 
  elseif ( "likecount" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ likecount %val    

  } 
  elseif ( "dislikecount" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ dislikecount %val    

  } 
  elseif ( "favoritecount" isin %line ) {
    var %val $token($yta_json_keyval_token(%line), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ favoritecount %val

  } 
  elseif ( "commentCount" isin %line ) {
    ; Quick and Dirty: Einfach ein Komma am Ende hinzufügen, weil sonst das Regex nicht greift
    var %val $token($yta_json_keyval_token(%line $+ $chr(44)), 2, 7)
    set %yta/ytrequests/ $+ %tick $+ / $+ commentcount %val    

    ; Comment Count ist das letzte Element das interessant ist für dieses Script
    sockclose $sockname
    yta_send_msg %tick
  } 
}

; Wird ausgeführt, wenn die Gegenseite ein Socket beendet
; Entsprechend, damit sich nicht zu viele globale Variablen ansammeln, ein unset versuchen
on *:SOCKCLOSE:yta/sockets/*: {
  var %tick $token($sockname, $numtok($sockname, 47), 47)
  unset %yta/ytrequests/ $+ %tick $+ /*
}

;; <#
;; Helfer Funktionen und Events
;; #>

; Parst die Zeichenfolge und teilt diese in Key:Val auf (Token, Trennzeichen 7) (Quick and Dirty Version)
; Argument $1: Zeichenfolge im Format \s+"<Key>":\s"<Val>",
; Rückgabe: Key und Val als Token oder nichts bei Fehler
; TODO Regex umschreiben, so das es auch greift, wenn kein Komma am Ende ist (letzte Element in einer Liste in JSON)
alias yta_json_keyval_token {
  if ( $isid ) {
    if ( $regex(yta_test, $1, /^\s+"(.*?)": "(.*?)" $+ $chr(44)$/) == 1 ) {
      var %key $regml(yta_test,1)
      var %val $regml(yta_test,2)
      return %key $+ $chr(7) $+ %val
    }

    return $null
  }
}

; Wraper, um einfacher auf die Request-Variable zugreifen zu können
; Argument $1: Tick Nummer vom Request
; Rückgabe: Inhalt der Request-Variable oder $null
; Beispiel: echo -ga Title: $yta_request_result(<tick>).title
alias yta_request_result {
  if ( $isid ) {
    if ( $var(%yta/ytrequests/ [ $+ [ $1 ] $+ ] /*) > 0 ) {
      return %yta/ytrequests/ [ $+ [ $1 ] $+ / $+ [ $prop ] ]
    }
    return $null
  }
}

; Gibt die eingestellte Nachricht am Abfrageort aus oder per Echo im aktiven Fenster
; Argument $1: yta request Tick Nummer
; Die Funktion erwartet als 1. Argument den Namen der globalen Variable 
; für den Request der ausgegeben werden soll
alias yta_send_msg {
  var %placeholders publishedAt $+ $chr(7) $+ title $+ $chr(7) $+ channelTitle $+ $chr(7) $+ duration $+ $chr(7) $+ favoritecount
  var %placeholders %placeholders $+ $chr(7) $+ viewcount $+ $chr(7) $+ likecount $+ $chr(7) $+ dislikecount  $+ $chr(7) $+ commentcount

  ; Replace mit dem Wraper befüllen
  var %replace $yta_request_result($1).publishedat $+ $chr(7) $+ $yta_request_result($1).title $+ $chr(7) $+ $yta_request_result($1).channeltitle 
  var %replace %replace $+ $chr(7) $+ $yta_request_result($1).duration $+ $chr(7) $+ $yta_request_result($1).favoritecount $+ $chr(7) $+ $yta_request_result($1).viewcount
  var %replace %replace $+ $chr(7) $+ $yta_request_result($1).likecount $+ $chr(7) $+ $yta_request_result($1).dislikecount $+ $chr(7) $+ $yta_request_result($1).commentcount

  var %dst $yta_request_result($1).dest
  var %net $yta_request_result($1).network
  if ( %yta/settings/General/echo == 1 ) {
    echo -gf %dst $yta_replace_placeholder(%yta/settings/Message/msg, %placeholders, %replace)
  } 
  else {
    .msg %dst $yta_replace_placeholder(%yta/settings/Message/msg, %placeholders, %replace)
  }
}

; Entfernt die Spamprotect Variable und Request Variable
; Spamprotect ist fest auf 30 Sekunden einprogrammiert und wenn in der Zeit keine Rückmeldung gekommen ist, 
; kann auch die requests Variable verworfen werden
; Argument $1: Spamprotect Variable Identifikation
alias yta_request_cleanup {
  var %tick %yta/spamprot/ [ $+ [ $1 ]  $+ /tick ]

  unset %yta/spamprot/ [ $+ [ $1 ] $+ /* ]
  unset %yta/ytrequests/ [ $+ [ %tick ] $+ /* ]
}

; Settings in die INI schreiben, Timer und Sockets anhalten und globale Variables löschen
alias yta_uninstall {
  yta_save_config
  sockclose yta/sockets/*

  var %i 1

  while ( %i <= $timer(0) ) {
    var %tname $timer(%i)

    if ( yta/timers/ isin %tname ) {
      .timer $+ %tname off
    }

    inc %i
  }

  unset %yta/*

  echo -ag - YouTube Announcer - Das Script ist nun deaktiviert und sollte auf keine YouTube Links mehr reagieren.
}

; Wenn das Script entladen wird, uninstall ausführen
on *:UNLOAD: {
  yta_uninstall
}

 more Info on this snippet


Read More

Auto Connect/Join/Identify v2.1


image
;Shows a link to the script when you right click a status, query or channel window
menu status,query,channel {
  Auto Connect/Join/Identify v2.1:/sci01
}

;Calls the dialog window initialisation and loads the first tab
alias sci01 { dialog -m scd01 scd01 | set %tab.scd01 1 }

;Initialises the dialog window
dialog scd01 {
  title "Auto Connect/Join/Identify v2.1"
  size -1 -1 355 390
  tab "Server 1", 1, 5 5 345 265
  tab "Server 2", 2
  tab "Server 3", 3
  tab "Server 4", 4
  tab "Server 5", 5

  text "Servers address", 6, 15 30 160 12
  edit "", 7, 15 45 160 20, autohs
  text "Server network", 43, 180 30 160 12
  edit "", 44, 180 45 160 20, autohs

  text "Primary nick", 8, 22 80 75 12
  edit "", 9, 20 94 85 20, autohs
  text "Password", 10, 112 80 75 12
  edit "", 11, 110 94 60 20, autohs
  text "Secondary nick", 40, 22 117 75 12
  edit "", 41, 20 132 85 20, autohs
  box "Nicknames", 48, 15 65 160 100

  text "Add channel to this server", 49, 22 180 140 20
  edit "", 50, 20 194 155 21, autohs
  button "Add Channel", 51, 20 220 155 25
  text "View/delete existing channels", 46, 182 180 150 20
  combo 45, 180 194 155 20, drop
  button "Delete", 52, 180 220 155 25
  box "Channels", 47, 15 165 325 90

  check "A Conn/Join", 33, 188 83 80 12
  check "A Nickname", 34, 188 103 88 12
  check "A Identify", 35, 188 123 80 12
  check "A Ghost", 42, 188 143 80 12
  box "Options", 32, 180 65 100 100

  button "SET", 36, 285 70 55 35
  button "CLOSE", 37, 285 110 55 35, cancel

  box "Help", 38, 5 270 345 110
  text "", 39, 10 283 325 92, multi
}

;On initialisation, display default help text and load first tab
on 1:dialog:scd01:init:*: {
  did -ra $dname 39 Please hover over a button, checkbox or Edit box for help.
  scd01.loadgui 1
}

;loads the gui with the information for the required tab ( called with $1 being tab number )
alias scd01.loadgui { 
  if ($rs($1, AC) == 1) { did -c scd01 33 } 
  else { did -u scd01 33 }
  if ($rs($1, AN) == 1) { did -c scd01 34 } 
  else { did -u scd01 34 }
  if ($rs($1, AP) == 1) { did -c scd01 35 } 
  else { did -u scd01 35 }
  if ($rs($1, AG) == 1) { did -c scd01 42 } 
  else { did -u scd01 42 }
  did -ra scd01 7 $rs($1, Server)
  did -ra scd01 44 $rs($1, Network)
  did -ra scd01 9 $rs($1, Nick)
  did -ra scd01 41 $rs($1, Nick2)
  if ($rs($1, Password) != $null) { did -ra scd01 11 [Hidden] }
  else did -ra scd01 11 [None]

  did -r scd01 45   
  set %rid 0 
  while (%rid < $rs($1,Channels)) {
    did -a scd01 45 $rs($1, Room $+ %rid)
    inc %rid
  }
  unset %rid
}

;When hovering over any of the edit boxes, check boxes or buttons, the help label will display help information for that element
on 1:dialog:scd01:mouse:*: {
  if ($did == 7) { did -ra $dname 39 Enter the server address here. e.g. irc.gamesurge.net }
  elseif ($did == 9) { did -ra $dname 39 Enter the primary Nickname you would like to use on this server. Your nick will automatically be set to what is entered here if you have the Auto Nickname option selected. $crlf $+ If it's already in use, and the Auto-ghost option is ticked, the nick will be ghosted and you will be set to this nick. }
  elseif ($did == 41) { did -ra $dname 39 Enter the secondary Nickname you would like to use on this server. If your Primary nick is already in use, and Auto-ghost is not enabled, your nick will automatically be set to this. }
  elseif ($did == 11) { did -ra $dname 39 Here you will enter the password to the nickname to the left if your nickname is registered and you selected the auto nickname option. Will automatically identify you when nickserv asks for the password }
  elseif ($did == 13) || ($did == 15) || ($did == 17) || ($did == 19) || ($did == 21) || ($did == 23) || ($did == 25) || ($did == 27) || ($did == 29) || ($did == 31) { did -ra $dname 39 If Auto connect is selected, you will join these channels when you connect to this server. }
  elseif ($did == 32) { did -ra $dname 39 Choose which options you would like for this server. Auto connect will automatically connect you to the server and the listed channels. Auto nick will automatically set your nick. Auto Password will automatically identify you when needed. Auto Ghost will ghost your primary nick if it is already in use. If not selected, your secondary nick will be used. $crlf $+ Auto-ghost requires a secondary nick active. }
  elseif ($did == 36) { did -ra $dname 39 By clicking this button all the info in the edit boxes will be saved for this server. }
  elseif ($did == 37) { did -ra $dname 39 By clicking this button all changes will be lost. Be sure to click the Set button is you want to save this configuration. }
  elseif ($did == 44) { did -ra $dname 39 Enter the servers network here. $crlf $+ Find this out by typing '//echo -a $network' whilst connected the the server. eg. GameSurge }
  elseif ($did == 50) || ($did == 51) { did -ra $dname 39 Enter a channel name and then click the Add button to add that channel to this servers autojoin list. If the channel has a password, enter it after the channel. $crlf e.g. #channelwithpassword password }
  elseif ($did == 45) || ($did == 52) { did -ra $dname 39 Use the dropdown menu to view the channels set to automatically join when this server starts. If you wish to delete one, pick it from the list then click the Delete button. }
}

;Listens for clicks on the tabs and set button
on 1:dialog:scd01:sclick:*: {
  ;If a tab is clicked, load that information into the editable fields and textboxes
  if (($did == 1) || ($did == 2) || ($did == 3) || ($did == 4) || ($did == 5)) {
    set %tab.scd01 $did
    scd01.loadgui $did
  }

  ;If the set button is clicked, save all information into the Settings.ini file
  if ($did == 36) {
    if ($did($dname, 7).text != $null) { $ws(%tab.scd01, Server, 7) }
    else { $rms(%tab.scd01, Server) }
    if ($did($dname, 44).text != $null) { $ws(%tab.scd01, Network, 44) }
    else { $rms(%tab.scd01, Network) }
    if ($did($dname, 9).text != $null) { $ws(%tab.scd01, Nick, 9) }
    else { $rms(%tab.scd01, Nick) }
    if ($did($dname, 41).text != $null) { $ws(%tab.scd01, Nick2, 41) }
    else { $rms(%tab.scd01, Nick2) }
    if (($did($dname, 11).text != $null) && ($did($dname, 11).text != [hidden]) && ($did($dname, 11).text != [none])) { $ws(%tab.scd01, Password, 11) }
    if ($did($dname, 11).text == $null) { $rms(%tab.scd01, Password) }

    if ($did($dname, 33).state == 1) { $ws(%tab.scd01, AC, 33) }
    else { $rms(%tab.scd01, AC) }
    if ($did($dname, 34).state == 1) { $ws(%tab.scd01, AN, 34) }
    else { $rms(%tab.scd01, AN) }
    if ($did($dname, 35).state == 1) { $ws(%tab.scd01, AP, 35) }
    else { $rms(%tab.scd01, AP) }
    if ($did($dname, 42).state == 1) { $ws(%tab.scd01, AG, 42) }
    else { $rms(%tab.scd01, AG) }
  }

  ;If the add channel button is clicked, add a channel to the current server in the Settings.ini file
  if ($did == 51) {
    if ($did($dname, 50).text != $null) { 

      if ($rs(%tab.scd01, Channels) != $null) {
        set %channels $rs(%tab.scd01, Channels)
      }
      else set %channels 0

      $ws(%tab.scd01, Room $+ %channels, 50) 
      did -a scd01 45 $rs(%tab.scd01, Room $+ %channels)
      inc %channels
      writeini Settings.ini Server $+ %tab.scd01 Channels %channels
      did -r scd01 50
      unset %channels
    }
  }

  ;If the delete channel button is clicked, delete the current channel in the combo box from the Settings.ini file
  if ($did == 52) {
    if ($did($dname, 45) != $null) {
      set %channels $rs(%tab.scd01, Channels)
      set %n $did($dname, 45).sel
      dec %n
      $rms(%tab.scd01, Room $+ %n)
      did -d scd01 45 $did($dname, 45).sel
      dec %channels
      set %s %n
      while (%n < %channels) {
        inc %s
        writeini Settings.ini Server $+ %tab.scd01 Room $+ %n $rs(%tab.scd01, Room $+ %s)
        inc %n
      }
      $rms(%tab.scd01, Room $+ %n)
      unset %s
      writeini Settings.ini Server $+ %tab.scd01 Channels %channels
      unset %channels
      unset %n
    }
  }
}

;When mIRC starts, connect to each of the servers in the Settings.ini file with the primary nick supplied, if there is one.
on *:Start: {
  if ($rs(1, AC) == 1) { server $rs(1, Server) $iif($rs(1, AN) == 1 && $rs(1, nick) != $null, -i $rs(1, Nick),) }
  set %servc 2
  while (%servc <= 5) {
    if ($rs(%servc, AC) == 1) { 
      server -m $rs(%servc, Server) $iif($rs(%servc, AN) == 1 && $rs(%servc, nick) != $null, -i $rs(%servc, Nick),)
    }
    inc %servc
  }
  unset %servc
}

;When you connect to a server, check that it's one in the Settings.ini file and then connect to the supplied channels
on *:Connect: {
  set %servc 1
  while (%servc <= 5) {
    if (($rs(%servc, Network) == $network) && ($rs(%servc, AC) == 1)) { 
      ;channel counter
      set %chanc 0
      while (%chanc < $rs(%servc, Channels)) {
        join $rs(%servc, Room $+ %chanc)
        inc %chanc
      }
      unset %chanc
      if (($rs(%servc, Password) != $null) && ($rs(%servc, AP) == 1) && ($rs(%servc, nick) == $me)) { nickserv identify $rs(%servc, Password) }
    }
    inc %servc
  }
  unset %servc
}

;When nickserv asks to identify, do so with the supplied password from the Settings.ini file
on *:notice:*:?: {
  if (($nick == nickserv) && (identify isin $1-)) { 
    set %servc 1
    while (%servc <= 5) {
      if (($rs(%servc, AP) == 1) && ($server == $rs(%servc, Server))) {
        nickserv identify $rs(%servc, Password) 
      }
      inc %servc
    }
    unset %servc
  }
}

;When mIRC tells you that your primary nickname is already in use, change to your secondary nick, ghost the primary, and then change to it
raw 433:*:{ 
  autoghost $1-
}
alias autoghost {
  set %servc 1
  while (%servc <= 5) {
    if ($server == $rs(%servc, Server)) && ($rs(%servc, AG) == 1) {
      nick $rs(%servc, Nick2)
      timerghost1 1 2 nickserv ghost $2 $rs(%servc, Password)
      timerghost2 1 3 nick $2
    }
    inc %servc
  }
  unset %servc
}

;called by $rs(server number, item)
alias rs {
  return $readini(Settings.ini, Server $+ $1, $2)
}

;called by $ws(server number, item, id to read from)
alias ws {
  ;if it's a check box, write the checkboxes state, else write the editboxes text
  if ($3 == 33) || ($3 == 34) || ($3 == 35) || ($3 == 42) writeini Settings.ini Server $+ $1 $2 1
  else writeini Settings.ini Server $+ $1 $2 $did($dname,$3).text
}

;called by $rms(server number, item)
alias rms {
  remini Settings.ini Server $+ $1 $2
}


Auto Connect/Join/Identify v1.0

Read More

mIRC Spotify Now Playing


image
    ; spotify now playing script
    ; written by Aaron Blakely <aaron@ephasic.org>
    ;
    ; Requires spotify.dll, get it here: http://www.tg007.net/dls/file/1460
    ; Put spotify.dll in your mIRC directory.
     
     
    on *:START: {
      timer -o 0 1 setnp
    }
     
    alias spotifynp {
      ; used for including this np in your own scripts
      ; not much other use, change the format here or do some
      ; string opperations in your own alais, to extract the data.
      ; ~ Aaron
     
      return $dll(spotify.dll, song,) - $dll(spotify.dll, artist,)
    }
     
    alias setnp {
      if (%lastnp != $spotifynp) {
        set %lastnp $v2
        clipboard $v2
      }
    }
     
    alias np {
      ; change the format if you desire.
      ; artist: $dll(spotify.dll, artist,)
      ; song: $dll(spotify.dll, song,)
      ; Will add support for others soon.
      ; ~ Aaron
      me is listening to ' $+ $dll(spotify.dll, song,) $+ ' by $dll(spotify.dll, artist, ) on Spotify.
    }




Read More