This is the new home of the egghelp.org community forum.
All data has been migrated (including user logins/passwords) to a new phpBB version.


For more information, see this announcement post. Click the X in the top right-corner of this box to dismiss this message.

Keyword script version 1.4.0.0

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
Post Reply
]
]x[
Voice
Posts: 16
Joined: Mon Jan 09, 2006 7:23 pm

Keyword script version 1.4.0.0

Post by ]x[ »

Hi there folks.

I was hoping that someone could help me out with a strange issue. I've been trying to use this script which i have been using for ages but somehow the output doesn't come out anymore.

The thing is I can add commands to the keyword.db but then you can call the command out, or even remove it anymore after you added it.


/msg #channel B0tt0r add -hubba Johnny Bravo for the win
[11:09] -B0tt0r - (keyword) {-hubba} was successfully added to the database.

/msg #channel B0tt0r remove -hubba Johnny Bravo for the win!
[11:22] -B0tt0r - (keyword) your keyword {-hubba} doesn't appear in the database.

Is there anyone that know where to look or can point me in the right direction on how to fix this script. Its probably some error relevant to upgrading to newer eggdrops because the original script is from 2006.

Thanks in advance,
code below :

Code: Select all


    #                       
    #       +------------------------------------------------------+
    #       | © Christian 'chris' Hopf <mail@dev.christianhopf.de> |
    #       +------------------------------------------------------+
    #                                                                     
    #          
    #           developer:  Christian 'chris' Hopf
    #           system:     eggdrop v1.6.18 - tcl/tk v.8.5a2
    #           product:    user defined triggers
    #           version:    1.4
    #                         
    #           contact:    mail@dev.christianhopf.de
    #           irc:        #chris at QuakeNet
    #           web:        www.christianhopf.de
    #


    # user defined triggers v1.4
    # copyright (c) 2006 Christian 'chris' Hopf

    # This program is free software; you can redistribute it and/or modify
    # it under the terms of the GNU General Public License as published by
    # the Free Software Foundation; either version 2 of the License, or
    # (at your option) any later version.

    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.

    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
    #
    #
    # changelog
    #
    #   18.12.2005 - v1.0 - release
    #   19.12.2005 - v1.1/v1.2 - fix:
    #                 - Bug by using existing proc names as keyword
    #                       
    #               add:
    #                 - clear function added
    #                 - flood timer for each trigger activated to stop spamming
    #   02.01.2006 - v1.3 - fix:
    #                 - unmatched open quote in list
    #   11.04.2006 - v1.4 - fix:
    #                 - fixed bug with teh "0"
    #                 
    #                add:
    #                 - added new triggers like NULL (only command needed, no trigger)
    #
    # short readme
    #   after setting up your eggdrop, you can get a list of all commands with 
    #   <botnick> help 
    #   or
    #   !help (only if u havn't change anything)
    #
    #   short help:
    #       you can add a keywords trigger with the command "add".
    #       if you want to use a newline, use \n in the message you added.
    #       e.g. /msg <channel> <botnick> add TEST TextOnLine1\nTextOnLine2 etc ...    
    
    # --- namespace ::keyword
    namespace eval ::keyword {
           
  
      # --- namespace variable   
      namespace eval variable {
        
        # string variable trigger
        variable trigger "!"
        
        # string variable keyword [ only need for /msg <botnick> ]
        variable keyword "trigger"        
                
        # string variable flag
        variable flag "n|n"
        
        # string variable database
        variable database ".keyword.db"       
        
        # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
        # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
        # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
        # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}} 
        
        # string variable author
        variable author "2006 Christian 'chris' Hopf \002(\002#chris - www.christianhopf.de\002)\002"
        
        # string variable version
        variable version "v1.4"
      
      }      
    
      if {![file exists $::keyword::variable::database]} {
        if { [catch { set database [open $::keyword::variable::database "w"] } error] } {
          die "can't create file <:( \[$::keyword::variable::database\]"
        }
        
        puts -nonewline $database ""
        close $database
      }
      
      # binds
      bind PUBM -|- {*} ::keyword::pubm
      bind MSGM -|- {*} ::keyword::msgm
      
      # - void proc pubm {bind PUBM}
      proc pubm { nickname hostname handle channel arguments } {
          ::keyword::irc::parse $nickname $hostname $handle $arguments $channel "pubm"
      }
      
      # - void proc msgm {bind MSGM}
      proc msgm { nickname hostname handle arguments } {
          ::keyword::irc::parse $nickname $hostname $handle $arguments [lindex [split $arguments] 2] "msgm"
      }      
      
      
      # namespace eval irc
      namespace eval irc {
        # - void proc parse
        proc parse { nickname hostname handle arguments channel mode} {
            global botnick lastcommand channelcommand lastnickname lasthandle lastchannel lasttrigger lastucommand
            
            if { [::keyword::utilities::exists [encrypt split $channel] [lindex [split $arguments] 0] "-global"] } {
              set message [join [::keyword::utilities::get:command [lindex [split $arguments] 0]]]
     
              if {[info exists ::keyword(last,used,$channel,[lindex [split $arguments] 0])] && [expr [unixtime] - $::keyword(last,used,$channel,[lindex [split $arguments] 0])] < 30} { 
                return
              }
                
              set ::keyword(last,used,$channel,[lindex [split $arguments] 0]) [unixtime]
                  
              foreach output [split $message "\n"] {
                putquick "PRIVMSG $channel :$output"
              }
              
              if { [info proc ::keyword::irc::commands:[string tolower [lindex [split $arguments] 1]]] == "" && [info proc ::keyword::irc::commands:[string tolower [lindex [split $arguments] 0]]] == "" } {
                return
              }
            }
            
            set utrigger [getuser $handle XTRA keyword-trigger]
            set temp $channel
            set save $arguments;
    
            if { $mode == "pubm" } {
              if {[llength $utrigger] < 1} {
                set utrigger [join [string trim $::keyword::variable::trigger]]
              }
    
              if { [string equal -nocase $botnick [lindex [split $arguments] 0]]} {
                set command [string tolower [lindex [split $arguments] 1]]
                set arguments [join [lrange [split $arguments] 2 end]]
                set trigger "$botnick $command"
  
              } elseif { $utrigger == "NULL" }  {
                set command [string tolower [lindex [split $arguments] 0]]
                set arguments [join [lrange [split $arguments] 1 end]]
                
                set trigger "$command"
              
              } elseif { [string equal -nocase [string index [lindex [split $arguments] 0] 0] $utrigger] } {
                set command [string range [string tolower [lindex [split $arguments] 0]] 1 end]
                set arguments [join [lrange [split $arguments] 1 end]]
  
                set trigger "${utrigger}$command"
              } else {
                return
              }
              
              if {[string index [lindex [split $arguments] 0] 0] == "#" && [validchan [lindex [split $arguments] 0]]} {
                set channel [lindex [split $arguments] 0]
                set arguments [join [lrange [split $arguments] 1 end]]
              }
            
            } elseif { $mode == "msgm" } {
              if { [string equal -nocase [lindex [split $arguments] 0] ${::keyword::variable::keyword}] } {
                set command [lindex [split $arguments] 1]
                set channel [lindex [split $arguments] 2]              
                set arguments [join [lrange [split $arguments] 3 end]]
                set trigger "$::keyword::variable::keyword $command"          
              } else {
                return
              }
              
            } else {
              return
            }
            
            if { [string index [lindex [split $arguments] 0] 0] == "#" || [string equal -nocase [lindex [split $arguments] 0] "-global"] } {
              set channel [lindex [split $arguments] 0]
              set arguments [join [lrange [split $arguments] 1 end]]
            }
            
            if { ![matchattr $handle $::keyword::variable::flag $temp] } {
              return
            } elseif {![info exists trigger] || [llength $trigger] < 1} {
              return
            } elseif {(![info exists command] || [llength $command] < 1)} {
              return
            } elseif { [info proc ::keyword::irc::command:$command] == ""  } {
              return
            } elseif { (![regexp -- {^#(.+)$} $channel] || ![validchan $channel]) && ![string equal -nocase $channel "-global"] } {
              putquick "PRIVMSG $nickname :\002(\002keyword\002)\002 you forgot the channel parameter"
              
              return
            }
            
            set channelcommand "$temp"
            set lastcommand  "$trigger"
            set lastucommand "$command"
            set lastnickname "$nickname"
            set lasthandle "$handle"
            set lastchannel "$channel"
            set lasttrigger [join [lrange $trigger 0 end-1]]
            
            ::keyword::irc::command:$command $nickname $hostname $handle $channel $arguments
        }
        
        # - void proc add
        proc command:add { nickname hostname handle channel arguments } {
          global lastcommand
          
          set trigger [::keyword::utilities::trigger $handle]; set keyword [lindex [split $arguments] 0]; set message [join [lrange $arguments 1 end]]
          if { $keyword == "" || $message == "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#channel?\037 <keyword> <message>"; return;}

          if {[info proc ::keyword::irc::commands:$keyword] != "" || [info proc ::keyword::irc::commands:[string range [join $keyword] 1 end]] != "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 sorry but you cant use that keyword, please choose an another one"; return; }
          if {[::keyword::utilities::exists [encrypt split $channel] [join $keyword] "-global"]} {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 your keyword {$keyword} does already appear in the database."
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 to overwrite use\002:\002 ${trigger}overwrite \037?#channel?\037|\037?-global?\037 <keyword> <message>"
          } elseif {[::keyword::utilities::add [encrypt split $channel] [encrypt split [join $keyword]] [encrypt split $message]]} {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 {[join $keyword]} was successfully added to the database."           
          } else {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while adding channel message to the database."
          }    
        }
        
        # - void proc remove
        proc command:remove { nickname hostname handle channel arguments } {
          global lastcommand
          set trigger [::keyword::utilities::trigger $handle]; set keyword [lindex [split $arguments] 0];
          if { $keyword == "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#channel?\037 <keyword>"; return; }
                       
          if {![::keyword::utilities::exists [encrypt split $channel] [join $keyword]]} {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 your keyword {[join $keyword]} doesn't appear in the database."
          } elseif {[::keyword::utilities::remove [encrypt split $channel] [join $keyword]]} {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 {[join $keyword]} successfully removed from the database."             
          } else {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while removing channel message from the database."
          }    
        }
        
        # - void proc clear
        proc command:clear { nickname hostname handle channel arguments } {        
          global lastcommand

          if { $arguments == "*" } { ::keyword::utilities::clear; putquick "NOTICE $nickname :\002(\002keyword\002)\002 database was successfully cleared."
          } elseif {[::keyword::utilities::clear [encrypt split $channel]]} { putquick "NOTICE $nickname :\002(\002keyword\002)\002 {$channel} was successfully cleared." 
          } else { putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while removing channel from the database."; }
        }
        
        # - void proc overwrite
        proc command:overwrite { command nickname hostname handle channel arguments } {
          global lastcommand

          set trigger [::keyword::utilities::trigger $handle]; set keyword [lindex [split $arguments] 0]; set message [join [lrange $arguments 1 end]]
          if { $keyword == "" || $message == "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#channel?\037|\037?-global?\037 <keyword> <message>"; return;}

          if {[info proc ::keyword::irc::commands:$keyword] != ""} { putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 sorry but you cant use that keyword, please choose an another one"; return; }
          if {![::keyword::utilities::exists [encrypt split $channel] [join $keyword] "-global"]} {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 your keyword {$keyword} doesn't appear in the database."
          } elseif {[::keyword::utilities::rewrite [encrypt split $channel] [join $keyword] [encrypt split $message]]} {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 $keyword was successfully re-added to the database."           
          } else {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while adding channel message to the database."
          }           
        }
            
        
        # - void procs help|showcommands {required string command} {required string nickname} {required string hostname} {required string handle} {required string channel} {required string arguments}    
        proc commands:help { nickname hostname handle channel arguments } { ::keyword::irc::commands:userhelp $command $nickname $hostname $handle $channel $arguments; }
        proc commands:showcommands { nickname hostname handle channel arguments } { ::keyword::irc::commands:userhelp $command $nickname $hostname $handle $channel $arguments; }
        
        
        # - void proc userhelp
        proc command:userhelp { nickname hostname handle channel arguments } {            
          if { ![matchattr $handle $::keyword::variable::flag $channel] } { return; }
          set trigger [::keyword::utilities::trigger $handle]
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 \037$command overview\002\037:\002"               
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}add \037?channel?\037 \037-global\037 <keyword> <message>"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}remove \037?channel?\037 \037-global\037 <#id/keyword>"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}overwrite \037?channel?\037 \037-global\037 <keyword> <message>"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}list \037?channel?\037|\037-global\037"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}clear \037?channel?\037|\037-global\037|\037*\037"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}trigger \037?#id?\037 \002(\002personal trigger, not global trigger\002)\002"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}version"           
        }
        
        # - void proc trigger
        proc command:trigger { nickname hostname handle channel arguments } { 
            global botnick botname lastcommand
            set trigger [::keyword::utilities::trigger $handle]
  
            array set triggers {
              "1" {$} "2" {!} "3" {?} "4" {.} "5" {-}
              "6" {²} "7" {%} "8" {&} "9" {*} "10" {:}
              "11" {§} "12" {°} "13" {^} "14" {NULL}
            }
                 
            if { [llength $arguments] < 1 } {
              putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#id?\037" 
              putquick "NOTICE $nickname :\002(\002keyword\002)\002 curren\037t\037\002:\002 $trigger"
              set list ""
              set id   0
              
              while {$id < 10} {
                incr id 1
                lappend list "#$id ($triggers($id))"
              }
              
              putquick "NOTICE $nickname :\002(\002keyword\002)\002 available triggers are:"
              putquick "NOTICE $nickname :[join $list ", "]"
              
              return
            }               
            
          if { [string range $arguments 1 2] < 15 && [string range $arguments 1 2] > 0 } {
            setuser $handle XTRA keyword-trigger $triggers([string range $arguments 1 2])
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 your personal trigger is now: [getuser $handle XTRA keyword-trigger]"
          } else {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?\002#\002id?\037"
          }
        }              
        
        # - void proc list
        proc command:list { nickname hostname handle channel arguments } {
          set list ""
          set count [llength [::keyword::utilities::create:list $channel]]
          
          if { $count == "1" } {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 $count message is added on my database\002:\002"
          } else {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 $count messages are added on my database\002:\002"
          }
          set data ""
          
          foreach messages [::keyword::utilities::create:list $channel] {                
            if { [llength $data] == 5 } {
              putquick "NOTICE $nickname :\002(\002keyword\002)\002 [join $data ", "]"
              set data ""
            }
            lappend data $messages
          }
          
          if { [llength $data] > 1 } {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 [join $data ", "]"
          } elseif { [llength $data] == 1 } {
            putquick "NOTICE $nickname :\002(\002keyword\002)\002 [join $data]"
          }
        }          
        
        # - void proc version
        proc command:version { nickname hostname handle channel arguments } {            
          if {[info exists ::keyword(protection_v,$channel)] && [expr [unixtime] - $::keyword(protection_v,$channel)] < 30} { return;}
          putquick "PRIVMSG $channel :\001ACTION is running the keyword script $::keyword::variable::version \002(\002c\002)\002 $::keyword::variable::author\001"
          set ::keyword(protection_v,$channel) [unixtime]        
        }
        
      }            
      
      # namespace eval utilities
      namespace eval utilities {
        
        # - void proc exists {required string channel} {required string keyword}
        proc exists { channel keyword {global "8427zthgf7tzht"} } {
          if { $keyword == "" || ![info exists keyword] || [string match *\"* $keyword] } { return 0; }
          if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
          set number 1
          while {![eof $database]} {
            if {[set line [gets $database]] != ""} {
              if { [lindex [split $line] 0] != $channel && [lindex [split $line] 0] != [encrypt split "$global"]  } { continue; }
              if {![isnumber [string range [join $keyword] 1 end]]} {
                if {([lindex [split $line] 0] == "$channel" || [lindex [split $line] 0] == [encrypt split "$global"]) && [lindex [split $line] 1] == "[encrypt split $keyword]"} {
                  close $database
                  return 1
                }
              } else {
                if {[lindex [split $line] 0] == "$channel" && $number == [string range [join $keyword] 1 end]} {
                  close $database
                  return 1
                }
              }
            }
            incr number
          }          
          close $database
          return 0
        }          
        
        # - void proc add {required string channel} {required string keyword} {required string message}
        proc add { channel keyword message } {
          if {[catch { set database [open $::keyword::variable::database "a"] } error]} { return 0; }
          puts $database "$channel $keyword $message"
          close $database
          return 1
        }          
        
        # - void proc remove {required string channel} {required string keyword}
        proc remove { channel keyword } {
          if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
          set refill ""
          set number 1
          while {![eof $database]} {
            if {[set line [gets $database]] != ""} {
              if {[lindex [split $line] 0] == "$channel"} {
                if {[lindex [split $line] 1] == "[encrypt split $keyword]"} { incr number; continue; }
                if {[isnumber [string range [join $keyword] 1 end]] && $number == [string range [join $keyword] 1 end]} { incr number; continue; }       
                incr number;
              }
              lappend refill $line
            }
          }
          close $database
          set database [open $::keyword::variable::database "w"]
          foreach data_refill $refill {
            puts $database $data_refill
          }
          close $database
          return 1
        }       
        
        # - void proc clear {optional string channel}
        proc clear { {channel ""} } {
          if { $channel == "*" || $channel == "" } {
            if {[file exists $::keyword::variable::database]} { file delete $::keyword::variable::database } 
            set database [open $::keyword::variable::database "w"]
            puts -nonewline $database ""
            close $database
            return; 
          }
          
          if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
          set refill ""
          set number 1
          while {![eof $database]} {
            if {[set line [gets $database]] != ""} {
              if {[lindex [split $line] 0] == "$channel"} { continue; }
              lappend refill $line
            }
          }
          close $database
          set database [open $::keyword::variable::database "w"]
          foreach data_refill $refill {
            puts $database $data_refill
          }
          close $database
          return 1
        }         
        
        # - void proc rewrite {required string channel} {required string keyword} {required string message}
        proc rewrite { channel keyword message } {
          if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
          set refill ""
          set number 1
          while {![eof $database]} {
            if {[set line [gets $database]] != ""} {
              if {[lindex [split $line] 0] == "$channel"} {
                if {[lindex [split $line] 1] == "[encrypt split $keyword]"} { continue; }
              }
              lappend refill $line
            }
          }
          close $database
          set database [open $::keyword::variable::database "w"]
          foreach data_refill $refill {
            puts $database $data_refill
          }
          puts $database "$channel [encrypt split $keyword] $message"
          close $database
          return 1
        }          
        
        # - void proc create:list {required string channel}
        proc create:list { channel } {
          set data ""
          set database [open $::keyword::variable::database "r"]
          while {![eof $database]} {
            if {[set line [gets $database]] != ""} {
              if { [lindex [split $line] 0] == "[encrypt split $channel]" } {
                lappend data "[decrypt split [lindex [split $line] 1]]"
              }
            }
          }
          close $database
          return $data
        }
        
        # - void proc get:command {required string command}
        proc get:command { command } {
          set data ""
          set database [open $::keyword::variable::database "r"]
          while {![eof $database]} {
            if {[set line [gets $database]] != ""} {
              if { [lindex [split $line] 1] == "[encrypt split $command]" } {
                close $database; return [decrypt split [lindex [split $line] 2]];
              }
            }
          }
          close $database
        }          
               
        # - void proc trigger {required string handle}
        proc trigger { handle } {
          set utrigger [getuser $handle XTRA keyword-trigger]
          if {[llength $utrigger] < 1 || ![validuser $handle]} {
            set utrigger [join [string trim $::keyword::variable::trigger]]
          }            
          return $utrigger        
        }
                   
      }  
      
      # log
      putlog "user defined keywords version <${::keyword::variable::version}> (c) $::keyword::variable::author successfully loaded"                   
      
    }
M
MMX
Voice
Posts: 4
Joined: Sun Mar 20, 2022 5:42 pm

Maybe...

Post by MMX »

This script uses [encrypt] and [decrypt] eggdrop tcl functions, which use some hashing algorithm depending on which encryption module is loaded on your eggdrop. The script will not work on newer versions of eggdrop, because the encryption module has changed and the hashes produced by [encrypt] are different every time.

So if you want to run this script on an up-to-date eggdrop, at the very least you will have to recode every IF logic where [encrypt] and [decrypt] are involved. Also do not pass [encrypt]-ed arguments to the procs.

EDIT (08.06.2023):
Fixed, bumped version to 1.4.1, tested on Eggdrop 1.9.5, TCL 8.6.12, pbkdf2 encryption module.
Changelog included in description.
NOTE: not tested on older eggdrop versions for backward compatibility.

Code: Select all

#       +------------------------------------------------------+
#       | © Christian 'chris' Hopf <mail@dev.christianhopf.de> |
#       +------------------------------------------------------+
#                                                                     
#         
#           developer:  Christian 'chris' Hopf
#           system:     eggdrop v1.6.18 - tcl/tk v.8.5a2
#           product:    user defined triggers
#           version:    1.4.1
#                         
#           contact:    mail@dev.christianhopf.de
#           irc:        #chris at QuakeNet
#           web:        www.christianhopf.de
#
#           update:     MMX 2023
#


# user defined triggers v1.4.1
# copyright (c) 2006 Christian 'chris' Hopf

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
#
# changelog
#
#   18.12.2005 - v1.0 - release
#   19.12.2005 - v1.1/v1.2 - fix:
#                 - Bug by using existing proc names as keyword
#                       
#               add:
#                 - clear function added
#                 - flood timer for each trigger activated to stop spamming
#   02.01.2006 - v1.3 - fix:
#                 - unmatched open quote in list
#   11.04.2006 - v1.4 - fix:
#                 - fixed bug with teh "0"
#                 
#                add:
#                 - added new triggers like NULL (only command needed, no trigger)
#   08.06.2023 - v1.4.1 - fix by MMX:
#                 - adjusted encrypt/decrypt logic to work on Eggdrop v1.9+
#                   (tested on Eggdrop 1.9.5, TCL 8.6.12, pbkdf2 encryption module)
#                 - fixed bug in "overwrite" proc - removed unnecessary argument
#                 - fixed bug in help/userhelp/showcommands - fixed proc names and arguments
#                 - relocated keywords.db file from eggdrop root to /scripts/
#                 - changed database creation error to log the message instead of killing the bot
#
# short readme
#   after setting up your eggdrop, you can get a list of all commands with
#   <botnick> help
#   or
#   !help (only if u havn't change anything)
#
#   short help:
#       you can add a keywords trigger with the command "add".
#       if you want to use a newline, use \n in the message you added.
#       e.g. /msg <channel> <botnick> add TEST TextOnLine1\nTextOnLine2 etc ...   

# --- namespace ::keyword
namespace eval ::keyword {
           
  # --- namespace variable   
  namespace eval variable {
   
    # string variable trigger
    variable trigger "!"
   
    # string variable keyword [ only need for /msg <botnick> ]
    variable keyword "trigger"       
           
    # string variable flag
    variable flag "n|n"
   
    # string variable database
    variable database "scripts/keywords.db"       
   
    # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
    # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
    # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
    # {{{ NOW don't change anything, if you aren't 100% sure what you are doing }}}
   
    # string variable author
    # MMX 2023 - adjusted to work with Eggdrop 1.9+
    variable author "2006 Christian 'chris' Hopf \002(\002#chris - www.christianhopf.de\002)\002"
   
    # string variable version
    # MMX 2023 - bumped version to 1.4.1
    variable version "v1.4.1 MMX fixed"
 
  }     

  if {![file exists $::keyword::variable::database]} {
    if { [catch { set database [open $::keyword::variable::database "w"] } error] } {
      putlog "KEYWORDS.tcl: can't create file <:( \[$::keyword::variable::database\]"
    }
   
    puts -nonewline $database ""
    close $database
  }
 
  # binds
  bind PUBM -|- {*} ::keyword::pubm
  bind MSGM -|- {*} ::keyword::msgm
 
  # - void proc pubm {bind PUBM}
  proc pubm { nickname hostname handle channel arguments } {
      ::keyword::irc::parse $nickname $hostname $handle $arguments $channel "pubm"
  }
 
  # - void proc msgm {bind MSGM}
  proc msgm { nickname hostname handle arguments } {
      ::keyword::irc::parse $nickname $hostname $handle $arguments [lindex [split $arguments] 2] "msgm"
  }     
 
 
  # namespace eval irc
  namespace eval irc {
    # - void proc parse
    proc parse { nickname hostname handle arguments channel mode} {
        global botnick lastcommand channelcommand lastnickname lasthandle lastchannel lasttrigger lastucommand
       
        if {[::keyword::utilities::exists $channel [lindex [split $arguments] 0] "-global"] } {
          set message [join [::keyword::utilities::get:command [lindex [split $arguments] 0]]]
 
          if {[info exists ::keyword(last,used,$channel,[lindex [split $arguments] 0])] && [expr [unixtime] - $::keyword(last,used,$channel,[lindex [split $arguments] 0])] < 30} {
            return
          }
           
          set ::keyword(last,used,$channel,[lindex [split $arguments] 0]) [unixtime]
             
          foreach output [split $message "\n"] {
            putquick "PRIVMSG $channel :$output"
          }
         
          if { [info proc ::keyword::irc::commands:[string tolower [lindex [split $arguments] 1]]] == "" && [info proc ::keyword::irc::commands:[string tolower [lindex [split $arguments] 0]]] == "" } {
            return
          }
        }
       
        set utrigger [getuser $handle XTRA keyword-trigger]
        set temp $channel
        set save $arguments;

        if { $mode == "pubm" } {
          if {[llength $utrigger] < 1} {
            set utrigger [join [string trim $::keyword::variable::trigger]]
          }

          if { [string equal -nocase $botnick [lindex [split $arguments] 0]]} {
            set command [string tolower [lindex [split $arguments] 1]]
            set arguments [join [lrange [split $arguments] 2 end]]
            set trigger "$botnick $command"

          } elseif { $utrigger == "NULL" }  {
            set command [string tolower [lindex [split $arguments] 0]]
            set arguments [join [lrange [split $arguments] 1 end]]
           
            set trigger "$command"
         
          } elseif { [string equal -nocase [string index [lindex [split $arguments] 0] 0] $utrigger] } {
            set command [string range [string tolower [lindex [split $arguments] 0]] 1 end]
            set arguments [join [lrange [split $arguments] 1 end]]

            set trigger "${utrigger}$command"
          } else {
            return
          }
         
          if {[string index [lindex [split $arguments] 0] 0] == "#" && [validchan [lindex [split $arguments] 0]]} {
            set channel [lindex [split $arguments] 0]
            set arguments [join [lrange [split $arguments] 1 end]]
          }
       
        } elseif { $mode == "msgm" } {
          if { [string equal -nocase [lindex [split $arguments] 0] ${::keyword::variable::keyword}] } {
            set command [lindex [split $arguments] 1]
            set channel [lindex [split $arguments] 2]             
            set arguments [join [lrange [split $arguments] 3 end]]
            set trigger "$::keyword::variable::keyword $command"         
          } else {
            return
          }
         
        } else {
          return
        }
       
        if { [string index [lindex [split $arguments] 0] 0] == "#" || [string equal -nocase [lindex [split $arguments] 0] "-global"] } {
          set channel [lindex [split $arguments] 0]
          set arguments [join [lrange [split $arguments] 1 end]]
        }
       
        if { ![matchattr $handle $::keyword::variable::flag $temp] } {
          return
        } elseif {![info exists trigger] || [llength $trigger] < 1} {
          return
        } elseif {(![info exists command] || [llength $command] < 1)} {
          return
        } elseif { [info proc ::keyword::irc::command:$command] == ""  } {
          return
        } elseif { (![regexp -- {^#(.+)$} $channel] || ![validchan $channel]) && ![string equal -nocase $channel "-global"] } {
          putquick "PRIVMSG $nickname :\002(\002keyword\002)\002 you forgot the channel parameter"
         
          return
        }
       
        set channelcommand "$temp"
        set lastcommand  "$trigger"
        set lastucommand "$command"
        set lastnickname "$nickname"
        set lasthandle "$handle"
        set lastchannel "$channel"
        set lasttrigger [join [lrange $trigger 0 end-1]]
       
        ::keyword::irc::command:$command $nickname $hostname $handle $channel $arguments
    }
   
    # - void proc add
    proc command:add { nickname hostname handle channel arguments } {
      global lastcommand
     
      set trigger [::keyword::utilities::trigger $handle]; set keyword [lindex [split $arguments] 0]; set message [join [lrange $arguments 1 end]]
      if { $keyword == "" || $message == "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#channel?\037 <keyword> <message>"; return;}

      if {[info proc ::keyword::irc::commands:$keyword] != "" || [info proc ::keyword::irc::commands:[string range [join $keyword] 1 end]] != "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 sorry but you cant use that keyword, please choose an another one"; return; }
      if {[::keyword::utilities::exists $channel [join $keyword] "-global"]} {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 your keyword {$keyword} does already appear in the database."
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 to overwrite use\002:\002 ${trigger}overwrite \037?#channel?\037|\037?-global?\037 <keyword> <message>"
      } elseif {[::keyword::utilities::add $channel $keyword $message]} {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 {[join $keyword]} was successfully added to the database."           
      } else {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while adding channel message to the database."
      }   
    }
   
    # - void proc remove
    proc command:remove { nickname hostname handle channel arguments } {
      global lastcommand
      set trigger [::keyword::utilities::trigger $handle]; set keyword [lindex [split $arguments] 0];
      if { $keyword == "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#channel?\037 <keyword>"; return; }
                   
      if {![::keyword::utilities::exists $channel [join $keyword]]} {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 your keyword {[join $keyword]} doesn't appear in the database."
      } elseif {[::keyword::utilities::remove $channel [join $keyword]]} {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 {[join $keyword]} successfully removed from the database."             
      } else {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while removing channel message from the database."
      }   
    }
   
    # - void proc clear
    proc command:clear { nickname hostname handle channel arguments } {       
      global lastcommand

      if { $arguments == "*" } { ::keyword::utilities::clear; putquick "NOTICE $nickname :\002(\002keyword\002)\002 database was successfully cleared."
      } elseif {[::keyword::utilities::clear $channel]} { putquick "NOTICE $nickname :\002(\002keyword\002)\002 {$channel} was successfully cleared."
      } else { putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while removing channel from the database."; }
    }
   
    # - void proc overwrite
    proc command:overwrite { nickname hostname handle channel arguments } {
      global lastcommand

      set trigger [::keyword::utilities::trigger $handle]; set keyword [lindex [split $arguments] 0]; set message [join [lrange $arguments 1 end]]
      if { $keyword == "" || $message == "" } { putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#channel?\037|\037?-global?\037 <keyword> <message>"; return;}

      if {[info proc ::keyword::irc::commands:$keyword] != ""} { putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 sorry but you cant use that keyword, please choose an another one"; return; }
      if {![::keyword::utilities::exists $channel [join $keyword] "-global"]} {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 your keyword {$keyword} doesn't appear in the database."
      } elseif {[::keyword::utilities::rewrite $channel [join $keyword] $message]} {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 $keyword was successfully re-added to the database."           
      } else {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 \0034error\003\002:\002 while adding channel message to the database."
      }           
    }
       
   
    # - void procs help|showcommands {required string command} {required string nickname} {required string hostname} {required string handle} {required string channel} {required string arguments}   
    proc command:help { nickname hostname handle channel arguments } { ::keyword::irc::command:userhelp $nickname $hostname $handle $channel $arguments; }
    proc command:showcommands { nickname hostname handle channel arguments } { ::keyword::irc::command:userhelp $nickname $hostname $handle $channel $arguments; }
   
   
    # - void proc userhelp
    proc command:userhelp { nickname hostname handle channel arguments } {           
      if { ![matchattr $handle $::keyword::variable::flag $channel] } { return; }
      set trigger [::keyword::utilities::trigger $handle]
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 \037Commands overview\002\037:\002"               
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}add \037?channel?\037 \037-global\037 <keyword> <message>"
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}remove \037?channel?\037 \037-global\037 <#id/keyword>"
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}overwrite \037?channel?\037 \037-global\037 <keyword> <message>"
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}list \037?channel?\037|\037-global\037"
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}clear \037?channel?\037|\037-global\037|\037*\037"
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}trigger \037?#id?\037 \002(\002personal trigger, not global trigger\002)\002"
      putquick "NOTICE $nickname :\002(\002keyword\002)\002 ${trigger}version"           
    }
   
    # - void proc trigger
    proc command:trigger { nickname hostname handle channel arguments } {
        global botnick botname lastcommand
        set trigger [::keyword::utilities::trigger $handle]

        array set triggers {
          "1" {$} "2" {!} "3" {?} "4" {.} "5" {-}
          "6" {²} "7" {%} "8" {&} "9" {*} "10" {:}
          "11" {§} "12" {°} "13" {^} "14" {NULL}
        }
             
        if { [llength $arguments] < 1 } {
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?#id?\037"
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 curren\037t\037\002:\002 $trigger"
          set list ""
          set id   0
         
          while {$id < 10} {
            incr id 1
            lappend list "#$id ($triggers($id))"
          }
         
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 available triggers are:"
          putquick "NOTICE $nickname :[join $list ", "]"
         
          return
        }               
       
      if { [string range $arguments 1 2] < 15 && [string range $arguments 1 2] > 0 } {
        setuser $handle XTRA keyword-trigger $triggers([string range $arguments 1 2])
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 your personal trigger is now: [getuser $handle XTRA keyword-trigger]"
      } else {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 synta\037x\037\002:\002 $lastcommand \037?\002#\002id?\037"
      }
    }             
   
    # - void proc list
    proc command:list { nickname hostname handle channel arguments } {
      set list ""
      set count [llength [::keyword::utilities::create:list $channel]]
     
      if { $count == "1" } {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 $count message is added on my database\002:\002"
      } else {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 $count messages are added on my database\002:\002"
      }
      set data ""
     
      foreach messages [::keyword::utilities::create:list $channel] {               
        if { [llength $data] == 5 } {
          putquick "NOTICE $nickname :\002(\002keyword\002)\002 [join $data ", "]"
          set data ""
        }
        lappend data $messages
      }
     
      if { [llength $data] > 1 } {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 [join $data ", "]"
      } elseif { [llength $data] == 1 } {
        putquick "NOTICE $nickname :\002(\002keyword\002)\002 [join $data]"
      }
    }         
   
    # - void proc version
    proc command:version { nickname hostname handle channel arguments } {           
      if {[info exists ::keyword(protection_v,$channel)] && [expr [unixtime] - $::keyword(protection_v,$channel)] < 30} { return;}
      putquick "PRIVMSG $channel :\001ACTION is running the keyword script $::keyword::variable::version \002(\002c\002)\002 $::keyword::variable::author\001"
      set ::keyword(protection_v,$channel) [unixtime]       
    }
   
  }           
 
  # namespace eval utilities
  namespace eval utilities {
   
    # - void proc exists {required string channel} {required string keyword}
    proc exists { channel keyword {global "8427zthgf7tzht"} } {
      if { $keyword == "" || ![info exists keyword] || [string match *\"* $keyword] } { return 0; }
      if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
      set number 1
      while {![eof $database]} {
        if {[set line [gets $database]] != ""} {
          if {[decrypt split [lindex [split $line] 0]] != $channel && [decrypt split [lindex [split $line] 0]] != $global} { continue; }
          if {![isnumber [string range [join $keyword] 1 end]]} {
            if {([decrypt split [lindex [split $line] 0]] == $channel || [decrypt split [lindex [split $line] 0]] == $global) && [decrypt split [lindex [split $line] 1]] == $keyword} {
              close $database
              return 1
            }
          } else {
            if {[decrypt split [lindex [split $line] 0]] == $channel && $number == [string range [join $keyword] 1 end]} {
              close $database
              return 1
            }
          }
        }
        incr number
      }         
      close $database
      return 0
    }         
   
    # - void proc add {required string channel} {required string keyword} {required string message}
    proc add { channel keyword message } {
      if {[catch { set database [open $::keyword::variable::database "a"] } error]} { return 0; }
      set chan [encrypt split $channel]
      set key [encrypt split [join $keyword]]
      set msg [encrypt split $message]
      puts $database "$chan $key $msg"
      close $database
      return 1
    }         
   
    # - void proc remove {required string channel} {required string keyword}
    proc remove { channel keyword } {
      if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
      set refill ""
      set number 1
      while {![eof $database]} {
        if {[set line [gets $database]] != ""} {
          if {[decrypt split [lindex [split $line] 0]] == $channel} {
            if {[decrypt split [lindex [split $line] 1]] == $keyword} { incr number; continue; }
            if {[isnumber [string range [join $keyword] 1 end]] && $number == [string range [join $keyword] 1 end]} { incr number; continue; }       
            incr number;
          }
          lappend refill $line
        }
      }
      close $database
      set database [open $::keyword::variable::database "w"]
      foreach data_refill $refill {
        puts $database $data_refill
      }
      close $database
      return 1
    }       
   
    # - void proc clear {optional string channel}
    proc clear { {channel ""} } {
      if { $channel == "*" || $channel == "" } {
        if {[file exists $::keyword::variable::database]} { file delete $::keyword::variable::database }
        set database [open $::keyword::variable::database "w"]
        puts -nonewline $database ""
        close $database
        return;
      }
     
      if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
      set refill ""
      set number 1
      while {![eof $database]} {
        if {[set line [gets $database]] != ""} {
          if {[decrypt split [lindex [split $line] 0]] == $channel} { continue; }
          lappend refill $line
        }
      }
      close $database
      set database [open $::keyword::variable::database "w"]
      foreach data_refill $refill {
        puts $database $data_refill
      }
      close $database
      return 1
    }         
   
    # - void proc rewrite {required string channel} {required string keyword} {required string message}
    proc rewrite { channel keyword message } {
      if {[catch { set database [open $::keyword::variable::database "r"] } error]} { return 0; }
      set refill ""
      set number 1
      while {![eof $database]} {
        if {[set line [gets $database]] != ""} {
          if {[decrypt split [lindex [split $line] 0]] == $channel} {
            if {[decrypt split [lindex [split $line] 1]] == $keyword} { continue; }
          }
          lappend refill $line
        }
      }
      close $database
      set database [open $::keyword::variable::database "w"]
      foreach data_refill $refill {
        puts $database $data_refill
      }
      puts $database "[encrypt split $channel] [encrypt split $keyword] [encrypt split $message]"
      close $database
      return 1
    }         
   
    # - void proc create:list {required string channel}
    proc create:list { channel } {
      set data ""
      set database [open $::keyword::variable::database "r"]
      while {![eof $database]} {
        if {[set line [gets $database]] != ""} {
          if {[decrypt split [lindex [split $line] 0]] == $channel} {
            lappend data "[decrypt split [lindex [split $line] 1]]"
          }
        }
      }
      close $database
      return $data
    }
   
    # - void proc get:command {required string command}
    proc get:command { command } {
      set data ""
      set database [open $::keyword::variable::database "r"]
      while {![eof $database]} {
        if {[set line [gets $database]] != ""} {
          if {[decrypt split [lindex [split $line] 1]] == $command} {
            close $database; return [decrypt split [lindex [split $line] 2]];
          }
        }
      }
      close $database
    }         
           
    # - void proc trigger {required string handle}
    proc trigger { handle } {
      set utrigger [getuser $handle XTRA keyword-trigger]
      if {[llength $utrigger] < 1 || ![validuser $handle]} {
        set utrigger [join [string trim $::keyword::variable::trigger]]
      }           
      return $utrigger       
    }
               
  } 
 
  # log
  putlog "user defined keywords version <${::keyword::variable::version}> (c) $::keyword::variable::author successfully loaded"                   
}
]
]x[
Voice
Posts: 16
Joined: Mon Jan 09, 2006 7:23 pm

Re: Maybe...

Post by ]x[ »

Man you are my hero for the upcoming week. Here to you mate and mucho appreciated. /me bows deeply to MMX
Post Reply