Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # =============================================================================
- # AA Who Is by SubstreamAI - Eggdrop TCL script
- # Adapted from Way2Death's awesome quote script
- # =============================================================================
- # Email: SubstreamAI@gmail.com
- # Note: Alien Arena is an OpenSource, free FPS game (red.planetarena.org).
- # =============================================================================
- #
- # This script is intended for Alien Arena server admin to research players
- # visiting their server(s). It will return records from collected IPs based on
- # name and IP searches. This information is most useful for forming an opinion
- # about a players behavior and building IP ranges to possilby ban.
- #
- # The server configuration cvar sv_iplogfile allows you to specify a file
- # to log IPs for joins and quits. This TCL script operates on a cleaned
- # version of that file. Records are reformatted with the IP address first
- # followed by the a space and then the palyer name (with the color codes
- # removed), e.g. ##.##.##.## InGamePlayerName
- #
- # Commands
- # aawhois ?/l#?
- # /l# sets the number of record results returned. Default is set in the
- # Trigger char is set in the script configuration section
- # Processing:
- # 1. The file is grepped for the player name (can be partial text). Results
- # are redirected to a "hitfile"
- # 2. Each IP in the hitfile is reduced to the first three ocets and the log
- # file is again grepped for those partial IPs. Results are redirected to
- # append the hitfile.
- # 3. The file is then run through sort | uniq to strip duplicates
- # 4. Finally the results are sent to the requesting user via PM
- #
- # IP2Name ?/l#?
- # /l# sets the number of record results returned. Default is 3
- # Trigger char is set in the script configuration section
- # Processing:
- # 1. The file is glob searched for an IP address (can be partial). results are
- # saved to a sorted, unique hitfile.
- # 2. Then results are sent to the requesting user via PM
- #
- # Notes
- # The purpose of IP2Name in case you have only an IP (for example from an IRC
- # client). IP2Name can supply you with list of possible player names to use
- # with !aaWhoIs. Future plans are to refine the list and possibly automaticaly
- # pass name(s) to !aaWhoIs. IP2Name defualts to 3 results but can be set with
- # /l##
- #
- # Todo: rcon to rename and download server logs
- # =============================================================================
- set scriptver([file rootname [file tail [info script]]]) "4.0beta"
- namespace eval aa_who_is {
- variable aawi
- #..................Configuration..................
- # Files, paths, and channel settings and variables
- set aawi(WorkingDir) $env(HOME)/eggdrop/Neblet
- set aawi(DataFile) "$aawi(WorkingDir)/IP_Collection.log"
- set aawi(DataFileBU) "$aawi(WorkingDir)/IP_Collection.old"
- set aawi(ExclusionFile) "$aawi(WorkingDir)/AAWhoIsExclusions.lst"
- set aawi(svLogDLPath) "$aawi(WorkingDir)/DO_Server_Logs"
- set aawi(log_tarball) $aawi(svLogDLPath)/LogsAdded/DO_Server_IP_Logs_Added.tar.gz
- set aawi(Channel) "#ducesoforion"
- set aawi(AdminNick) "\[DO\]Rigel"
- # Select this to your perferred command prefix, "" is acceptable.
- set aawi(trigger) "!"
- # Access required to read quotes & access help.
- # "-" everyone
- # "a" auto op (by chanserv)
- # "o" op
- # "n" owner
- # "m" master
- # "y" half op
- # "v" voice
- # Google eggdrop user flags for more
- # The script will execute if a user has any of the flags specified below
- set aawi(userflag) "o"
- set aawi(adminflag) "n"
- # Return limits and other limits
- set aawi(NameLimit) "20"
- set aawi(IPLimit) "3"
- set aawi(RecurLimit) "3"
- # Time Masks for FTP Transfer and Import (mm hh dd mm yyyy)
- set aawi(FTPTimeMask) "00 02 * * *"
- set aawi(ImportTimeMaks) "03 02 * * *"
- #................End Configuration................(Do not edit past here)
- # =============================================================================
- #......................Binds......................
- bind msg $aawi(userflag) aaWhoIs [namespace current]::aaWI_search
- bind msg $aawi(userflag) ip2name [namespace current]::IP2Name_search
- bind msg $aawi(userflag) aaAdd [namespace current]::Add_Record
- bind msg $aawi(userflag) aaDelete [namespace current]::Delete_Record
- bind msg $aawi(userflag) WhyDel [namespace current]::Why_Delete
- bind msg $aawi(userflag) IPLogHelp [namespace current]::cmd_Help
- bind msg $aawi(adminflag) SortIPLog [namespace current]::IPlog_sort
- bind msg $aawi(adminflag) RepairIPLog [namespace current]::Repair_IPLog
- bind msg $aawi(adminflag) GetIPLogs [namespace current]::FTPDnLd
- bind msg $aawi(adminflag) ImpIPLogs [namespace current]::ImportIPLogs
- bind msg $aawi(adminflag) EditIPLog [namespace current]::edit_Collection
- bind msg $aawi(adminflag) EditIPArchive [namespace current]::edit_archive
- bind msg $aawi(adminflag) CodeAAWI [namespace current]::komodo_aawhois
- bind time - $aawi(FTPTimeMask) [namespace current]::autoFTPDnLd
- bind time - $aawi(ImportTimeMaks) [namespace current]::autoImportIPLogs
- bind evnt -|- prerehash [namespace current]::aaRehash_Clean
- proc aaRehash_Clean {Text} {
- # [11:24:57] Tcl error [aaRehash_Clean]: can't read "aawi(userflag)": no such variable
- variable aawi
- catch {unbind msg $aawi(userflag) aaWhoIs [namespace current]::aaWI_search}
- catch {unbind msg $aawi(userflag) ip2name [namespace current]::IP2Name_search}
- catch {unbind msg $aawi(userflag) aaAdd [namespace current]::Add_Record}
- catch {unbind msg $aawi(userflag) aaDelete [namespace current]::Delete_Record}
- catch {unbind msg $aawi(userflag) WhyDel [namespace current]::Why_Delete}
- catch {unbind msg $aawi(userflag) IPLogHelp [namespace current]::cmd_Help}
- catch {unbind msg $aawi(adminflag) SortIPLog [namespace current]::IPlog_sort}
- catch {unbind msg $aawi(adminflag) RepairIPLog [namespace current]::Repair_IPLog}
- catch {unbind msg $aawi(adminflag) GetIPLogs [namespace current]::FTPDnLd}
- catch {unbind msg $aawi(adminflag) ImpIPLogs [namespace current]::ImportIPLogs}
- catch {unbind msg $aawi(adminflag) EditIPLog [namespace current]::edit_Collection}
- catch {unbind msg $aawi(adminflag) EditIPArchive [namespace current]::edit_archive}
- catch {unbind msg $aawi(adminflag) CodeAAWI [namespace current]::komodo_aawhois}
- catch {unbind time - $aawi(FTPTimeMask) [namespace current]::autoFTPDnLd}
- catch {unbind time - $aawi(ImportTimeMaks) [namespace current]::autoImportIPLogs}
- catch {unbind evnt -|- prerehash [namespace current]::aaRehash_Clean}
- }
- #.................Initialization..................
- # source $env(HOME)/eggdrop/scripts/saitools.tcl
- package require ftp
- set aawi(DeleteReason) ""
- putlog "aaWhoIs TCL version $aawi(version) by SubstreamAI"
- # =============================================================================
- #.................Function Procs..................
- #..................Filter Procs...................
- # Remove the ^# color codes
- proc StripColorCodes {Data} {
- regsub -all {\^[[:graph:]]{1}} $Data "" Data
- return $Data
- }
- # Remove the ^# color codes and various clan tag braces { } [ ]
- proc subst_spec_chars {Text} {
- set Text "[[namespace current]::StripColorCodes $Text]"
- set Text [string map {\{ ? \} ? \[ ? \] ? \\ ?} $Text]
- return $Text
- }
- # Removes invalid lines from the search results
- proc CleanLogs {cleanfilelines} {
- logmsg ""
- set NewFileLines [list]
- # Eliminate lines without IP and PlayerName info
- foreach Element $cleanfilelines {
- # Each valid line should have a colon between the IP and port, and a # > 0 in the 3rd field
- if {[string match "*:*" $Element] != 0 && [lindex [split $Element "\t"] 2] != 0} {
- # The 4th field contains the player name, so eleminate lines with no name
- if {[llength [split $Element "\t"]] >= 4} {
- set PlayerName [join [lrange [split $Element "\t"] 3 end]]
- # The first element after splitting will be IP:Port so...
- set IP_Addr [lindex [split $Element "\t"] 0]
- # ... lose the port#
- set IP_Addr [lindex [split $IP_Addr ":"] 0]
- # Sometimes 2 lines will end up on 1. If there is an IP in the player name, skip it
- if {[string match "*$IP_Addr*" $PlayerName] == 0} {
- set newLine "$IP_Addr $PlayerName"
- lappend NewFileLines $newLine
- }
- }
- }
- }
- return [lsort -unique $NewFileLines]
- }
- #.................Function Procs..................
- # separate option switches, prevent injection
- proc parse_search_string {text} {
- variable aawi
- #Process option switches
- set switch1 [string tolower [lindex [split $text] 0]]
- set switch2 [string tolower [lindex [split $text] 1]]
- # check for /l# to change return lines limit set in configuration secion
- if {[string match "/l*" $switch1] || [string match "/l*" $switch2]} {
- if {[string match "/l*" $switch1]} {
- set limitswitch $switch1
- } else {
- set limitswitch $switch2
- }
- # strip the /l (want only the integer)
- regsub -all "/l" $limitswitch "" limitswitch
- # set limitswitch [string map {"/l" ""} $limitswitch]
- if {[string is integer -strict $limitswitch]} {
- set aawi(limit) $limitswitch
- set firstchar [expr {[string first /l $text] + 2}]
- set lastchar [expr {[string first " " $text $firstchar] - 1}]
- # remove the entire switch from our search string
- regsub -all "/l${aawi(limit)} " $text "" text
- regsub -all "/L${aawi(limit)} " $text "" text
- }
- }
- # prevent sneaking in extra shell commands (e.g. !aaWhoIs test; rm -rf *)
- regsub -all ";" $text "\." text
- return [string trim $text]
- }
- # Extracts the player name from a log record
- proc ExtractPlayerName {DataLine Method} {
- # Method: s = short (truncate name after 8 chars) l = long (full)
- set Method [string tolower $Method]
- set PlayerName [join [lrange [split $DataLine] 1 end]]
- if {$Method == "s"} {
- set PlayerName [string range $PlayerName 0 7]
- }
- return $PlayerName
- # set name [string range $DataLine [expr {$i + 1}] [expr {$i + 8}]]
- }
- # Extracts the player IP from a log record
- proc ExtractIP {DataLine Method} {
- # Method: s = short (tuncate last octet, d = dynamic (change last octet to 0, l = long (full)
- set Method [string tolower $Method]
- set IP [lindex [split $DataLine] 0]
- # In case this proc is used for the old line format "port:IP Player Name"
- if {[string match ":" $IP]} {
- set IP [lindex [split $IP ":"] 1 end]
- }
- if {$Method == "s"} {
- set IP [string range $IP 0 [string last . $IP]]
- }
- if {$Method == "d" } {
- set IP [string range $IP 0 [string last . $IP]]
- set IP [concat $IP "0"]
- }
- return $IP
- }
- # Extracts the Index Number from a log record
- proc ExtractIndex {DataLine} {
- # Remove the Player Name
- if {[string first ":" $DataLine] == -1} {
- logmsg "No index found in $DataLine"
- return -1
- }
- return [lindex [split $DataLine ":"] 0]
- }
- #................Subroutine Procs.................
- # Build list of names, and another list of IPs from the names, then combine them
- proc SearchIPCollection {SearchList} {
- variable aawi
- global lastbind
- set NamesFound [list "0.0.0.0 Names added for: $SearchList"]
- # 2nd list to output with text format codes
- set PrintNames [list "0.0.0.0 Names added for: $SearchList"]
- set IPsFound [list "0.0.0.0 More names from the above IPs"]
- # 2nd list to output with text format codes
- set PrintIPs [list "0.0.0.0 More names from the above IPs"]
- # Add heading records to search exclusions
- lappend aawi(ExclusionList) "Names added for: [join $SearchList]"
- lappend aawi(ExclusionList) "More names from the above IPs"
- # The IPExclusionList will grow to prevent duplicates
- set IPExclusionList [list "192.168.101."]
- # SearchList will be names for aaWhoIs and IPs for IP2Name
- foreach SearchString $SearchList {
- if {[string trim $SearchString] != "" && [string length $SearchString] > 3} {
- logmsg $SearchString
- set NewHits [lsearch -glob -all -inline -nocase $aawi(IPCollection) "*$SearchString*"]
- # Format the SearchString in the output (substituted later)
- set CodedString [formattext bold "$SearchString"]
- # Remove elements with excluded IPs.
- foreach Element $NewHits {
- set IPString [[namespace current]::ExtractIP $Element s]
- # No duplicates from cummulative results
- if {[lsearch $IPExclusionList $IPString] == -1 && [lsearch $aawi(SearchResults) $Element] == -1} {
- # No duplicates from current results
- if {[lsearch $NamesFound $Element] == -1 && [lsearch $IPsFound $Element] == -1} {
- lappend NamesFound $Element
- # Seconds list with the formated output text
- lappend PrintNames [[namespace current]::substring $CodedString $SearchString $Element]
- }
- }
- }
- }
- # for IP2Name, all we need is a few names, no need to continue to deeper IP searches
- if {[string tolower $lastbind] == "ip2name"} {break}
- # Build list of unique IPs found for the current SearchString
- set IPList [list]
- foreach Element $NamesFound {
- set IPString [[namespace current]::ExtractIP $Element s]
- # If its not blank and not excluded, add it and exclude it from further searches
- if {$IPString != "" && [lsearch $IPExclusionList $IPString] == -1} {
- lappend IPList $IPString
- lappend IPExclusionList $IPString
- }
- }
- # Search for the IPs
- foreach IPString $IPList {
- set NewHits [lsearch -glob -all -inline -nocase $aawi(IPCollection) "*$IPString*"]
- # Format the SearchString in the output (substituted later)
- set CodedString [formattext bold "$IPString"]
- foreach Hit $NewHits {
- # No duplicates from cummulative results
- if {[lsearch $aawi(SearchResults) $Hit] == -1} {
- # No duplicates from current results
- if {[lsearch $NamesFound $Hit] == -1 && [lsearch $IPsFound $Hit] == -1} {
- lappend IPsFound $Hit
- # Seconds list with the formated output text
- lappend PrintIPs [[namespace current]::substring $CodedString $IPString $Hit]
- }
- }
- }
- }
- }
- set HitsFound [list]
- if {[llength $NamesFound] > 1} {
- lappend HitsFound {*}$NamesFound
- # Seconds list with the formated output text
- lappend aawi(Results2Print) {*}$PrintNames
- if {[llength $IPsFound] > 1} {
- lappend HitsFound {*}$IPsFound
- # Seconds list with the formated output text
- lappend aawi(Results2Print) {*}$PrintIPs
- }
- }
- return $HitsFound
- }
- proc BuildNameList {} {
- variable aawi
- set NameList [list]
- foreach Element $aawi(SearchResults) {
- set Name [[namespace current]::ExtractPlayerName $Element l]
- if {$Element == ""} {
- set aawi(SearchResults) [ldelete $aawi(SearchResults) $Element]
- }
- if {[lsearch -nocase $aawi(ExclusionList) $Name] == -1} {
- # Check duplicates, i.e. -unique
- if {[lsearch $NameList $Name] == -1} {
- lappend NameList $Name
- }
- }
- }
- return $NameList
- }
- proc print_hitlist {search results nick} {
- variable aawi
- global lastbind
- logcmdproc
- set number 0
- set TtlResults [llength $results]
- set HeadingCount [llength [lsearch -all $aawi(SearchResults) "0.0.0.0 *"]]
- say medium $nick "There are [expr {$TtlResults - $HeadingCount}] matches for \002$search\002"
- if {$TtlResults > $aawi(limit)} {
- say medium $nick "The return limit is set to \002$aawi(limit)\002 lines. Change with \002/l#\002, i.e. $lastbind /l$TtlResults $search"
- }
- foreach line $results {
- if {[lindex $line 0] == "0.0.0.0"} {
- say medium $nick [formattext bold $line]
- } else {
- say medium $nick $line
- }
- # Don't count the header line
- if {[[namespace current]::ExtractIP $line l] != "0.0.0.0"} {
- set number [expr {$number + 1}]
- if {$number == $aawi(limit)} {
- break
- }
- }
- }
- say medium $nick "End of list"
- return 1
- }
- # Retrieves the server logs via FTP
- proc FTPDownload {nick rest} {
- variable aawi
- global errorInfo lastbind
- set TempLogFile TmpSrvConsole.tmp
- set ServerList [file2list "$aawi(WorkingDir)/DO_ServerList.lst"]
- putquick "PRIVMSG $nick :Importing Server IP Logs via FTP"
- foreach svString $ServerList {
- if {$svString == ""} {continue}
- set ServerName [lindex [split $svString " "] 0]
- set Server [lindex [split $svString " "] 1]
- set svPort [lindex [split $svString " "] 2]
- set svPW [lindex [split $svString " "] 3]
- set UserName [lindex [split $svString " "] 4]
- set FTP_PW [lindex [split $svString " "] 5]
- set Location [join [lrange [split $svString " "] 6 end]]
- putcmdlog "Attempting FTP Download for $Location Logs"
- if {[catch {ftp::Open $Server $UserName $FTP_PW -port 21 -mode passive} Session]} {
- logmsg "Connection failed: $ServerName $Location: $Session"
- say med $nick "$ServerName $Location Connection Refused"
- ftp::Close $Session
- continue
- }
- if {[ftp::Cd $Session "/alienarena/arena/"] == 0} {
- say medium $nick "$ServerName $Location: Unable to change directories"
- logmsg "$ServerName $Location Unable to change directories: $errorInfo"
- continue
- }
- ::sai_rcon::tcl_rcon $Server $svPort $svPW "logname $TempLogFile"
- set DnLdList [ftp::NList $Session "*.log"]
- ftp::Type $Session binary
- foreach LogFile $DnLdList {
- set LocalFile $aawi(svLogDLPath)/[string map {".log" ""} $LogFile]
- set LocalFile ${LocalFile}_[string map {", " "_"} $Location][clock format [clock seconds] -format {%Y%m%d}]
- set LocalFile [string map {" " "_" "-" ""} $LocalFile].log
- # Rename if exists to prevent overwriting
- if {[file exists $LocalFile] == 1} {
- set Count 0
- while {[file exists $LocalFile] == 1 && $Count < 10} {
- set Count [expr {$Count + 1}]
- set LocalFile [string map {".log" ""} $LocalFile]x.log
- }
- if {$Count >= 10} {
- say medium $nick "Delete the old logs first, $Count duplicate filenames"
- logmsg "Transfer Aborted after $Count duplicate filenames"
- ftp::Close $Session
- break
- }
- logmsg "Conflict, file renamed: $LocalFile"
- }
- if {[ftp::Get $Session $LogFile $LocalFile] == 0} {
- say fast $nick "$ServerName $Location: Transfer $LogFile failed"
- logmsg "Get $LogFile from $ServerName $Location failed: $errorInfo"
- } else {
- say fast $nick "$ServerName $Location: Transfer $LogFile successful"
- if {[ftp::Delete $Session $LogFile] != 1} {
- say fast $nick "Failed to delete $LogFile from server $ServerName!"
- logmsg "Delete $LogFile from $ServerName $Location Failed: $errorInfo"
- }
- }
- }
- ::sai_rcon::tcl_rcon $Server $svPort $svPW "exec LogName.cfg"
- ftp::Delete $Session $TempLogFile
- ftp::Close $Session
- }
- }
- # Imports recently DLed server logs to the log collection file and sorts it
- proc ImportLogFiles {nick rest} {
- variable aawi
- set NewLogs [list]
- set LogsAdded [list]
- set aawi(IPCollection) [file2list $aawi(DataFile)]
- say medium $nick "Adding downloaded files to IP Collection..."
- # Remove any duplicates
- if {[lsearch $aawi(IPCollection) ""] != -1} {
- set aawi(IPCollection) [ldelete $aawi(IPCollection) ""]
- }
- # load the logfile names
- set globFileList [glob -nocomplain -directory $aawi(svLogDLPath)/ -- "IP_*.log"]
- if {$globFileList == ""} {
- say medium $nick "No log files found in $aawi(svLogDLPath)"
- return -1
- }
- # Load the files to a list
- foreach LogFile $globFileList {
- lappend NewLogs {*}[file2list $LogFile]
- lappend LogsAdded [string trimleft $LogFile $aawi(svLogDLPath)/]
- }
- set NewLogs [[namespace current]::CleanLogs $NewLogs]
- set aawi(IPCollection) [lsort -unique [list {*}$aawi(IPCollection) {*}$NewLogs]]
- # make a backup of the IP Collection before updating it
- file copy -force $aawi(DataFile) $aawi(DataFileBU)
- list2file $aawi(IPCollection) "$aawi(DataFile)" w
- say medium $nick "Files added to collection: $LogsAdded"
- # if {[file exists $aawi(log_tarball)] == 1} {
- # eval exec tar -rvzf $aawi(log_tarball) ${aawi(svLogDLPath)}/IP_*.log
- # } else {
- # eval exec tar -cvzf $aawi(log_tarball) ${aawi(svLogDLPath)}/IP_*.log
- # }
- # move the files to the trash
- #file rename -force -- ${aawi(svLogDLPath)}/IP_*.log /home/rigel/.local/share/Trash
- eval exec trash-put [glob ${aawi(svLogDLPath)}/IP_*.log]
- return 1
- }
- # Substitus one string for another within a string (Non-Case Sensitve)
- proc substring {NewStr OldStr Source} {
- if {[string match -nocase *$OldStr* $Source] == 0} {
- logmsg "String \"$OldStr\" not found in source \"$Source\""
- return "-1"
- }
- set start [string first [string tolower $OldStr] [string tolower $Source]]
- set end [expr {$start + [string length $OldStr] - 1}]
- if {$NewStr == ""} {return [string replace $Source $start $end]}
- return [string replace $Source $start $end $NewStr]
- }
- #..............Channel Command Procs..............
- # Searches the IP Log for a player name
- proc aaWI_search {nick host hand rest} {
- variable aawi
- logcmdproc
- set aawi(limit) $aawi(NameLimit)
- if {$rest == ""} {
- say medium $nick "Searching requires a name to search for..."
- break
- }
- set rest [[namespace current]::parse_search_string $rest]
- set rest [[namespace current]::subst_spec_chars $rest]
- # Make the search string a tcl list (expected by [namespace current]::SearchIPCollection)
- set NameSearch [split $rest "\n"]
- set aawi(IPCollection) [split [[namespace current]::subst_spec_chars [join [file2list $aawi(DataFile)] "~"]] "~"]
- set aawi(ExclusionList) [file2list $aawi(ExclusionFile)]
- set NameHitsLast 1
- set NameHits 0
- set HeadingCount 1
- set HitPasses 0
- # Verify the validity of the search first
- if {[lsearch -nocase $aawi(IPCollection) "*$NameSearch*"] == -1} {
- say medium $nick "No Matches Found: $NameSearch"
- return
- }
- # Reset the list for a new search
- set aawi(SearchResults) [list]
- # Seconds list with the formated output text
- set aawi(Results2Print) [list]
- while {$HitPasses < $aawi(RecurLimit)} {
- set HitPasses [expr {$HitPasses + 1}]
- logmsg "Building hitlist, pass $HitPasses"
- say fast $nick "Searching database for $NameHitsLast name(s) and IPs (Pass $HitPasses)"
- set aawi(SearchResults) [list {*}$aawi(SearchResults) {*}[[namespace current]::SearchIPCollection $NameSearch]]
- # Seconds list with the formated output text
- set aawi(Results2Print) [list {*}$aawi(Results2Print) {*}[[namespace current]::SearchIPCollection $NameSearch]]
- set HeadingCount [llength [lsearch -all $aawi(SearchResults) "0.0.0.0 *"]]
- set NameHits [expr {[llength $aawi(SearchResults)] - $HeadingCount}]
- if {$NameHits > 50} {
- logmsg "Search process ABORTED after $NameHits hits over $HitPasses passes."
- say medium $nick "Search process ABORTED after $NameHits hits over $HitPasses passes."
- break
- }
- say fast $nick "[expr {$NameHits - $NameHitsLast}] additional names found..."
- if {$NameHits <= $NameHitsLast} {
- break
- }
- set NameHitsLast $NameHits
- set NameSearch [namespace current]::BuildNameList
- }
- say fast $nick "End of search process, now printing results..."
- # [namespace current]::print_hitlist $rest $aawi(SearchResults) $nick <== Would print bare (unformated) text
- [namespace current]::print_hitlist $rest $aawi(Results2Print) $nick
- endcmdproc ""
- return
- }
- # Searches the IP Log for an IP
- proc IP2Name_search {nick host hand rest} {
- variable aawi
- logcmdproc
- set aawi(IPCollection) [file2list $aawi(DataFile)]
- set aawi(limit) $aawi(IPLimit)
- if {$rest == ""} {
- putserv "PRIVMSG $nick :Searching requires a name to search for..."
- break
- }
- set rest [[namespace current]::parse_search_string $rest]
- set rest [[namespace current]::subst_spec_chars $rest]
- # use only the first 3 octets (plus the last dot) for the search
- if {[llength [split $rest "."]] > 3} {
- set rest "[join [lrange [split $rest "."] 0 2] "."]."
- }
- # Make the search string a tcl list (expected by [namespace current]::SearchIPCollection)
- set IPSearch [split $rest "\n"]
- putcmdlog "IP2Name: Building hitlist"
- putquick "PRIVMSG $nick :Searching database for $IPSearch\*"
- # Reset the list for a new search
- set aawi(SearchResults) [list]
- set aawi(SearchResults) [[namespace current]::SearchIPCollection $IPSearch]
- if {[llength $aawi(SearchResults)] == 0} {
- putserv "PRIVMSG $nick :No Matches Found: $rest"
- return
- }
- [namespace current]::print_hitlist "$rest" $aawi(SearchResults) $nick
- endcmdproc ""
- return
- }
- # Time bind: downloads the logs via FTP
- proc autoFTPDnLd {Min Hour Day Month Year} {
- variable aawi
- global botnick
- logmsg "[timestamp]"
- if {[onchan $aawi(AdminNick)]} {
- set nick $aawi(AdminNick)
- } else {
- set nick $botnick
- }
- [namespace current]::FTPDownload $nick "autoTime"
- endproc
- }
- # Msg bind: downloads the logs via FTP
- proc FTPDnLd {nick host hand rest} {
- variable aawi
- logcmdproc
- [namespace current]::FTPDownload $nick "ManualCall"
- endcmdproc ""
- }
- # Time bind: cleans, formats, and adds log to the IP Collection
- proc autoImportIPLogs {Min Hour Day Month Year} {
- variable aawi
- global botnick
- logmsg "[timestamp]"
- if {[onchan $aawi(AdminNick)]} {
- set nick $aawi(AdminNick)
- } else {
- set nick $botnick
- }
- [namespace current]::ImportLogFiles $nick "autoTime"
- endproc
- }
- # Msg bind: cleans, formats, and adds log to the IP Collection
- proc ImportIPLogs {nick host hand rest} {
- variable aawi
- logcmdproc
- [namespace current]::ImportLogFiles $nick "ManualCall"
- endcmdproc ""
- }
- # Sorts IP_Collection.log and eliminates duplicates
- proc IPlog_sort {nick host hand rest} {
- variable aawi
- logcmdproc
- putserv "PRIVMSG $nick :Sorting IP Log..."
- SortFile $aawi(DataFile) $aawi(DataFileBU)
- endcmdproc ""
- return
- }
- # Repair corrupted lines in the Log file. Deletes blanks, removes multiple IP's, converts dynamic IP from #.#.#.* to #.#.#.0
- proc Repair_IPLog {nick host hand rest} {
- global lastbind aawi
- logcmdproc
- putquick "PRIVMSG $nick :Reparing the IP Collection Log"
- lappend RepairedLines "The following lines will be added to $aawi(WorkingDir)/AAWhoIs_Archived_Records.lst"
- set aawi(IPCollection) [file2list $aawi(DataFile)]
- # Remove blank lines
- foreach Line $aawi(IPCollection) {
- if {$Line == ""} {
- set aawi(IPCollection) [ldelete $aawi(IPCollection) ""]
- }
- }
- # Find multiple IPs and dyanamic IPs using #.#.#.*
- foreach Line $aawi(IPCollection) {
- set IP_Addr [[namespace current]::ExtractIP $Line l]
- set PlayerName [[namespace current]::ExtractPlayerName $Line l]
- # Fix dyanamic IPs using #.#.#.* to use #.#.#.0 instead
- if {[lindex [split $IP_Addr "."] 3] == "\*"} {
- set IP_Addr [string map {"\.\*" ".0"} $IP_Addr]
- set Indx [lsearch $aawi(IPCollection) $Line]
- set NewLine "$IP_Addr $PlayerName"
- set aawi(IPCollection) [lreplace $aawi(IPCollection) $Indx $Indx $NewLine]
- lappend RepairedLines "[timestamp] $nick $lastbind: $Line ==> $NewLine"
- unset Indx
- }
- # Fix multiple IPs in line
- set IP_Addr "[lindex [split $IP_Addr "."] 2]."
- if {[lsearch [split $PlayerName] "$IP_Addr*"] != -1} {
- # Strip the IP(s) from the name
- while {[lsearch [split $PlayerName] "$IP_Addr*"] != -1} {
- set IP_Addr [lindex [split $PlayerName] 0]
- set PlayerName [lindex [split $PlayerName] 1]
- }
- # Update the list
- set NewLine "$IP_Addr $PlayerName"
- set ReplaceIndices [lsearch -all -exact $aawi(IPCollection) $Line]
- foreach Indx $ReplaceIndices {
- set aawi(IPCollection) [lreplace $aawi(IPCollection) $Indx $Indx $NewLine]
- lappend RepairedLines "[timestamp] $nick $lastbind: $Line ==> $NewLine"
- }
- }
- }
- # viewlist $RepairedLines
- list2file $RepairedLines "$aawi(WorkingDir)/AAWhoIs_Archived_Records.lst" a
- list2file $aawi(IPCollection) $aawi(DataFile) w
- # list2file [lsort $aawi(IPCollection)] $aawi(DataFile) w
- endcmdproc "[expr {[llength $RepairedLines] - 1}] records changed"
- return
- }
- # Manually add a record to the IP Collection
- proc Add_Record {nick host hand AddMe} {
- variable aawi
- global lastbind
- logcmdproc
- set aawi(IPCollection) [file2list $aawi(DataFile)]
- lappend aawi(IPCollection) $AddMe
- set aawi(IPCollection) [lsort -unique $aawi(IPCollection)]
- # Save updated data
- if {![list2file $aawi(IPCollection) $aawi(DataFile) a]} {
- putserv "PRIVMSG $nick : Unable to save updated IP Collection"
- logmsg "Unable to save appended $aawi(DataFile)"
- return -1
- }
- endcmdproc ""
- return 1
- }
- # Record a reason for deleting a record
- proc Why_Delete {nick host hand DelReason} {
- global lastbind aawi
- logcmdproc
- set expireTime 30
- set aawi(DeleteReason) $DelReason
- endcmdproc "expires in $expireTime seconds"
- # reset the var after it expires
- utimer $expireTime [list set $aawi(DeleteReason) ""]
- }
- # Delete a record from the IP Collection
- proc Delete_Record {nick host hand DeleteMe} {
- variable aawi
- global lastbind
- logcmdproc
- if {$aawi(DeleteReason) == ""} {
- putserv "PRIVMSG $nick : Please first enter a reason for the deletion; sample /msg Neblet WhyDel Record was corrupt)"
- return -1
- }
- # Verify $DeleteMe is in the IP Collection Database
- set aawi(IPCollection) [file2list $aawi(DataFile)]
- set DeleteMe [lsearch -exact -inline $aawi(IPCollection) $DeleteMe]
- if {$DeleteMe == []} {
- putserv "PRIVMSG $nick : Not found in the IP Collection Database: $DeleteMe"
- return -1
- }
- # Set log line as list (needed by list2file) so it can be saved
- lappend DeleteList "[timestamp] $nick $lastbind $DeleteMe - Reason: $aawi(DeleteReason)"
- # Save DeleteList first and if it fails, abort
- if {[list2file $DeleteList "$aawi(WorkingDir)/AAWhoIs_Archived_Records.lst" a] != 1} {
- putserv "PRIVMSG $nick : Unable to delete $DeleteMe - cannot create archive"
- logmsg "Failed to create archive - nothing deleted!"
- return -1
- }
- # Delete the record from the list and save it
- set aawi(IPCollection) [ldelete $aawi(IPCollection) $DeleteMe]
- # If list2file fails, abort
- if {[list2file $aawi(IPCollection) $aawi(DataFile) w] == -1} {
- putserv "PRIVMSG $nick : Failed to update IP Collection Database!"
- logmasg "Failed to save updated IP Collection!"
- return -1
- }
- set aawi(DeleteReason) ""
- endcmdproc ""
- return
- }
- # Edit the IP Collection File
- proc edit_Collection {nick host hand rest} {
- variable aawi
- putquick "PRIVMSG $nick :Editing IP Collection with gedit"
- logcmdproc
- exec -- gedit $aawi(DataFile)
- endcmdproc ""
- return
- }
- # Edit the IP Archive File
- proc edit_archive {nick host hand rest} {
- variable aawi
- putquick "PRIVMSG $nick :Editing IP Collection with gedit"
- logcmdproc
- exec -- gedit "$aawi(WorkingDir)/AAWhoIs_Archived_Records.lst"
- endcmdproc ""
- return
- }
- # Edit this script with Komodo
- proc komodo_aawhois {nick host hand rest} {
- variable aawi
- global env
- putquick "PRIVMSG $nick :Loading aawhois.tcl in Komodo"
- logcmdproc
- exec -- $env(HOME)/Komodo-Edit-6/lib/mozilla/komodo $env(HOME)/eggdrop/scripts/aawhois.tcl
- endcmdproc ""
- return
- }
- # IP Collection Log Maintenance Command list for bot owner
- proc cmd_Help {nick host hand rest} {
- logcmdproc
- say cmd $nick "IP Collection Log User commands are: aaWhoIS, IP2Name, aaAdd, WhyDel, aaDelete, IPLogHelp"
- say cmd $nick "IP Collection Log Admin commands are: SortIPLog, GetIPLogs, RepairIPLog, GetIPLog, ImpIPLogs, EditIPLog, EditIPArchive, CodeAAWI"
- endcmdproc ""
- return
- }
- }
Add Comment
Please, Sign In to add comment