tclserv

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 7693825f4f605b4f1c7701af5348d2e7ed704aa3
parent 73391b1705bf318fb2484e34f7a8ecd12feb2b16
Author: Jaffa Cake <j4jackj@template.hostname>
Date:   Sun, 10 Aug 2014 07:16:37 -0400

topic lock.

Diffstat:
Mchanserv.help | 6+++++-
Mcore/0002-p10.tcl | 13+++++++++++++
Dmodules/0001-chanserv.tcl | 289------------------------------------------------------------------------------
Amodules/0001-eggcompat.tcl | 303+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Amodules/0005-chanserv.tcl | 310+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dmodules/0005-eggcompat.tcl | 301-------------------------------------------------------------------------------
6 files changed, 631 insertions(+), 591 deletions(-)

diff --git a/chanserv.help b/chanserv.help @@ -32,9 +32,13 @@ channel protection bot. operators on the chattr list. autohalfop Automatically give half operator to all channel half operators on the chattr list. - ... and so on with voice and the various bitches, with a new one: + ... and so on with voice and the various bitches, with a few new ones: operit Automatically op all IRC operators, halfop all network halfops and voice all network voices. + topiclock Locks the channel topic to be whatever you + set with topic. + +topic lsu channel View the userlist for a channel. diff --git a/core/0002-p10.tcl b/core/0002-p10.tcl @@ -20,6 +20,15 @@ proc ::p10::sendSid {sck sname sid {realname "In use by Services"}} { puts $sck $sl } +proc ::p10::topic {sck uid targ topic} { + set sid [string repeat "A" [expr {2-[string length [b64e $::numeric]]}]] + append sid [b64e $::numeric] + set sendid [b64e $uid] + set sendnn [string repeat "A" [expr {3-[string length $sendid]}]] + append sendnn $sendid + puts $sck [format "%s%s T %s :%s" $sid $sendnn $targ $topic] +} + proc ::p10::privmsg {sck uid targ msg} { global sid set sendid [b64e $uid] @@ -157,6 +166,10 @@ proc ::p10::irc-main {sck} { tnda set "channels/$::netname($sck)/$chan/$::netname($sck)/ts" [lindex $comd 3] } + "T" { + callbind $sck topic "-" "-" [lindex $comd 2] [join $payload " "] + } + "OM" { set ctr 3 foreach {c} [split [lindex $comd 3] {}] { diff --git a/modules/0001-chanserv.tcl b/modules/0001-chanserv.tcl @@ -1,289 +0,0 @@ -source chanserv.conf -$::maintype sendUid $sock $cs(nick) $cs(ident) $cs(host) $cs(host) 77 "Channels Server" -bind $::sock msg 77 "register" regchan -bind $::sock msg 77 "adduser" adduserchan -bind $::sock msg 77 "users" lsuchan -bind $::sock msg 77 "lsu" lsuchan -bind $::sock msg 77 "convertop" convertop -#bind $::sock msg 77 "deluser" deluserchan -bind $::sock msg 77 "up" upchan -bind $::sock pub "-" "@up" upchanfant -bind $::sock pub "-" "@rand" randfant -bind $::sock pub "-" "@request" requestbot -bind $::sock msg 77 "down" downchan -bind $::sock msg 77 "hello" regnick -bind $::sock msg 77 "chpass" chpassnick -bind $::sock msg 77 "login" idnick -bind $::sock msg 77 "help" chanhelp -bind $::sock msg 77 "cookie" authin -bind $::sock msg 77 "cauth" cookieauthin -bind $::sock mode "-" "+" checkop -bind $::sock mode "-" "-" checkdeop -bind $::sock create "-" "-" checkcreate - -proc authin {from msg} { - set uname [lindex $msg 0 0] - if {[string first "/" $uname] != -1} {return} - $::maintype notice $::sock 77 $from "CHALLENGE [set cookie [b64e [rand 1000000000 9999999999]]] SHA1" - tnda set "cookieauth/$from/cookie" $cookie - tnda set "cookieauth/$from/name" $uname -} - -proc cookieauthin {from msg} { - set uname [lindex $msg 0 0] - set response [lindex $msg 0 1] - if {[string first "/" $uname] != -1} {return} - if {$response == ""} {return} - set checkresp "[tnda get "cookieauth/$from/name"]:[nda get "usernames/[string tolower $uname]/password"]:[tnda get "cookieauth/$from/cookie"]" - set isresp [pwhash "$checkresp"] - puts stdout "$response $isresp $checkresp" - if {$response == $isresp} { - $::maintype notice $::sock 77 $from "You have successfully logged in as $uname." - $::maintype setacct $::sock $from $uname - callbind $::sock evnt "-" "login" $from $uname - } { - $::maintype notice $::sock 77 $from "You used the wrong password; try again." - } -} - -proc randfant {cname msg} { - set from [lindex $msg 0 0] - set froni [tnda get "nick/$::netname($::sock)/$from"] - if {![string is integer [lindex $msg 1 0]] ||![string is integer [lindex $msg 1 1]]} {return} - if {(""==[lindex $msg 1 0]) || (""==[lindex $msg 1 1])} {return} - if {[lindex $msg 1 0] == [lindex $msg 1 1]} {$::maintype privmsg $::sock 77 $cname "\002$froni:\002 Your request would have caused a divide by zero and was not processed.";return} - $::maintype privmsg $::sock 77 $cname "\002$froni:\002 Your die rolled [rand [lindex $msg 1 0] [lindex $msg 1 1]]" -} - -proc lsuchan {from msg} { - set cname [lindex $msg 0 0] - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {[string length [nda get "regchan/$ndacname"]] == 0} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "Channel does not exist." - return - } - set xses [nda get "regchan/$ndacname/levels"] - $::maintype notice $::sock 77 $from "Access | Flags | Username" - $::maintype notice $::sock 77 $from "-------+------------------" - foreach {nick lev} $xses { - if {$lev == 0} {continue} - # Case above? User not actually on access list - set nl [format "%3d" $lev] - set repeats [string repeat " " [expr {6-[string length [nda get "eggcompat/attrs/$ndacname/$nick"]]}]] - $::maintype notice $::sock 77 $from " $nl | $repeats[string range [nda get "eggcompat/attrs/$ndacname/$nick"] 0 5] | $nick" - } - $::maintype notice $::sock 77 $from "-------+------------------" - $::maintype notice $::sock 77 $from " | End of access list" -} - -proc upchanfant {cname msg} { - set from [lindex $msg 0 0] - if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {1>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![string match "\[olvmn\]" [nda get "eggcompat/attrs/$ndacname/[tnda get "login/$::netname($::sock)/$from"]"]]} { - $::maintype privmsg $::sock 77 $cname "You fail at life." - $::maintype privmsg $::sock 77 $cname "Channel not registered to you." - return - } - set lev [nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"] - set sm "+" - set st "" - if {""!=[nda get "eggcompat/attrs/$ndacname/[tnda get "login/$::netname($::sock)/$from"]"]} { - if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |v $cname]} {set sm v} - if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |l $cname]} {set sm h} - if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |omn $cname]} {set sm o} - } { - if {$lev >= 1} {set sm "v"; append st "v"} - if {$lev >= 150} {set sm "h"; append st "l"} - if {$lev >= 200} {set sm "o"; append st "o"} - if {$lev >= 300} {append st "m"} - if {$lev >= 500} {append st "n"} - chattr [tnda get "login/$::netname($::sock)/$from"] +$st $cname - } - $::maintype putmode $::sock 77 $cname $sm $from [tnda get "channels/$ndacname/$::netname($::sock)/ts"] -} - -proc convertop {from msg} { - if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} - set cname [lindex $msg 0 0] - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {500>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"]} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "You must be the founder to request an oplevel-to-flags conversion." - return - } - foreach {login lev} [nda get "regchan/$ndacname/levels"] { - set st "" - if {$lev >= 1} {append st "v"} - if {$lev >= 150} {append st "l"} - if {$lev >= 200} {append st "o"} - if {$lev >= 300} {append st "m"} - if {$lev >= 500} {append st "n"} - chattr $login +$st $cname - } - $::maintype notice $::sock 77 $from "Converted all access levels to flags." - lsuchan $from $msg -} - -proc requestbot {cname msg} { - set from [lindex $msg 0 0] - set bot [lindex $msg 1 0] - if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {150>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![matchattr [tnda get "login/$::netname($::sock)/$from"] lmno|lmno $cname]} { - $::maintype privmsg $::sock 77 $cname "You fail at life." - $::maintype privmsg $::sock 77 $cname "You must be at least halfop to request $bot." - return - } - callbind $::sock request [string tolower $bot] "-" $cname -} - -foreach {chan _} [nda get "regchan"] { - $::maintype putjoin $::sock 77 [::base64::decode [string map {[ /} $chan]] [nda get "regchan/$chan/ts"] - tnda set "channels/$chan/ts" [nda get "regchan/$chan/$::netname($::sock)/ts"] - $::maintype putmode $::sock 77 [::base64::decode [string map {[ /} $chan]] "+nt" "" [nda get "regchan/$chan/ts"] -} - -proc checkop {mc ftp} { - set f [lindex $ftp 0 0] - set t [lindex $ftp 0 1] - set p [lindex $ftp 0 2] - if {"o"!=$mc} {return} - set chan [string map {/ [} [::base64::encode [string tolower $t]]] - tnda set "channels/$chan/modes/$p" "[tnda get "channels/$chan/modes/$::netname($::sock)/$::netname($::sock)/$p"]o" -} - -proc checkcreate {mc ftp} { - set chan [string map {/ [} [::base64::encode [string tolower $mc]]] - tnda set "channels/$chan/modes/$::netname($::sock)/$ftp" "o" - puts stdout "channels/$chan/modes/$ftp" -} - -proc checkdeop {mc ftp} { - set f [lindex $ftp 0 0] - set t [lindex $ftp 0 1] - set p [lindex $ftp 0 2] - if {"o"!=$mc} {return} - set chan [string map {/ [} [::base64::encode [string tolower $t]]] - tnda set "channels/$chan/modes/$p" [string map {o ""} [tnda get "channels/$chan/modes/$::netname($::sock)/$::netname($::sock)/$p"]] -} - -proc chanhelp {from msg} { - set fp [open ./chanserv.help r] - set data [split [read $fp] "\r\n"] - close $fp - foreach {line} $data { - $::maintype notice $::sock 77 $from "$line" - } -} - -proc regchan {from msg} { - if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} - set cname [lindex $msg 0 0] - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {[string length [nda get "regchan/$ndacname"]] != 0} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "Channel already exists." - return - } - if {-1==[string first "o" [tnda get "channels/$ndacname/modes/$::netname($::sock)/$from"]]} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "You are not an operator." - return - } - $::maintype notice $::sock 77 $from "Guess what? :)" - nda set "regchan/$ndacname/levels/[tnda get "login/$::netname($::sock)/$from"]" 500 - nda set "regchan/$ndacname/ts" [tnda get "channels/$ndacname/$::netname($::sock)/ts"] - $::maintype putjoin $::sock 77 $cname [tnda get "channels/$ndacname/$::netname($::sock)/ts"] - chattr [tnda get "login/$::netname($::sock)/$from"] +mno $cname - callbind $::sock "reg" "-" "-" $cname [tnda get "channels/$ndacname/$::netname($::sock)/ts"] -} - -proc adduserchan {from msg} { - if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} - set cname [lindex $msg 0 0] - set adduser [lindex $msg 0 1] - set addlevel [lindex $msg 0 2] - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {![string is integer $addlevel]} {return} - if {$addlevel > [nda get "regchan/$ndacname/levels/[tnda get "login/$::netname($::sock)/$from"]"]} {$::maintype notice $::sock 77 $from "You can't do that; you're not the channel's Dave";return} - if {[nda get "regchan/$ndacname/levels/$adduser"] > [nda get "regchan/$ndacname/levels/[tnda get "login/$::netname($::sock)/$from"]"]} {$::maintype notice $::sock 77 $from "You can't do that; the person you're changing the level of is more like Dave than you.";return} - if {$adduser == [tnda get "login/$from"]} {$::maintype notice $::sock 77 $from "You can't change your own level, even if you're downgrading. Sorreh :/$::netname($::sock)/";return} - $::maintype notice $::sock 77 $from "Guess what? :) User added." - nda set "regchan/$ndacname/levels/[string tolower $adduser]" $addlevel -} - -proc upchan {from msg} { - puts stdout [nda get regchan] - if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} - set cname [lindex $msg 0 0] - set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] - if {1>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"]} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "Channel not registered to you." - return - } - set lev [nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"] - set sm "+" - set st "" - if {""!=[nda get "eggcompat/attrs/$ndacname/[tnda get "login/$::netname($::sock)/$from"]"]} { - if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |v $cname]} {set sm v} - if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |l $cname]} {set sm h} - if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |omn $cname]} {set sm o} - } { - if {$lev >= 1} {set sm "v"; append st "v"} - if {$lev >= 150} {set sm "h"; append st "l"} - if {$lev >= 200} {set sm "o"; append st "o"} - if {$lev >= 300} {append st "m"} - if {$lev >= 500} {append st "n"} - chattr [tnda get "login/$::netname($::sock)/$from"] +$st $cname - } - $::maintype putmode $::sock 77 $cname $sm $from [tnda get "channels/$ndacname/$::netname($::sock)/ts"] -} - -proc regnick {from msg} { - set uname [lindex $msg 0 0] - if {[string first "/" $uname] != -1} {return} - set pw [lindex $msg 0 1] - if {""!=[nda get "usernames/[string tolower $uname]"]} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "Account already exists; try LOGIN" - return - } - nda set "usernames/[string tolower $uname]/password" [pwhash $pw] - $::maintype setacct $::sock $from $uname - callbind $::sock evnt "-" "login" $from $uname -} - -proc chpassnick {from msg} { - set uname [lindex $msg 0 0] - if {[string first "/" $uname] != -1} {return} - set pw [lindex $msg 0 1] - set newpw [lindex $msg 0 2] - set checkpw [split [nda get "usernames/[string tolower $uname]/password"] "/"] - set ispw [pwhash $pw] - - if {$ispw != [nda get "usernames/[string tolower $uname]/password"]} { - $::maintype notice $::sock 77 $from "You fail at life." - $::maintype notice $::sock 77 $from "Wrong pass." - return - } - nda set "usernames/[string tolower $uname]/password" [pwhash $newpw] - $::maintype notice $::sock 77 $from "Password changed." -} - -proc idnick {from msg} { - set uname [lindex $msg 0 0] - if {[string first "/" $uname] != -1} {return} - set pw [lindex $msg 0 1] - set checkpw [split [nda get "usernames/[string tolower $uname]/password"] "/"] - set ispw [pwhash $pw] - if {$ispw == [nda get "usernames/[string tolower $uname]/password"]} { - $::maintype notice $::sock 77 $from "You have successfully logged in as $uname." - $::maintype setacct $::sock $from $uname - callbind $::sock evnt "-" "login" $from $uname - } { - $::maintype notice $::sock 77 $from "You cannot log in as $uname. You have the wrong password." - } -} diff --git a/modules/0001-eggcompat.tcl b/modules/0001-eggcompat.tcl @@ -0,0 +1,303 @@ +source chanserv.conf + +bind $::sock mode "-" "+" bitchopcheck +bind $::sock mode "-" "-" protectopcheck +bind $::sock join "-" "-" autoopcheck + +proc protectopcheck {mc ftp} { + set f [lindex $ftp 0 0] + set t [lindex $ftp 0 1] + set p [lindex $ftp 0 2] + if {"o"==$mc && ![channel get $t protectop]} {return} + if {"h"==$mc && ![channel get $t protecthalfop]} {return} + if {"v"==$mc && ![channel get $t protectvoice]} {return} + switch -- $mc { + "o" { + if {[matchattr [tnda get "login/$::netname($::sock)/$p"] |omn $t]} { + p10 putmode $::sock 77 $t +$mc "$p" [tnda get "channels/[ndaenc $t]/$::netname($::sock)/ts"] + } + } + "h" { + if {[matchattr [tnda get "login/$::netname($::sock)/$p"] |l $t]} { + p10 putmode $::sock 77 $t +$mc "$p" [tnda get "channels/[ndaenc $t]/$::netname($::sock)/ts"] + } + } + "v" { + if {[matchattr [tnda get "login/$::netname($::sock)/$p"] |v $t]} { + p10 putmode $::sock 77 $t +$mc "$p" [tnda get "channels/[ndaenc $t]/$::netname($::sock)/ts"] + } + } + } +} + +proc autoopcheck {c ft} { + set f [lindex $ft 0];set t [lindex $ft 1] + if {[matchattr [tnda get "login/$::netname($::sock)/$f"] omn|] && [channel get $c operit]} { + p10 putmode $::sock 77 $c +o $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] + return + } + if {[matchattr [tnda get "login/$::netname($::sock)/$f"] |omn $c] && [channel get $c autoop]} { + p10 putmode $::sock 77 $c +o $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] + return + } + if {[matchattr [tnda get "login/$::netname($::sock)/$f"] l|] && [channel get $c operit]} { + p10 putmode $::sock 77 $c +h $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] + return + } + if {[matchattr [tnda get "login/$::netname($::sock)/$f"] |l $c] && [channel get $c autohalfop]} { + p10 putmode $::sock 77 $c +h $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] + return + } + if {[matchattr [tnda get "login/$::netname($::sock)/$f"] v|] && [channel get $c operit]} { + p10 putmode $::sock 77 $c +v $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] + return + } + if {[matchattr [tnda get "login/$::netname($::sock)/$f"] |v $c] && [channel get $c autovoice]} { + p10 putmode $::sock 77 $c +v $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] + return + } +} + +proc bitchopcheck {mc ftp} { + set f [lindex $ftp 0] + set t [lindex $ftp 1] + set p [lindex $ftp 2] + puts stdout "$ftp" + if {"o"==$mc && ![channel get $t bitch]} {return} + if {"h"==$mc && ![channel get $t halfbitch]} {return} + if {"v"==$mc && ![channel get $t voicebitch]} {return} + switch -glob -- $mc { + "o" { + if {![matchattr [tnda get "login/$::netname($::sock)/$p"] |omn $t]} { + puts stdout "M $t -$mc $p [nda get "regchan/[ndaenc $t]/ts"]" + p10 putmode $::sock 77 $t "-$mc" "$p" [nda get "regchan/[ndaenc $t]/ts"] + } + } + "h" { + if {![matchattr [tnda get "login/$::netname($::sock)/$p"] |l $t]} { + puts stdout "M $t -$mc $p [nda get "regchan/[ndaenc $t]/ts"]" + p10 putmode $::sock 77 $t "-$mc" "$p" [nda get "regchan/[ndaenc $t]/ts"] + } + } + "v" { + if {![matchattr [tnda get "login/$::netname($::sock)/$p"] |v $t]} { + puts stdout "M $t -$mc $p [nda get "regchan/[ndaenc $t]/ts"]" + p10 putmode $::sock 77 $t "-$mc" "$p" [nda get "regchan/[ndaenc $t]/ts"] + } + } + } +} + +proc utimer {seconds tcl-command} {after [expr $seconds * 1000] ${tcl-command}} +proc timer {minutes tcl-command} {after [expr $minutes * 60 * 1000] ${tcl-command}} +proc utimers {} {set t {}; foreach a [after info] {lappend t "0 [lindex [after info $a] 0] $a"}; return $t} +proc timers {} {set t {}; foreach a [after info] {lappend t "0 [lindex [after info $a] 0] $a"}; return $t} +proc killtimer id {return [after cancel $id]} +proc killutimer id {return [after cancel $id]} +proc ndaenc {n} { + return [string map {/ [} [::base64::encode [string tolower $n]]] +} + +proc isbotnick {n} {return [expr {$n == $::botnick}]} + +proc putserv {msg} { + puts $::sock ":$::botnick $msg" + puts stdout ":$::botnick $msg" +} + +proc puthelp {msg} { + puts $::sock ":$::botnick $msg" +} + +proc putquick {msg} { + puts $::sock ":$::botnick $msg" +} + +proc putnow {msg} { + puts $::sock ":$::botnick $msg" +} + +proc ndadec {n} { + return [::base64::decode [string map {[ /} $n]] +} + +proc msgmt {from msg} { + set handle [lindex $msg 0 0] + set attr [lindex $msg 0 1] + set chan [lindex $msg 0 2] + p10 notice $::sock 77 $from "$handle $attr $chan Matchattr result: [matchattr $handle $attr $chan]" +} + +bind $::sock msg 77 "matchattr" msgmt + +proc matchattr {handle attr {chan "*"}} { + set handle [string tolower $handle] + if {-1!=[string first "&" $attr]} {set and 1} {set and 0} + set gattr [lindex [split $attr "&|"] 0] + set cattr [lindex [split $attr "&|"] 1] + set isattrg 0 + foreach {c} [split [nda get "eggcompat/attrs/global/$handle"] {}] { + foreach {k} [split $gattr {}] { + if {$c == $k} {set isattrg 1} + } + } + set isattrc 0 + if {"*"!=$chan} { + foreach {c} [split [nda get "eggcompat/attrs/[ndaenc $chan]/$handle"] {}] { + foreach {k} [split $cattr {}] { + if {$c == $k} {set isattrc 1} + } + } + } + if {$and && ($isattrg == $isattrc) && ($isattrc == 1)} {return 1} + if {!$and && ($isattrg || $isattrc)} {return 1} + return 0 +} + +proc chattr {handle attr {chan "*"}} { + set handle [string tolower $handle] + if {$chan == "*"} { + set del [list] + set app "" + set state app + foreach {c} [split $attr {}] { + if {"+"==$c} {set state app;continue} + if {"-"==$c} {set state del;continue} + if {$state=="del"} { + lappend del $c "" + } + if {$state=="app"} { + lappend del $c "" + append app $c + } + } + nda set "eggcompat/attrs/global/$handle" [join [concat [string map $del [nda get "eggcompat/attrs/global/$handle"]] $app] ""] + } { + set del [list] + set app "" + set state app + foreach {c} [split $attr {}] { + if {"+"==$c} {set state app;continue} + if {"-"==$c} {set state del;continue} + if {$state=="del"} { + lappend del $c "" + } + if {$state=="app"} { + lappend del $c "" + append app $c + } + } + puts stdout [ndaenc $chan] + nda set "eggcompat/attrs/[ndaenc $chan]/$handle" [join [concat [string map $del [nda get "eggcompat/attrs/[ndaenc $chan]/$handle"]] $app] ""] + } +} + +proc channels {} { + foreach {chan _} [nda get "regchan"] { + lappend ret $chan + } + return $ret +} + +namespace eval channel { + proc ::channel::get {chan flag} { + if {[::set enda [nda get "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]"]]!=""} {return $enda} {return 0} + } + proc ::channel::set {chan flags} { + if {[llength $flags] != 1} { + foreach {flag} $flags { + ::set bit [string index $flag 0] + if {$bit=="+"} {::set bitt 1} {::set bitt 0} + ::set flag [string range $flag 1 end] + nda set "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]" $bitt + } + } { + ::set bit [string index $flags 0] + if {$bit=="+"} {::set bitt 1} {::set bitt 0} + ::set flag [string range $flags 1 end] + nda set "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flags]]" $bitt + } + } + namespace export * + namespace ensemble create +} + +proc validuser {n} { + if {""==[nda get "usernames/$n"]} {return 0} {return 1} +} + +bind $::sock msg 77 "chanset" msgchanset +bind $::sock msg 77 "chattr" msgchattr +bind $::sock msg 77 "setxtra" msgxtra +set botnick $cs(nick) +chattr $cs(admin) +mnolv + +proc msgchanset {from msg} { + set ndacname [ndaenc [lindex $msg 0 0]] + set chanset [lindex $msg 0 1] + if {300>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![matchattr [tnda get "login/$::netname($::sock)/$from"] m|m [lindex $msg 0 0]]} { + p10 notice $::sock 77 $from "Only channel super-operators (300) and above and network masters may use eggdrop-compatible chansets." + return + } + channel set [lindex $msg 0 0] $chanset + p10 notice $::sock 77 $from "Eggdrop compatible chanset $chanset set on [lindex $msg 0 0]." +} + +proc msgchattr {from msg} { + set ndacname [ndaenc [lindex $msg 0 2]] + set handle [lindex $msg 0 0] + set hand [lindex $msg 0 0] + set attrs [lindex $msg 0 1] + set chan [lindex $msg 0 2] + set ch [lindex $msg 0 2] + if {$chan==""} { + set chan "*" + set ch "global" + } + foreach {c} [split $attrs {}] { + if {$c == "+"} {continue} + if {$c == "-"} {continue} + if {$c == "v"} {set $c "mn|lmno"} + if {$c == "l"} {set $c "mn|mno"} + if {$c == "o"} {set $c "mn|omn"} + if {$c == "m"} {set $c "mn|mn"} + if {$c == "n"} {set $c "n|n"} + if {![matchattr [tnda get "login/$::netname($::sock)/$from"] $c $chan]} { + p10 notice $::sock 77 $from "You may only give flags you already possess (Any of flags $c required to set $attrs)." + return + } + } + if {"*"!=$chan} {chattr $hand $attrs} {chattr $hand $attrs $chan} + p10 notice $::sock 77 $from "Global flags for $hand are now [nda get "eggcompat/attrs/global/[string tolower $handle]"]" + if {$ch != "global"} {p10 notice $::sock 77 $from "Flags on $chan for $hand are now [nda get "eggcompat/attrs/$ndacname/[string tolower $handle]"]"} +} + +proc nick2hand {nick} { + foreach {uid nic} [tnda get "nick"] { + if {$nick == $nic} {return [tnda get "login/$::netname($::sock)/$uid"]} + } +} + +proc getuser {nick datafield {dataval "body"}} { + return [nda get "usernames/$nick/setuser/[ndaenc $datafield]/[ndaenc $dataval]"] +} + +proc setuser {nick datafield {dataval "body"} val} { + return [nda set "usernames/$nick/setuser/[ndaenc $datafield]/[ndaenc $dataval]" $val] +} + +proc msgxtra {from msg} { + if {[set log [tnda get "login/$::netname($::sock)/$from"]]==""} { + p10 notice $::sock 77 $from "Until you've registered with the bot, you have no business setting XTRA values." + return + } + set subfield [lindex $msg 0 0] + set value [join [lrange [lindex $msg 0] 1 end] " "] + setuser $log "XTRA" $subfield $value + p10 notice $::sock 77 $from "Set your user record XTRA $subfield to $value." +} + +proc chandname2name {channame} {return $channame} +proc channame2dname {channame} {return $channame} + +proc islinked {bot} {return 0} diff --git a/modules/0005-chanserv.tcl b/modules/0005-chanserv.tcl @@ -0,0 +1,310 @@ +$::maintype sendUid $sock $cs(nick) $cs(ident) $cs(host) $cs(host) 77 "Channels Server" +bind $::sock msg 77 "register" regchan +bind $::sock msg 77 "adduser" adduserchan +bind $::sock msg 77 "users" lsuchan +bind $::sock msg 77 "lsu" lsuchan +bind $::sock msg 77 "convertop" convertop +#bind $::sock msg 77 "deluser" deluserchan +bind $::sock msg 77 "up" upchan +bind $::sock pub "-" "@up" upchanfant +bind $::sock pub "-" "@rand" randfant +bind $::sock pub "-" "@request" requestbot +bind $::sock msg 77 "down" downchan +bind $::sock msg 77 "hello" regnick +bind $::sock msg 77 "chpass" chpassnick +bind $::sock msg 77 "login" idnick +bind $::sock msg 77 "help" chanhelp +bind $::sock msg 77 "topic" chantopic +bind $::sock msg 77 "cookie" authin +bind $::sock msg 77 "cauth" cookieauthin +bind $::sock mode "-" "+" checkop +bind $::sock mode "-" "-" checkdeop +bind $::sock topic "-" "-" checktopic +bind $::sock create "-" "-" checkcreate + +proc checktopic {chan topic} { + set ndacname [string map {/ [} [::base64::encode [string tolower $chan]]] + if {[channel get $chan topiclock]} {$::maintype topic $::sock 77 "$chan" "[nda get "regchan/$ndacname/topic"]"} +} + +proc chantopic {from msg} { + set cname [lindex $msg 0 0] + set topic [join [lrange [lindex $msg 0] 1 end] " "] + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {150>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![matchattr [tnda get "login/$::netname($::sock)/$from"] lmno|lmno $cname]} { + $::maintype privmsg $::sock 77 $cname "You must be at least halfop to change the stored channel topic." + return + } + nda set "regchan/$ndacname/topic" "$topic" + $::maintype topic $::sock 77 "$cname" "$topic" + $::maintype privmsg $::sock 77 "$cname" "[tnda get "nick/$::netname($::sock)/$from"] ([tnda get "login/$::netname($::sock)/$from"]) changed topic." +} + +proc authin {from msg} { + set uname [lindex $msg 0 0] + if {[string first "/" $uname] != -1} {return} + $::maintype notice $::sock 77 $from "CHALLENGE [set cookie [b64e [rand 1000000000 9999999999]]] SHA1" + tnda set "cookieauth/$from/cookie" $cookie + tnda set "cookieauth/$from/name" "$uname" +} + +proc cookieauthin {from msg} { + set uname [lindex $msg 0 0] + set response [lindex $msg 0 1] + if {[string first "/" $uname] != -1} {return} + if {$response == ""} {return} + set checkresp "[tnda get "cookieauth/$from/name"]:[nda get "usernames/[string tolower $uname]/password"]:[tnda get "cookieauth/$from/cookie"]" + set isresp [pwhash "$checkresp"] + puts stdout "$response $isresp $checkresp" + if {$response == $isresp} { + $::maintype notice $::sock 77 $from "You have successfully logged in as $uname." + $::maintype setacct $::sock $from $uname + callbind $::sock evnt "-" "login" $from $uname + } { + $::maintype notice $::sock 77 $from "You used the wrong password; try again." + } +} + +proc randfant {cname msg} { + set from [lindex $msg 0 0] + set froni [tnda get "nick/$::netname($::sock)/$from"] + if {![string is integer [lindex $msg 1 0]] ||![string is integer [lindex $msg 1 1]]} {return} + if {(""==[lindex $msg 1 0]) || (""==[lindex $msg 1 1])} {return} + if {[lindex $msg 1 0] == [lindex $msg 1 1]} {$::maintype privmsg $::sock 77 $cname "\002$froni:\002 Your request would have caused a divide by zero and was not processed.";return} + $::maintype privmsg $::sock 77 $cname "\002$froni:\002 Your die rolled [rand [lindex $msg 1 0] [lindex $msg 1 1]]" +} + +proc lsuchan {from msg} { + set cname [lindex $msg 0 0] + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {[string length [nda get "regchan/$ndacname"]] == 0} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "Channel does not exist." + return + } + set xses [nda get "regchan/$ndacname/levels"] + $::maintype notice $::sock 77 $from "Access | Flags | Username" + $::maintype notice $::sock 77 $from "-------+------------------" + foreach {nick lev} $xses { + if {$lev == 0} {continue} + # Case above? User not actually on access list + set nl [format "%3d" $lev] + set repeats [string repeat " " [expr {6-[string length [nda get "eggcompat/attrs/$ndacname/$nick"]]}]] + $::maintype notice $::sock 77 $from " $nl | $repeats[string range [nda get "eggcompat/attrs/$ndacname/$nick"] 0 5] | $nick" + } + $::maintype notice $::sock 77 $from "-------+------------------" + $::maintype notice $::sock 77 $from " | End of access list" +} + +proc upchanfant {cname msg} { + set from [lindex $msg 0 0] + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {1>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![string match "\[olvmn\]" [nda get "eggcompat/attrs/$ndacname/[tnda get "login/$::netname($::sock)/$from"]"]]} { + $::maintype privmsg $::sock 77 $cname "You fail at life." + $::maintype privmsg $::sock 77 $cname "Channel not registered to you." + return + } + set lev [nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"] + set sm "+" + set st "" + if {""!=[nda get "eggcompat/attrs/$ndacname/[tnda get "login/$::netname($::sock)/$from"]"]} { + if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |v $cname]} {set sm v} + if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |l $cname]} {set sm h} + if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |omn $cname]} {set sm o} + } { + if {$lev >= 1} {set sm "v"; append st "v"} + if {$lev >= 150} {set sm "h"; append st "l"} + if {$lev >= 200} {set sm "o"; append st "o"} + if {$lev >= 300} {append st "m"} + if {$lev >= 500} {append st "n"} + chattr [tnda get "login/$::netname($::sock)/$from"] +$st $cname + } + $::maintype putmode $::sock 77 $cname $sm $from [tnda get "channels/$ndacname/$::netname($::sock)/ts"] +} + +proc convertop {from msg} { + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set cname [lindex $msg 0 0] + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {500>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"]} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "You must be the founder to request an oplevel-to-flags conversion." + return + } + foreach {login lev} [nda get "regchan/$ndacname/levels"] { + set st "" + if {$lev >= 1} {append st "v"} + if {$lev >= 150} {append st "l"} + if {$lev >= 200} {append st "o"} + if {$lev >= 300} {append st "m"} + if {$lev >= 500} {append st "n"} + chattr $login +$st $cname + } + $::maintype notice $::sock 77 $from "Converted all access levels to flags." + lsuchan $from $msg +} + +proc requestbot {cname msg} { + set from [lindex $msg 0 0] + set bot [lindex $msg 1 0] + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {150>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![matchattr [tnda get "login/$::netname($::sock)/$from"] lmno|lmno $cname]} { + $::maintype privmsg $::sock 77 $cname "You fail at life." + $::maintype privmsg $::sock 77 $cname "You must be at least halfop to request $bot." + return + } + callbind $::sock request [string tolower $bot] "-" $cname +} + +foreach {chan _} [nda get "regchan"] { + $::maintype putjoin $::sock 77 [::base64::decode [string map {[ /} $chan]] [nda get "regchan/$chan/ts"] + tnda set "channels/$chan/ts" [nda get "regchan/$chan/$::netname($::sock)/ts"] + $::maintype putmode $::sock 77 [::base64::decode [string map {[ /} $chan]] "+nt" "" [nda get "regchan/$chan/ts"] + if {[channel get [::base64::decode [string map {[ /} $chan]] topiclock]} {$::maintype topic $::sock 77 [::base64::decode [string map {[ /} $chan]] [nda get "regchan/$chan/topic"]} +} + +proc checkop {mc ftp} { + set f [lindex $ftp 0 0] + set t [lindex $ftp 0 1] + set p [lindex $ftp 0 2] + if {"o"!=$mc} {return} + set chan [string map {/ [} [::base64::encode [string tolower $t]]] + tnda set "channels/$chan/modes/$p" "[tnda get "channels/$chan/modes/$::netname($::sock)/$::netname($::sock)/$p"]o" +} + +proc checkcreate {mc ftp} { + set chan [string map {/ [} [::base64::encode [string tolower $mc]]] + tnda set "channels/$chan/modes/$::netname($::sock)/$ftp" "o" + puts stdout "channels/$chan/modes/$ftp" +} + +proc checkdeop {mc ftp} { + set f [lindex $ftp 0 0] + set t [lindex $ftp 0 1] + set p [lindex $ftp 0 2] + if {"o"!=$mc} {return} + set chan [string map {/ [} [::base64::encode [string tolower $t]]] + tnda set "channels/$chan/modes/$p" [string map {o ""} [tnda get "channels/$chan/modes/$::netname($::sock)/$::netname($::sock)/$p"]] +} + +proc chanhelp {from msg} { + set fp [open ./chanserv.help r] + set data [split [read $fp] "\r\n"] + close $fp + foreach {line} $data { + $::maintype notice $::sock 77 $from "$line" + } +} + +proc regchan {from msg} { + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set cname [lindex $msg 0 0] + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {[string length [nda get "regchan/$ndacname"]] != 0} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "Channel already exists." + return + } + if {-1==[string first "o" [tnda get "channels/$ndacname/modes/$::netname($::sock)/$from"]]} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "You are not an operator." + return + } + $::maintype notice $::sock 77 $from "Guess what? :)" + nda set "regchan/$ndacname/levels/[tnda get "login/$::netname($::sock)/$from"]" 500 + nda set "regchan/$ndacname/ts" [tnda get "channels/$ndacname/$::netname($::sock)/ts"] + $::maintype putjoin $::sock 77 $cname [tnda get "channels/$ndacname/$::netname($::sock)/ts"] + chattr [tnda get "login/$::netname($::sock)/$from"] +mno $cname + callbind $::sock "reg" "-" "-" $cname [tnda get "channels/$ndacname/$::netname($::sock)/ts"] +} + +proc adduserchan {from msg} { + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set cname [lindex $msg 0 0] + set adduser [lindex $msg 0 1] + set addlevel [lindex $msg 0 2] + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {![string is integer $addlevel]} {return} + if {$addlevel > [nda get "regchan/$ndacname/levels/[tnda get "login/$::netname($::sock)/$from"]"]} {$::maintype notice $::sock 77 $from "You can't do that; you're not the channel's Dave";return} + if {[nda get "regchan/$ndacname/levels/$adduser"] > [nda get "regchan/$ndacname/levels/[tnda get "login/$::netname($::sock)/$from"]"]} {$::maintype notice $::sock 77 $from "You can't do that; the person you're changing the level of is more like Dave than you.";return} + if {$adduser == [tnda get "login/$from"]} {$::maintype notice $::sock 77 $from "You can't change your own level, even if you're downgrading. Sorreh :/$::netname($::sock)/";return} + $::maintype notice $::sock 77 $from "Guess what? :) User added." + nda set "regchan/$ndacname/levels/[string tolower $adduser]" $addlevel +} + +proc upchan {from msg} { + puts stdout [nda get regchan] + if {""==[tnda get "login/$::netname($::sock)/$from"]} {$::maintype notice $::sock 77 $from "You fail at life.";return} + set cname [lindex $msg 0 0] + set ndacname [string map {/ [} [::base64::encode [string tolower $cname]]] + if {1>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"]} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "Channel not registered to you." + return + } + set lev [nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$::netname($::sock)/$from"]]"] + set sm "+" + set st "" + if {""!=[nda get "eggcompat/attrs/$ndacname/[tnda get "login/$::netname($::sock)/$from"]"]} { + if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |v $cname]} {set sm v} + if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |l $cname]} {set sm h} + if {[matchattr [tnda get "login/$::netname($::sock)/$from"] |omn $cname]} {set sm o} + } { + if {$lev >= 1} {set sm "v"; append st "v"} + if {$lev >= 150} {set sm "h"; append st "l"} + if {$lev >= 200} {set sm "o"; append st "o"} + if {$lev >= 300} {append st "m"} + if {$lev >= 500} {append st "n"} + chattr [tnda get "login/$::netname($::sock)/$from"] +$st $cname + } + $::maintype putmode $::sock 77 $cname $sm $from [tnda get "channels/$ndacname/$::netname($::sock)/ts"] +} + +proc regnick {from msg} { + set uname [lindex $msg 0 0] + if {[string first "/" $uname] != -1} {return} + set pw [lindex $msg 0 1] + if {""!=[nda get "usernames/[string tolower $uname]"]} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "Account already exists; try LOGIN" + return + } + nda set "usernames/[string tolower $uname]/password" [pwhash $pw] + $::maintype setacct $::sock $from $uname + callbind $::sock evnt "-" "login" $from $uname +} + +proc chpassnick {from msg} { + set uname [lindex $msg 0 0] + if {[string first "/" $uname] != -1} {return} + set pw [lindex $msg 0 1] + set newpw [lindex $msg 0 2] + set checkpw [split [nda get "usernames/[string tolower $uname]/password"] "/"] + set ispw [pwhash $pw] + + if {$ispw != [nda get "usernames/[string tolower $uname]/password"]} { + $::maintype notice $::sock 77 $from "You fail at life." + $::maintype notice $::sock 77 $from "Wrong pass." + return + } + nda set "usernames/[string tolower $uname]/password" [pwhash $newpw] + $::maintype notice $::sock 77 $from "Password changed." +} + +proc idnick {from msg} { + set uname [lindex $msg 0 0] + if {[string first "/" $uname] != -1} {return} + set pw [lindex $msg 0 1] + set checkpw [split [nda get "usernames/[string tolower $uname]/password"] "/"] + set ispw [pwhash $pw] + if {$ispw == [nda get "usernames/[string tolower $uname]/password"]} { + $::maintype notice $::sock 77 $from "You have successfully logged in as $uname." + $::maintype setacct $::sock $from $uname + callbind $::sock evnt "-" "login" $from $uname + } { + $::maintype notice $::sock 77 $from "You cannot log in as $uname. You have the wrong password." + } +} diff --git a/modules/0005-eggcompat.tcl b/modules/0005-eggcompat.tcl @@ -1,301 +0,0 @@ -bind $::sock mode "-" "+" bitchopcheck -bind $::sock mode "-" "-" protectopcheck -bind $::sock join "-" "-" autoopcheck - -proc protectopcheck {mc ftp} { - set f [lindex $ftp 0 0] - set t [lindex $ftp 0 1] - set p [lindex $ftp 0 2] - if {"o"==$mc && ![channel get $t protectop]} {return} - if {"h"==$mc && ![channel get $t protecthalfop]} {return} - if {"v"==$mc && ![channel get $t protectvoice]} {return} - switch -- $mc { - "o" { - if {[matchattr [tnda get "login/$::netname($::sock)/$p"] |omn $t]} { - p10 putmode $::sock 77 $t +$mc "$p" [tnda get "channels/[ndaenc $t]/$::netname($::sock)/ts"] - } - } - "h" { - if {[matchattr [tnda get "login/$::netname($::sock)/$p"] |l $t]} { - p10 putmode $::sock 77 $t +$mc "$p" [tnda get "channels/[ndaenc $t]/$::netname($::sock)/ts"] - } - } - "v" { - if {[matchattr [tnda get "login/$::netname($::sock)/$p"] |v $t]} { - p10 putmode $::sock 77 $t +$mc "$p" [tnda get "channels/[ndaenc $t]/$::netname($::sock)/ts"] - } - } - } -} - -proc autoopcheck {c ft} { - set f [lindex $ft 0];set t [lindex $ft 1] - if {[matchattr [tnda get "login/$::netname($::sock)/$f"] omn|] && [channel get $c operit]} { - p10 putmode $::sock 77 $c +o $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] - return - } - if {[matchattr [tnda get "login/$::netname($::sock)/$f"] |omn $c] && [channel get $c autoop]} { - p10 putmode $::sock 77 $c +o $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] - return - } - if {[matchattr [tnda get "login/$::netname($::sock)/$f"] l|] && [channel get $c operit]} { - p10 putmode $::sock 77 $c +h $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] - return - } - if {[matchattr [tnda get "login/$::netname($::sock)/$f"] |l $c] && [channel get $c autohalfop]} { - p10 putmode $::sock 77 $c +h $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] - return - } - if {[matchattr [tnda get "login/$::netname($::sock)/$f"] v|] && [channel get $c operit]} { - p10 putmode $::sock 77 $c +v $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] - return - } - if {[matchattr [tnda get "login/$::netname($::sock)/$f"] |v $c] && [channel get $c autovoice]} { - p10 putmode $::sock 77 $c +v $f [tnda get "channels/[ndaenc $c]/$::netname($::sock)/ts"] - return - } -} - -proc bitchopcheck {mc ftp} { - set f [lindex $ftp 0] - set t [lindex $ftp 1] - set p [lindex $ftp 2] - puts stdout "$ftp" - if {"o"==$mc && ![channel get $t bitch]} {return} - if {"h"==$mc && ![channel get $t halfbitch]} {return} - if {"v"==$mc && ![channel get $t voicebitch]} {return} - switch -glob -- $mc { - "o" { - if {![matchattr [tnda get "login/$::netname($::sock)/$p"] |omn $t]} { - puts stdout "M $t -$mc $p [nda get "regchan/[ndaenc $t]/ts"]" - p10 putmode $::sock 77 $t "-$mc" "$p" [nda get "regchan/[ndaenc $t]/ts"] - } - } - "h" { - if {![matchattr [tnda get "login/$::netname($::sock)/$p"] |l $t]} { - puts stdout "M $t -$mc $p [nda get "regchan/[ndaenc $t]/ts"]" - p10 putmode $::sock 77 $t "-$mc" "$p" [nda get "regchan/[ndaenc $t]/ts"] - } - } - "v" { - if {![matchattr [tnda get "login/$::netname($::sock)/$p"] |v $t]} { - puts stdout "M $t -$mc $p [nda get "regchan/[ndaenc $t]/ts"]" - p10 putmode $::sock 77 $t "-$mc" "$p" [nda get "regchan/[ndaenc $t]/ts"] - } - } - } -} - -proc utimer {seconds tcl-command} {after [expr $seconds * 1000] ${tcl-command}} -proc timer {minutes tcl-command} {after [expr $minutes * 60 * 1000] ${tcl-command}} -proc utimers {} {set t {}; foreach a [after info] {lappend t "0 [lindex [after info $a] 0] $a"}; return $t} -proc timers {} {set t {}; foreach a [after info] {lappend t "0 [lindex [after info $a] 0] $a"}; return $t} -proc killtimer id {return [after cancel $id]} -proc killutimer id {return [after cancel $id]} -proc ndaenc {n} { - return [string map {/ [} [::base64::encode [string tolower $n]]] -} - -proc isbotnick {n} {return [expr {$n == $::botnick}]} - -proc putserv {msg} { - puts $::sock ":$::botnick $msg" - puts stdout ":$::botnick $msg" -} - -proc puthelp {msg} { - puts $::sock ":$::botnick $msg" -} - -proc putquick {msg} { - puts $::sock ":$::botnick $msg" -} - -proc putnow {msg} { - puts $::sock ":$::botnick $msg" -} - -proc ndadec {n} { - return [::base64::decode [string map {[ /} $n]] -} - -proc msgmt {from msg} { - set handle [lindex $msg 0 0] - set attr [lindex $msg 0 1] - set chan [lindex $msg 0 2] - p10 notice $::sock 77 $from "$handle $attr $chan Matchattr result: [matchattr $handle $attr $chan]" -} - -bind $::sock msg 77 "matchattr" msgmt - -proc matchattr {handle attr {chan "*"}} { - set handle [string tolower $handle] - if {-1!=[string first "&" $attr]} {set and 1} {set and 0} - set gattr [lindex [split $attr "&|"] 0] - set cattr [lindex [split $attr "&|"] 1] - set isattrg 0 - foreach {c} [split [nda get "eggcompat/attrs/global/$handle"] {}] { - foreach {k} [split $gattr {}] { - if {$c == $k} {set isattrg 1} - } - } - set isattrc 0 - if {"*"!=$chan} { - foreach {c} [split [nda get "eggcompat/attrs/[ndaenc $chan]/$handle"] {}] { - foreach {k} [split $cattr {}] { - if {$c == $k} {set isattrc 1} - } - } - } - if {$and && ($isattrg == $isattrc) && ($isattrc == 1)} {return 1} - if {!$and && ($isattrg || $isattrc)} {return 1} - return 0 -} - -proc chattr {handle attr {chan "*"}} { - set handle [string tolower $handle] - if {$chan == "*"} { - set del [list] - set app "" - set state app - foreach {c} [split $attr {}] { - if {"+"==$c} {set state app;continue} - if {"-"==$c} {set state del;continue} - if {$state=="del"} { - lappend del $c "" - } - if {$state=="app"} { - lappend del $c "" - append app $c - } - } - nda set "eggcompat/attrs/global/$handle" [join [concat [string map $del [nda get "eggcompat/attrs/global/$handle"]] $app] ""] - } { - set del [list] - set app "" - set state app - foreach {c} [split $attr {}] { - if {"+"==$c} {set state app;continue} - if {"-"==$c} {set state del;continue} - if {$state=="del"} { - lappend del $c "" - } - if {$state=="app"} { - lappend del $c "" - append app $c - } - } - puts stdout [ndaenc $chan] - nda set "eggcompat/attrs/[ndaenc $chan]/$handle" [join [concat [string map $del [nda get "eggcompat/attrs/[ndaenc $chan]/$handle"]] $app] ""] - } -} - -proc channels {} { - foreach {chan _} [nda get "regchan"] { - lappend ret $chan - } - return $ret -} - -namespace eval channel { - proc ::channel::get {chan flag} { - if {[::set enda [nda get "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]"]]!=""} {return $enda} {return 0} - } - proc ::channel::set {chan flags} { - if {[llength $flags] != 1} { - foreach {flag} $flags { - ::set bit [string index $flag 0] - if {$bit=="+"} {::set bitt 1} {::set bitt 0} - ::set flag [string range $flag 1 end] - nda set "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flag]]" $bitt - } - } { - ::set bit [string index $flags 0] - if {$bit=="+"} {::set bitt 1} {::set bitt 0} - ::set flag [string range $flags 1 end] - nda set "eggcompat/chansets/[ndaenc $chan]/[ndaenc [string map {+ ""} $flags]]" $bitt - } - } - namespace export * - namespace ensemble create -} - -proc validuser {n} { - if {""==[nda get "usernames/$n"]} {return 0} {return 1} -} - -bind $::sock msg 77 "chanset" msgchanset -bind $::sock msg 77 "chattr" msgchattr -bind $::sock msg 77 "setxtra" msgxtra -set botnick $cs(nick) -chattr $cs(admin) +mnolv - -proc msgchanset {from msg} { - set ndacname [ndaenc [lindex $msg 0 0]] - set chanset [lindex $msg 0 1] - if {300>[nda get "regchan/$ndacname/levels/[string tolower [tnda get "login/$from"]]"] && ![matchattr [tnda get "login/$::netname($::sock)/$from"] m|m [lindex $msg 0 0]]} { - p10 notice $::sock 77 $from "Only channel super-operators (300) and above and network masters may use eggdrop-compatible chansets." - return - } - channel set [lindex $msg 0 0] $chanset - p10 notice $::sock 77 $from "Eggdrop compatible chanset $chanset set on [lindex $msg 0 0]." -} - -proc msgchattr {from msg} { - set ndacname [ndaenc [lindex $msg 0 2]] - set handle [lindex $msg 0 0] - set hand [lindex $msg 0 0] - set attrs [lindex $msg 0 1] - set chan [lindex $msg 0 2] - set ch [lindex $msg 0 2] - if {$chan==""} { - set chan "*" - set ch "global" - } - foreach {c} [split $attrs {}] { - if {$c == "+"} {continue} - if {$c == "-"} {continue} - if {$c == "v"} {set $c "mn|lmno"} - if {$c == "l"} {set $c "mn|mno"} - if {$c == "o"} {set $c "mn|omn"} - if {$c == "m"} {set $c "mn|mn"} - if {$c == "n"} {set $c "n|n"} - if {![matchattr [tnda get "login/$::netname($::sock)/$from"] $c $chan]} { - p10 notice $::sock 77 $from "You may only give flags you already possess (Any of flags $c required to set $attrs)." - return - } - } - if {"*"!=$chan} {chattr $hand $attrs} {chattr $hand $attrs $chan} - p10 notice $::sock 77 $from "Global flags for $hand are now [nda get "eggcompat/attrs/global/[string tolower $handle]"]" - if {$ch != "global"} {p10 notice $::sock 77 $from "Flags on $chan for $hand are now [nda get "eggcompat/attrs/$ndacname/[string tolower $handle]"]"} -} - -proc nick2hand {nick} { - foreach {uid nic} [tnda get "nick"] { - if {$nick == $nic} {return [tnda get "login/$::netname($::sock)/$uid"]} - } -} - -proc getuser {nick datafield {dataval "body"}} { - return [nda get "usernames/$nick/setuser/[ndaenc $datafield]/[ndaenc $dataval]"] -} - -proc setuser {nick datafield {dataval "body"} val} { - return [nda set "usernames/$nick/setuser/[ndaenc $datafield]/[ndaenc $dataval]" $val] -} - -proc msgxtra {from msg} { - if {[set log [tnda get "login/$::netname($::sock)/$from"]]==""} { - p10 notice $::sock 77 $from "Until you've registered with the bot, you have no business setting XTRA values." - return - } - set subfield [lindex $msg 0 0] - set value [join [lrange [lindex $msg 0] 1 end] " "] - setuser $log "XTRA" $subfield $value - p10 notice $::sock 77 $from "Set your user record XTRA $subfield to $value." -} - -proc chandname2name {channame} {return $channame} -proc channame2dname {channame} {return $channame} - -proc islinked {bot} {return 0}