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.

deop/devoice on idle

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

@speechles : I fail to undestand what error you are pointing in the change I suggested above. Just woke up so go easy on me. :)

No matter what time I would have set to cron bind it simply doesn't appear in .binds command in telnet, at least on my Windrop testing.. :roll: So I thought it's a bug in Windrop or something, thus why I mentioned the above change. Anyway, the {*/10 * * * *} is correct, as in it should trigger the proc every 10 minutes. Sure, "/?0" would have done the same thing.

As for variable assignments I left them there on purpose. I know all about the special meaning args has in TCL. :P

If some other user will have a look on the code will not understand why I did used args when clearly the book stated it has 5 arguments. Anyway...

@Amr : What version of TCL do you have? Do a .status from your bot and it will be mentioned there if you don't know where to look.
Once the game is over, the king and the pawn go back in the same box.
User avatar
Amr
Halfop
Posts: 94
Joined: Fri Sep 14, 2007 7:13 am
Location: Egypt

Post by Amr »

Tcl version: 8.4.13 (header version 8.4.13)
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

caesar wrote:@Amr : What version of TCL do you have? Do a .status from your bot and it will be mentioned there if you don't know where to look.
He has tcl 8.4 and lsearch does not have a -nocase option. The segment below makes it tcl 8.4 friendly. Change:

Code: Select all

      set excempt [channel get $chan idleExempt]
      set time [channel get $chan idleTime]
      foreach user $users {
         if {[lsearch -nocase $excempt $user] != -1} continue
Into...

Code: Select all

      set excempt [string tolower [channel get $chan idleExempt]]
      set time [channel get $chan idleTime]
      foreach user $users {
         if {[lsearch -exact $excempt [string tolower $user]] != -1} continue
User avatar
Amr
Halfop
Posts: 94
Joined: Fri Sep 14, 2007 7:13 am
Location: Egypt

Post by Amr »

we got another one here ;

Code: Select all

               set pos [lsearch -nocase $checkList $user:1]
               if {$pos == -1} {
                  lappend checkList $user:2
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

You only need to alter the "set pos" line, like I've done below:

Code: Select all

set pos [lsearch -exact [string tolower $checkList] [string tolower $user:1]]
I should've looked ahead to see if there were more to change. That looks like the last one. ;)
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

I know speechles, hence I've asked him about the TCL version. :roll:

Anyway, I would rather convert all the lists to lower case from the start by replacing:

Code: Select all

set users [lrange [chanlist $chan] 1 end]
set excempt [channel get $chan idleExempt]
set time [channel get $chan idleTime]
foreach user $users {
if {[lsearch -nocase $excempt $user] != -1} continue
with:

Code: Select all

set users [string tolower [lrange [chanlist $chan] 1 end]]
set excempt [string tolower [channel get $chan idleExempt]]
set time [channel get $chan idleTime]
foreach user $users {
if {[lsearch -exact $excempt $user] != -1} continue
as the string to lower conversion is made only once not repeated in a for loop, and then:

Code: Select all

set pos [lsearch -nocase $checkList $user:1]
with:

Code: Select all

set pos [lsearch -exact $checkList $user:1]
and it should be TCL 8.4 friendly. :)
Once the game is over, the king and the pawn go back in the same box.
User avatar
Amr
Halfop
Posts: 94
Joined: Fri Sep 14, 2007 7:13 am
Location: Egypt

Post by Amr »

okay the whole script is below;

Code: Select all

namespace eval idlemode {
   setudef flag idleMode
   setudef str idleExempt
   setudef int idleTime
bind time - {10*} [namespace current]::idleTime
proc idleTime {args} {
      foreach chan [channels] {
         if {![channel get $chan idleMode]} continue
            cronCheck $chan
      }
   }

   proc cronCheck {chan} {
      variable idle
      switch -- [catch {botisop $chan} err] {
         "0" {
            if {!$err} {
               putlog "idleMode error: I'm not oped in $chan channel."
               return
            }
         }
         "1" {
            putlog "idleMode error: $chan channel is not valid."
            return
         }
      }
      set users [string tolower [lrange [chanlist $chan] 1 end]]
set excempt [string tolower [channel get $chan idleExempt]]
set time [channel get $chan idleTime]
foreach user $users { 
         if {[lsearch -exact $excempt $user] != -1} continue
         if {[isop $user $chan]} {
            lappend checkList $user:1
         }
         if {[isvoice $user $chan]} {
            if {[info exists checkList]} {
               set pos [lsearch -exact $checkList $user:1] 
               if {$pos == -1} {
                  lappend checkList $user:2
               } else {
                  set checkList [lreplace $checkList $pos $pos $user:3]
               }
            } else {
               lappend checkList $user:2
            }
         }
      }
      foreach ele [split $checkList] {
         scan $ele {%[^:]:%s} user count
         checkIdle $count $user $chan $time
      }
   }

   proc checkIdle {mode user chan time} {
      set idle [getchanidle $user $chan]
      if {$idle >= $time} {
         switch -- $mode {
            "1" {
               pushmode $chan -o $user
               putlog "idleMode: deoped $user in $chan cos was idle for $idle minutes"
            }
            "2" {
               pushmode $chan -v $user
               putlog "idleMode: devoiced $user in $chan cos was idle for $idle minutes"
            }
            "3" {
               puthelp "MODE $chan -ov $user $user"
               putlog "idleMode: deoped and devoiced $user in $chan cos was idle for $idle minutes"
            }
         }
      }
   }
}

putlog "idlemode.tcl loaded..."
I got no errors + the bot respond after about 1 hour not 10 mins.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

That's cos of the time bind. Either make it:

Code: Select all

bind time - {*/10 * * * *} [namespace current]::idleTime 
or as speechles suggested:

Code: Select all

bind time - {?0*} [namespace current]::idleTime 
Once the game is over, the king and the pawn go back in the same box.
User avatar
speechles
Revered One
Posts: 1398
Joined: Sat Aug 26, 2006 10:19 pm
Location: emerald triangle, california (coastal redwoods)

Post by speechles »

Code: Select all

bind time - {*/10 * * * *} [namespace current]::idleTime 
This is absolutely wrong. This is cron syntax. The fellow is using tcl 8.4. Cron exists in tcl 8.5. So how will a bind to time interpret the cron syntax? It won't... It will never match so will never get invoked.

http://forum.egghelp.org/viewtopic.php?p=72492
Perhaps you need to read this thread?
User avatar
Amr
Halfop
Posts: 94
Joined: Fri Sep 14, 2007 7:13 am
Location: Egypt

Post by Amr »

another thing , the bot deop/devoice the users which is on the idleExempt + It will deop/devoice the users which their idle less than 60 minutes :/
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Meh, I'll stop replying on forum at late hours as apparently I screw things up. Will try to test the code and return later on.

Edit: Here is the code I've tested and it's working fine. I haven't waited 10 minutes to see if the time bind is called, just forced it to run at my request. How did you add users in the except list? Could you provide an example?

Code: Select all

namespace eval idlemode {

	setudef flag idleMode
	setudef str idleExempt
	setudef int idleTime
	
	bind time {?0 *} [namespace current]::idleTime

	proc idleTime {args} {
		foreach chan [channels] {
			if {![channel get $chan idleMode]} continue
				timedCheck $chan
		}
	}

	proc timedCheck {chan} {
		variable idle
		switch -- [catch {botisop $chan} err] {
			"0" {
				if {!$err} {
					putlog "idleMode error: I'm not oped in $chan channel."
					return
				}
			}
			"1" {
				putlog "idleMode error: $chan channel is not valid."
				return
			}
		}
		set users [string tolower [lrange [chanlist $chan] 1 end]]
		set except [string tolower [channel get $chan idleExempt]]
		set time [channel get $chan idleTime]
		foreach user $users {
			if {[lsearch -exact $except $user] != -1} continue 
			if {[isop $user $chan]} {
				lappend checkList $user:1
			}
			if {[isvoice $user $chan]} {
				if {[info exists checkList]} {
					set pos [lsearch -exact $checkList $user:1]
					if {$pos == -1} {
						lappend checkList $user:2
					} else {
						set checkList [lreplace $checkList $pos $pos $user:3]
					}
				} else {
					lappend checkList $user:2
				}
			}
		}
		if {[info exists checkList]} {
			foreach ele [split $checkList] {
				scan $ele {%[^:]:%s} user count
				checkIdle $count $user $chan $time
			}
		}
	}

	proc checkIdle {mode user chan time} {
		set idle [getchanidle $user $chan]
		if {$idle >= $time} {
			switch -- $mode {
				"1" {
					pushmode $chan -o $user
					putlog "idleMode: deoped $user in $chan cos was idle for $idle minutes"
				}
				"2" {
					pushmode $chan -v $user
					putlog "idleMode: devoiced $user in $chan cos was idle for $idle minutes"
				}
				"3" {
					puthelp "MODE $chan -ov $user $user"
					putlog "idleMode: deoped and devoiced $user in $chan cos was idle for $idle minutes"
				}
			}
		}
	}
}

putlog "idlemode.tcl loaded..."
PS: I've found and fixed a bug that occurred when the only op was an user that was in except list.
Once the game is over, the king and the pawn go back in the same box.
User avatar
Amr
Halfop
Posts: 94
Joined: Fri Sep 14, 2007 7:13 am
Location: Egypt

Post by Amr »

I'm adding users like this .chanset #chan idleExempt "user1 user2 3 4 5 6 7 8 9 10"
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Drop the ". Apart that, any issues so far?
Once the game is over, the king and the pawn go back in the same box.
User avatar
Amr
Halfop
Posts: 94
Joined: Fri Sep 14, 2007 7:13 am
Location: Egypt

Post by Amr »

I got no reaction from the bot after the last editing.
btw how to force it to run the scan by my request.
User avatar
caesar
Mint Rubber
Posts: 3778
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

For some reason I still can't see the cron nor the time bind in the .binds list while the bind is in a namespace, thus explains why nothing happens. This needs more testing. :roll:

If you got .tcl active in telnet with the bot then do .tcl idlemode::idleTime
Once the game is over, the king and the pawn go back in the same box.
Post Reply