rendered paste bodyproc readlogtimer {} {
global dZStimer errorInfo
if {[catch {readlog}]} {
putlog "dZSbot error: Unhandled error, please report to developers:\n$errorInfo"
}
set dZStimer [utimer 1 readlogtimer]
}
proc readlog {} {
global defaultsection disable glversion lastread loglist max_log_change msgreplace msgtypes variables
set lines ""
foreach {logtype logid logpath} $loglist {
if {![file readable $logpath]} {
putlog "dZSbot error: Unable to read log file \"$logpath\"."
continue
}
## The regex pattern to use for the logfile
switch -exact -- $logtype {
0 {set regex {^.+ \d+:\d+:\d+ \d{4} (\S+): (.+)}}
1 - 2 {set regex {^.+ \d+:\d+:\d+ \d{4} \[(\d+)\s*\] (.+)}}
default {putlog "dZSbot error: Internal error, unknown log type ($logtype)."; continue}
}
## Read the log data
set logsize [file size $logpath]
if {$lastread($logid) < $logsize && ($logsize - $lastread($logid) - $max_log_change) < 0} {
if {![catch {set handle [open $logpath r]} error]} {
seek $handle $lastread($logid)
set data [read -nonewline $handle]
set logsize [tell $handle]
close $handle
foreach line [split $data "\n"] {
## Remove the date and time from the log line.
if {[regexp $regex $line result event line]} {
lappend lines $logtype $event $line
} else {
putlog "dZSbot warning: Invalid log line: $line"
}
}
} else {
putlog "dZSbot error: Unable to open log file \"$logpath\" ($error)."
}
}
set lastread($logid) $logsize
}
foreach {type event line} $lines {
## Login and sysop log specific parsing.
if {$type == 1 && ![parselogin $line event line]} {
putlog "dZSbot error: Unknown login.log line: $line"
continue
} elseif {$type == 2 && ![parsesysop $line event line]} {
set event "SYSOP"
set line [list $line]
}
ng_debug "Received event: $event (log: $type)."
## Check that the log line is a valid Tcl list.
if {[catch {llength $line} error]} {
putlog "dZSbot error: Invalid log line (not a tcl list): $line"
continue
}
## Invite users to public and private channels.
if {[string equal $event "INVITE"]} {
foreach {nick user group flags} $line {break}
ng_inviteuser $nick $user $group $flags
}
if {[lsearch -exact $msgtypes(SECTION) $event] != -1} {
set path [lindex $line 0]
if {[denycheck $path]} {continue}
set section [getsectionname $path]
# Replace messages with custom messages
foreach {name value} [array get msgreplace] {
set value [split $value ":"]
if {[string equal $event [lindex $value 0]]} {
if {[string match -nocase [lindex $value 1] $path]} {
set event [lindex $value 2]
}
}
}
} elseif {[lsearch -exact $msgtypes(DEFAULT) $event] != -1} {
set section $defaultsection
} else {
putlog "dZSbot error: Undefined message type \"$event\", check \"msgtypes(SECTION)\" and \"msgtypes(DEFAULT)\" in the config."
continue
}
## If a pre-event script returns false, skip the announce.
if {![eventhandler precommand $event [list $section $line]] || ([info exists disable($event)] && $disable($event) == 1)} {
ng_debug "Announce skipped, \"$event\" is disabled or a pre-command script returned false."
continue
}
if {![info exists variables($event)]} {
putlog "dZSbot error: \"variables($event)\" not defined in the config, type becomes \"$defaultsection\"."
set event $defaultsection
}
if {![eventcheck $section $event]} {
set rlzname [string map {"\"" ""} [lindex $line 0]]
set release_replaced [string map {"." " "} $rlzname]
sndall $event $section [ng_format $event $section $line]
eventhandler postcommand $event [list $section $line]
}
}
if {$glversion == 1} {
launchnuke
}
return
}
proc parselogin {line eventvar datavar} {