Posted to tcl by Simbaa at Tue Oct 17 17:11:53 GMT 2017view raw

  1. ###############################################################################################################################
  2. # #
  3. # LoReZ ShoutCast Script v2.1 (sc.tcl) #
  4. # Email: lorez@bigvibez.com #
  5. # IRC: #bigvibez @ Quakenet #
  6. # #
  7. # Please contact me if you notice any bugs #
  8. # #
  9. # Installation: Put the script and the config file into your scripts directory, add "source scripts/sc.tcl" to your eggdrop #
  10. # config and rehash the bot. (http package is REQUIRED for this script to work) # #
  11. # #
  12. ###############################################################################################################################
  13.  
  14. ###############################################################################################################################
  15. # START OF TCL CODE #
  16. ###############################################################################################################################
  17.  
  18. package require http
  19. namespace eval sc {
  20. variable vars
  21. variable sets
  22. variable triggers
  23. variable texts
  24. variable offadv 0
  25. source scripts/sc.cfg
  26. proc init {} {
  27. set start [clock clicks]
  28. set sc::offadv 0
  29. bind time - "* * * * *" sc::check
  30. bind nick - * sc::nick
  31. foreach x [array names sc::triggers] {
  32. if {$sc::sets(pub) == 1} {
  33. bind pub [expr {($x == "kick") || ($x == "setdj") || ($x == "unsetdj") ? "$sc::vars(flag)" : "-"}] $sc::vars(trigger)$sc::triggers($x) "sc::pub $x"
  34. }
  35. if {$sc::sets(msg) == 1} {
  36. bind msg [expr {($x == "kick") || ($x == "setdj") || ($x == "unsetdj") ? "$sc::vars(flag)" : "-"}] $sc::vars(trigger)$sc::triggers($x) "sc::msg $x"
  37. }
  38. }
  39. if {$sc::sets(adv) == 1} {
  40. timer $sc::sets(advtime) "sc::post privmsg none all {$sc::texts(adv)}"
  41. }
  42. putlog "sc.tcl v2.1 by LoReZ successfully initialized in [expr {([clock clicks]-$start)/1000.0}]ms"
  43. }
  44. proc pub {text nick uhost hand chan args} {
  45. if {([lsearch -exact [string tolower $sc::vars(chans)] [string tolower $chan]] != -1) || ($sc::vars(chans) == "")} {
  46. sc::cmd $text $nick $chan $args
  47. }
  48. }
  49. proc msg {text nick uhost hand args} {
  50. sc::cmd $text $nick none $args
  51. }
  52. proc nick {nick uhost hand chan newnick} {
  53. set tmp [open $sc::vars(file) r]
  54. gets $tmp streamdata
  55. gets $tmp songdata
  56. gets $tmp djdata
  57. close $tmp
  58. if {$nick == [lindex $djdata 0]} {
  59. set tmp [open $sc::vars(file) w+]
  60. puts $tmp $streamdata
  61. puts $tmp $songdata
  62. puts $tmp "$newnick [expr {([lindex $djdata 1] == $nick) ? $newnick : [lindex $djdata 1]}] [lrange $djdata 2 end]"
  63. close $tmp
  64. if {([lindex $djdata 1] == $nick) && ($sc::sets(djtopchg) == 1)} {
  65. sc::post topic none all "$sc::texts(djtopic)"
  66. }
  67. }
  68. }
  69. proc cmd {text nick chan args} {
  70. if {[file exists $sc::vars(file)] != 1} {
  71. sc::check * * * * *
  72. }
  73. set tmp [open $sc::vars(file) r]
  74. gets $tmp streamdata
  75. gets $tmp songdata
  76. gets $tmp djdata
  77. close $tmp
  78. switch -exact $text {
  79. help {
  80. set sc::offadv 1
  81. putquick "privmsg $nick :Available Commands:"
  82. foreach x [array names sc::triggers] {
  83. if {$x != "help"} {
  84. if {(([matchattr [nick2hand $nick $chan] +$sc::vars(flag) $chan] != 1) && ($x != "kick") && ($x != "setdj") && ($x != "unsetdj")) || ([matchattr [nick2hand $nick $chan] +$sc::vars(flag) $chan] == 1)} {
  85. set sc::offadv 1
  86. putquick "privmsg $nick :$sc::vars(trigger)[expr {($x == "setdj") ? "$sc::triggers($x) <djname> <showname>" : [expr {(($x == "wish") || ($x == "greet")) ? "$sc::triggers($x) <$x>" : "$sc::triggers($x)"}]}]"
  87. }
  88. }
  89. }
  90. set sc::offadv 1
  91. putquick "privmsg $nick :End of Commands"
  92. }
  93. kick {
  94. putquick "privmsg $nick :Source successfully kicked"
  95. if {[lindex $streamdata 15] == 1} {
  96. set sock [socket $sc::vars(ip) $sc::vars(port)]
  97. puts $sock "GET /admin.cgi?mode=kicksrc HTTP/1.1"
  98. puts $sock "User-Agent:Mozilla"
  99. puts $sock "Host: $sc::vars(ip)"
  100. puts $sock "Authorization: Basic $sc::vars(adpass)"
  101. puts $sock ""
  102. flush $sock
  103. }
  104. }
  105. setdj {
  106. putquick "privmsg $nick :New DJ set"
  107. if {[lindex $streamdata 15] == 1} {
  108. set tmp [open $sc::vars(file) w+]
  109. puts $tmp $streamdata
  110. puts $tmp $songdata
  111. puts $tmp "$nick [expr {([lindex $args 0] == "{}") ? $nick : [lindex [lindex $args 0] 0]}] [lrange [lindex $args 0] 1 end]"
  112. close $tmp
  113. if {$sc::sets(anndj) == 1} {
  114. sc::post privmsg none all "$sc::texts(djchg)"
  115. }
  116. if {$sc::sets(djtopchg) == 1} {
  117. sc::post topic none all "$sc::texts(djtopic)"
  118. }
  119. }
  120. }
  121. unsetdj {
  122. putquick "privmsg $nick :DJ unset"
  123. if {[lindex $streamdata 15] == 1} {
  124. set tmp [open $sc::vars(file) w+]
  125. puts $tmp $streamdata
  126. puts $tmp $songdata
  127. puts $tmp "none none none"
  128. close $tmp
  129. if {$sc::sets(anndj) == 1} {
  130. sc::post privmsg none all "$sc::texts(djchg)"
  131. }
  132. if {$sc::sets(djtopchg) == 1} {
  133. sc::post topic none all "$sc::texts(ontopic)"
  134. }
  135. }
  136. }
  137. default {
  138. if {($text != "wish") && ($text != "greet")} {
  139. sc::post privmsg $nick $chan "$sc::texts($text)"
  140. } else {
  141. if {[lindex $streamdata 15] == 1} {
  142. if {([lindex $args 0] == "{}")} {
  143. putquick "privmsg $nick :Nothing specified"
  144. } else {
  145. if {[lindex $djdata 1] == "none"} {
  146. putquick "privmsg $sc::vars(intern) :[string totitle $text] by $nick: $args"
  147. } else {
  148. putquick "privmsg [expr {($sc::sets(wishgreet) == 1) ? $sc::vars(intern) : [lindex $djdata 0]}] :[string totitle $text] by $nick: $args"
  149. putquick "privmsg $nick :[string totitle $text] sent to [expr {($sc::sets(wishgreet) == 1) ? $sc::vars(intern) : [lindex $djdata 0]}]"
  150. }
  151. }
  152. } else {
  153. sc::post privmsg $nick none "$sc::texts(offcmd)"
  154. }
  155. }
  156. }
  157. }
  158. putlog "sc.tcl v2.1 $nick used $sc::vars(trigger)$sc::triggers($text)"
  159. }
  160. proc check {min hour day month year} {
  161. set start [clock clicks]
  162. if {[file exists $sc::vars(file)] == 1} {
  163. set tmp [open $sc::vars(file) r]
  164. gets $tmp olddata
  165. gets $tmp songdata
  166. gets $tmp djdata
  167. close $tmp
  168. } else {
  169. set olddata "0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0"
  170. set djdata "none none none"
  171. }
  172. http::config -useragent "Mozilla 5.0"
  173. set con [http::geturl http://$sc::vars(ip):$sc::vars(port)/admin.cgi?pass=$sc::vars(pass)&mode=viewxml&page=0 -timeout 10000]
  174. set urldata [http::data $con]
  175. http::cleanup $con
  176. foreach {y z} {21 ! 22 \" 23 # 24 \$ 25 % 26 + 27 ' 28 \( 29 \) 2A * 2B + 2C , 2E . 2F / 3A : 3B \; 3C < 3D = 3E > 3F ? 40 @ 5B \[ 5C \\ 5D \] 5F _ 60 ` C0 À C1 Á C2 Â C3 Ã C4 Ä C5 Å C6 Æ C7 Ç C8 È C9 É CA Ê CB Ë CC Ì CD Í CE Î CF Ï D1 Ñ D2 Ò D3 Ó D4 Ô D5 Õ D6 Ö D9 Ù DA Ú DB Û DC Ü DD Ý DF ß E0 à E1 á E2 â E3 ã E4 ä E5 å E6 æ E7 ç E8 è E9 é EA ê EB ë EC ì ED í EE î EF ï F0 ð F1 ñ F2 ò F3 ó F4 ô F5 õ F6 ö F9 ù FA ú FB û FC ü FD ý FE þ FF ÿ} {
  177. regsub -all "&#x$y;" $urldata "$z" urldata
  178. }
  179. regsub -all ".*<SHOUTCASTSERVER>" $urldata "" data1
  180. regsub -all "<WEBDATA>.*" $data1 "" data1
  181. regsub -all ".*<SONGHISTORY>" $urldata "\{" data2
  182. regsub -all "</SONGHISTORY>.*" $data2 " \}" data2
  183. set x 0
  184. foreach y {CURRENTLISTENERS PEAKLISTENERS MAXLISTENERS REPORTEDLISTENERS AVERAGETIME SERVERGENRE SERVERURL SERVERTITLE SONGTITLE SONGURL IRC ICQ AIM WEBHITS STREAMHITS STREAMSTATUS BITRATE CONTENT VERSION SONG PLAYEDAT TITLE} {
  185. if {$x < 19} {
  186. regsub -all ".*<$y>" $data1 "" data10
  187. regsub -all "</$y>.*" $data10 "" data10
  188. lappend streamdata [expr {(($data10 == "0") || ($data10 == "")) && ([string match -nocase *listeners "$y"] != 1) && ([string match -nocase *hits "$y"] != 1) && ([string match -nocase *time "$y"] != 1) ? "N/A" : $data10}]
  189. }
  190. if {$x > 18} {
  191. regsub -all "<$y>" $data2 "\{" data2
  192. regsub -all "</$y>" $data2 "\} " data2
  193. }
  194. incr x
  195. }
  196. set tmp [open $sc::vars(file) w+]
  197. puts $tmp $streamdata
  198. puts $tmp $data2
  199. puts $tmp $djdata
  200. close $tmp
  201. if {[lindex $olddata 15] != [lindex $streamdata 15]} {
  202. if { ($sc::sets(ann) == 1)} {
  203. set sc::offadv [expr {([lindex $streamdata 15] == 1) ? 0 : 1}]
  204. sc::post privmsg none all "[expr {([lindex $streamdata 15] == 1) ? $sc::texts(on) : $sc::texts(off)}]"
  205. }
  206. if {$sc::sets(topchg) == 1} {
  207. set sc::offadv [expr {([lindex $streamdata 15] == 1) ? 0 : 1}]
  208. sc::post topic none all "[expr {([lindex $streamdata 15] == 1) ? $sc::texts(ontopic) : $sc::texts(offtopic)}]"
  209. }
  210. }
  211. foreach {x y z} {8 anntrack songchg 0 annlist listchg 1 annpeak peakchg 16 annbitrate bitratechg} {
  212. if {([lindex $olddata $x] != [lindex $streamdata $x]) && ($sc::sets($y) == 1)} {
  213. sc::post privmsg all all "$sc::texts($z)"
  214. }
  215. }
  216. putlog "sc.tcl v2.1 received information from $sc::vars(ip):$sc::vars(port) in [expr {([clock clicks]-$start)/1000.0}]ms"
  217. }
  218. proc post {mode nick chan text} {
  219. set tmp [open $sc::vars(file) r]
  220. gets $tmp streamdata
  221. gets $tmp songdata
  222. gets $tmp djdata
  223. close $tmp
  224. if {([lindex $streamdata 15] == 1) || ($sc::offadv == 1)} {
  225. foreach x [lindex $songdata 0] {
  226. append lastsongs "[lindex $x 1] :: "
  227. }
  228. lappend streamdata $sc::vars(ip) $sc::vars(port) $sc::vars(desc) ":: $lastsongs" [expr {(([lindex $djdata 0] == "none") || ([lindex $djdata 0] == "{}") || ([lindex $djdata 0] == "")) ? "No DJ" : [lindex $djdata 0]}] [expr {(([lindex $djdata 1] == "none") || ([lindex $djdata 1] == "{}") || ([lindex $djdata 1] == "")) ? "No DJ" : [lindex $djdata 1]}] [expr {(([lindex $djdata 2] == "none") || ([lindex $djdata 2] == "{}") || ([lindex $djdata 2] == "")) ? "No Show" : [lrange $djdata 2 end]}] [expr {([lindex $streamdata 15] == 1) ? "online" : "offline"}]
  229. set x 0
  230. foreach y {listeners peak max unique avgtime genre url title song songurl irc icq aim webhits streamhits streamstatus bitrate content version ip port desc lastsongs djnick dj showname status} {
  231. regsub -all "%$y" $text "[lindex $streamdata $x]" text
  232. incr x
  233. }
  234. if {$mode == "topic"} {
  235. foreach chans [channels] {
  236. if {$sc::vars(chans) == ""} {
  237. if {$sc::sets(qtopic) == 1} {
  238. putquick "privmsg TheQBot@CServe.quakenet.org :SETTOPIC $chans $text"
  239. } else {
  240. putquick "$mode $chans :$text"
  241. }
  242. } else {
  243. if {([lsearch -exact [string tolower $sc::vars(chans)] [string tolower $chans]] != -1)} {
  244. if {$sc::sets(qtopic) == 1} {
  245. putquick "privmsg TheQBot@CServe.quakenet.org :SETTOPIC $chans $text"
  246. } else {
  247. putquick "$mode $chans :$text"
  248. }
  249. }
  250. }
  251. }
  252. } else {
  253. if {($sc::sets(reply) != 1) || ($chan == "none")} {
  254. putquick "$mode $nick :$text"
  255. }
  256. if {(($sc::sets(reply) == 1) && ($chan != "none")) || ($chan == "all")} {
  257. foreach chans [channels] {
  258. if {$sc::vars(chans) == ""} {
  259. putquick "$mode $chans :$text"
  260. } else {
  261. if {([lsearch -exact [string tolower $sc::vars(chans)] [string tolower $chans]] != -1)} {
  262. putquick "$mode $chans :$text"
  263. }
  264. }
  265. }
  266. }
  267. }
  268. } else {
  269. putquick "$mode [expr {((($sc::sets(reply) != 1) || ($chan == "none")) && ($chan != "all")) ? $nick : $chan}] :$sc::texts(offcmd)"
  270. }
  271. set sc::offadv 0
  272. }
  273. sc::init
  274. }
  275.  
  276. ###############################################################################################################################
  277. # END OF TCL CODE #
  278. ###############################################################################################################################
  279.