mIRC SHOUTcast Bot v1.3

By dsabecky on May 19, 2011

This script allows for a simple SHOUTcast stream management bot to reside in your channel, while announcing current playing songs. I've been adding little improvements here and there, and I'm willing to take suggestions for features.

Configure:
Set the variables under the "Configuration" section, then restart mIRC and the bot will do the rest. :)

It includes:

  • Auto announce (for songs on the shoutcast stream)
  • Manage topic (changes topic when DJ changes)
  • Auto connect / identify (Anope; nickserv)

Commands (that require the user to have @op to use):
!kickdj - kicks active dj
!info - messages user stream information (eg: url, port, dj pass, etc)
!cycle - bot does a /hop

Commands (anyone can use):
!dj - messages user current DJ
!song - messages user current song
!tune/!url/!listen - messages user the link to the stream
!listeners - messages the user with current listener amount

Changelog:

1.3
Cleaned up source code so it's readable by human eyes.
Removed !stats.

1.2
Fixed issue with raw XML leaking into variables.

1.1
Rewrote the XML parser which fixes the song announce loop.

1.0.1
Fixed issue with topic not updating properly.

1.0
Initial version.

This code is released under the public domain.

; This code is released under the public domain.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                 ;; 
;;  CONFIGURATION  ;;
;;                 ;;
;;;;;;;;;;;;;;;;;;;;;

alias sc_cfg {

  ; website URL
  set %stream.site http://google.com

  ; stream url (without http:// or trailing slash)
  set %stream.url listen.google.com

  ; radio stations name
  set %stream.name Google's Online Radio

  ; port that the server runs on
  set %stream.port 8000

  ; admin username (usually admin)
  set %stream.user admin

  ; admin password
  set %stream.adpass QW#h34h4sdfGHES

  ; dj password
  set %stream.djpass poiuytrewq

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  ; manage topic (1 is on, 0 is off)
  set %cfg.top 1

  ; announce new song (1 is on, 0 is off)
  set %cfg.ann 1

  ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

  ; bots nick
  set %irc.nick Google

  ; bots alt nick
  set %irc.anick Google_

  ; bots username
  set %irc.user Google

  ; bots realname
  set %irc.name Google IRC Bot

  ; irc server
  set %irc.server irc.google.com

  ; irc port (prepend + for SSL servers)
  set %irc.port +7000

  ; irc channel
  set %irc.chan #radio

  ; NickServ password
  set %irc.pass q3w24yh%W$%Ty#Q$GF#5rGHERhsef
}

; channel topic format
alias sc.topic { return %stream.name $chr(124) Current DJ: $iif(%sc.status == 1,%sc.dj,None) $chr(124) %stream.site }

; song announce format
alias sc.ann { return %sc.dj is playing %sc.song }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                ;;
;;  ON FUNCTIONS  ;;
;;                ;;
;;;;;;;;;;;;;;;;;;;;

on *:start: {

  ; set variables
  sc_cfg

  ; connect to server
  server %irc.server %irc.port -i %irc.nick %irc.anick %irc.user %irc.name

}

on *:notice:*This nickname is registered and protected.*:*: { .msg NickServ IDENTIFY %irc.pass }

on *:notice:*Password accepted - you are now recognized.*:*: { .join %irc.chan }

on *:join:%irc.chan: { $iif($nick == $me, .timercon 0 10 sc_con) }

on *:disconnect: { .timers off }

on *:kick:%irc.chan: { $iif($knick == $me, timers off) }

on *:part:%irc.chan: { $iif($nick == $me, timers off) }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;               ;;
;;  SC COMMANDS  ;;
;;               ;;
;;;;;;;;;;;;;;;;;;;

; connect to shoutcast server
alias sc_con {
  if ($sock(sc).to == $null) { sockopen sc %stream.url %stream.port  }
  elseif ($sock(sc).to > 8) { sockclose sc | sockopen sc %stream.url %stream.port }
}

; kick dj
alias sc_kick { sockopen sckick %stream.url %stream.port }

; topic change
alias sc_topic { if (%cfg.top == 1) { topic %irc.chan $sc.topic } }

; song announce
alias sc_msg { if (%cfg.ann == 1) { msg %irc.chan $sc.ann } }

; send error message to user
alias sc_errmsg {
  if ($1 == op) { msg $2 You must have @ (operator) status to use this. }
  if ($1 == offline) { msg $2 The stream is currently offline. }
}

; filters characters back from html ascii codes
alias sc_filter { return $replace($1-, &#x26 $+ $chr(59), $chr(38), &#x27 $+ $chr(59), $chr(39)) }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                ;;
;;  @OP TRIGGERS  ;;
;;                ;;
;;;;;;;;;;;;;;;;;;;;

; !cycle: bot /cycles in channel
on *:text:!cycle:%irc.chan: {
  if ($nick isop %irc.chan) { hop %irc.chan }
  else { sc_errmsg op $nick }
}

; !info: sends the required dj information
on *:text:!info:%irc.chan: {
  if ($nick isop %irc.chan) {
    msg $nick host: %stream.url port: %stream.port pass: %stream.djpass
    msg $nick description: %stream.name url: %stream.site aim: Use your DJ name irc: %irc.chan
  }
  else { sc_errmsg op $nick }
}

; !kickdj: kicks current dj
on *:text:!kickdj:%irc.chan: {
  if ($nick isop %irc.chan) { sc_kick | msg %irc.chan Kicking current DJ.. }
  else { sc_errmsg op $nick }
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                 ;;
;;  USER TRIGGERS  ;;
;;                 ;;
;;;;;;;;;;;;;;;;;;;;;

; !dj: sends active dj
on *:text:!dj:%irc.chan: {
  if (%sc.status == 1) { msg $nick Current DJ: %sc.dj }
  else { sc_errmsg offline $nick }
}

; !song: sends the current song
on *:text:!song:%irc.chan: {
  if (%sc.status == 1) { msg $nick Playing: %sc.song }
  else { sc_errmsg offline $nick }
}

on *:text:!listeners:%irc.chan: {
  if (%sc.status == 1) { msg $nick Listeners: %sc.clisten $+ / $+ %sc.mlisten ( $+ %sc.dj $+ ) }
  else { errmsg offline $nick }
}

on *:text:!tune:%irc.chan: { msg $nick Tune in at: http:// $+ %stream.url $+ : $+ %stream.port $+ /listen.pls }
on *:text:!url:%irc.chan: { msg $nick Tune in at: http:// $+ %stream.url $+ : $+ %stream.port $+ /listen.pls }
on *:text:!listen:%irc.chan: { msg $nick Tune in at: http:// $+ %stream.url $+ : $+ %stream.port $+ /listen.pls }

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;                ;;
;;  KICK SOCKETS  ;;
;;                ;;
;;;;;;;;;;;;;;;;;;;;

on *:sockopen:sckick: {
  sockwrite -nt sckick GET /admin.cgi?mode=kicksrc HTTP/1.0
  sockwrite -nt sckick User-Agent: Mozilla/5.0
  sockwrite -nt sckick Accept: text/xml,application/xml,application/xhtml+xml,text/html
  sockwrite -nt sckick Authorization: Basic $encode(%stream.user $+ : $+ %stream.adpass, m)
  sockwrite -nt sckick $crlf
}

on *:sockread:sckick: {
  sockread -fn %tmp
  if (HTTP/1.0 302 Found isin %tmp) { msg %irc.chan ..DJ was successfully kicked. }
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;               ;;
;;  XML SOCKETS  ;;
;;               ;;
;;;;;;;;;;;;;;;;;;;

on *:sockopen:sc: {
  sockwrite -nt sc GET /admin.cgi?mode=viewxml HTTP/1.0
  sockwrite -nt sc User-Agent: Mozilla/5.0
  sockwrite -nt sc Accept: text/xml,application/xml,application/xhtml+xml,text/html
  sockwrite -nt sc Authorization: Basic $encode(%stream.user $+ : $+ %stream.adpass, m)
  sockwrite -nt sc $crlf
}

on *:sockread:sc: {
  sockread -fn %xml

  ; assign variable in proper order, halt reading, scan info, relay, garbage collection!
  if (<?xml isin %xml) { set %a $mid(%xml,2033,$len(%xml)) }
  elseif (> isin %xml) { set %a %a $+ %xml }

  if (</SHOUTCASTSERVER> isin %a) {

    HALTDEF
    unset %xml

    ; dj
    var %z $sc_filter($left($gettok($replace(%a, <AIM>, $chr(189), </AIM>, $chr(189)),2,189),$len($gettok($replace(%a, <AIM>, $chr(189), </AIM>, $chr(189)),2,189))))
    if (%z != %sc.dj) && (%sc.dj) { set %sc.dj %z | sc_topic }
    else { set %sc.dj %z }

    ; status
    var %z $gettok($replace(%a, <STREAMSTATUS>, $chr(189), </STREAMSTATUS>, $chr(189)),2,189)
    if (%z != %sc.status) && (%sc.status) { set %sc.status %z | sc_topic }
    else { set %sc.status %z }

    ; current listeners
    var %z $gettok($replace(%a, <CURRENTLISTENERS>, $chr(189), </CURRENTLISTENERS>, $chr(189)),2,189)
    set %sc.clisten %z

    ; peak listeners
    var %z $gettok($replace(%a, <PEAKLISTENERS>, $chr(189), </PEAKLISTENERS>, $chr(189)),2,189)
    set %sc.plisten %z

    ; max listeners
    var %z $gettok($replace(%a, <MAXLISTENERS>, $chr(189), </MAXLISTENERS>, $chr(189)),2,189)
    set %sc.mlisten %z

    ; genre
    var %z $gettok($replace(%a, <SERVERGENRE>, $chr(189), </SERVERGENRE>, $chr(189)),2,189)
    set %sc.genre %z

    ; song title
    var %z $sc_filter($left($gettok($replace(%a, <SONGTITLE>, $chr(189), </SONGTITLE>, $chr(189)),2,189),$len($gettok($replace(%a, <SONGTITLE>, $chr(189), </SONGTITLE>, $chr(189)),2,189))))
    if (%z != %sc.song) { set %sc.song %z | sc_msg }

    unset %a
  }
}

Comments

Sign in to comment.
Chemich   -  Mar 18, 2015

Question regarding this script, I setup an AutoDJ on Winamp and when I do !dj when it's connected this happens. Would there be any means to fixing this?

 Respond  
MrKrotos   -  Jan 19, 2015

Great script! One question though :P
If the track title contains special chars like ampersand & this is shown in IRC as the html type code.
I see there is "htmlconv()", is this what I would need to show these chars correctly? Or maybe the reverse?

ProIcons  -  Jan 20, 2015

.

Sign in to comment

LegallyBrunette2013   -  Aug 19, 2014

looking for a script that will have a dj radio announcer and also a !request so that when someone puts that in the channel it automatically will also go to channel and the DJ that is djing at the time any help would be greatly appreciated

 Respond  
ProIcons   -  Jul 09, 2012

Well it should work fine. Provide me in message your Shoutcast's IP Address and etc, to check it up

 Respond  
DragonHeart   -  Jul 07, 2012

ProIcons? Any luck?

 Respond  
DragonHeart   -  Mar 17, 2012

yes, I can get the info from my shoutcast page.

 Respond  
ProIcons   -  Mar 16, 2012

In order to to that DragonHeart, your shoutcast server must support this feature, if you still interesting and in your shoutcast panel this feature exists reply.

DragonHeart  -  Apr 19, 2015

Any luck?

Sign in to comment

DragonHeart   -  Mar 16, 2012

Are you able to add a !last10 songs played feature?

 Respond  
opt1cal   -  Feb 28, 2012

I'll be the first to admit that I don't know a great deal about scripting in mIRC etc so please forgive the newbie question.
I'm just going through the config settings, and want to know what parts need to be changed
here is the original text in the script

; website URL
set %stream.site http://google.com

and this is what i've changed it to

; website URL
set %stream.site http://www.trivialityzone.co.uk/news.php

is that the correct format? just want to clear that up before i go do the rest :)

 Respond  
ProIcons   -  Aug 18, 2011

just give me a live working example to check it...

 Respond  
StonaJakey   -  Aug 18, 2011

http://91.121.xxx.xxx:8000/admin.cgi?sid=1

the admin panel is the same, only difference is the link you use to get to it, along with the different config settings for 2.0 (alot more customizable)

you can view the conf builder here: http://bogproghome.hopto.org/config_builder/config_builder.html

ive looked over and tested a bunch of shoutcast scripts, the biggest issue seems to be the song announce, they usually end up looking like a bunch of weird text as its trying to pull the info from the wrong url.

 Respond  
ProIcons   -  Aug 17, 2011

give me a sample link of the panel of the new shoutcast

 Respond  
StonaJakey   -  Aug 17, 2011

Does this work with the shoutcast 2.0 server? or only the 1.9.8 version?

 Respond  
dsabecky   -  May 29, 2011

@troll: Load it in your remotes, set the variables, restart the IRC client.

 Respond  
troll   -  May 25, 2011

cant get it to work

 Respond  
jasonh   -  May 22, 2011

thanks for sharing this script, works great.

 Respond  
DragonHeart   -  May 21, 2011

Also being able to have 2 links (one for hi-fi and one for lo-fi) would be a cool feature.

 Respond  
ProIcons   -  May 21, 2011

Anyway Pretty coded, nice job.

 Respond  
Jethro   -  May 21, 2011

I believe in you, dsabecky. Don't let us down and keep up the good work.

 Respond  
dsabecky   -  May 20, 2011

DragonHeart: I'll keep that in mind. Sounds like a nice feature to have.

 Respond  
dsabecky   -  May 20, 2011

Prolcons: You may have seen it on my site (pentarserv.com/src) or on pastebin where I host the code and use the embed feature for my site. Other than that, I wrote it myself.

 Respond  
Jethro   -  May 20, 2011

Prolcons, if you want to accuse someone of claiming other people's work as his or her own, be sure to provide a link or any reliable source that resembles or mimics the code. "I think" are two words that are too flimsy for an accusation.

 Respond  
ProIcons   -  May 20, 2011

I thing i have seen this code before... is it yours?

 Respond  
DragonHeart   -  May 20, 2011

How about the !last10 feature to show the last 10 songs played?

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.