# Offline logging for sbnc by Worrum # Questions, remarks, suggestions: join #sbnc # Clientside options settable through /sbnc set # This version is for 1.2! internalbind svrlogon log:redetach internalbind attach log:attach internalbind detach log:detach internalbind command log:settings if {[bncgetglobaltag chanlog] == ""} { bncsetglobaltag chanlog "privmsg,notice" } proc log:settings {client parameters} { if {[string equal -nocase [lindex $parameters 0] "set"]} { if {[string equal -nocase [lindex $parameters 1] "offlinelog"]} { if {[string equal [lindex $parameters 2] ""]} { bncreply "Syntax: /sbnc set offlinelog on/off" if {[string equal -nocase [getbncuser $client tag offlinelog] ""]} { bncreply "Current value: off" } else { bncreply "Current value: [getbncuser $client tag offlinelog]" } haltoutput return } elseif {![string equal -nocase [lindex $parameters 2] "on"] && ![string equal -nocase [lindex $parameters 2] "off"]} { bncreply "Value should be either on or off." haltoutput return } else { if {[string equal -nocase [lindex $parameters 2] "off"]} { setbncuser $client tag offlinelog bncreply "Done." haltoutput return } setbncuser $client tag offlinelog [string tolower [lindex $parameters 2]] bncreply "Done." haltoutput } } elseif {[string equal -nocase [lindex $parameters 1] "offlinelog.method"]} { if {[string equal [lindex $parameters 2] ""]} { bncreply "Syntax: /sbnc set offlinelog.method auto/query" if {[string equal -nocase [getbncuser $client tag offlinelog.method] ""]} { bncreply "Current value: auto" } else { bncreply "Current value: [getbncuser $client tag offlinelog.method]" } haltoutput return } elseif {![string equal -nocase [lindex $parameters 2] "auto"] && ![string equal -nocase [lindex $parameters 2] "query"]} { bncreply "Value should be either auto or query." haltoutput return } else { setbncuser $client tag offlinelog.method [lindex $parameters 2] bncreply "Done." haltoutput } } elseif {[string equal -nocase [lindex $parameters 1] "offlinelog.exclude"]} { if {[string equal [lindex $parameters 2] ""]} { bncreply "Syntax: /sbnc set offlinelog.exclude #channel1,#channel2,#channel3 or none to unset it" if {[string equal -nocase [getbncuser $client tag offlinelog.exclude] ""]} { bncreply "Current value: none" } else { bncreply "Current value: [getbncuser $client tag offlinelog.exclude]" } haltoutput return } else { foreach item [split [lindex $parameters 2] ,] { if {[lsearch -exact "[string tolower [internalchannels]] none" [string tolower $item]] == -1 || !([string equal -nocase [lindex $parameters 3] ""])} { bncreply "One of the settings you supplied are incorrect, either wrong channel was specified or wrong syntax used." bncreply "Syntax: offlinelog.exclude #channel1,#channel2,#channel3" bncreply "Valid options are: [join [internalchannels] , ],none" haltoutput return } } if {[string equal -nocase [lindex $parameters 2] "none"]} { setbncuser $client tag offlinelog.exclude bncreply "Done." haltoutput return } setbncuser $client tag offlinelog.exclude [string tolower [lindex $parameters 2]] bncreply "Done." haltoutput } } elseif {[string equal -nocase [lindex $parameters 1] "offlinelog.options"]} { if {[string equal [lindex $parameters 2] ""]} { bncreply "Syntax: /sbnc set offlinelog.options option1,option2,option3" bncreply "Valid options are: [bncgetglobaltag chanlog] or reset." if {[string equal -nocase [getbncuser $client tag offlinelog.options] ""]} { bncreply "Current value: [bncgetglobaltag chanlog]" } else { bncreply "Current value: [getbncuser $client tag offlinelog.options]" } haltoutput return } else { foreach item [split [lindex $parameters 2] ,] { if {[lsearch -exact [split [list [bncgetglobaltag chanlog],reset] ,] [string tolower $item]] == -1 || !([string equal -nocase [lindex $parameters 3] ""])} { bncreply "One of the settings you supplied are incorrect or wrong syntax used." bncreply "Syntax: offlinelog.options option1,option2,option3 or reset." bncreply "Valid options are: [bncgetglobaltag chanlog],reset" haltoutput return } } if {[string equal -nocase [lindex $parameters 2] "reset"]} { setbncuser $client tag offlinelog.options bncreply "Done." haltoutput return } setbncuser $client tag offlinelog.options [string tolower [lindex $parameters 2]] bncreply "Done." haltoutput } } elseif {[string equal [lindex $parameters 1] ""]} { if {[string equal -nocase [getbncuser $client tag offlinelog] ""]} { utimer 0 [list bncreply "offlinelog - off"] } else { utimer 0 [list bncreply "offlinelog - [getbncuser $client tag offlinelog]"] } if {[string equal -nocase [getbncuser $client tag offlinelog.method] ""]} { utimer 0 [list bncreply "offlinelog.method - Auto"] } else { utimer 0 [list bncreply "offlinelog.method - [getbncuser $client tag offlinelog.method]"] } if {[string equal -nocase [getbncuser $client tag offlinelog.exclude] ""]} { utimer 0 [list bncreply "offlinelog.exclude - None set"] } else { utimer 0 [list bncreply "offlinelog.exclude - [getbncuser $client tag offlinelog.exclude]"] } if {[string equal -nocase [getbncuser $client tag offlinelog.options] ""]} { utimer 0 [list bncreply "offlinelog.options - [bncgetglobaltag chanlog]"] } else { utimer 0 [list bncreply "offlinelog.options - [getbncuser $client tag offlinelog.options]"] } } } if {[string equal [lindex $parameters 0] "unset"]} { if {[string equal -nocase [lindex $parameters 1] "offlinelog"]} { setbncuser $client tag offlinelog bncreply "Done." haltoutput } if {[string equal -nocase [lindex $parameters 1] "offlinelog.method"]} { setbncuser $client tag offlinelog.method bncreply "Done." haltoutput } if {[string equal -nocase [lindex $parameters 1] "offlinelog.exclude"]} { setbncuser $client tag offlinelog.exclude bncreply "Done." haltoutput } if {[string equal -nocase [lindex $parameters 1] "offlinelog.options"]} { setbncuser $client tag offlinelog.options bncreply "Done." haltoutput } } if {[string equal -nocase [lindex $parameters 0] "playlog"]} { if {![file exists users/$client.clog]} { bncreply "Your channel log is empty." } else { log:playlog $client bncreply "Done." } haltoutput } if {[string equal -nocase [lindex $parameters 0] "eraselog"]} { if {![file exists users/$client.clog]} { bncreply "Your channel log is empty." } else { file delete "users/$client.clog" bncreply "Done." } haltoutput } if {[string equal -nocase [lindex $parameters 0] "logwhat"] && [getbncuser [getctx] admin]} { if {[string equal [lindex $parameters 1] ""]} { bncreply "Current value: [bncgetglobaltag chanlog]" bncreply "For help type : /msg -sbnc help logwhat" haltoutput return } else { foreach item [split [lindex $parameters 1] ,] { if {[lsearch -exact [list none privmsg notice join part kick quit nick topic mode] [string tolower $item]] == -1 || !([string equal -nocase [lindex $parameters 2] ""])} { bncreply "One of the settings you supplied are incorrect or wrong syntax used." bncreply "Syntax: /sbnc logwhat option1,option2,option3" bncreply "Valid options are: none (log nothing), privmsg, notice, join* , part, kick, quit*, nick*, topic, mode. *: Can be VERY spammy" haltoutput return } } bncsetglobaltag chanlog [string tolower [lindex $parameters 1]] bncreply "Done." haltoutput } } if {[string equal -nocase [lindex $parameters 0] "help"]} { bncaddcommand playlog User "plays your channel logs (if available)" "Play's your channel logs \n Note: Gets auto-erased after being played" bncaddcommand eraselog User "erases your channel logs (if available)" "Erase your channel logs if you aren't interested in them" if {[getbncuser [getctx] admin]} { bncaddcommand logwhat Admin "set logging options" "Tell sbnc what to log for all clients \nSyntax: /sbnc logwhat option1,option2,option3 \n Valid options are: none (log nothing), privmsg, notice, join* , part, kick, quit*, nick*, topic, mode. *: Can be VERY spammy" } } } proc log:attach {client} { internalunbind server log:pubm PRIVMSG $client internalunbind server log:notc NOTICE $client internalunbind server log:join JOIN $client internalunbind server log:part PART $client internalunbind server log:sign QUIT $client internalunbind server log:kick KICK $client internalunbind server log:topic TOPIC $client internalunbind server log:nick NICK $client internalunbind server log:mode MODE $client if {[file exists users/$client.clog]} { if {[string equal -nocase [getbncuser $client tag offlinelog.method] "query"]} { setctx $client bncreply "You have new channel messages. Use '/msg -sBNC playlog' to view them." return } else { utimer 5 [list log:playlog $client] } } } proc log:redetach {client} { log:detach $client } proc log:detach {client} { if {[getbncuser $client hasclient] || [string equal -nocase [getbncuser $client tag offlinelog] ""] || [string equal -nocase [bncgetglobaltag chanlog] "none"]} {return "Client attached, or none/off set"} set x [split [getbncuser $client tag offlinelog.options] ,] if {[string equal -nocase $x ""]} { set x [split [bncgetglobaltag chanlog] ,] } if {!([lsearch -exact $x "privmsg"] == -1)} { internalbind server log:pubm PRIVMSG $client } if {!([lsearch -exact $x "notice"] == -1)} { internalbind server log:notc NOTICE $client } if {!([lsearch -exact $x "join"] == -1)} { internalbind server log:join JOIN $client } if {!([lsearch -exact $x "part"] == -1)} { internalbind server log:part PART $client } if {!([lsearch -exact $x "quit"] == -1)} { internalbind server log:sign QUIT $client } if {!([lsearch -exact $x "kick"] == -1)} { internalbind server log:kick KICK $client } if {!([lsearch -exact $x "topic"] == -1)} { internalbind server log:topic TOPIC $client } if {!([lsearch -exact $x "nick"] == -1)} { internalbind server log:nick NICK $client } if {!([lsearch -exact $x "mode"] == -1)} { internalbind server log:mode MODE $client } putmainlog "Starting offline log for $client" } proc log:pubm {client arg} { if {![string equal -nocase [lindex $arg 1] "PRIVMSG"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1) || [isbotnick [lindex [split [lindex $arg 0] !] 0]]} {return exclude} if {[regexp "^\001ACTION (.*?)\001$" [lindex $arg 3] foo text]} { log:everything $client ":[lindex $arg 0] PRIVMSG [lindex $arg 2] :\001ACTION \002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]:\002 [join [lrange [split [lindex $arg 3] " "] 1 end] " "]" } else { log:everything $client ":[lindex $arg 0] PRIVMSG [lindex $arg 2] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]:\002 [lindex $arg 3]" } haltoutput } proc log:notc {client arg} { if {![string equal -nocase [lindex $arg 1] "NOTICE"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1) || [isbotnick [lindex [split [lindex $arg 0] !] 0]]} {return exclude} log:everything $client ":[lindex $arg 0] NOTICE [lindex $arg 2] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]:\002 [lindex $arg 3]" haltoutput } proc log:join {client arg} { if {![string equal -nocase [lindex $arg 1] "JOIN"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1)} {return exclude} log:everything $client ":-sBNC!core@shroudbnc.info PRIVMSG [lindex $arg 2] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]:\002 user [lindex [split [lindex $arg 0] !] 0] joined:" log:everything $client ":[lindex $arg 0] JOIN [lindex $arg 2]" } proc log:part {client arg} { if {![string equal -nocase [lindex $arg 1] "PART"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1)} {return exclude} log:everything $client ":[lindex $arg 0] PART [lindex $arg 2] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]\002 [lindex $arg 3]" } proc log:sign {client arg} { if {![string equal -nocase [lindex $arg 1] "QUIT"] || !([string equal [getbncuser $client tag offlinelog.exclude] ""])} {return exclude} log:everything $client ":[lindex $arg 0] QUIT :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]\002 [lindex $arg 2]" } proc log:kick {client arg} { if {![string equal -nocase [lindex $arg 1] "KICK"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1)} {return exclude} log:everything $client ":[lindex $arg 0] KICK [lindex $arg 2] [lindex $arg 3] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]\002 [lindex $arg 4]" } proc log:topic {client arg} { if {![string equal -nocase [lindex $arg 1] "TOPIC"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1)} {return exclude} log:everything $client ":[lindex $arg 0] TOPIC [lindex $arg 2] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]\002 [lindex $arg 3]" } proc log:nick {client arg} { if {![string equal -nocase [lindex $arg 1] "NICK"] || !([string equal [getbncuser $client tag offlinelog.exclude] ""])} {return exclude} setctx $client foreach chan [internalchannels] { if {[onchan [lindex $arg 2] $chan]} { log:everything $client ":-sBNC!core@shroudbnc.info PRIVMSG $chan :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]:\002 user [lindex [split [lindex $arg 0] !] 0] changed nicks to [lindex $arg 2]:" } } log:everything $client ":[lindex $arg 0] NICK :[lindex $arg 2]" } proc log:mode {client arg} { if {![string equal -nocase [lindex $arg 1] "MODE"] || !([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower [lindex $arg 2]]] == -1)} {return exclude} log:everything $client ":-sBNC!core@shroudbnc.info PRIVMSG [lindex $arg 2] :\002\[[clock format [clock seconds] -format {%d/%m %H:%M:%S}]\]:\002 user [lindex [split [lindex $arg 0] !] 0] changed mode [lindex $arg 3] [lrange $arg 4 end]:" log:everything $client ":[lindex $arg 0] MODE [lindex $arg 2] [lindex $arg 3] [lrange $arg 4 end]" } proc log:everything {client arg} { set r [open users/$client.clog a+]; puts $r "$arg"; close $r } proc log:playlog {client} { setctx $client if {![file exists users/$client.clog]} {return empty} set fd [open users/$client.clog r] set logfile { } while {![eof $fd]} { set tmp [gets $fd] if {[eof $fd]} {break} set logfile [lappend logfile [string trim $tmp]] } close $fd foreach tmp $logfile { putclient "$tmp" } file delete "users/$client.clog" if {[string equal [getbncuser $client tag offlinelog.options] ""]} { set foo [split [bncgetglobaltag chanlog] ,] } else { set foo [split [getbncuser $client tag offlinelog.options] ,] } if {([lsearch $foo "join"] == -1) && ([lsearch $foo "part"] == -1) && ([lsearch $foo "quit"] == -1) && ([lsearch $foo "kick"] == -1) && ([lsearch $foo "mode"] == -1) && ([lsearch $foo "nick"] == -1)} {return noresync} foreach chan [internalchannels] { if {!([lsearch [split [getbncuser $client tag offlinelog.exclude] ,] [string tolower $chan]] == -1)} {continue} set x [simul $client "MODE $chan"] putclient $x set y [simul $client "NAMES $chan"] putclient $y } return done }