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.

Auto Voice System

Requests for complete scripts or modifications/fixes for scripts you didn't write. Response not guaranteed, and no thread bumping!
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Auto Voice System

Post by a41 »

I have been in search of specific requirement for a script that can do the following.

- Add a user to an auto-voice list.
- Voice user on join which is in the list.
- De-voice inactive user after 60 minutes.
- Voice the user when it becomes active (from the list)

I have searched a lot but was unable to find that would do this from the list of users.

I am not good in TCL so any help would be really appreciated.

xox
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

What do you mean by "Add a user to an auto-voice list." ? You do this or the bot dose it based on an action or something? The rest is easy peasy.
Once the game is over, the king and the pawn go back in the same box.
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

like !autovoice nick
that it maintains a list of users that will get voice. not everyone.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Two questions:

1. In what format should the host-mask of the user you want to add to this list should be like?

2. Want to create a user and add hosts there or want to maintain a list? Easiest would be adding hosts to a specific auto-voice user, else would have to create the saving function so the list would be maintained upon a restart or killing the bot for whatever reason and starting it back.
Once the game is over, the king and the pawn go back in the same box.
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

THe userlist should be maintained so incase the bot restarts or get offline. It still works.

I think a simplest way is to user Bot user list with +g for autovoice. I maybe wrong, this way the list will be maintained.

Logically i think if idle time is checked and if the user is in the list with +g (autovoice) it should give voice back to an active user.

I have seen autovoice scripts on join but a user already in channel but devoiced, this should give voice back once the user become active.

That is what I am trying to achieve in this.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Code: Select all

namespace eval idleDevoice {

	# Default idle time in minutes
	set idleTime 60

	setudef flag idleDevoice		
	
	bind cron - {* * * * *} [namespace current]::idle:cron
	bind pubm g|g * [namespace current]::idle:voice
	
	proc idle:cron {min hour day month weekday} {
		variable idleTime
		set now [clock seconds]
		foreach channel [channels] {
			if {![channel get $channel idleDevoice]} continue
			if {![botisop $channel]} continue
			foreach member [chanlist $channel &g] {
				if {[isbotnick $member]} continue
				if {[isop $member $channel] || ![isvoice $member $channel]} continue
				set chanidle [getchanidle $member $channel]
				if {$chanidle >= $idleTime} {
					lappend userList $member
				}
			}
			idle:push $channel $userList
		}
	}

	proc idle:voice {nick uhost hand chan text} {
		if {![botisop $chan]} return
		if {[isvoice $nick $chan]} return
		pushmode $chan +v $nick
	}
	
	proc idle:push {channel userList} {
		if {![botisop $channel]} return
		set max 6
        set len [llength $userList]
        while {$len > 0} {
			if {$len > $max} {
				set mode [string repeat "v" $max]
				set users [join [lrange $userList 0 [expr {$max - 1}]]]
				set userList [lrange $userList $max end]
				incr len -$max
			} else {
				set mode [string repeat "v" $len]
				set users [join $userList]
				set len 0
			}
            pushmode $channel -$mode $users
		}
	}
}
Haven't tested anything cos don't have the time nor the possibility at the moment to test stuff out.

Edit: Fixed an error.
Last edited by caesar on Tue Feb 20, 2018 2:45 pm, edited 1 time in total.
Once the game is over, the king and the pawn go back in the same box.
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

thank you! i will test and see what I find out.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

The:

Code: Select all

if {![isvoice $nick $chan]} return
should have been without ! like

Code: Select all

if {[isvoice $nick $chan]} return
meaning if nick is already voiced we don't try to voice them again.

Edit: Oh, and forgot to mention in first post that you have to set the channels where you want this to be active with: .chanset #channel +idleDevoice

For testing purposes should set the idleTime to a few minutes to see if things work or not.
Once the game is over, the king and the pawn go back in the same box.
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

This is the error I got.

Tcl error [::idleDevoice::idle:cron]: can't read "userList": no such variable
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Ah, right. Replace the:

Code: Select all

idle:push $channel $userList 
line with:

Code: Select all

if {[info exists userList]} {
	idle:push $channel $userList 
}
Once the game is over, the king and the pawn go back in the same box.
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

I am running it and it works fine. There are a few things that I have noticed.

- It does not devoice a user for 60 minutes that is not in list. (means any manually voiced user stays voiced)

- Is there a way to add exclusion for devoice for certain nicks?

thanks for your help.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Was under impression that only the users that are in that special voiced user should be voiced/devoiced. We can easily fix this by changing this line:

Code: Select all

foreach member [chanlist $channel &g] {
to this:

Code: Select all

foreach member [chanlist $channel] {
As for nick exclusions that's easy, we add this function:

Code: Select all

proc idle:nick {nick} {
	set skip [list "user_1" "user_2" "user_3" "and so on"]
	if {[isbotnick $nick] || [expr [lsearch -nocase $skip $nick]] > -1} return 0
	return 1
}
at the end of the code but still inside the last }, and then before:

Code: Select all

set chanidle [getchanidle $member $channel] 
add:

Code: Select all

if {[idle:nick $member]} continue
If you want those nick exclusions to be different for each channel or editable "online" (meaning not having to edit the tcl file and rehash the bot) then need to change things a bit. Just let me know if it's the case.
Once the game is over, the king and the pawn go back in the same box.
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

Devoice works but adding the exclusion portion producing this error

Tcl error [::idleDevoice::idle:cron]: invalid command name "0"
User avatar
a41
Voice
Posts: 10
Joined: Thu Feb 15, 2018 7:46 pm

Post by a41 »

I had to remove the user exclusion as everything stopped working other than voicing a user. Devoice stopped working.

Code: Select all



namespace eval idleDevoice {

   # Default idle time in minutes
   set idleTime 60

   setudef flag idleDevoice      
   
   bind cron - {* * * * *} [namespace current]::idle:cron
   bind pubm g|g * [namespace current]::idle:voice
   
   proc idle:cron {min hour day month weekday} {
      variable idleTime
      set now [clock seconds]
      foreach channel [channels] {
         if {![channel get $channel idleDevoice]} continue
         if {![botisop $channel]} continue
         foreach member [chanlist $channel] {
            if {[isbotnick $member]} continue
			
            if {[isop $member $channel] || ![isvoice $member $channel]} continue
            set chanidle [getchanidle $member $channel]
            if {$chanidle >= $idleTime} {
               lappend userList $member
            }
         }
         
		  if {[info exists userList]} {
          idle:push $channel $userList
} 
      }
   }

   proc idle:voice {nick uhost hand chan text} {
      if {![botisop $chan]} return
      if {[isvoice $nick $chan]} return
      pushmode $chan +v $nick
   }
   
   proc idle:push {channel userList} {
      if {![botisop $channel]} return
      set max 6
        set len [llength $userList]
        while {$len > 0} {
         if {$len > $max} {
            set mode [string repeat "v" $max]
            set users [join [lrange $userList 0 [expr {$max - 1}]]]
            set userList [lrange $userList $max end]
            incr len -$max
         } else {
            set mode [string repeat "v" $len]
            set users [join $userList]
            set len 0
         }
            pushmode $channel -$mode $users
      }
   }
}
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Ah, in that case replace the idle:nick function with:

Code: Select all

proc idle:nick {nick} {
	set skip [list "user_1" "user_2" "user_3" "and so on"]
	set test [expr {[lsearch -nocase $skip $nick] > -1 ? "1" : "0"}]
}
and instead of the:

Code: Select all

if {[idle:nick $member]} continue 
add:

Code: Select all

if {[isbotnick $nick] || [idle:nick $member]} continue 
inside that foreach loop.
Once the game is over, the king and the pawn go back in the same box.
Post Reply