set The_Owner "Xeno" set cmdpfix "@" set priv_log_file "priv_msg_log.txt" set chan_log_file "chan_msg_log.txt" ##################### END OF CONFIG ####################### ################# TEACHING SECTION ################# ##### Variables and binds ###### set valid_types "question nonquest" bind pub - ${cmdpfix}bind pub:learn bind pub - ${cmdpfix}unbind pub:forget bind pub - ${cmdpfix}commands pub:listall bind pub n ${cmdpfix}deletedb pub:deletedb bind pub - ${cmdpfix}addcmd pub:addtype bind pub - ${cmdpfix}delcmd pub:deltype ##### Interface database procs ###### proc pub:learn {nick host hand chan args} { global The_Owner cmdpfix custom_types set custom_types "[get_type_list 1] [get_type_list 2] [get_type_list 3]" if { ![matchattr $hand "W"] } { putquick "notice $nick :A special teaching flag (\002+W\002) is required to use this command." putquick "notice $nick :To recieve this flag, please contact \002$The_Owner\002." return 0 } set args [lindex $args 0] set args [split $args] if { [llength $args] < 1 } { putquick "notice $nick :Usage: ${cmdpfix}learn " putquick "notice $nick :Valid type entries are: \002$valid_types $custom_types" putquick "notice $nick :To add new type entries use the \002${cmdpfix}addtype\002 command." return 0 } set work_file [lindex $args 0] set work_file [string tolower $work_file] set work_phrase [lrange $args 1 end] if { ![regexp $work_file "$valid_types $custom_types"] } { putserv "NOTICE $nick : Entry type \002$work_file\002 is invalid." putserv "NOTICE $nick : Valid type entries are: \002$valid_types $custom_types" return 0 } if { [ai_addphrase "Databases/$chan/$work_file.ai" $work_phrase] != 1 } { putserv "NOTICE $nick : Error writing to file (check permissions?)" return 0 } putlog "$nick !$hand! LEARN: type: \002$work_file\002, phrase: \002$work_phrase\002" putserv "PRIVMSG $chan :$nick: Added to \002$work_file\002 database: [join $work_phrase]" set f [open Databases/$chan/logfile.txt a] puts $f "LEARN: \[[realtime date], [realtime]\], (!$hand! $nick!$host) (DB:$work_file) PHR: $work_phrase" close $f } proc pub:forget {nick host hand chan args} { global valid_types The_Owner cmdpfix custom_types set custom_types "[get_type_list 1] [get_type_list 2] [get_type_list 3]" if { ![matchattr $hand "W"] } { putquick "notice $nick :A special teaching flag (\002+W\002) is required to use this command." putquick "notice $nick :To recieve this flag, please contact \002$The_Owner\002." return 0 } set args [lindex $args 0] set args [split $args] if { [llength $args] < 1 } { putquick "notice $nick :Usage: ${cmdpfix}forget " putquick "notice $nick :Valid type entries are: \002$valid_types $custom_types" putquick "notice $nick :To remove type entries use the \002${cmdpfix}deltype\002 command." return 0 } set work_file [lindex $args 0] set work_file [string tolower $work_file] set work_phrase [lrange $args 1 end] if { [ai_delphrase "$ai_db_directory$work_file.ai" $work_phrase] == 0} { putserv "NOTICE $nick : Phrase \002$work_phrase\002 not found in \002$work_file\002, or type is invalid." putserv "NOTICE $nick : Valid type entries are: \002$valid_types $custom_types" return 0 } putlog "$nick |$hand| FORGET: type: \002$work_file\002, phrase: \002$work_phrase\002" putserv "PRIVMSG $chan :$nick: Removed from \002$work_file\002 database: $work_phrase" set f [open Databases/$chan/logfile.txt a] puts $f "FORGET: \[[realtime date], [realtime]\], (!$hand! $nick!$host) (DB:$work_file) PHR: $work_phrase" close $f } proc pub:listall {nick host hand chan args} { global valid_types The_Owner cmdpfix custom_types set custom_types "[get_type_list 1] [get_type_list 2] [get_type_list 3]" if { ![matchattr $hand "W"] } { putquick "notice $nick :A special teaching flag (\002+W\002) is required to use this command." putquick "notice $nick :To recieve this flag, please contact \002$The_Owner\002." return 0 } set args [lindex $args 0] set args [split $args] if { [lindex $args 0] == "" } { putquick "notice $nick :Valid type entries are: \002$custom_types" return 0 } set work_file [lindex $args 0] set start_from [lindex $args 1] if { $work_file == "log" } { set work_file $logfile } { set work_file "Databases/$chan/$work_file.ai" } if { [ai_getall $work_file $nick $start_from] == 0 } { putserv "NOTICE $nick : Valid type entries are: \002$custom_types" return 0 } putlog "$nick !$hand! AI-LIST-ALL: file: \002$work_file\002" } proc pub:deletedb {nick host hand chan args} { global valid_types The_Owner cmdpfix custom_types set custom_types "[get_type_list 1] [get_type_list 2] [get_type_list 3]" if { ![matchattr $hand "W"] } { putquick "notice $nick :A special teaching flag (\002+W\002) is required to use this command." putquick "notice $nick :To recieve this flag, please contact \002$The_Owner\002." return 0 } set args [lindex $args 0] set args [split $args] if { [lindex $args 0] == "" } { putquick "notice $nick :Usage: ${cmdpfix}deletedb " putquick "notice $nick :Valid type entries are: \002$valid_types $custom_types" return 0 } set work_file [lindex $args 0] set work_file [string tolower $work_file] if { $work_file == "log" } { set work_file Databases/$chan/logfile } { set work_file "Databases/$chan/$work_file.ai" } if { [ai_delfile $work_file] == 0} { putserv "NOTICE $nick : Entry type \002$work_file\002 is invalid or there was an error deleting the file." putserv "NOTICE $nick : Valid type entries are: \002$valid_types $custom_types" return 0 } putlog "$nick !$hand! DELETE DATABASE FILE: file: \002$work_file\002" putserv "PRIVMSG $chan :$nick: Deleted the \002$work_file\002 database." set f [open Databases/$chan/logfile.txt a] puts $f "DELETE DATABASE: \[[realtime date], [realtime]\], (!$hand! $nick!$host) DB: $work_file" close $f } ###### Interface type procs ####### proc pub:addtype {nick host hand chan args} { global valid_types The_Owner cmdpfix custom_types if { ![matchattr $hand "W"] } { putquick "notice $nick :A special teaching flag (\002+W\002) is required to use this command." putquick "notice $nick :To recieve this flag, please contact \002$The_Owner\002." return 0 } set args [lindex $args 0] set args [split $args] if { [llength $args] < 3 } { putquick "notice $nick :Usage: ${cmdpfix}addtype " putquick "notice $nick :To add new keywords to existing type entries use the \002${cmdpfix}addkeyword\002 command." return 0 } set custom_types "[get_type_list 1] [get_type_list 2] " set existing_types "$valid_types $custom_types" set work_file [lindex $args 0] set work_file [string tolower $work_file] set work_phrase [lrange $args 2 end] set work_phrase [string tolower $work_phrase] set work_type [lindex $args 1] set work_type [string tolower $work_type] set the_type 0 if { $work_type == "question" } { set the_type 1 } if { $work_type == "nonquest" } { set the_type 2 } if { $work_type == "react" } { set the_type 3 } if { $the_type == 0 } { putquick "notice $nick :Invalid orientation (2nd argument). Must be \002question\002, \002nonquest\002 or \002react\002." return 0 } if { [regexp " $work_file " $existing_types] } { notice $nick "Type entry \002$work_file\002 ia already in use." if { [regexp " $work_file " " $custom_types "] } { putquick "notice $nick :Please choose a different type name, or use the \002${cmdpfix}addkeyword\002 command to add new keywords to \002$work_file\002 type." } { putquick "notice $nick :Please choose a different type name." } return 0 } if { $work_phrase == "" } { putquick "notice $nick :Initial keyword not specified." return 0 } add_type $work_file $the_type $work_phrase putlog "$nick !$hand! ADD-NEW-TYPE: type: \002$work_file\002, orien: \002$the_type\002, kwds: \002$work_phrase\002" putserv "PRIVMSG $chan :$nick: Added new type \002$work_file\002 with \002$work_type\002 orientation and keywords: \002[join $work_phrase]" set f [open Databases/$chan/logfile.txt a] puts $f "ADD-TYPE: \[[realtime date], [realtime]\], (!$hand! $nick!$host) - TYPE:$work_file ORN:$the_type KWD:$work_phrase" close $f } proc pub:deltype {nick host hand chan args} { global valid_types The_Owner cmdpfix custom_types set custom_types "[get_type_list 1] [get_type_list 2] [get_type_list 3]" if { ![matchattr $hand "W"] } { putquick "notice $nick :A special teaching flag (\002+W\002) is required to use this command." putquick "notice $nick :To recieve this flag, please contact \002$The_Owner\002." return 0 } set args [lindex $args 0] set args [split $args] if { [lindex $args 0] == "" } { putquick "notice $nick :Usage: ${cmdpfix}deltype " putquick "notice $nick :Valid type entries are: \002$custom_types" return 0 } set work_file [lindex $args 0] set work_file [string tolower $work_file] if { [del_type $work_file] == 0} { putserv "NOTICE $nick : Entry type \002$work_file\002 is invalid." putserv "NOTICE $nick : Valid type entries are: \002$custom_types" return 0 } putlog "$nick |$hand| DEL-TYPE: type: \002$work_file\002" putserv "PRIVMSG $chan :$nick: Removed the \002$work_file\002 type and all the keywords for it." set f [open Databases/$chan/logfile.txt a] puts $f "DEL-TYPE: \[[realtime date], [realtime]\], (!$hand! $nick!$host) TYPE:$work_file" close $f } proc ai_getphrase { ai_file } { set phrases "" if { ![file exists $ai_file] } { return "" } set fd [open $ai_file r] while {![eof $fd]} { gets $fd text if {$text != ""} { lappend phrases $text } } close $fd return [lindex $phrases [rand [llength $phrases]]] } proc ai_getall { ai_file nick number } { if { $number == ""} { set nummber 0 } if { ![file exists $ai_file] } { return 0 } putserv "PRIVMSG $nick : Listing database, file: \002$ai_file\002, starting from line \002$number\002" set line_num 0 set fd [open $ai_file r] while {![eof $fd]} { incr line_num gets $fd text if {$text != ""} { if { $line_num >= $number } { putserv "PRIVMSG $nick : \002$line_num\002 $text" } } } close $fd putserv "PRIVMSG $nick : End of list." return 1 } proc ai_addphrase { ai_file phrase } { set phrase [join $phrase] putlog "WRITING TO FILE $ai_file: \002$phrase" if {[catch {open $ai_file a} fd]} { return 0 } else { puts $fd $phrase close $fd return 1 } } proc ai_delphrase { ai_file phrase } { set what "" set phraserem 0 set phrase [join $phrase] if {[catch {open $ai_file r} fd]} { return 0 } else { while {![eof $fd]} { gets $fd text if {[string tolower $text] != [string tolower $phrase]} { append what "$text\n" } else { set phraserem 1 } } close $fd if {[catch {open $ai_file w} fd]} { return 0 } else { puts $fd $what close $fd return $phraserem } } } proc ai_delfile { file } { if {[file exists $file]} { file delete -force $file if {[file exists $file]} { return 0 } else { return 1 } } else { return 0 } } proc ai_searchdb { ai_file phrase nick } { set phrase [join $phrase] set line 0 set found 0 set retstr "" if { ![file exists $ai_file] } { return "" } if { $phrase == "" } { return "" } set fd [open $ai_file r] while {![eof $fd]} { incr line gets $fd text if {$text != ""} { if { [regexp $phrase $text] } { putserv "PRIVMSG $nick : \002$ai_file: $line\002 $text" incr found set retstr "$found" } } } close $fd return "$retstr" } ###### Now the core type procs ######## proc add_type { ai_type type_type keywords chan } { global set fh [open Databases/$chan/AI-type.dat a] if { $type_type == 1} { puts $fh "$ai_type => $keywords" } if { $type_type == 2} { puts $fh "$ai_type -> $keywords" } if { $type_type == 3} { puts $fh "$ai_type _> $keywords" } close $fh } proc del_type { ai_type chan } { global set what "" set phraserem 0 if {[catch {open Databases/$chan/AI-type.dat r} fd]} { return 0 } else { while {![eof $fd]} { gets $fd text set first_word [lindex [split $text] 0] if {[string tolower $first_word] == [string tolower $ai_type]} { set phraserem 1 } else { append what "$text\n" } } close $fd if {[catch {open Databases/$chan/AI-type.dat w} fd]} { return 0 } else { puts $fd $what close $fd return $phraserem } } } proc get_type_list { type_type } { global set result "" if { $type_type == 1} { set requested_type "=>" } if { $type_type == 2} { set requested_type "->" } if { $type_type == 3} { set requested_type "_>" } if {[catch {open databases/$chan/AI-type.dat r} fd]} { return "" } else { while {![eof $fd]} { gets $fd text set first_word [lindex [split $text] 0] set current_type [lindex [split $text] 1] if { $current_type == $requested_type } { append result " $first_word" } } close $fd } set result [join $result] set result [split $result] return "$result" }