Guest User

Untitled

a guest
Sep 10th, 2018
287
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
TCL 31.33 KB | None | 0 0
  1. # =============================================================================
  2. # AA Who Is by SubstreamAI - Eggdrop TCL script
  3. # Adapted from Way2Death's awesome quote script
  4. # =============================================================================
  5. # Email: SubstreamAI@gmail.com
  6. # Note: Alien Arena is an OpenSource, free FPS game (red.planetarena.org).
  7. # =============================================================================
  8. #
  9. # This script is intended for Alien Arena server admin to research players
  10. # visiting their server(s).  It will return records from collected IPs based on
  11. # name and IP searches. This information is most useful for forming an opinion
  12. # about a players behavior and building IP ranges to possilby ban.
  13. #
  14. # The server configuration cvar sv_iplogfile allows you to specify a file
  15. # to log IPs for joins and quits.  This TCL script operates on a cleaned
  16. # version of that file. Records are reformatted with the IP address first
  17. # followed by the a space and then the palyer name (with the color codes
  18. # removed), e.g. ##.##.##.## InGamePlayerName
  19. #
  20. # Commands
  21. # aawhois ?/l#?
  22. # /l# sets the number of record results returned.  Default is set in the
  23. # Trigger char is set in the script configuration section
  24. # Processing:
  25. # 1. The file is grepped for the player name (can be partial text). Results
  26. # are redirected to a "hitfile"
  27. # 2. Each IP in the hitfile is reduced to the first three ocets and the log
  28. # file is again grepped for those partial IPs.  Results are redirected to
  29. # append the hitfile.
  30. # 3. The file is then run through sort | uniq to strip duplicates
  31. # 4. Finally the results are sent to the requesting user via PM
  32. #
  33. # IP2Name ?/l#?
  34. # /l# sets the number of record results returned.  Default is 3
  35. # Trigger char is set in the script configuration section
  36. # Processing:
  37. # 1. The file is glob searched for an IP address (can be partial). results are
  38. # saved to a sorted, unique hitfile.
  39. # 2. Then results are sent to the requesting user via PM
  40. #
  41. # Notes
  42. # The purpose of IP2Name in case you have only an IP (for example from an IRC
  43. # client).  IP2Name can supply you with list of possible player names to use
  44. # with !aaWhoIs. Future plans are to refine the list and possibly automaticaly
  45. # pass name(s) to !aaWhoIs. IP2Name defualts to 3 results but can be set with
  46. # /l##
  47. #
  48. # Todo: rcon to rename and download server logs
  49. # =============================================================================
  50. set scriptver([file rootname [file tail [info script]]]) "4.0beta"
  51. namespace eval aa_who_is {
  52.     variable aawi
  53.  
  54.     #..................Configuration..................
  55.     # Files, paths, and channel settings and variables
  56.     set aawi(WorkingDir) $env(HOME)/eggdrop/Neblet
  57.     set aawi(DataFile) "$aawi(WorkingDir)/IP_Collection.log"
  58.     set aawi(DataFileBU) "$aawi(WorkingDir)/IP_Collection.old"
  59.     set aawi(ExclusionFile) "$aawi(WorkingDir)/AAWhoIsExclusions.lst"
  60.     set aawi(svLogDLPath) "$aawi(WorkingDir)/DO_Server_Logs"
  61.     set aawi(log_tarball) $aawi(svLogDLPath)/LogsAdded/DO_Server_IP_Logs_Added.tar.gz
  62.     set aawi(Channel) "#ducesoforion"
  63.     set aawi(AdminNick) "\[DO\]Rigel"
  64.  
  65.     # Select this to your perferred command prefix, "" is acceptable.
  66.     set aawi(trigger) "!"
  67.  
  68.     # Access required to read quotes & access help.
  69.     # "-" everyone
  70.     # "a" auto op (by chanserv)
  71.     # "o" op
  72.     # "n" owner
  73.     # "m" master
  74.     # "y" half op
  75.     # "v" voice
  76.     # Google eggdrop user flags for more
  77.     # The script will execute if a user has any of the flags specified below
  78.     set aawi(userflag) "o"
  79.     set aawi(adminflag) "n"
  80.  
  81.     # Return limits and other limits
  82.     set aawi(NameLimit) "20"
  83.     set aawi(IPLimit) "3"
  84.     set aawi(RecurLimit) "3"
  85.  
  86.     # Time Masks for FTP Transfer and Import (mm hh dd mm yyyy)
  87.     set aawi(FTPTimeMask) "00 02 * * *"
  88.     set aawi(ImportTimeMaks) "03 02 * * *"
  89.  
  90.     #................End Configuration................(Do not edit past here)
  91.     # =============================================================================
  92.     #......................Binds......................
  93.     bind msg $aawi(userflag) aaWhoIs [namespace current]::aaWI_search
  94.     bind msg $aawi(userflag) ip2name [namespace current]::IP2Name_search
  95.     bind msg $aawi(userflag) aaAdd [namespace current]::Add_Record
  96.     bind msg $aawi(userflag) aaDelete [namespace current]::Delete_Record
  97.     bind msg $aawi(userflag) WhyDel [namespace current]::Why_Delete
  98.     bind msg $aawi(userflag) IPLogHelp [namespace current]::cmd_Help
  99.     bind msg $aawi(adminflag) SortIPLog [namespace current]::IPlog_sort
  100.     bind msg $aawi(adminflag) RepairIPLog [namespace current]::Repair_IPLog
  101.     bind msg $aawi(adminflag) GetIPLogs [namespace current]::FTPDnLd
  102.     bind msg $aawi(adminflag) ImpIPLogs [namespace current]::ImportIPLogs
  103.     bind msg $aawi(adminflag) EditIPLog [namespace current]::edit_Collection
  104.     bind msg $aawi(adminflag) EditIPArchive [namespace current]::edit_archive
  105.     bind msg $aawi(adminflag) CodeAAWI [namespace current]::komodo_aawhois
  106.  
  107.     bind time - $aawi(FTPTimeMask) [namespace current]::autoFTPDnLd
  108.     bind time - $aawi(ImportTimeMaks) [namespace current]::autoImportIPLogs
  109.     bind evnt -|- prerehash [namespace current]::aaRehash_Clean
  110.  
  111.     proc aaRehash_Clean {Text} {
  112.         # [11:24:57] Tcl error [aaRehash_Clean]: can't read "aawi(userflag)": no such variable
  113.         variable aawi
  114.         catch {unbind msg $aawi(userflag) aaWhoIs [namespace current]::aaWI_search}
  115.         catch {unbind msg $aawi(userflag) ip2name [namespace current]::IP2Name_search}
  116.         catch {unbind msg $aawi(userflag) aaAdd [namespace current]::Add_Record}
  117.         catch {unbind msg $aawi(userflag) aaDelete [namespace current]::Delete_Record}
  118.         catch {unbind msg $aawi(userflag) WhyDel [namespace current]::Why_Delete}
  119.         catch {unbind msg $aawi(userflag) IPLogHelp [namespace current]::cmd_Help}
  120.         catch {unbind msg $aawi(adminflag) SortIPLog [namespace current]::IPlog_sort}
  121.         catch {unbind msg $aawi(adminflag) RepairIPLog [namespace current]::Repair_IPLog}
  122.         catch {unbind msg $aawi(adminflag) GetIPLogs [namespace current]::FTPDnLd}
  123.         catch {unbind msg $aawi(adminflag) ImpIPLogs [namespace current]::ImportIPLogs}
  124.         catch {unbind msg $aawi(adminflag) EditIPLog [namespace current]::edit_Collection}
  125.         catch {unbind msg $aawi(adminflag) EditIPArchive [namespace current]::edit_archive}
  126.         catch {unbind msg $aawi(adminflag) CodeAAWI [namespace current]::komodo_aawhois}
  127.  
  128.         catch {unbind time - $aawi(FTPTimeMask) [namespace current]::autoFTPDnLd}
  129.         catch {unbind time - $aawi(ImportTimeMaks) [namespace current]::autoImportIPLogs}
  130.         catch {unbind evnt -|- prerehash [namespace current]::aaRehash_Clean}
  131.     }
  132.  
  133.     #.................Initialization..................
  134.     # source $env(HOME)/eggdrop/scripts/saitools.tcl
  135.     package require ftp
  136.     set aawi(DeleteReason) ""
  137.     putlog "aaWhoIs TCL version $aawi(version) by SubstreamAI"
  138.  
  139.     # =============================================================================
  140.     #.................Function Procs..................
  141.     #..................Filter Procs...................
  142.     # Remove the ^# color codes
  143.     proc StripColorCodes {Data} {
  144.         regsub -all {\^[[:graph:]]{1}} $Data "" Data
  145.         return $Data
  146.     }
  147.  
  148.     # Remove the ^# color codes and various clan tag braces { } [ ]
  149.     proc subst_spec_chars {Text} {
  150.         set Text "[[namespace current]::StripColorCodes $Text]"
  151.         set Text [string map {\{ ? \} ? \[ ? \] ? \\ ?} $Text]
  152.         return $Text
  153.     }
  154.  
  155.     # Removes invalid lines from the search results
  156.     proc CleanLogs {cleanfilelines} {
  157.         logmsg ""
  158.         set NewFileLines [list]
  159.         # Eliminate lines without IP and PlayerName info
  160.         foreach Element $cleanfilelines {
  161.             # Each valid line should have a colon between the IP and port, and a # > 0 in the 3rd field
  162.             if {[string match "*:*" $Element] != 0 && [lindex [split $Element "\t"] 2] != 0} {
  163.                 # The 4th field contains the player name, so eleminate lines with no name
  164.                 if {[llength [split $Element "\t"]] >= 4} {
  165.                     set PlayerName [join [lrange [split $Element "\t"] 3 end]]
  166.                     # The first element after splitting will be IP:Port so...
  167.                     set IP_Addr [lindex [split $Element "\t"] 0]
  168.                     # ... lose the port#
  169.                     set IP_Addr [lindex [split $IP_Addr ":"] 0]
  170.                     # Sometimes 2 lines will end up on 1.  If there is an IP in the player name, skip it
  171.                     if {[string match "*$IP_Addr*" $PlayerName] == 0} {
  172.                         set newLine "$IP_Addr $PlayerName"
  173.                         lappend NewFileLines $newLine
  174.                     }
  175.                 }
  176.             }
  177.         }
  178.         return [lsort -unique $NewFileLines]
  179.     }
  180.  
  181.     #.................Function Procs..................
  182.     # separate option switches, prevent injection
  183.     proc parse_search_string {text} {
  184.         variable aawi
  185.         #Process option switches
  186.         set switch1 [string tolower [lindex [split $text] 0]]
  187.         set switch2 [string tolower [lindex [split $text] 1]]
  188.         # check for /l# to change return lines limit set in configuration secion
  189.         if {[string match "/l*" $switch1] || [string match "/l*" $switch2]} {
  190.             if {[string match "/l*" $switch1]} {
  191.                 set limitswitch $switch1
  192.             } else {
  193.                 set limitswitch $switch2
  194.             }
  195.             # strip the /l (want only the integer)
  196.             regsub -all "/l" $limitswitch "" limitswitch
  197.             #        set limitswitch [string map {"/l" ""} $limitswitch]
  198.             if {[string is integer -strict $limitswitch]} {
  199.                 set aawi(limit) $limitswitch
  200.                 set firstchar [expr {[string first /l $text] + 2}]
  201.                 set lastchar [expr {[string first " " $text $firstchar] - 1}]
  202.                 # remove the entire switch from our search string
  203.                 regsub -all "/l${aawi(limit)} " $text "" text
  204.                 regsub -all "/L${aawi(limit)} " $text "" text
  205.             }
  206.         }
  207.         # prevent sneaking in extra shell commands (e.g. !aaWhoIs test; rm -rf *)
  208.         regsub -all ";" $text "\." text
  209.         return [string trim $text]
  210.     }
  211.  
  212.     # Extracts the player name from a log record
  213.     proc ExtractPlayerName {DataLine Method} {
  214.         # Method: s = short (truncate name after 8 chars) l = long (full)
  215.         set Method [string tolower $Method]
  216.         set PlayerName [join [lrange [split $DataLine] 1 end]]
  217.         if {$Method == "s"} {
  218.             set PlayerName [string range $PlayerName 0 7]
  219.         }
  220.         return $PlayerName
  221.         #    set name [string range $DataLine [expr {$i + 1}] [expr {$i + 8}]]
  222.     }
  223.  
  224.     # Extracts the player IP from a log record
  225.     proc ExtractIP {DataLine Method} {
  226.         # Method: s = short (tuncate last octet, d = dynamic (change last octet to 0, l = long (full)
  227.         set Method [string tolower $Method]
  228.         set IP [lindex [split $DataLine] 0]
  229.         # In case this proc is used for the old line format "port:IP Player Name"
  230.         if {[string match ":" $IP]} {
  231.             set IP  [lindex [split $IP ":"] 1 end]
  232.         }
  233.         if {$Method == "s"} {
  234.             set IP [string range $IP 0 [string last . $IP]]
  235.         }
  236.         if {$Method == "d" } {
  237.             set IP [string range $IP 0 [string last . $IP]]
  238.             set IP [concat $IP "0"]
  239.         }
  240.         return $IP
  241.     }
  242.  
  243.     # Extracts the Index Number from a log record
  244.     proc ExtractIndex {DataLine} {
  245.         # Remove the Player Name
  246.         if {[string first ":" $DataLine] == -1} {
  247.             logmsg "No index found in $DataLine"
  248.             return -1
  249.         }
  250.         return [lindex [split $DataLine ":"] 0]
  251.     }
  252.  
  253.     #................Subroutine Procs.................
  254.     # Build list of names, and another list of IPs from the names, then combine them
  255.     proc SearchIPCollection {SearchList} {
  256.         variable aawi
  257.         global lastbind
  258.         set NamesFound [list "0.0.0.0 Names added for: $SearchList"]
  259.         # 2nd list to output with text format codes
  260.         set PrintNames [list "0.0.0.0 Names added for: $SearchList"]
  261.         set IPsFound [list "0.0.0.0 More names from the above IPs"]
  262.         # 2nd list to output with text format codes
  263.         set PrintIPs [list "0.0.0.0 More names from the above IPs"]
  264.         # Add heading records to search exclusions
  265.         lappend aawi(ExclusionList) "Names added for: [join $SearchList]"
  266.         lappend aawi(ExclusionList) "More names from the above IPs"
  267.         # The IPExclusionList will grow to prevent duplicates
  268.         set IPExclusionList [list "192.168.101."]
  269.         # SearchList will be names for aaWhoIs and IPs for IP2Name
  270.         foreach SearchString $SearchList {
  271.             if {[string trim $SearchString] != "" && [string length $SearchString] > 3} {
  272.                 logmsg $SearchString
  273.                 set NewHits [lsearch -glob -all -inline -nocase $aawi(IPCollection) "*$SearchString*"]
  274.                 # Format the SearchString in the output (substituted later)
  275.                 set CodedString [formattext bold "$SearchString"]
  276.                 # Remove elements with excluded IPs.
  277.                 foreach Element $NewHits {
  278.                     set IPString [[namespace current]::ExtractIP $Element s]
  279.                     # No duplicates from cummulative results
  280.                     if {[lsearch $IPExclusionList $IPString] == -1 && [lsearch $aawi(SearchResults) $Element] == -1} {
  281.                         # No duplicates from current results
  282.                         if {[lsearch $NamesFound $Element] == -1 && [lsearch $IPsFound $Element] == -1} {
  283.                             lappend NamesFound $Element
  284.                             # Seconds list with the formated output text
  285.                             lappend PrintNames [[namespace current]::substring $CodedString $SearchString $Element]
  286.                         }
  287.                     }
  288.                 }
  289.             }
  290.             # for IP2Name, all we need is a few names, no need to continue to deeper IP searches
  291.             if {[string tolower $lastbind] == "ip2name"} {break}
  292.             # Build list of unique IPs found for the current SearchString
  293.             set IPList [list]
  294.             foreach Element $NamesFound {
  295.                 set IPString [[namespace current]::ExtractIP $Element s]
  296.                 # If its not blank and not excluded, add it and exclude it from further searches
  297.                 if {$IPString != "" && [lsearch $IPExclusionList $IPString] == -1} {
  298.                     lappend IPList $IPString
  299.                     lappend IPExclusionList $IPString
  300.                 }
  301.             }
  302.             # Search for the IPs
  303.             foreach IPString $IPList {
  304.                 set NewHits [lsearch -glob -all -inline -nocase $aawi(IPCollection) "*$IPString*"]
  305.                 # Format the SearchString in the output (substituted later)
  306.                 set CodedString [formattext bold "$IPString"]
  307.                 foreach Hit $NewHits {
  308.                     # No duplicates from cummulative results
  309.                     if {[lsearch $aawi(SearchResults) $Hit] == -1} {
  310.                         # No duplicates from current results
  311.                         if {[lsearch $NamesFound $Hit] == -1 && [lsearch $IPsFound $Hit] == -1} {
  312.                             lappend IPsFound $Hit
  313.                             # Seconds list with the formated output text
  314.                             lappend PrintIPs [[namespace current]::substring $CodedString $IPString $Hit]
  315.                         }
  316.                     }
  317.                 }
  318.             }
  319.         }
  320.         set HitsFound [list]
  321.         if {[llength $NamesFound] > 1} {
  322.             lappend HitsFound {*}$NamesFound
  323.             # Seconds list with the formated output text
  324.             lappend aawi(Results2Print) {*}$PrintNames
  325.             if {[llength $IPsFound] > 1} {
  326.                 lappend HitsFound {*}$IPsFound
  327.                 # Seconds list with the formated output text
  328.                 lappend aawi(Results2Print) {*}$PrintIPs
  329.             }
  330.         }
  331.         return $HitsFound
  332.     }
  333.  
  334.     proc BuildNameList {} {
  335.         variable aawi
  336.         set NameList [list]
  337.         foreach Element $aawi(SearchResults) {
  338.             set Name [[namespace current]::ExtractPlayerName $Element l]
  339.             if {$Element == ""} {
  340.                 set aawi(SearchResults) [ldelete $aawi(SearchResults) $Element]
  341.             }
  342.             if {[lsearch -nocase $aawi(ExclusionList) $Name] == -1} {
  343.                 # Check duplicates, i.e. -unique
  344.                 if {[lsearch $NameList $Name] == -1} {
  345.                     lappend NameList $Name
  346.                 }
  347.             }
  348.         }
  349.         return $NameList
  350.     }
  351.  
  352.     proc print_hitlist {search results nick} {
  353.         variable aawi
  354.         global lastbind
  355.         logcmdproc
  356.         set number 0
  357.         set TtlResults [llength $results]
  358.         set HeadingCount [llength [lsearch -all $aawi(SearchResults) "0.0.0.0 *"]]
  359.         say medium $nick "There are [expr {$TtlResults - $HeadingCount}] matches for \002$search\002"
  360.         if {$TtlResults > $aawi(limit)} {
  361.             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"
  362.         }
  363.         foreach line $results {
  364.             if {[lindex $line 0] == "0.0.0.0"} {
  365.                 say medium $nick [formattext bold $line]
  366.             } else {
  367.                 say medium $nick $line
  368.             }
  369.             # Don't count the header line
  370.             if {[[namespace current]::ExtractIP $line l] != "0.0.0.0"} {
  371.                 set number [expr {$number + 1}]
  372.                 if {$number == $aawi(limit)} {
  373.                     break
  374.                 }
  375.             }
  376.         }
  377.         say medium $nick "End of list"
  378.         return 1
  379.     }
  380.  
  381.     # Retrieves the server logs via FTP
  382.     proc FTPDownload {nick rest} {
  383.         variable aawi
  384.         global errorInfo lastbind
  385.         set TempLogFile TmpSrvConsole.tmp
  386.         set ServerList [file2list "$aawi(WorkingDir)/DO_ServerList.lst"]
  387.         putquick "PRIVMSG $nick :Importing Server IP Logs via FTP"
  388.         foreach svString $ServerList {
  389.             if {$svString == ""} {continue}
  390.             set ServerName [lindex [split $svString " "] 0]
  391.             set Server     [lindex [split $svString " "] 1]
  392.             set svPort     [lindex [split $svString " "] 2]
  393.             set svPW       [lindex [split $svString " "] 3]
  394.             set UserName   [lindex [split $svString " "] 4]
  395.             set FTP_PW     [lindex [split $svString " "] 5]
  396.             set Location   [join [lrange [split $svString " "] 6 end]]
  397.             putcmdlog "Attempting FTP Download for $Location Logs"
  398.             if {[catch {ftp::Open $Server $UserName $FTP_PW -port 21 -mode passive} Session]} {
  399.                 logmsg "Connection failed: $ServerName $Location: $Session"
  400.                 say med $nick "$ServerName $Location Connection Refused"
  401.                 ftp::Close $Session
  402.                 continue
  403.             }
  404.             if {[ftp::Cd $Session "/alienarena/arena/"] == 0} {
  405.                 say medium $nick "$ServerName $Location: Unable to change directories"
  406.                 logmsg "$ServerName $Location Unable to change directories: $errorInfo"
  407.                 continue
  408.             }
  409.             ::sai_rcon::tcl_rcon $Server $svPort $svPW "logname $TempLogFile"
  410.             set DnLdList [ftp::NList $Session "*.log"]
  411.             ftp::Type $Session binary
  412.             foreach LogFile $DnLdList {
  413.                 set LocalFile $aawi(svLogDLPath)/[string map {".log" ""} $LogFile]
  414.                 set LocalFile ${LocalFile}_[string map {", " "_"} $Location][clock format [clock seconds] -format {%Y%m%d}]
  415.                 set LocalFile [string map {" " "_" "-" ""} $LocalFile].log
  416.                 # Rename if exists to prevent overwriting
  417.                 if {[file exists $LocalFile] == 1} {
  418.                     set Count 0
  419.                     while {[file exists $LocalFile] == 1 && $Count < 10} {
  420.                         set Count [expr {$Count + 1}]
  421.                         set LocalFile [string map {".log" ""} $LocalFile]x.log
  422.                     }
  423.                     if {$Count >= 10} {
  424.                         say medium $nick "Delete the old logs first, $Count duplicate filenames"
  425.                         logmsg "Transfer Aborted after $Count duplicate filenames"
  426.                         ftp::Close $Session
  427.                         break
  428.                     }
  429.                     logmsg "Conflict, file renamed: $LocalFile"
  430.                 }
  431.                 if {[ftp::Get $Session $LogFile $LocalFile] == 0} {
  432.                     say fast $nick "$ServerName $Location: Transfer  $LogFile failed"
  433.                     logmsg "Get $LogFile from $ServerName $Location failed: $errorInfo"
  434.                 } else {
  435.                     say fast $nick "$ServerName $Location: Transfer  $LogFile successful"
  436.                     if {[ftp::Delete $Session $LogFile] != 1} {
  437.                         say fast $nick "Failed to delete $LogFile from server $ServerName!"
  438.                         logmsg "Delete $LogFile from $ServerName $Location Failed: $errorInfo"
  439.                     }
  440.                 }
  441.             }
  442.             ::sai_rcon::tcl_rcon $Server $svPort $svPW "exec LogName.cfg"
  443.             ftp::Delete $Session $TempLogFile
  444.             ftp::Close $Session
  445.         }
  446.     }
  447.  
  448.     # Imports recently DLed server logs to the log collection file and sorts it
  449.     proc ImportLogFiles {nick rest} {
  450.         variable aawi
  451.         set NewLogs [list]
  452.         set LogsAdded [list]
  453.         set aawi(IPCollection) [file2list $aawi(DataFile)]
  454.         say medium $nick "Adding downloaded files to IP Collection..."
  455.         # Remove any duplicates
  456.         if {[lsearch $aawi(IPCollection) ""] != -1} {
  457.             set aawi(IPCollection) [ldelete $aawi(IPCollection) ""]
  458.         }
  459.         # load the logfile names
  460.         set globFileList [glob -nocomplain -directory $aawi(svLogDLPath)/ -- "IP_*.log"]
  461.         if {$globFileList == ""} {
  462.             say medium $nick "No log files found in $aawi(svLogDLPath)"
  463.             return -1
  464.         }
  465.         # Load the files to a list
  466.         foreach LogFile $globFileList {
  467.             lappend NewLogs {*}[file2list $LogFile]
  468.             lappend LogsAdded [string trimleft $LogFile $aawi(svLogDLPath)/]
  469.         }
  470.         set NewLogs [[namespace current]::CleanLogs $NewLogs]
  471.         set aawi(IPCollection) [lsort -unique [list {*}$aawi(IPCollection) {*}$NewLogs]]
  472.         # make a backup of the IP Collection before updating it
  473.         file copy -force $aawi(DataFile) $aawi(DataFileBU)
  474.         list2file $aawi(IPCollection) "$aawi(DataFile)" w
  475.         say medium $nick "Files added to collection: $LogsAdded"
  476.         #   if {[file exists $aawi(log_tarball)] == 1} {
  477.         #       eval exec tar -rvzf $aawi(log_tarball) ${aawi(svLogDLPath)}/IP_*.log
  478.         #   } else {
  479.         #       eval exec tar -cvzf $aawi(log_tarball) ${aawi(svLogDLPath)}/IP_*.log
  480.         #   }
  481.         # move the files to the trash
  482.         #file rename -force -- ${aawi(svLogDLPath)}/IP_*.log /home/rigel/.local/share/Trash
  483.         eval exec trash-put [glob ${aawi(svLogDLPath)}/IP_*.log]
  484.         return 1
  485.     }
  486.  
  487.     # Substitus one string for another within a string (Non-Case Sensitve)
  488.     proc substring {NewStr OldStr Source} {
  489.         if {[string match -nocase *$OldStr* $Source] == 0} {
  490.             logmsg "String \"$OldStr\" not found in source \"$Source\""
  491.             return "-1"
  492.         }
  493.         set start [string first [string tolower $OldStr] [string tolower $Source]]
  494.         set end [expr {$start + [string length $OldStr] - 1}]
  495.         if {$NewStr == ""} {return [string replace $Source $start $end]}
  496.         return [string replace $Source $start $end $NewStr]
  497.     }
  498.  
  499.     #..............Channel Command Procs..............
  500.     # Searches the IP Log for a player name
  501.     proc aaWI_search {nick host hand rest} {
  502.         variable aawi
  503.         logcmdproc
  504.         set aawi(limit) $aawi(NameLimit)
  505.         if {$rest == ""} {
  506.             say medium $nick "Searching requires a name to search for..."
  507.             break
  508.         }
  509.         set rest [[namespace current]::parse_search_string $rest]
  510.         set rest [[namespace current]::subst_spec_chars $rest]
  511.         # Make the search string a tcl list (expected by [namespace current]::SearchIPCollection)
  512.         set NameSearch [split $rest "\n"]
  513.         set aawi(IPCollection) [split [[namespace current]::subst_spec_chars [join [file2list $aawi(DataFile)] "~"]] "~"]
  514.         set aawi(ExclusionList) [file2list $aawi(ExclusionFile)]
  515.         set NameHitsLast 1
  516.         set NameHits 0
  517.         set HeadingCount 1
  518.         set HitPasses 0
  519.         # Verify the validity of the search first
  520.         if {[lsearch -nocase $aawi(IPCollection) "*$NameSearch*"] == -1} {
  521.             say medium $nick "No Matches Found: $NameSearch"
  522.             return
  523.         }
  524.         # Reset the list for a new search
  525.         set aawi(SearchResults) [list]
  526.         # Seconds list with the formated output text
  527.         set aawi(Results2Print) [list]
  528.         while {$HitPasses < $aawi(RecurLimit)} {
  529.             set HitPasses [expr {$HitPasses + 1}]
  530.             logmsg "Building hitlist, pass $HitPasses"
  531.             say fast $nick "Searching database for $NameHitsLast name(s) and IPs (Pass $HitPasses)"
  532.             set aawi(SearchResults) [list {*}$aawi(SearchResults) {*}[[namespace current]::SearchIPCollection $NameSearch]]
  533.             # Seconds list with the formated output text
  534.             set aawi(Results2Print) [list {*}$aawi(Results2Print) {*}[[namespace current]::SearchIPCollection $NameSearch]]
  535.             set HeadingCount [llength [lsearch -all $aawi(SearchResults) "0.0.0.0 *"]]
  536.             set NameHits [expr {[llength $aawi(SearchResults)] - $HeadingCount}]
  537.             if {$NameHits > 50} {
  538.                 logmsg "Search process ABORTED after $NameHits hits over $HitPasses passes."
  539.                 say medium $nick "Search process ABORTED after $NameHits hits over $HitPasses passes."
  540.                 break
  541.             }
  542.             say fast $nick "[expr {$NameHits - $NameHitsLast}] additional names found..."
  543.             if {$NameHits <= $NameHitsLast} {
  544.                 break
  545.             }
  546.             set NameHitsLast $NameHits
  547.             set NameSearch [namespace current]::BuildNameList
  548.         }
  549.         say fast $nick "End of search process, now printing results..."
  550.         #    [namespace current]::print_hitlist $rest $aawi(SearchResults) $nick  <== Would print bare (unformated) text
  551.         [namespace current]::print_hitlist $rest $aawi(Results2Print) $nick
  552.         endcmdproc ""
  553.         return
  554.     }
  555.  
  556.     # Searches the IP Log for an IP
  557.     proc IP2Name_search {nick host hand rest} {
  558.         variable aawi
  559.         logcmdproc
  560.         set aawi(IPCollection) [file2list $aawi(DataFile)]
  561.         set aawi(limit) $aawi(IPLimit)
  562.         if {$rest == ""} {
  563.             putserv "PRIVMSG $nick :Searching requires a name to search for..."
  564.             break
  565.         }
  566.         set rest [[namespace current]::parse_search_string $rest]
  567.         set rest [[namespace current]::subst_spec_chars $rest]
  568.         # use only the first 3 octets (plus the last dot) for the search
  569.         if {[llength [split $rest "."]] > 3} {
  570.             set rest "[join [lrange [split $rest "."] 0 2] "."]."
  571.         }
  572.         # Make the search string a tcl list (expected by [namespace current]::SearchIPCollection)
  573.         set IPSearch [split $rest "\n"]
  574.         putcmdlog "IP2Name: Building hitlist"
  575.         putquick "PRIVMSG $nick :Searching database for $IPSearch\*"
  576.         # Reset the list for a new search
  577.         set aawi(SearchResults) [list]
  578.         set aawi(SearchResults) [[namespace current]::SearchIPCollection $IPSearch]
  579.         if {[llength $aawi(SearchResults)] == 0} {
  580.             putserv "PRIVMSG $nick :No Matches Found: $rest"
  581.             return
  582.         }
  583.         [namespace current]::print_hitlist "$rest" $aawi(SearchResults) $nick
  584.         endcmdproc ""
  585.         return
  586.     }
  587.  
  588.     # Time bind: downloads the logs via FTP
  589.     proc autoFTPDnLd {Min Hour Day Month Year} {
  590.         variable aawi
  591.         global botnick
  592.         logmsg "[timestamp]"
  593.         if {[onchan $aawi(AdminNick)]} {
  594.             set nick $aawi(AdminNick)
  595.         } else {
  596.             set nick $botnick
  597.         }
  598.         [namespace current]::FTPDownload $nick "autoTime"
  599.         endproc
  600.     }
  601.  
  602.     # Msg bind: downloads the logs via FTP
  603.     proc FTPDnLd {nick host hand rest} {
  604.         variable aawi
  605.         logcmdproc
  606.         [namespace current]::FTPDownload $nick "ManualCall"
  607.         endcmdproc ""
  608.     }
  609.  
  610.     # Time bind: cleans, formats, and adds log to the IP Collection
  611.     proc autoImportIPLogs {Min Hour Day Month Year} {
  612.         variable aawi
  613.         global botnick
  614.         logmsg "[timestamp]"
  615.         if {[onchan $aawi(AdminNick)]} {
  616.             set nick $aawi(AdminNick)
  617.         } else {
  618.             set nick $botnick
  619.         }
  620.         [namespace current]::ImportLogFiles $nick "autoTime"
  621.         endproc
  622.     }
  623.  
  624.     # Msg bind: cleans, formats, and adds log to the IP Collection
  625.     proc ImportIPLogs {nick host hand rest} {
  626.         variable aawi
  627.         logcmdproc
  628.         [namespace current]::ImportLogFiles $nick "ManualCall"
  629.         endcmdproc ""
  630.     }
  631.  
  632.     # Sorts IP_Collection.log and eliminates duplicates
  633.     proc IPlog_sort {nick host hand rest} {
  634.         variable aawi
  635.         logcmdproc
  636.         putserv "PRIVMSG $nick :Sorting IP Log..."
  637.         SortFile $aawi(DataFile) $aawi(DataFileBU)
  638.         endcmdproc ""
  639.         return
  640.     }
  641.  
  642.     # Repair corrupted lines in the Log file.  Deletes blanks, removes multiple IP's, converts dynamic IP from #.#.#.* to #.#.#.0
  643.     proc Repair_IPLog {nick host hand rest} {
  644.         global lastbind aawi
  645.         logcmdproc
  646.         putquick "PRIVMSG $nick :Reparing the IP Collection Log"
  647.         lappend RepairedLines "The following lines will be added to $aawi(WorkingDir)/AAWhoIs_Archived_Records.lst"
  648.         set aawi(IPCollection) [file2list $aawi(DataFile)]
  649.         # Remove blank lines
  650.         foreach Line $aawi(IPCollection) {
  651.             if {$Line == ""} {
  652.                 set aawi(IPCollection) [ldelete $aawi(IPCollection) ""]
  653.             }
  654.         }
  655.         # Find multiple IPs and dyanamic IPs using #.#.#.*
  656.         foreach Line $aawi(IPCollection) {
  657.             set IP_Addr [[namespace current]::ExtractIP $Line l]
  658.             set PlayerName [[namespace current]::ExtractPlayerName $Line l]
  659.             # Fix dyanamic IPs using #.#.#.* to use #.#.#.0 instead
  660.             if {[lindex [split $IP_Addr "."] 3] == "\*"} {
  661.                 set IP_Addr [string map {"\.\*" ".0"} $IP_Addr]
  662.                 set Indx [lsearch $aawi(IPCollection) $Line]
  663.                 set NewLine "$IP_Addr $PlayerName"
  664.                 set aawi(IPCollection) [lreplace $aawi(IPCollection) $Indx $Indx $NewLine]
  665.                 lappend RepairedLines "[timestamp] $nick $lastbind: $Line ==> $NewLine"
  666.                 unset Indx
  667.             }
  668.             # Fix multiple IPs in line
  669.             set IP_Addr "[lindex [split $IP_Addr "."] 2]."
  670.             if {[lsearch [split $PlayerName] "$IP_Addr*"] != -1} {
  671.                 # Strip the IP(s) from the name
  672.                 while {[lsearch [split $PlayerName] "$IP_Addr*"] != -1} {
  673.                     set IP_Addr [lindex [split $PlayerName] 0]
  674.                     set PlayerName [lindex [split $PlayerName] 1]
  675.                 }
  676.                 # Update the list
  677.                 set NewLine "$IP_Addr $PlayerName"
  678.                 set ReplaceIndices [lsearch -all -exact $aawi(IPCollection) $Line]
  679.                 foreach Indx $ReplaceIndices {
  680.                     set aawi(IPCollection) [lreplace $aawi(IPCollection) $Indx $Indx $NewLine]
  681.                     lappend RepairedLines "[timestamp] $nick $lastbind: $Line ==> $NewLine"
  682.                 }
  683.             }
  684.         }
  685.         #    viewlist $RepairedLines
  686.         list2file $RepairedLines "$aawi(WorkingDir)/AAWhoIs_Archived_Records.lst" a
  687.         list2file $aawi(IPCollection) $aawi(DataFile) w
  688.         #    list2file [lsort $aawi(IPCollection)] $aawi(DataFile) w
  689.         endcmdproc "[expr {[llength $RepairedLines] - 1}] records changed"
  690.         return
  691.     }
  692.  
  693.     # Manually add a record to the IP Collection
  694.     proc Add_Record {nick host hand AddMe} {
  695.         variable aawi
  696.         global lastbind
  697.         logcmdproc
  698.         set aawi(IPCollection) [file2list $aawi(DataFile)]
  699.         lappend aawi(IPCollection) $AddMe
  700.         set aawi(IPCollection) [lsort -unique $aawi(IPCollection)]
  701.         # Save updated data
  702.         if {![list2file $aawi(IPCollection) $aawi(DataFile) a]} {
  703.             putserv "PRIVMSG $nick : Unable to save updated IP Collection"
  704.             logmsg "Unable to save appended $aawi(DataFile)"
  705.             return -1
  706.         }
  707.         endcmdproc ""
  708.         return 1
  709.     }
  710.  
  711.     # Record a reason for deleting a record
  712.     proc Why_Delete {nick host hand DelReason} {
  713.         global lastbind aawi
  714.         logcmdproc
  715.         set expireTime 30
  716.         set aawi(DeleteReason) $DelReason
  717.         endcmdproc "expires in $expireTime seconds"
  718.         # reset the var after it expires
  719.         utimer $expireTime [list set $aawi(DeleteReason) ""]
  720.     }
  721.  
  722.     # Delete a record from the IP Collection
  723.     proc Delete_Record {nick host hand DeleteMe} {
  724.         variable aawi
  725.         global lastbind
  726.         logcmdproc
  727.         if {$aawi(DeleteReason) == ""} {
  728.             putserv "PRIVMSG $nick : Please first enter a reason for the deletion; sample /msg Neblet WhyDel Record was corrupt)"
  729.             return -1
  730.         }
  731.         # Verify $DeleteMe is in the IP Collection Database
  732.         set aawi(IPCollection) [file2list $aawi(DataFile)]
  733.         set DeleteMe [lsearch -exact -inline $aawi(IPCollection) $DeleteMe]
  734.         if {$DeleteMe == []} {
  735.             putserv "PRIVMSG $nick : Not found in the IP Collection Database: $DeleteMe"
  736.             return -1
  737.         }
  738.         # Set log line as list (needed by list2file) so it can be saved
  739.         lappend DeleteList "[timestamp] $nick $lastbind $DeleteMe - Reason: $aawi(DeleteReason)"
  740.         # Save DeleteList first and if it fails, abort
  741.         if {[list2file $DeleteList "$aawi(WorkingDir)/AAWhoIs_Archived_Records.lst" a] != 1} {
  742.             putserv "PRIVMSG $nick : Unable to delete $DeleteMe - cannot create archive"
  743.             logmsg "Failed to create archive - nothing deleted!"
  744.             return -1
  745.         }
  746.         # Delete the record from the list and save it
  747.         set aawi(IPCollection) [ldelete $aawi(IPCollection) $DeleteMe]
  748.         # If list2file fails, abort
  749.         if {[list2file $aawi(IPCollection) $aawi(DataFile) w] == -1} {
  750.             putserv "PRIVMSG $nick : Failed to update IP Collection Database!"
  751.             logmasg "Failed to save updated IP Collection!"
  752.             return -1
  753.         }
  754.         set aawi(DeleteReason) ""
  755.         endcmdproc ""
  756.         return
  757.     }
  758.  
  759.     # Edit the IP Collection File
  760.     proc edit_Collection {nick host hand rest} {
  761.         variable aawi
  762.         putquick "PRIVMSG $nick :Editing IP Collection with gedit"
  763.         logcmdproc
  764.         exec -- gedit $aawi(DataFile)
  765.         endcmdproc ""
  766.         return
  767.     }
  768.  
  769.     # Edit the IP Archive File
  770.     proc edit_archive {nick host hand rest} {
  771.         variable aawi
  772.         putquick "PRIVMSG $nick :Editing IP Collection with gedit"
  773.         logcmdproc
  774.         exec -- gedit "$aawi(WorkingDir)/AAWhoIs_Archived_Records.lst"
  775.         endcmdproc ""
  776.         return
  777.     }
  778.  
  779.     # Edit this script with Komodo
  780.     proc komodo_aawhois {nick host hand rest} {
  781.         variable aawi
  782.         global env
  783.         putquick "PRIVMSG $nick :Loading aawhois.tcl in Komodo"
  784.         logcmdproc
  785.         exec -- $env(HOME)/Komodo-Edit-6/lib/mozilla/komodo $env(HOME)/eggdrop/scripts/aawhois.tcl
  786.         endcmdproc ""
  787.         return
  788.     }
  789.  
  790.     # IP Collection Log Maintenance Command list for bot owner
  791.     proc cmd_Help {nick host hand rest} {
  792.         logcmdproc
  793.         say cmd $nick "IP Collection Log User commands are: aaWhoIS, IP2Name, aaAdd, WhyDel, aaDelete, IPLogHelp"
  794.         say cmd $nick "IP Collection Log Admin commands are: SortIPLog, GetIPLogs, RepairIPLog, GetIPLog, ImpIPLogs, EditIPLog, EditIPArchive, CodeAAWI"
  795.         endcmdproc ""
  796.         return
  797.     }
  798.  
  799. }
Add Comment
Please, Sign In to add comment