# 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 "!++" and "!--" 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 " for score. "!stats" for total items and average karma (unlocked items). # "!find " and "!rfind " to search for things in the database. # "!instant" changes a random thing -/+1 , "!random" returns some items. # Privileged users can "!lock ", "!unlock ", and "!delete " # They can also "!immortalize " 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 \"++\" and \"--\" 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 \" and \"!krfind \" 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."