# IRC Karma for Eggdrops by Lily (lily@disorg.net)
# This is a Karma database script for Eggdrop bots.
# It has flood control built in, and basic self-karma prevention.
# Requires TCL8.4 or greater, and the sqlite3 tcl lib. (not mysql!)
# For deb/ubuntu, that is the libsqlite3-tcl package. Adjust for your flavor.
# !! 3.x USERS PLEASE NOTE!!! The database change for 4.x means that unless
# you manually edit your db, you will have to start over. Sorry! You may not want
# karma entropy and expiry anyway, and thats the big new feature here.
# 1.0 - self karma prevention
# 2.0 - flood control, maries mods added
# 2.5 - command triggers fixed, extra commands removed. comments added. 20101220
# 3.0 - converted to sqlite. code cleanup. 20111030
# 3.1 - search and help. 20111104
# 3.2 - changed dbfile varname to prevent namespace collison 20120220
# 4.0 - added db timestamping and karma expiry, changed scoring update loop. 20120828
# 4.1 - karma entropy 20120903
# 4.2 - !instant changes a random thing -/+1 , !random returns things. 20120905
# 4.3 - locked text change, faster decay for high vals, trim item whitespace 20130215
# 4.4 - Immortal karma (user request). Expanded stats. Fixes (locked text, high val decay) 20130526
# 4.5 - strip ASCII codes from input. 20211221
# TODO - randomize days a little on entropy
### Usage ###
# Once you have loaded this from your bots config and rehashed it,
# do: .chanset #yourchannel +lkarma
# In your channel you can "!<item>++" and "!<item>--" with any word or phrase.
# "!good" and "!bad" return the top (and bottom) ten. "!khelp" for help.
# "!lfind" returns locked items. "!ifind" returns immortalized items.
# "!karma <item>" for score. "!stats" for total items and average karma (unlocked items).
# "!find <item>" and "!rfind <item>" to search for things in the database.
# "!instant" changes a random thing -/+1 , "!random" returns some items.
# Privileged users can "!lock <item>", "!unlock <item>", and "!delete <item>"
# They can also "!immortalize <item>" and remove it from entropy. Cannot be unset.
### Settings ###
set karma(logchan) "#fire-trail"
# Set this to f allow friends in the bot to use karma (+f flag)
# Set this to - if you want everyone to be able to.
set karma(flags) "-|-"
# Default flags allow only bot owners to lock/unlock karma.
set karma(lockflags) "n|-"
# Default flags allow only bot owners to delete karma from the database.
set karma(deleteflags) "n|-"
# x times in y seconds to trigger flood protection
set kfflood 4:300
###############################################
set karma(version) "4.5"
setudef flag lkarma
package require sqlite3
set kdbfile "./lkarma.db"
if {![file exists $kdbfile]} {
sqlite3 kdb $kdbfile
kdb eval {CREATE TABLE lkarma(item TEXT NOT NULL COLLATE NOCASE, karma INTEGER NOT NULL, locked TEXT NOT NULL default 'N', modtime INTEGER NOT NULL)}
kdb close
}
bind pubm $karma(flags) "% *--" fixkarma
bind pubm $karma(flags) "% *++" fixkarma
proc fixkarma {nick uhost hand chan text} {
global karma kdbfile kfcount kfflood
if {[string match "*+lkarma*" [channel info $chan]]} {
set uhost [string tolower $uhost]
set acct [getaccount $nick]
set hand [finduser -account $acct]
set chan [string tolower $chan]
set item [string range $text 0 [expr [string length $text] -3]]
set item [stripcodes bcruag $item]
set item [string trim $item]
if {$hand == "rss"} { return 0 }
sqlite3 kdb $kdbfile
if {$item == ""} {
return 0
}
if {[string match -nocase *$nick* $item]} {
puthelp "NOTICE $chan :\[karma\] self karma is a selfish pursuit."
return 0
}
if {($acct != "*")} {
if {([string match -nocase *$acct* $item])} {
puthelp "NOTICE $chan :\[karma\] self karma is a selfish pursuit."
return 0
}
}
set score [string range $text end-1 end]
if {[string match "++" $score]} {
set scoring +1
} elseif {[string match "--" $score]} {
set scoring -1
}
if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] == "Y"} {
set lockedk [kdb eval {SELECT karma FROM lkarma WHERE item=$item}]
puthelp "NOTICE $chan :\[karma\] '$item' now has $lockedk karma!"
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] $nick!$uhost ($acct) ++'d locked '$item' in $chan - score: $lockedk"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] $nick!$uhost ($acct) --'d locked '$item' in $chan - score: $lockedk"
}
return 0
}
if {![info exists kfcount($uhost)]} {
set kfcount($uhost) 0
}
if {$kfcount($uhost) == [lindex $kfflood 0]} {
puthelp "NOTICE $nick :please dont flood the karmabot, $nick. try again later."
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - flood* $nick!$uhost ($acct) ++'d '$item' in $chan"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - flood* $nick!$uhost ($acct) --'d '$item' in $chan"
}
return 0
}
# check if it was likely a command to another bot
#if {[string index $text 0] == "!"} {
# if {[string match "++" $score]} {
# puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - starts with !* $nick!$uhost ($acct) ++'d '$item' in $chan"
# } elseif {[string match "--" $score]} {
# puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - starts with !* $nick!$uhost ($acct) --'d '$item' in $chan"
# }
# return 0
#}
# ignore things that begin with common certificate headers
if {[string match "---*---" $text]} {
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - matches ---*--- $nick!$uhost ($acct) ++'d '$item' in $chan"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - matches ---*--- $nick!$uhost ($acct) --'d '$item' in $chan"
}
return 0
}
# ignore things that begin with "http"
if {[string match "http*" $text]} {
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - starts with http* $nick!$uhost ($acct) ++'d '$item' in $chan"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - starts with http* $nick!$uhost ($acct) --'d '$item' in $chan"
}
return 0
}
# ignore things that contain a "://"
if {[string match "*://*" $text]} {
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - seems like url *://* $nick!$uhost ($acct) ++'d '$item' in $chan"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - seems like url *://* $nick!$uhost ($acct) --'d '$item' in $chan"
}
return 0
}
# ignore karma requests from bots
set accthand [finduser -account [getaccount $nick]]
if {[string match $accthand "*"]} {
# not needed once eggdrop adds support for nickserv account to nick2hand
set accthand [nick2hand $nick]
}
if {![string match $accthand "*"]} {
if {[matchattr $accthand +B]} {
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - is a known bot* $nick!$uhost ($acct) ++'d '$item' in $chan"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] *ignored - is a known bot* $nick!$uhost ($acct) --'d '$item' in $chan"
}
return 0
}
}
incr kfcount($uhost)
set ktime [clock seconds]
if {[llength [kdb eval {SELECT karma FROM lkarma WHERE item=$item}]] == 0} {
kdb eval {INSERT INTO lkarma (item,karma,modtime) VALUES ($item,0,$ktime)}
}
if {[kdb eval {SELECT karma FROM lkarma WHERE item=$item}] < 900} {
kdb eval {UPDATE lkarma SET karma=karma+$scoring, modtime=$ktime WHERE item=$item}
} {
kdb eval {UPDATE lkarma SET karma=karma+$scoring WHERE item=$item}
}
set newkarma [kdb eval {SELECT karma FROM lkarma WHERE item=$item}]
puthelp "NOTICE $chan :\[karma\] '$item' now has $newkarma karma!"
if {[string match "++" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] $nick!$uhost ($acct) ++'d '$item' in $chan - new score: $newkarma"
} elseif {[string match "--" $score]} {
puthelp "PRIVMSG $karma(logchan) :\[karma\] $nick!$uhost ($acct) --'d '$item' in $chan - new score: $newkarma"
}
kdb close
}
}
###Other Commands###
bind pub $karma(flags) !khelp karmahelp
proc karmahelp {nick uhost hand chan text} {
if {[string match "*+lkarma*" [channel info $chan]]} {
if {![string match "" $text]} {return 0}
puthelp "NOTICE $chan :\[karma\] you may \"<item>++\" and \"<item>--\" any word or phrase. \"!kbest\" and \"!kworst\" return the top (and bottom) ten. \"!karma \[item\]\" to look up individual scores. \"!kstats\" for statistics. Use \"!kfind <item>\" and \"!krfind <item>\" to search for things in the database ordered by karma in ascending or descending order (respectively), or just use \"!krand\" for ten random things."
}
}
bind pub $karma(flags) !karma checkkarma
proc checkkarma {nick uhost hand chan text} {
if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
if {[string match "*+lkarma*" [channel info $chan]]} {
global karma kdbfile
if {[string match "" $text]} {
set text $nick
}
set item [string trim $text]
sqlite3 kdb $kdbfile
set current [kdb eval {SELECT karma FROM lkarma WHERE item=$item}]
if {[llength $current] == 0} {
set current 0
}
if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] == "Y"} {
puthelp "NOTICE $chan :\[karma\] \"$item\"\ is locked at \002$current\002."
} else {
puthelp "NOTICE $chan :\[karma\] \"$item\" has $current karma"
}
if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] == "U"} {
puthelp "NOTICE $chan :\[karma\] \"$item\" has been immortalized"
}
kdb close
}
}
bind pub $karma(flags) !kstats karmastats
proc karmastats {nick uhost hand chan text} {
if {![string match "" $text]} {return 0}
global karma kdbfile
if {[string match "*+lkarma*" [channel info $chan]]} {
sqlite3 kdb $kdbfile
set lcount [kdb eval {SELECT COUNT(*) FROM lkarma WHERE locked='Y'}]
set ucount [kdb eval {SELECT COUNT(*) FROM lkarma WHERE locked='U'}]
set gcount [kdb eval {SELECT COUNT(*) FROM lkarma WHERE karma > 0 AND locked='N'}]
set bcount [kdb eval {SELECT COUNT(*) FROM lkarma WHERE karma < 0 AND locked='N'}]
set total [kdb eval {SELECT COUNT(*) FROM lkarma}]
set average [kdb eval {SELECT AVG(karma) FROM lkarma WHERE locked='N'}]
set average [expr round($average)]
puthelp "NOTICE $chan :\[karma\] stats: $total items in the database. good: $gcount, bad: $bcount, average karma: $average"
kdb close
}
}
bind pub $karma(flags) !kbest goodkarma
bind pub $karma(flags) !ktop goodkarma
proc goodkarma {nick uhost hand chan text} {
if {![string match "" $text]} {return 0}
global karma kdbfile
if {[string match "*+lkarma*" [channel info $chan]]} {
sqlite3 kdb $kdbfile
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE locked='N' ORDER BY karma DESC, item ASC LIMIT 0,10} ] {
append outvar "$item: $score "
}
puthelp "NOTICE $chan :\[karma\] $outvar"
kdb close
}
}
bind pub $karma(flags) !kworst badkarma
bind pub $karma(flags) !kbottom badkarma
proc badkarma {nick uhost hand chan text} {
if {![string match "" $text]} {return 0}
global karma kdbfile
if {[string match "*+lkarma*" [channel info $chan]]} {
sqlite3 kdb $kdbfile
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE locked='N' ORDER BY karma ASC, item ASC LIMIT 0,10}] {
append outvar "$item: $score "
}
puthelp "NOTICE $chan :\[karma\] $outvar"
kdb close
}
}
#bind pub $karma(flags) !lfind lockedkarma
#bind pub $karma(flags) !lkarma lockedkarma
#proc lockedkarma {nick uhost hand chan text} {
# if {![string match "" $text]} {return 0}
# global karma kdbfile
# if {[string match "*+lkarma*" [channel info $chan]]} {
# sqlite3 kdb $kdbfile
# set lcount [kdb eval {SELECT COUNT(*) FROM lkarma WHERE locked='Y'}]
# if {$lcount != 0} {
# foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE locked='Y' ORDER BY karma DESC} ] {
# append outvar "$item:\002$score\002 "
# }
# puthelp "NOTICE $chan :\[karma\] \002$lcount\002 locked items: $outvar"
# } {
# puthelp "NOTICE $chan :\[karma\] there are no locked items."
# }
# kdb close
# }
#}
#
#bind pub $karma(flags) !ifind immkarma
#bind pub $karma(flags) !ikarma immkarma
#proc immkarma {nick uhost hand chan text} {
# if {![string match "" $text]} {return 0}
# global karma kdbfile
# if {[string match "*+lkarma*" [channel info $chan]]} {
# sqlite3 kdb $kdbfile
# set icount [kdb eval {SELECT COUNT(*) FROM lkarma WHERE locked='U'}]
# if {$icount != 0} {
# foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE locked='U' ORDER BY karma DESC} ] {
# append outvar "$item:\002$score\002 "
# }
# puthelp "NOTICE $chan :\[karma\] \002$icount\002 immortal items: $outvar"
# } {
# puthelp "NOTICE $chan :\[karma\] there are no immortal items."
# }
# kdb close
# }
#}
bind pub $karma(flags) !krand randkarma
proc randkarma {nick uhost hand chan text} {
if {![string match "" $text]} {return 0}
global karma kdbfile
if {[string match "*+lkarma*" [channel info $chan]]} {
sqlite3 kdb $kdbfile
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE locked='N' ORDER BY RANDOM() LIMIT 10} ] {
append outvar "$item: $score "
}
puthelp "NOTICE $chan :\[karma\] $outvar"
kdb close
}
}
#bind pub $karma(flags) !instant instantkarma
#proc instantkarma {nick uhost hand chan text} {
# return 0
# if {![string match "" $text]} {return 0}
# global karma kdbfile kfcount kfflood
# if {[string match "*+lkarma*" [channel info $chan]]} {
# set uhost [string tolower $uhost]
# set chan [string tolower $chan]
# sqlite3 kdb $kdbfile
# if {![info exists kfcount($uhost:$chan)]} {
# set kfcount($uhost:$chan) 0
# }
# if {$kfcount($uhost:$chan) == [lindex $kfflood 0]} {
# puthelp "PRIVMSG $chan :Please dont flood karma, $nick, try again later."
# return 0
# }
# incr kfcount($uhost:$chan)
# lappend choices "+1" "-1"
# set scoring [lindex $choices [expr {int(rand()*[llength $choices])}]]
# putlog "$scoring instant karma randomly selected"
# sqlite3 kdb $kdbfile
# set ktime [clock seconds]
# set rando [kdb onecolumn {SELECT item FROM lkarma WHERE locked='N' ORDER BY RANDOM() LIMIT 1}]
# kdb eval {UPDATE lkarma SET karma=karma+$scoring, modtime=$ktime WHERE item=$rando}
# set newkarma [kdb eval {SELECT karma FROM lkarma WHERE item=$rando}]
# puthelp "PRIVMSG $chan :Karma for \002$rando\002 is now \002$newkarma\002."
# kdb close
# }
#}
bind pub $karma(flags) !kfind findkarma
proc findkarma {nick uhost hand chan text} {
if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
if {[string match "*+lkarma*" [channel info $chan]]} {
global karma kdbfile
if {[string match "" $text]} {
puthelp "NOTICE $chan :What should be found?"
} {
sqlite3 kdb $kdbfile
set word [string trim $text]
set spatrn "%$word%"
set scount [kdb eval {SELECT COUNT(1) FROM lkarma WHERE item LIKE $spatrn}]
if {$scount == 0 } {
puthelp "NOTICE $chan :\[karma\] '$word' not found."
} {
if {$scount < 9 } {
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE item LIKE $spatrn ORDER BY karma DESC LIMIT 0,9}] {
append sreturn "$item: '$score' "
}
puthelp "NOTICE $chan :\[karma\] $scount matches for '$word': $sreturn"
} {
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE item LIKE $spatrn ORDER BY karma DESC LIMIT 0,10}] {
append spos "$item: $score "
}
puthelp "NOTICE $chan :\[karma\] $scount matches for '$word'. top 10 matches: $spos"
}
}
kdb close
}
}
}
bind pub $karma(flags) !krfind rfindkarma
proc rfindkarma {nick uhost hand chan text} {
if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
if {[string match "*+lkarma*" [channel info $chan]]} {
global karma kdbfile
if {[string match "" $text]} {
puthelp "NOTICE $chan :\[karma\] what should be found?"
} {
sqlite3 kdb $kdbfile
set word [string trim $text]
set spatrn "%$word%"
set scount [kdb eval {SELECT COUNT(1) FROM lkarma WHERE item LIKE $spatrn}]
if {$scount == 0 } {
puthelp "NOTICE $chan :\[karma\] '$word' not found"
} {
if {$scount < 9 } {
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE item LIKE $spatrn ORDER BY karma ASC LIMIT 0,9}] {
append sreturn "$item: $score "
}
puthelp "NOTICE $chan :\[karma\] $scount matches for '$word': $sreturn"
} {
foreach {item score} [kdb eval {SELECT item,karma FROM lkarma WHERE item LIKE $spatrn ORDER BY karma ASC LIMIT 0,10}] {
append sneg "$item: $score "
}
puthelp "NOTICE $chan :\[karma\] $scount matches for '$word'. bottom 10 matches: $sneg"
}
}
kdb close
}
}
}
#bind pub $karma(lockflags) !lock lockkarma
#proc lockkarma {nick uhost hand chan text} {
# if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
# global karma kdbfile
# if {[string match "*+lkarma*" [channel info $chan]]} {
# set item [string trim $text]
# if {$item == ""} {
# puthelp "NOTICE $chan :\[karma\] what should be locked?"
# return
# }
# sqlite3 kdb $kdbfile
# if {[llength [kdb eval {SELECT locked FROM lkarma WHERE item=$item}]] == 0} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is not in the database."
# } {
# if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] != "N"} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is already locked."
# } {
# kdb eval {UPDATE lkarma SET locked='Y' WHERE item=$item}
# puthelp "NOTICE $chan :\[karma\] \002$item\002 locked."
# }
# }
# kdb close
# }
#}
#
#bind pub $karma(lockflags) !unlock unlockkarma
#proc unlockkarma {nick uhost hand chan text} {
# if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
# global karma kdbfile
# if {[string match "*+lkarma*" [channel info $chan]]} {
# set item [string trim $text]
# if {$item == ""} {
# puthelp "NOTICE $chan :\[karma\] what should be unlocked?"
# return
# }
# sqlite3 kdb $kdbfile
# if {[llength [kdb eval {SELECT locked FROM lkarma WHERE item=$item}]] == 0} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is not in the database."
# } {
# if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] != "Y"} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is not locked."
# } {
# kdb eval {UPDATE lkarma SET locked='N' WHERE item=$item}
# puthelp "NOTICE $chan :\[karma\] \002$item\002 unlocked."
# }
# }
# kdb close
# }
#}
#
#bind pub $karma(lockflags) !immortalize immortkarma
#proc immortkarma {nick uhost hand chan text} {
# if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
# global karma kdbfile
# if {[string match "*+lkarma*" [channel info $chan]]} {
# set item [string trim $text]
# if {$item == ""} {
# puthelp "NOTICE $chan :\[karma\] what should be immortalized?"
# return
# }
# sqlite3 kdb $kdbfile
# if {[llength [kdb eval {SELECT locked FROM lkarma WHERE item=$item}]] == 0} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is not in the database."
# } {
# if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] == "U"} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is already immortalized."
# } {
# kdb eval {UPDATE lkarma SET locked='U' WHERE item=$item}
# puthelp "NOTICE $chan :\[karma\] \002$item\002 immortalized!"
# }
# }
# kdb close
# }
#}
#
#bind pub $karma(deleteflags) !delete deletekarma
#proc deletekarma {nick uhost hand chan text} {
# if {[regexp -nocase {(.*)(\+\+|\-\-)$} $text]} {return 0}
# global karma kdbfile
# if {[string match "*+lkarma*" [channel info $chan]]} {
# set item [string trim $text]
# if {$item == ""} {
# puthelp "NOTICE $chan :\[karma\] what should be deleted?"
# return
# }
# sqlite3 kdb $kdbfile
# if {[llength [kdb eval {SELECT item FROM lkarma WHERE item=$item}]] == 0} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 is not in the database."
# } {
# if {[kdb eval {SELECT locked FROM lkarma WHERE item=$item}] != "N"} {
# puthelp "NOTICE $chan :\[karma\] \002$item\002 can't be deleted."
# } {
# kdb eval {DELETE FROM lkarma WHERE item=$item}
# puthelp "NOTICE $chan :\[karma\] \002$item\002 deleted."
# }
# }
# kdb close
# }
#}
####TIMER CODE###
# removed call to this everything above for now, i don't like the karma fuzzing... the 'delete stuff at 0 karma for X days' could be interesting, though.
# was just going to wholesale remove that until I saw that lol
proc karmaupdate {} {
return 0
# global kdbfile
# sqlite3 kdb $kdbfile
# set kutime [clock seconds]
## plus/minus 1 to 5 days to kutime at random here? or in each loop?
#
# set xtime [expr $kutime - (90 * 86400)]
# kdb eval {DELETE FROM lkarma WHERE modtime < $xtime AND karma between -1 and 1 and locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $xtime AND karma between 2 and 22 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $xtime AND karma between -22 and -2 AND locked='N'}
#
# set ytime [expr $kutime - (30 * 86400)]
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $ytime AND karma between 23 and 54 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $ytime AND karma between -54 and -23 AND locked='N'}
#
# set yytime [expr $kutime - (7 * 86400)]
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $yytime AND karma between 55 and 80 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $yytime AND karma between -80 and -55 AND locked='N'}
#
# set yyytime [expr $kutime - (2 * 86400)]
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $yyytime AND karma between 81 and 120 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $yyytime AND karma between -120 and -81 AND locked='N'}
#
# set ztime [expr $kutime - 86400]
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $ztime AND karma between 121 and 540 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $ztime AND karma between -540 and -121 AND locked='N'}
#
# set zztime [expr $kutime - (86400 / 3)]
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $zztime AND karma between 541 and 959 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $zztime AND karma between -959 and -541 AND locked='N'}
#
# set zzztime [expr $kutime - (86400 / 5)]
# kdb eval {UPDATE lkarma SET karma=karma-1, modtime=$kutime WHERE modtime < $zzztime AND karma > 960 AND locked='N'}
# kdb eval {UPDATE lkarma SET karma=karma+1, modtime=$kutime WHERE modtime < $zzztime AND karma < -960 AND locked='N'}
#
# kdb close
}
proc kfreset {} {
global kfcount kfflood
if {[info exists kfcount]} {
unset kfcount
}
utimer [lindex $kfflood 1] kfreset
}
if {![string match *kfreset* [utimers]]} {
global kfflood
utimer [lindex $kfflood 1] kfreset
}
set kfflood [split $kfflood :]
putlog "LilyKarma $karma(version) loaded."