egghelp.org community Forum Index
[ egghelp.org home | forum home ]
egghelp.org community
Discussion of eggdrop bots, shell accounts and tcl scripts.
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Idle Whois

 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Script Requests
View previous topic :: View next topic  
Author Message
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Sat Apr 02, 2016 1:48 pm    Post subject: Idle Whois Reply with quote

There is an idle tcl that kick / ban you taking the time to whois?
I do not find a tcl that every 10/15 minutes to do a whois to the user and if exceeds 90 minutes of inactivity in the public and private give the kick/ban.
I look for an antidle that makes a Whois to the user verifying how long it really is inactive, many antiidle do not detect that a person can be in PVT. I have no connection problem from multiple servers since certain clients connect only to a server


Last edited by MrBeta on Wed Apr 07, 2021 6:06 am; edited 1 time in total
Back to top
View user's profile Send private message Visit poster's website
simo
Owner


Joined: 22 Mar 2015
Posts: 941

PostPosted: Sun Apr 03, 2016 8:48 am    Post subject: Reply with quote

check the tcl archive i saw several there

http://www.egghelp.org/tclhtml/3478-4-0-0-1-idle.htm
Back to top
View user's profile Send private message
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Sun Apr 03, 2016 2:15 pm    Post subject: Reply with quote

I have search but no one perform a whois for see the real idle time, i don't want kick or ban people to talk in private but only who is inactive.
More tcl work on idle of the user in the public channel because in all irc network with many server is impossible to see the idle time if the user isn't in the same server of the bot.
I search for a tcl that not ban for mistake the user and perform a real user's whois in the same server
Back to top
View user's profile Send private message Visit poster's website
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Sun Apr 03, 2016 3:00 pm    Post subject: Reply with quote

Most, if not all, use the get the idle time from the channel aka getchanidle, but this like you also mentioned doesn't mean that person isn't active in another channel or talks with someone in PM.

Unless the bot has ircop privileges you have no other way but rely on getchanidle and filter out the members that didn't get over the defined limit and whois only those that did.

Will get back to this in the morning with something for you to test. Now going to bed. Rolling Eyes
_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Sun Apr 03, 2016 4:40 pm    Post subject: Reply with quote

Thank you very much caesar Wink
Back to top
View user's profile Send private message Visit poster's website
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Tue Apr 05, 2016 3:27 am    Post subject: Reply with quote

been a bit busy with work yesterday and didn't get to finish the code as I wanted so done it today. Smile
Code:

namespace eval idleBan {

   # Default idle time in minutes
   set idle(idle_default) 30
   
   # Delay in seconds between WHOIS commands so the bot won't flood itself off
   set idle(whois_delay) 3

   # kick reason for beeing idle in the channel
   set idle(reason) "Don't be idle in %channel channel please, %duration minutes ban."
   
   # Ban type: 1 - channel ban, 2 - ban in it's internal bans list (newchanban)
   set idle(ban_type) 1
   
   # Ban lifetime (if above is set to 2) in minutes. If set to 0 will be permanent.
   set idle(ban_lifetime) 60

   # Don't edit past this line unless you know what you are doing!

   setudef flag idleban
   setudef int idletime

   bind cron - {?0*} [namespace current]::idle:cron
   bind raw - 317 [namespace current]::idle:raw
   bind part - * [namespace current]::idle:del
   bind sign - * [namespace current]::idle:del
   bind nick - * [namespace current]::idle:nick
   bind kick - * [namespace current]::idle:kick

   proc idle:cron {min hour day month weekday} {
      variable idle
      foreach channel [channels] {
         if {![channel get $channel idleban]} continue
         if {![botisop $channel]} continue
         set idletime [channel get $channel idletime]
         if {!$idletime} {
            channel set idletime $idle(default)
         }
         set channel [string tolower $channel]
         foreach member [chanlist $channel] {
            if {[isbotnick $member]} continue
            if {[isop $member $channel]} continue
            if {[isvoice $member $channel]} continue
            set handle [nick2hand $member $channel]
            if {[matchattr $handle f|f]} continue
            set chanidle [getchanidle $member $channel]
            if {$chanidle >= $idletime} {
               variable check
               if {![onchan $member $channel]} return
               set pos -1
               if {[info exists check($channel)]} {
                  set pos [idle:pos $member $check($channel)]
               }
               if {$pos == -1} {
                  lappend check($channel) $member
               }
               utimer $idle(whois_delay) [list puthelp "WHOIS $member $member"]
            }
         }
      }
   }

   proc idle:raw {from key text} {
      variable check
      if {![info exists check]} return
      if {[scan [lrange $text 1 2] {%s%d} member seconds] != 2} return
      foreach channel [channels] {
         if {![channel get $channel idleban] || ![botisop $channel]} {
            idle:action channel $channel
            continue
         }
         set idletime [channel get $channel idletime]
         set idle [expr $seconds / 60]
         if {$idle < $idletime} {
            idle:action member $channel $member
         } else {
            idle:punish $channel $member $idle
         }
      }
   }

   proc idle:del {nick uhost hand channel {text ""}} {
      if {[channel get $channel idleban]} {
         if {[isbotnick $nick]} {
            idle:action channel $channel
         } else {
            idle:action member $channel $nick
         }
      }
   }

   proc idle:nick {nick uhost hand channel newnick} {
      if {[isbotnick $nick]} return
      if {[channel get $channel idleban]} {
         idle:action nick $channel $nick $newnick
      }
   }

   proc idle:kick {nick uhost hand channel vict reason} {
      if {[channel get $channel idleban]} {
         if {[isbotnick $vict]} {
            idle:action channel $channel
         } else {
            idle:action member $channel $vict
         }
      }
   }

   proc idle:action {act channel {member ""} {newnick ""}} {
      variable check
      set channel [string tolower $channel]
      if {![info exists check($channel)]} return
      switch -- $act {
         default {
            return
         }
         "member" {
            set pos [idle:pos $member [join $check($channel)]]
            if {$pos != -1} {
               set check($channel) [lreplace $check($channel) $pos $pos]
            }
         }
         "channel" {
            if {[info exists check($channel)]} {
               unset check($channel)
            }
         }
         "nick" {
            set pos [idle:pos $member [join $check($channel)]]
            if {$pos != -1} {
               set check($channel) [lreplace $check($channel) $pos $pos $newnick]
            }
         }
      }
   }

   proc idle:getChannels {member} {
      variable check
      set matched ""
      foreach channel [channels] {
         if {![channel get $channel idleban] || ![botisop $channel]} {
            idle:action channel $channel
            continue
         }
         foreach member [join $check($channel)] {
            if {![onchan $member $channel]} {
               idle:action member $channel $member
            }
            if {[string equal -nocase $nick $member]} {
               lappend matched $channel
            }
         }
      }
      return $matched
   }

   proc idle:punish {channels member idle} {
      variable check
      foreach channel [join $channels] {
         if {![channel get $channel idleban] || ![botisop $channel]} {
            idle:action channel $channel
         } else {
            if {[onchan $member $channel]} {
               scan [getchanhost $member $channel] {%*[^@]@%s} host
               set mask "*!*@$host"
            }
            idle:action member $channel $member
            idle:stack $channel $member $mask
            idle:check $channel
         }
      }
   }

   proc idle:stack {channel member mask} {
      variable kicks
      variable bans
      set channel [string tolower $channel]
      set pos -1
      if {[info exists kicks($channel)]} {
         set pos [idle:pos $member $kicks($channel)]
      }
      if {$pos == -1} {
         lappend kicks($channel) $member
      } else {
         set pos -1
      }
      if {[info exists bans($channel)]} {
         set pos [idle:pos $mask $bans($channel)]
      }
      if {$pos == -1} {
         lappend bans($channel) $mask
      }
   }

   proc idle:pos {needle haystack} {
      set count -1
      set match 0
      foreach element [join $haystack] {
         incr count
         if {[string equal -nocase $needle $element]} {
            set match 1
            break
         }
      }
      return "[expr $match>0?$count:"-1"]"
   }

   proc idle:check {channel} {
      variable check
      if {[info exists check($channel)]} {
         set len [llength [join $check($channel)]]
         if {$len} {
            utimer 3 [list [namespace current]::idle:action check $channel]
         } else {
            if {[botisop $channel]} {
               variable bans
               if {[info exists bans($channel)]} {
                  idle:stackBans $channel $bans($channel)
               }
               unset bans($channel)
               variable kicks
               if {[info exists kicks($channel)]} {
                  idle:stackKicks $channel $kicks($channel)
               }
               unset kicks($channel)
            }
         }
      }
   }

   proc idle:stackBans {channel banlist {max 6}} {
      variable idle
      set len [llength $banlist]
      while {$len > 0} {
         if {$len > $max} {
         set mode [string repeat "b" $max]
         set masks [join [lrange $banlist 0 [expr {$max - 1}]]]
         set banlist [lrange $banlist $max end]
         incr len -$max
         } else {
            set mode [string repeat "b" $len]
            set masks [join $banlist]
            incr len -$len
         }
         pushmode $channel +$mode $masks
         if {$idle(ban_type) == 2} {
            idle:newbans $channel $masks
         }
      }
   }
   
   proc idle:newbans {channel banlist} {
      variable idle
      foreach mask [join $banlist] {
         set reason [string map [list "%channel" "$channel" "%duration" "$idle(ban_lifetime)"] $idle(reason)]
         newchanban $channel $mask "Anti-Idle" $reason $idle(ban_lifetime)
      }
   }

   proc idle:stackKicks {channel kicklist {max 6}} {
      variable idle
      set len [llength $kicklist]
      while {$len > 0} {
         if {$len > $max} {
            set stack [join [lrange $kicklist 0 [expr {$max - 1}]]]
            set kicklist [lrange $kicklist $max end]
         } else {
            set stack [join $kicklist]
            incr len -$len
         }
         set reason [string map [list "%channel" "$channel" "%duration" "$idle(ban_lifetime)"] $idle(reason)]
         putkick [join $stack ","] $reason
      }
   }
}

I did some testings and should do what you want if I got it right.

The bot will do a idle check every 10 minutes and if a member is idle in the channel for more than the specified amount of minutes will do a whois. Depending on how many members had to be whois-ed the bot will wait until the list is empty and then proceed with the punishment.

This works for all channels that are set to +idleban (.chanset #channel +idleban from DCC Chat/Telnet with the bot). Be sure to set the idletime (.chanset #channel idletime <minutes> from DCC Chat/Telnet with the bot) else the default (30 minutes as I left it) will be set and used.

Load this on a test bot and see if things go as planned and reply back if you encounter any problems/issues.

Edit: I used pushmode and putkick that are using slow queues and it's better from my point of view, but I guess you can replace those with a faster queue system if it's badly needed.

I've extended this so much that I didn't think about all the features it should have so right now this misses two features that I'm working on:
- purge bans that are in the idle bans list upon outside ban settings
- purge nicks that are in the idle kicks list upon: nick change, kick, part and quit.

Will update this soon. Smile
_________________
Once the game is over, the king and the pawn go back in the same box.


Last edited by caesar on Wed Apr 06, 2016 8:24 am; edited 1 time in total
Back to top
View user's profile Send private message
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Tue Apr 05, 2016 4:27 am    Post subject: Reply with quote

Great! If I may add another request is to not make whois for op that often are other eggy, exclude the ban and whois for operators, users who has certain flag on the bot
I test it in the evening, again thanks caesar
Back to top
View user's profile Send private message Visit poster's website
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Tue Apr 05, 2016 4:42 am    Post subject: Reply with quote

Right now it will skip a member from idle checking if: has op (@), is voiced (+), or is a valid user having local or global friend (f) flag. Will add more.
_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Wed Apr 06, 2016 7:58 am    Post subject: Reply with quote

[11:53:04] Tcl error [::idleBan::idle:kick]: can't read "channel": no such variable

Don't kick or ban, i have this error message
Back to top
View user's profile Send private message Visit poster's website
caesar
Mint Rubber


Joined: 14 Oct 2001
Posts: 3741
Location: Mint Factory

PostPosted: Wed Apr 06, 2016 8:22 am    Post subject: Reply with quote

Replace:
Code:

proc idle:kick {nick uhost hand chan vict reason} {

with:
Code:

proc idle:kick {nick uhost hand channel vict reason} {

Another busy day at work and didn't get to do much.. Rolling Eyes
_________________
Once the game is over, the king and the pawn go back in the same box.
Back to top
View user's profile Send private message
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Thu Apr 07, 2016 5:54 am    Post subject: Reply with quote

Hello caesar now have not errors but don't ban.
Your work has rightly priority, idleban can wait Wink
Back to top
View user's profile Send private message Visit poster's website
MrBeta
Voice


Joined: 28 Dec 2013
Posts: 35

PostPosted: Wed Apr 07, 2021 2:04 pm    Post subject: Reply with quote

Not developed project but returning useful Sad
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Script Requests All times are GMT - 4 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Forum hosting provided by Reverse.net

Powered by phpBB © 2001, 2005 phpBB Group
subGreen style by ktauber