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 

[Solved]Voice/devoice script with extra features
Goto page 1, 2  Next
 
Post new topic   Reply to topic    egghelp.org community Forum Index -> Script Requests
View previous topic :: View next topic  
Author Message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Sun Jan 14, 2018 9:34 am    Post subject: [Solved]Voice/devoice script with extra features Reply with quote

Hello!

I looked for autovoice scripts in the archive (there are many) but I want a bit more.

"Normal" features are:
- autovoice everyone joining my channel
- turn on and off the script via DCC: .chanset #channel +av.
- public and private commands for my bot would be !voice nick, !devoice nick;
"Extras" would be:
- If a user devoiced with "!devoice user" or "mode #chanel -v user"
and if the devoiced user parts my channel and joins again to gain +v, bot must not give the +v flag to him only if a pre-defined time has gone. This time should be set in the script config section in hours.
- If a devoiced user stays in my channel but changes his nick to gain +v,
bot must not give the +v flag to him.
- I don't want to send any message to the user who is trying to gain +v after devoiced.


My I ask If anyone create this tcl?

I found a similar scripts but it is not working well (mute.tcl).

Thank You!


Last edited by m4s on Wed Feb 07, 2018 3:47 pm; edited 1 time in total
Back to top
View user's profile Send private message
caesar
Ass Kicker


Joined: 14 Oct 2001
Posts: 3455
Location: Area 51

PostPosted: Mon Jan 15, 2018 8:48 am    Post subject: Reply with quote

Here's something I think should do what you asked BUT the kicker is that I haven't tested anything so not sure if works or not.

The !voice/!devoice commands accept multiple nicks per line, the duration is in seconds, the script stores ignores in user@host format and cleanup is done automatically every minute (can be changed later on cos is a cron job).

Load this on a test bot and see what happens:
- if when someone joins the bot gives voice
- remove it's voice via !devoice <nick> and have him rejoin the channel
- give his voice via !voice and then ask him to rejoin the channel
- do the same stuff mentioned above but with 2 members (!devoice <nick 1> <nick 2>)
- devoice one either by you changing the channel mode ( you set -v on the user) or via !devoice. have user rejoin and then wait 1 minute and do another rejoin.

Test the stuff out and let me know the outcome.
Code:

namespace eval av {

   set duration 360

   setudef flag av
   array set ignoreList {}

   bind join - * [namespace current]::joining
   bind pub o|o !voice [namespace current]::voice
   bind pub o|o !devoice [namespace current]::devoice
   bind mode - "% +v" [namespace current]::mcVoice
   bind mode - "% -v" [namespace current]::mcDevoice
   bind cron - {*/1 * * * *} [namespace current]::reset

   proc joining {nick uhost hand chan} {
      global ignoreList
      if {![channel get $chan av] || [isbotnick $nick] || ![botisop $chan]} return
      if {[lsearch -nocase [dict keys [join $ignoreList($chan)]] $uhost] < 0} {
         pushmode $chan +v $nick
      }
   }

   proc voice {nick uhost hand chan text} {
      if {![channel get $chan av] || ![botisop $chan] || ![llength $text]} return
      foreach user [split $text] {
         if {[isbotnick $user] || ![onchan $user] || [isvoice $user $chan]} continue
         lappend voiceList $user
      }
      if {[info exists voiceList]} {
         push $chan "+" $voiceList
      }
   }

   proc devoice {nick uhost hand chan text} {
      if {![channel get $chan av] || ![botisop $chan] || ![llength $text]} return
      foreach user [split $text] {
         if {[isbotnick $user] || ![onchan $user] || ![isvoice $user $chan]} continue
         lappend voiceList $user
      }
      if {[info exists voiceList]} {
         push $chan "-" $voiceList
      }
   }

   proc push {chan mc userList} {
      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 $chan $mc$mode $users
      }
   }

   proc mcVoice {nick uhost hand chan mc target} {
      global ignoreList
      if {![channel get $chan av] || ![botisop $chan]} return
      if {[array get ignoreList $chan] != {}} {
         set pos [lsearch -nocase [dict keys [join $ignoreList($chan)]] $uhost]
         if ($pos >= 0) {
            set ignoreList($chan) [lreplace $ignoreList($chan) $pos $pos]
         }
      }
   }

   proc mcDevoice {nick uhost hand chan mc target} {
      global ignoreList
      if {![channel get $chan av] || ![botisop $chan]} return
      set now [clock seconds]
      if {[array get ignoreList $chan] != {}} {
         set pos [lsearch -nocase [dict keys [join $ignoreList($chan)]] $uhost]
         if ($pos >= 0) {
            set ignoreList($chan) [lreplace $ignoreList($chan) $pos $pos [list $uhost $now]]
            return
         }
      }
      lappend ignoreList($chan) [list $uhost $now]
   }

   proc reset {min hour day month weekday} {
      global ignoreList
      global duration
      set now [clock seconds]
      foreach chan [channels] {
         if {![channel get $chan av]} {
            if {[array get ignoreList $chan] != {}} {   
               array unset ignoreList $chan
            }
            continue
         }
         if {[array get ignoreList $chan] != {}} {
            set x 0
            foreach time [dict values [join $ignoreList(a)]] {
               if {($now - $time) >=  $duration} {
                  set ignoreList($chan) [lreplace $ignoreList($chan) $x $x]
                  incr x
               }
            }
         }
      }
   }
}

Edit: Fixed binds. /facepalm
_________________
You may say anything about me, but at least don't misspell my name. xD


Last edited by caesar on Mon Jan 15, 2018 3:42 pm; edited 1 time in total
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Mon Jan 15, 2018 12:14 pm    Post subject: Reply with quote

Hi Caesar!

First thank you to help me, that is kind of you. Smile

First test results are:

Script is loaded I set the +av flag via DCC.
Bot doesn't give +v after someone joining to my channel and the public commands don't work. There are no error messages in the partyline.
The bot is opped on the test channel and the script is loaded.
(I added this line to the script to see it: putlog "\002*Caesar's autovoice script has been successfully LOADED")

I used the .binds *av* to see 'something', I got this:
cron -|- */1 * * * * 14 ::av::reset
mode -|- % -v 0 ::av::mcDevoice
mode -|- % +v 0 ::av::mcVoice


P.s.: I forgot to mention but it would be great if the public commands work for only users who has the +o flag.
Back to top
View user's profile Send private message
caesar
Ass Kicker


Joined: 14 Oct 2001
Posts: 3455
Location: Area 51

PostPosted: Mon Jan 15, 2018 3:41 pm    Post subject: Reply with quote

The commands and that voice on joining part doesn't work because I'm an idiot. Don't know how i missed that and why you don't get any errors. /facepalm

Make this change:
Code:

bind join - * [namespace current]::joining
bind pub o|o !voice [namespace current]::voice
bind pub o|o !devoice [namespace current]::devoice

_________________
You may say anything about me, but at least don't misspell my name. xD
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Mon Jan 15, 2018 4:42 pm    Post subject: Reply with quote

Everyone makes mistakes...that is normal. Smile

I made the changes.
I got this error after joining:
Tcl error [::av::joining]: can't read "ignoreList(#mychannel)": no such variable

!voice nick and !devoice nick work, but !voice nick1 nick2 don't.
I got this continously:
Tcl error [::av::reset]: can't read "ignoreList(a)": no such element in array

If I use /mode #channel +v nick to give +v I got this:
Tcl error [::av::mcVoice]: unbalanced open paren
in expression "(-1"

But I guess my explanation was not good sorry about it. I try to explain my request again.
The bot should give +v to everyone who joins to my channel. That is the default.
Nick1 joins bot sets mode +v.
- If an op devoices nick1, and nick1 parts and joins again bot must not give the +v.
Here I thought to set a timer. Bot should wait for example six hours. If nick1 leaves and joins after six hours bot can give the +v.
- If an op devoices nick1 and nick1 changes his nick to nick2 bot must not give the +v to nick2.
-Public commands !voice, !devoice for +o flag users.

I found a very similar script but it is not working for me and perhaps helps something.
(https://gist.github.com/anonymous/2a5d393e6fd49680dee05c0f41835e59).
Back to top
View user's profile Send private message
caesar
Ass Kicker


Joined: 14 Oct 2001
Posts: 3455
Location: Area 51

PostPosted: Tue Jan 16, 2018 1:56 am    Post subject: Reply with quote

A quick fix of some of the bugs: replace global with variable, replace $ignoreList(a) with $ignoreList($chan)

Will have to do some testing of my own cos I'm making a fool of myself with posting untested stuff. Rolling Eyes

Edit: From the limited testing I've done the mass voice/devoice should work. Not sure how mode change works, I mean if it's triggered for each mode change or just once for all modes if are in a single line.

The script you mentioned is the same mute.tcl that at first glance doesn't know how to mute more than one member. Anyway, will get back to this as soon as I done some proper testing.

Second edit: Here's an updated and slightly tested code. Ignore the above.
Code:

namespace eval av {

        set duration 60

        setudef flag av
        array set ignoreList {}

        bind join * * [namespace current]::joining
        bind pub o !voice [namespace current]::voice
        bind pub o !devoice [namespace current]::devoice
        bind mode - "% +v" [namespace current]::mcVoice
        bind mode - "% -v" [namespace current]::mcDevoice
        bind cron - {*/1 * * * *} [namespace current]::reset

        proc joining {nick uhost hand chan} {
                variable ignoreList
                if {![channel get $chan av] || [isbotnick $nick] || ![botisop $chan]} return
                if {[array get ignoreList $chan] != {}} {
                        if {[lsearch -nocase [dict keys [join $ignoreList($chan)]] $uhost] != -1} return
                }
                pushmode $chan +v $nick
        }

        proc voice {nick uhost hand chan text} {
                variable ignoreList
                if {![channel get $chan av] || ![botisop $chan] || ![llength $text]} return
                foreach user [split $text] {
                        if {[isbotnick $user] || ![onchan $user $chan] || [isvoice $user $chan]} continue
                        lappend voiceList $user
                }
                if {[info exists voiceList]} {
                        push $chan "+" $voiceList
                }
        }

        proc devoice {nick uhost hand chan text} {
                if {![channel get $chan av] || ![botisop $chan] || ![llength $text]} return
                foreach user [split $text] {
                        if {[isbotnick $user] || ![onchan $user $chan] || ![isvoice $user $chan]} continue
                        lappend voiceList $user
                }
                if {[info exists voiceList]} {
                        push $chan "-" $voiceList
                }
        }

        proc push {chan mc userList} {
                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 $chan $mc$mode $users
                }
        }

        proc mcVoice {nick uhost hand chan mc target} {
                variable ignoreList
                if {![channel get $chan av] || ![botisop $chan]} return
                if {[array get ignoreList $chan] != {}} {
                        set pos [lsearch -nocase [dict keys [join $ignoreList($chan)]] [getchanhost $target $chan]]
                        if {$pos >= 0} {
                                set ignoreList($chan) [lreplace $ignoreList($chan) $pos $pos]
                        }
                }
        }

        proc mcDevoice {nick uhost hand chan mc target} {
                variable ignoreList
                if {![channel get $chan av] || ![botisop $chan]} return
                set now [clock seconds]
            set uhost [getchanhost $target $chan]
                if {[array get ignoreList $chan] != {}} {
                        set pos [lsearch -nocase [dict keys [join $ignoreList($chan)]] $uhost]
                        if {$pos >=0 } {
                                set ignoreList($chan) [lreplace $ignoreList($chan) $pos $pos [list $uhost $now]]
                                return
                        }
                }
                lappend ignoreList($chan) [list $uhost $now]
        }

        proc reset {min hour day month weekday} {
                variable ignoreList
                variable duration
                set now [clock seconds]
                foreach chan [channels] {
                        if {![channel get $chan av]} {
                                if {[array get ignoreList $chan] != {}} {
                                        array unset ignoreList $chan
                                }
                                continue
                        }
                        if {[array get ignoreList $chan] != {}} {
                                set x 0
                                foreach time [dict values [join $ignoreList($chan)]] {
                                        if {($now - $time) >=  $duration} {
                                                set ignoreList($chan) [lreplace $ignoreList($chan) $x $x]
                                                incr x
                                        }
                                }
                        }
                }
        }
}

I can't test if it works with multiple voiced/devoiced members at the same time so need you test this for me and reply with the result.
_________________
You may say anything about me, but at least don't misspell my name. xD
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Tue Jan 16, 2018 2:02 pm    Post subject: Reply with quote

Caesar!

It's a great job from you! Thank You!
The main features work I got no error messages! Smile
The only thing (but this was not my request) is the "!voice nick1 nick2" and the "!devoice nick1 nick2" don't work. But it is not important for me.

I have questions. Smile
What time is the "set durations"?
How do you mean "cleanup is done automatically every minute (can be changed later on cos is a cron job)."

An example: I devoiced nick1, and I don't want to give the +v only after 12 hours.
How can I set this?

Thanks!
Back to top
View user's profile Send private message
caesar
Ass Kicker


Joined: 14 Oct 2001
Posts: 3455
Location: Area 51

PostPosted: Tue Jan 16, 2018 3:36 pm    Post subject: Reply with quote

I did some limited testing on voicing/devoicing multiple nicks and worked. Will try to do a live test cos can't see right now what's not working properly.

12 hours in seconds means 12 x 60 x 60 and is equal with 43200, so if you change the set duration 60 in set duration 43200 then rehash the bot to "notice" the change. I left it to 60 seconds for my testing.

The "cleanup" is done automatically by the "reset" function that is executed once every 1 minute (this {*/1 * * * *} actually). If you want to do a cleanup let's say every 10 minutes then that becomes {*/10 * * * *} for example. If you google crontab will find plenty of examples how to set a different moment to execute that function.

Keep in mind that if for instance you muted someone at let's say 10:00:01 for let's say 1 hour then the bot will not lift the mute at 11:00:01 but at 11:01:00 when the cleanup function is executed again, so the user will actually be muted for 1 hour and 59 seconds. I didn't opt for another method to run the cleanup every second because you said hours in first post so 1 minute give or take is not really that much. Smile
_________________
You may say anything about me, but at least don't misspell my name. xD
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Wed Jan 17, 2018 11:44 am    Post subject: Reply with quote

Thanks Caesar I see!

I started to use your script. I want to wait a bit to see it is working well -i am sure it will!
If I find something I will post it here but I think this topic will be closed soon! Wink
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Sun Jan 21, 2018 11:03 am    Post subject: Reply with quote

Hi Caesar,

A tested a bit. The only thing which is not working is the "!voice nick1 nick2" and
"!devoice nick1 nick2".

Test1:
!voice nick1 nick2 -> nothing happens -> no error msg
!voice nick1, nick2 -> voice is only given to nick2 -> no error msg

I gave voice to nick1 and nick2 to run test2.

Test2:
!devoice nick1 nick2- > nothing happens -> no error msg
!devoice nick1, nick2 -> bot took v from only nick2 -> no error msg


Is it possibly to use the !voice, !devoice commands via the bot? I mean in private commands.
Back to top
View user's profile Send private message
SpiKe^^
Owner


Joined: 12 May 2006
Posts: 530
Location: Tennessee, USA

PostPosted: Sun Jan 21, 2018 12:11 pm    Post subject: Don't use pushmode here! Reply with quote

Is my opinion that [pushmode] only works with simple 1 item mode change, and not a combined mode change like this script is feeding it.

As a test, search out this line in the script...
Code:
pushmode $chan $mc$mode $users


and change it to more like this...
Code:
putquick "MODE $chan $mc$mode $users"

_________________
SpiKe^^

Get BogusTrivia 2.06.4.7 at www.mytclscripts.com
Back to top
View user's profile Send private message Visit poster's website
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Sun Jan 21, 2018 12:36 pm    Post subject: Re: Don't use pushmode here! Reply with quote

Thank You SpiKe^^!
That was the problem. Now it works!! Smile
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Sun Jan 21, 2018 12:44 pm    Post subject: 1st error message Reply with quote

But on my testbot I got this error message:

Tcl error [::av::reset]: list doesn't contain element 1

I just used !voice nick1 nick2 and !devoice nick1 nick2....
Back to top
View user's profile Send private message
m4s
Halfop


Joined: 30 Jan 2017
Posts: 40

PostPosted: Fri Jan 26, 2018 12:46 pm    Post subject: Reply with quote

Hi,

The script works fine for some days,
I want to close this topic but before I do I have two questions. Smile

My channel is not too big so I could not test it.
1. If more then one user joins the channel at the same time will this script give the +v in one line?
I mean:
[19:10] Nick joined the channel
[19:10] Nick2 joined the channel
I want: bot sets mode +vv nick1 nick2

Shall I change this line:
Quote:
pushmode $chan +v $nick

to:
Quote:
putquick "MODE $chan +v $nick"


2. The error message I shared with you in my previous post means nothing?
I haven't met with it since then...

Thank you for the replies!
Back to top
View user's profile Send private message
caesar
Ass Kicker


Joined: 14 Oct 2001
Posts: 3455
Location: Area 51

PostPosted: Fri Jan 26, 2018 3:02 pm    Post subject: Reply with quote

Sorry for the delay, lately I've been very busy with work and didn't get to do some proper testing.

Will see tomorrow if will have some to test a few things and see from and under what circumstances you get that error and reply back.
_________________
You may say anything about me, but at least don't misspell my name. xD
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    egghelp.org community Forum Index -> Script Requests All times are GMT - 4 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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