| 1 | # bMotion - Diagnostics |
|---|
| 2 | # |
|---|
| 3 | |
|---|
| 4 | ############################################################################### |
|---|
| 5 | # bMotion - an 'AI' TCL script for eggdrops |
|---|
| 6 | # Copyright (C) James Michael Seward 2000-2008 |
|---|
| 7 | # |
|---|
| 8 | # This program is free software; you can redistribute it and/or modify |
|---|
| 9 | # it under the terms of the GNU General Public License as published by |
|---|
| 10 | # the Free Software Foundation; either version 2 of the License, or |
|---|
| 11 | # (at your option) any later version. |
|---|
| 12 | # |
|---|
| 13 | # This program is distributed in the hope that it will be useful, but |
|---|
| 14 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 16 | # General Public License for more details. |
|---|
| 17 | # |
|---|
| 18 | # You should have received a copy of the GNU General Public License |
|---|
| 19 | # along with this program; if not, write to the Free Software |
|---|
| 20 | # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 21 | ############################################################################### |
|---|
| 22 | |
|---|
| 23 | # Check if a channel has uppercase letters in it |
|---|
| 24 | # |
|---|
| 25 | proc bMotion_diagnostic_channel1 { } { |
|---|
| 26 | global bMotionInfo |
|---|
| 27 | |
|---|
| 28 | #not used now |
|---|
| 29 | return 0 |
|---|
| 30 | |
|---|
| 31 | set err 0 |
|---|
| 32 | set cleanChannels [list] |
|---|
| 33 | foreach chan $bMotionInfo(randomChannels) { |
|---|
| 34 | set chan2 [string tolower $chan] |
|---|
| 35 | if {$chan != $chan2} { |
|---|
| 36 | #case difference |
|---|
| 37 | set err 1 |
|---|
| 38 | } |
|---|
| 39 | lappend cleanChannels $chan2 |
|---|
| 40 | } |
|---|
| 41 | set bMotionInfo(randomChannels) $cleanChannels |
|---|
| 42 | |
|---|
| 43 | if {$err == 1} { |
|---|
| 44 | putlog "Self-diagnostics indicate you have a channel with a captial letter in in your settings file." |
|---|
| 45 | putlog " This has been fixed on the fly at load time, but you will need to edit the settings file" |
|---|
| 46 | putlog " to prevent this reoccuring. Please use all lower-case characters for defining channels." |
|---|
| 47 | } |
|---|
| 48 | } |
|---|
| 49 | |
|---|
| 50 | # |
|---|
| 51 | # Check the bot's configured for all the channels in the list |
|---|
| 52 | proc bMotion_diagnostic_channel2 { } { |
|---|
| 53 | global bMotionInfo |
|---|
| 54 | |
|---|
| 55 | #not used now |
|---|
| 56 | return 0 |
|---|
| 57 | |
|---|
| 58 | set notOnChans "" |
|---|
| 59 | set botChans [list] |
|---|
| 60 | foreach chan [channels] { |
|---|
| 61 | lappend botChans [string tolower $chan] |
|---|
| 62 | } |
|---|
| 63 | |
|---|
| 64 | foreach chan $bMotionInfo(randomChannels) { |
|---|
| 65 | if {[lsearch -exact $botChans $chan] < 0} { |
|---|
| 66 | #configured chan the bot doesn't know about |
|---|
| 67 | append notOnChans "$chan " |
|---|
| 68 | } |
|---|
| 69 | } |
|---|
| 70 | if {$notOnChans != ""} { |
|---|
| 71 | putlog "The following channels are in the settings file, but not configured in eggdrop (typos?): $notOnChans" |
|---|
| 72 | } |
|---|
| 73 | } |
|---|
| 74 | |
|---|
| 75 | # |
|---|
| 76 | # check the channels are set in the right format |
|---|
| 77 | proc bMotion_diagnostic_channel3 { } { |
|---|
| 78 | global bMotionInfo |
|---|
| 79 | |
|---|
| 80 | #not used now |
|---|
| 81 | return 0 |
|---|
| 82 | |
|---|
| 83 | if [regexp {#[^ ]+ *#.+} [lindex $bMotionInfo(randomChannels) 0]] { |
|---|
| 84 | putlog "bMotion self-diagnostics indicate you have set your channel list in settings.tcl" |
|---|
| 85 | putlog " incorrectly. You must have a pair of double-quotes around EACH channel, not" |
|---|
| 86 | putlog " the entire list. bMotion WILL NOT WORK with this configuration error." |
|---|
| 87 | } |
|---|
| 88 | } |
|---|
| 89 | |
|---|
| 90 | # bMotion_diagnostic_timers <<<1 |
|---|
| 91 | # make sure we only have one instance of each timer |
|---|
| 92 | proc bMotion_diagnostic_timers { } { |
|---|
| 93 | bMotion_putloglev d * "running level 4 diagnostic on timers" |
|---|
| 94 | set alltimers [timers] |
|---|
| 95 | set seentimers [list] |
|---|
| 96 | foreach t $alltimers { |
|---|
| 97 | bMotion_putloglev 1 * "checking timer $t" |
|---|
| 98 | set t_function [lindex $t 1] |
|---|
| 99 | set t_name [lindex $t 2] |
|---|
| 100 | set t_function [string tolower $t_function] |
|---|
| 101 | if {[lsearch $seentimers $t_function] >= 0} { |
|---|
| 102 | bMotion_putloglev d * "bMotion: A level 4 diagnostic has found a duplicate timer $t_name for $t_function ... removing (this is not an error)" |
|---|
| 103 | #remove timer |
|---|
| 104 | killtimer $t_name |
|---|
| 105 | } else { |
|---|
| 106 | #add to seen list |
|---|
| 107 | lappend seentimers $t_function |
|---|
| 108 | } |
|---|
| 109 | } |
|---|
| 110 | } |
|---|
| 111 | |
|---|
| 112 | # bMotion_diagnostic_utimers <<<1 |
|---|
| 113 | # make sure we have only one instance of each utimer |
|---|
| 114 | proc bMotion_diagnostic_utimers { } { |
|---|
| 115 | bMotion_putloglev d * "running level 4 diagnostic on utimers" |
|---|
| 116 | set alltimers [utimers] |
|---|
| 117 | set seentimers [list] |
|---|
| 118 | foreach t $alltimers { |
|---|
| 119 | bMotion_putloglev 1 * "checking timer $t" |
|---|
| 120 | set t_function [lindex $t 1] |
|---|
| 121 | set t_name [lindex $t 2] |
|---|
| 122 | set t_function [string tolower $t_function] |
|---|
| 123 | if {[lsearch $seentimers $t_function] >= 0} { |
|---|
| 124 | bMotion_putloglev d * "bMotion: A level 4 diagnostic has found a duplicate utimer $t_name for $t_function ... removing (this is not an error)" |
|---|
| 125 | #remove timer |
|---|
| 126 | killutimer $t_name |
|---|
| 127 | } else { |
|---|
| 128 | #add to seen list |
|---|
| 129 | lappend seentimers $t_function |
|---|
| 130 | } |
|---|
| 131 | } |
|---|
| 132 | } |
|---|
| 133 | |
|---|
| 134 | ### bMotion_diagnostic_plugins <<<1 |
|---|
| 135 | # check some plugins loaded |
|---|
| 136 | proc bMotion_diagnostic_plugins { } { |
|---|
| 137 | bMotion_putloglev 5 * "bMotion_diagnostic_plugins" |
|---|
| 138 | foreach t {simple complex output action_simple action_complex irc_event management} { |
|---|
| 139 | set arrayName "bMotion_plugins_$t" |
|---|
| 140 | upvar #0 $arrayName cheese |
|---|
| 141 | if {[llength [array names cheese]] == 0} { |
|---|
| 142 | putlog "bMotion: diagnostics: No $t plugins loaded, something is wrong!" |
|---|
| 143 | } |
|---|
| 144 | } |
|---|
| 145 | } |
|---|
| 146 | |
|---|
| 147 | ### bMotion_diagnostic_settings <<<1 |
|---|
| 148 | # check needed settings are defined |
|---|
| 149 | proc bMotion_diagnostic_settings { } { |
|---|
| 150 | global bMotionInfo bMotionSettings |
|---|
| 151 | |
|---|
| 152 | set errors 0 |
|---|
| 153 | |
|---|
| 154 | if {![info exists bMotionInfo(gender)]} { |
|---|
| 155 | putlog "bMotion: diagnostics: Gender not defined, check settings file!" |
|---|
| 156 | set errors 1 |
|---|
| 157 | } |
|---|
| 158 | |
|---|
| 159 | if {![info exists bMotionInfo(orientation)]} { |
|---|
| 160 | putlog "bMotion: diagnostics: Orientation not defined, check settings file!" |
|---|
| 161 | set errors 1 |
|---|
| 162 | } |
|---|
| 163 | |
|---|
| 164 | if {![info exists bMotionSettings(kinky)]} { |
|---|
| 165 | putlog "bMotion: diagnostics: kinky not defined, check settings file!" |
|---|
| 166 | set errors 1 |
|---|
| 167 | } |
|---|
| 168 | |
|---|
| 169 | if {![info exists bMotionSettings(friendly)]} { |
|---|
| 170 | putlog "bMotion: diagnostics: friendly not defined, check settings file!" |
|---|
| 171 | set errors 1 |
|---|
| 172 | } |
|---|
| 173 | |
|---|
| 174 | if {![info exists bMotionSettings(melMode)]} { |
|---|
| 175 | putlog "bMotion: diagnostics: melMode not defined, check settings file!" |
|---|
| 176 | set errors 1 |
|---|
| 177 | } |
|---|
| 178 | |
|---|
| 179 | if {![info exists bMotionSettings(needI)]} { |
|---|
| 180 | putlog "bMotion: diagnostics: needI not defined, check settings file!" |
|---|
| 181 | set errors 1 |
|---|
| 182 | } |
|---|
| 183 | |
|---|
| 184 | if {![info exists bMotionInfo(balefire)]} { |
|---|
| 185 | putlog "bMotion: diagnostics: balefire not defined, check settings file!" |
|---|
| 186 | set errors 1 |
|---|
| 187 | } |
|---|
| 188 | |
|---|
| 189 | if {![info exists bMotionSettings(useAway)]} { |
|---|
| 190 | putlog "bMotion: diagnostics: useAway not defined, check settings file!" |
|---|
| 191 | set errors 1 |
|---|
| 192 | } |
|---|
| 193 | |
|---|
| 194 | if {![info exists bMotionSettings(botnicks)]} { |
|---|
| 195 | putlog "bMotion: diagnostics: botnicks not defined, check settings file!" |
|---|
| 196 | set errors 1 |
|---|
| 197 | } |
|---|
| 198 | |
|---|
| 199 | if {![info exists bMotionSettings(noAwayFor)]} { |
|---|
| 200 | putlog "bMotion: diagnostics: noAwayFor not defined, check settings file!" |
|---|
| 201 | set errors 1 |
|---|
| 202 | } |
|---|
| 203 | |
|---|
| 204 | if {![info exists bMotionSettings(typos)]} { |
|---|
| 205 | putlog "bMotion: diagnostics: typos not defined, check settings file!" |
|---|
| 206 | set errors 1 |
|---|
| 207 | } |
|---|
| 208 | |
|---|
| 209 | if {![info exists bMotionSettings(colloq)]} { |
|---|
| 210 | putlog "bMotion: diagnostics: colloq not defined, check settings file!" |
|---|
| 211 | set errors 1 |
|---|
| 212 | } |
|---|
| 213 | |
|---|
| 214 | if {![info exists bMotionSettings(homophone)]} { |
|---|
| 215 | putlog "bMotion: diagnostics: homophone not defined, check settings file!" |
|---|
| 216 | set errors 1 |
|---|
| 217 | } |
|---|
| 218 | |
|---|
| 219 | |
|---|
| 220 | if {![info exists bMotionInfo(minRandomDelay)]} { |
|---|
| 221 | putlog "bMotion: diagnostics: minRandomDelay not defined, check settings file!" |
|---|
| 222 | set errors 1 |
|---|
| 223 | } |
|---|
| 224 | |
|---|
| 225 | if {![info exists bMotionInfo(maxRandomDelay)]} { |
|---|
| 226 | putlog "bMotion: diagnostics: maxRandomDelay not defined, check settings file!" |
|---|
| 227 | set errors 1 |
|---|
| 228 | } |
|---|
| 229 | |
|---|
| 230 | if {![info exists bMotionInfo(maxIdleGap)]} { |
|---|
| 231 | putlog "bMotion: diagnostics: maxIdleGap not defined, check settings file!" |
|---|
| 232 | set errors 1 |
|---|
| 233 | } |
|---|
| 234 | |
|---|
| 235 | if {![info exists bMotionInfo(brigDelay)]} { |
|---|
| 236 | putlog "bMotion: diagnostics: brigDelay not defined, check settings file!" |
|---|
| 237 | set errors 1 |
|---|
| 238 | } |
|---|
| 239 | |
|---|
| 240 | if {![info exists bMotionSettings(silenceTime)]} { |
|---|
| 241 | putlog "bMotion: diagnostics: silenceTime not defined, check settings file!" |
|---|
| 242 | set errors 1 |
|---|
| 243 | } |
|---|
| 244 | |
|---|
| 245 | if {![info exists bMotionSettings(languages)]} { |
|---|
| 246 | putlog "bMotion: diagnostics: languages not defined, check settings file!" |
|---|
| 247 | set errors 1 |
|---|
| 248 | } |
|---|
| 249 | |
|---|
| 250 | if {![info exists bMotionSettings(typingSpeed)]} { |
|---|
| 251 | putlog "bMotion: diagnostics: typingSpeed not defined, check settings file!" |
|---|
| 252 | set errors 1 |
|---|
| 253 | } |
|---|
| 254 | |
|---|
| 255 | if {![info exists bMotionSettings(disableFloodChecks)]} { |
|---|
| 256 | putlog "bMotion: diagnostics: disableFloodChecks not defined, check settings file!" |
|---|
| 257 | set errors 1 |
|---|
| 258 | } |
|---|
| 259 | |
|---|
| 260 | if {![info exists bMotionSettings(abstractMaxAge)]} { |
|---|
| 261 | putlog "bMotion: diagnostics: abstractMaxAge not defined, check settings file!" |
|---|
| 262 | set errors 1 |
|---|
| 263 | } |
|---|
| 264 | |
|---|
| 265 | if {![info exists bMotionSettings(abstractMaxNumber)]} { |
|---|
| 266 | putlog "bMotion: diagnostics: abstractMaxNumber not defined, check settings file!" |
|---|
| 267 | set errors 1 |
|---|
| 268 | } |
|---|
| 269 | if {![info exists bMotionSettings(factsMaxItems)]} { |
|---|
| 270 | putlog "bMotion: diagnostics: factsMaxItems not defined, check settings file!" |
|---|
| 271 | set errors 1 |
|---|
| 272 | } |
|---|
| 273 | if {![info exists bMotionSettings(factsMaxFacts)]} { |
|---|
| 274 | putlog "bMotion: diagnostics: factsMaxFacts not defined, check settings file!" |
|---|
| 275 | set errors 1 |
|---|
| 276 | } |
|---|
| 277 | if {![info exists bMotionSettings(bitlbee)]} { |
|---|
| 278 | putlog "bMotion: diagnostics: bitlbee not defined, check settings file!" |
|---|
| 279 | set errors 1 |
|---|
| 280 | } |
|---|
| 281 | |
|---|
| 282 | if {$errors == 1} { |
|---|
| 283 | putlog "bMotion: ### MISSING ONE OR MORE CONFIG SETTINGS ###" |
|---|
| 284 | putlog "bMotion: ### It's likely that your bot will be broken!" |
|---|
| 285 | } |
|---|
| 286 | } |
|---|
| 287 | |
|---|
| 288 | ### bMotion_diagnostic_userinfo |
|---|
| 289 | # Check to see if the user has added IRL and GENDER to their userinfo stuff |
|---|
| 290 | proc bMotion_diagnostic_userinfo { } { |
|---|
| 291 | global userinfo-fields |
|---|
| 292 | |
|---|
| 293 | if {![info exists userinfo-fields]} { |
|---|
| 294 | putlog "bMotion: diagnostics indicate you haven't loaded the userinfo TCL script" |
|---|
| 295 | putlog " this is not required, but is strongly recommended" |
|---|
| 296 | return |
|---|
| 297 | } |
|---|
| 298 | |
|---|
| 299 | if {![string match "*GENDER*" ${userinfo-fields}]} { |
|---|
| 300 | putlog "bMotion: diagnostics indicate you haven't added the GENDER field to the" |
|---|
| 301 | putlog " userinfo.tcl script. This is not required, but is recommended" |
|---|
| 302 | return |
|---|
| 303 | } |
|---|
| 304 | |
|---|
| 305 | if {![string match "*IRL*" ${userinfo-fields}]} { |
|---|
| 306 | putlog "bMotion: diagnostics indicate you haven't added the IRL field to the" |
|---|
| 307 | putlog " userinfo.tcl script. This is not required, but is recommended" |
|---|
| 308 | return |
|---|
| 309 | } |
|---|
| 310 | return |
|---|
| 311 | } |
|---|
| 312 | |
|---|
| 313 | ### bMotion_diagnostic_bitlbee |
|---|
| 314 | # Check if bitlbee mode is enabled, but the bot doesn't know about #bitlbee/&bitlbee |
|---|
| 315 | proc bMotion_diagnostic_bitlbee { } { |
|---|
| 316 | global bMotionSettings |
|---|
| 317 | if {!$bMotionSettings(bitlbee)} { |
|---|
| 318 | return |
|---|
| 319 | } |
|---|
| 320 | |
|---|
| 321 | set found_bitlbee 0 |
|---|
| 322 | foreach channel [channels] { |
|---|
| 323 | if [string match -nocase "*bitlbee" $channel] { |
|---|
| 324 | set found_bitlbee 1 |
|---|
| 325 | break |
|---|
| 326 | } |
|---|
| 327 | } |
|---|
| 328 | |
|---|
| 329 | if {!$found_bitlbee} { |
|---|
| 330 | putlog "bMotion: bitlbee mode is enabled, but I don't seem to be" |
|---|
| 331 | putlog " configured to be in a bitlbee channel... maybe you" |
|---|
| 332 | putlog " should turn bitlbee mode off else things will go weird!" |
|---|
| 333 | } |
|---|
| 334 | } |
|---|
| 335 | |
|---|
| 336 | ### bMotion_diagnostic_parsing |
|---|
| 337 | # Try to build every abstract we can and make sure it parses ok |
|---|
| 338 | # This is not run automatically! |
|---|
| 339 | # This is run as an admin plugin, so it tries to output to the admin stuff |
|---|
| 340 | proc bMotion_diagnostic_parsing { } { |
|---|
| 341 | bMotion_putadmin "Counting abstracts..." |
|---|
| 342 | set all_abstracts [bMotion_abstract_get_names] |
|---|
| 343 | set all_abstracts_size [llength $all_abstracts] |
|---|
| 344 | bMotion_putadmin "Found $all_abstracts_size abstracts" |
|---|
| 345 | |
|---|
| 346 | set broken [list] |
|---|
| 347 | set errors 0 |
|---|
| 348 | set count_abstract 0 |
|---|
| 349 | set count_lines 0 |
|---|
| 350 | set i 0 |
|---|
| 351 | |
|---|
| 352 | foreach abstract $all_abstracts { |
|---|
| 353 | incr i |
|---|
| 354 | if {[expr $i % 10] == 0} { |
|---|
| 355 | bMotion_putadmin "Processing abstract $i: $abstract..." |
|---|
| 356 | } |
|---|
| 357 | set abstract_contents [bMotion_abstract_all $abstract] |
|---|
| 358 | bMotion_putloglev d * "Processing [llength $abstract_contents] items for abstract $abstract" |
|---|
| 359 | incr count_abstract |
|---|
| 360 | foreach content $abstract_contents { |
|---|
| 361 | incr count_lines |
|---|
| 362 | set line "" |
|---|
| 363 | set fail "" |
|---|
| 364 | catch { |
|---|
| 365 | set line [bMotion_process_macros "" $content] |
|---|
| 366 | set line [bMotionDoInterpolation $line "JamesOff" "moretext" "#diagnostics"] |
|---|
| 367 | # bit of a hack! |
|---|
| 368 | set line [bMotion_plugin_output_preprocess "#diagnostics" $line] |
|---|
| 369 | } |
|---|
| 370 | if {($line == "") || [regexp {%(?!(SETTING|ruser|r?bot|BOT|percent|channel))[^%2\| ]} $line matches moo]} { |
|---|
| 371 | incr errors |
|---|
| 372 | lappend broken "$abstract:$content\r\n -> $line" |
|---|
| 373 | } |
|---|
| 374 | } |
|---|
| 375 | } |
|---|
| 376 | |
|---|
| 377 | bMotion_putadmin "Finished." |
|---|
| 378 | bMotion_putadmin "$errors errors found in $count_lines lines in $count_abstract abstracts." |
|---|
| 379 | foreach line $broken { |
|---|
| 380 | bMotion_putadmin $line |
|---|
| 381 | } |
|---|
| 382 | } |
|---|
| 383 | |
|---|
| 384 | ### bMotion_diagnostic_auto <<<1 |
|---|
| 385 | proc bMotion_diagnostic_auto { min hr a b c } { |
|---|
| 386 | bMotion_putloglev 5 * "bMotion_diagnostic_auto" |
|---|
| 387 | putlog "bMotion: running level 4 self-diagnostic" |
|---|
| 388 | bMotion_diagnostic_timers |
|---|
| 389 | bMotion_diagnostic_utimers |
|---|
| 390 | } |
|---|
| 391 | #>>> |
|---|
| 392 | |
|---|
| 393 | if {$bMotion_testing == 0} { |
|---|
| 394 | bMotion_putloglev d * "Running a level 5 self-diagnostic..." |
|---|
| 395 | |
|---|
| 396 | bMotion_diagnostic_channel1 |
|---|
| 397 | bMotion_diagnostic_channel2 |
|---|
| 398 | bMotion_diagnostic_channel3 |
|---|
| 399 | bMotion_diagnostic_plugins |
|---|
| 400 | bMotion_diagnostic_settings |
|---|
| 401 | bMotion_diagnostic_userinfo |
|---|
| 402 | bMotion_diagnostic_bitlbee |
|---|
| 403 | |
|---|
| 404 | bMotion_putloglev d * "Diagnostics complete." |
|---|
| 405 | } |
|---|
| 406 | |
|---|
| 407 | bind time - "30 * * * *" bMotion_diagnostic_auto |
|---|