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.

Help with invite script

Help for those learning Tcl or writing their own scripts.
Post Reply
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Help with invite script

Post by juanamores »

With this code I get the BoT invite all users who are on the guest list my channel.

Each time a guest user joins one of the channels where you will find the BoT it will invite them to my channel.

The problem occurs when the user joins many channels where the BoT is, because then gets 1 invite per channel, inviting him many times.
How I can limit the BoT invites at a maximum of 3 times per user?

Code: Select all

bind join - * join:chkinvite

proc join:chkinvite {nick uhost hand chan} {
   set x 1
    foreach ic [channels] {
	  if {[onchan $nick $ic]} {continue}
		if {([matchinvite $nick!$uhost $ic]) && ($nick != $::botnick) && [botisop $ic]} {
	     putserv "INVITE $nick $ic"
		 } else {
			continue
   }
incr x
		}
}
Moderator edit: Modified title to be relevant to the content
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
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 myInvites {

	# define the channel where you want people to be invited to
	variable inviteTo "#something"
	
	# define the number of max invites a user will receive
	variable maxInvites 3
	
	# define the amount of time in seconds after a user can get a new set of invites
	variable resetTime 1800

	# don't edit past this line
	bind join - * [namespace current]::checkInvite
	bind cron - {?0*} [namespace current]::resetInvites

	proc checkInvite {nick uhost hand chan} {
		if {[isbotnick $nick] || ![botisop $chan]} return
		
		variable inviteTo
		
		if {[string equal $chan $inviteTo] || [onchan $nick $inviteTo]} return
		
		global invites
		variable maxInvites
		
		set match 0
		if {(![isInvite "$nick!$uhost"])} {
			incr match
			lappend invites [list "$nick!$uhost" [unixtime] 1]
		} else {
			set x 0
			foreach {m c i} [join $invites] {
				if {![string equal "$nick!$uhost" $m]} continue
				if {$i < $maxInvites} {
					killInvite $m
					set invites [lreplace $invites $x $x [list $m $c [incr i]]]
					incr match
				}
			}
		}
		if {$match} {
			puthelp "INVITE $nick $inviteTo"
		}
	}

	proc isInvite {mask} {
		global invites
		set match 0
		if {[info exists invites]} {
			foreach {m c i} [join $invites] {
				putlog "m: $m | c: $c | i: $i"
				if {[string equal $m $mask]} {
					incr match
					break
				}
			}
		}
		return $match
	}
	
	proc killInvite {mask} {
		global invites
		if {![info exists invites]} return
		set x -1
		foreach {m c i} [join $invites] {
			incr x
			if {[string equal $m $mask]} {
				incr match
				break
			}
		}
		if {$match} {
			set invites [lreplace invites $x $x]
		}
	}
	
	proc resetInvites {min hour day month weekday} {
		global invites
		variable resetTime
		if {[info exists invites]} {
			set now [unixtime]
			foreach {m c i} [join $invites] {
				putlog "time: [expr $now - $c]"
				if {[expr $now - $c] < $resetTime} continue
				putlog "remove: $m"
				killInvite $m
			}
		}
	}
}
I did some limited testing and I think it's doing what you asked for.
Once the game is over, the king and the pawn go back in the same box.
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

Thank you very much caesar for the code.
I still have not analyzed it, but just triggered it began to invite a lot of nicks he does NOT have invite status in my channel.
Like I said , I just need to invite the nicks that have added in to the invite list with newchaninvite $mychan $nickinv invite 0 sticky.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Ah crap. With this the bot invites everyone that joins one of the channels he is OP on. :|

I tried with internal list of invites and on Undernet where i tested things it was setting +r mode and some other weird behavior. Will change the code to use the internal list and leave you to test it.
Once the game is over, the king and the pawn go back in the same box.
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Alright. I've returned with a piece of code that will use the internal invite list.

Code: Select all

namespace eval myInvites {
	bind join - * [namespace current]::checkInvite
	bind cron - {?0*} [namespace current]::resetInvites
	
	# define the channel where you want people to be invited to
	variable inviteTo "#something"
	
	# define the number of max invites a user will receive
	variable maxInvites 3
	
	# define the amount of time in seconds after a user can get a new set of invites
	variable resetTime 1800

	proc checkInvite {nick uhost hand chan} {
		if {[isbotnick $nick] || ![botisop $chan]} return

		variable inviteTo
		if {[string equal $chan $inviteTo] || [onchan $nick $inviteTo]} return

		variable maxInvites
		set now [unixtime]
		foreach ele [invitelist $inviteTo] {
			lassign $ele hostmask comment expiration added active creator
			if {![string equal "$nick!$uhost" $hostmask]} continue
			if {[scan $comment {%d%d} n e] !=2} {
				set comment [list 0 [expr $now + $resetTime]]
			} else {
				set comment [list [incr n] $e]
			}
			killchaninvite $inviteTo $hostmask
			newchaninvite $inviteTo $hostmask $creator $comment $expiration
			lassign $comment n e
			if {$n <= $maxInvites} {
				puthelp "INVITE $nick $inviteTo"
			}
		}
		checkExpired
	}
	
	proc resetInvites {min hour day month weekday} {
		checkExpired
	}

	proc checkExpired args {
		variable resetTime
		variable inviteTo
		set now [unixtime]
		foreach ele [invitelist $inviteTo] {
			lassign $ele hostmask comment expiration added active creator
			if {[scan $comment {%d%d} n e] !=2} {
				set comment [list 0 [expr $now + $resetTime]]
				if {[killchaninvite $inviteTo $hostmask]} {
					newchaninvite $inviteTo $hostmask $creator $comment $expiration
				}
			}
			lassign $comment n e
			if {$e > $now} continue
			if {[killchaninvite $inviteTo $hostmask]} {
				newchaninvite $inviteTo $hostmask $creator [list 0 [expr $now + $resetTime]] $expiration
			}
		}
	}
}
The thing is it will change all the comments of invites to "X Y" where X is number of invites sent and Y is the timestamp when the X is reset back to 0.

I did some limited testing so you will have to test it better.
Once the game is over, the king and the pawn go back in the same box.
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

caesar wrote: The thing is it will change all the comments of invites to "X Y" where X is number of invites sent and Y is the timestamp when the X is reset back to 0.
I did not understand this part of the comments.
Do I have to add a comment when I make the invite list ?

I tried the code without change and continues to invite the same nick +3 times if the nick joins more than 3 channels where the BoT is.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

I meant that the invites will be like:
.tcl invitelist #something
Tcl: {cez!~foo@blah.com {1 1465297023} 1465296876 1465296936 0 Invite}
The {1 1465297023} is the comment and 1 is the number of invites I got and the 1465297023 is the timestamp the invites number will be reset so I can get another set of 3 invites.

Do a .tcl invitelist #channel and show me just one output to see if things are working or not.

I did some limited testing and was giving just 3 invites, but to be honest I haven't tested the part where the comment in the invite didn't match that syntax.
Once the game is over, the king and the pawn go back in the same box.
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

Yes, At this time all nicks are at zero

Code: Select all

Tcl: {JeanPaul!*@* {0 1465443209} 0 1465441408 0 invite} {marianella!*@* {0 1465443305} 0 1465441505 0 invite} {Sandra_45!*@* {0 1465443305} 0 1465441505 0 invite}.............
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Ah. I see where I screwed up. Give this a try:

Code: Select all

namespace eval myInvites {
	bind join - * [namespace current]::checkInvite
	bind cron - {?0*} [namespace current]::resetInvites
	
	# define the channel where you want people to be invited to
	variable inviteTo "#channel"
	
	# define the number of max invites a user will receive
	variable maxInvites 3
	
	# define the amount of time in seconds after a user can get a new set of invites
	variable resetTime 1800

	proc checkInvite {nick uhost hand chan} {
		if {[isbotnick $nick] || ![botisop $chan]} return

		variable inviteTo
		if {[string equal $chan $inviteTo] || [onchan $nick $inviteTo]} return

		variable maxInvites
		set now [unixtime]
		set mask "$nick!$uhost"
		
		if {[isInvite $mask $inviteTo]} {
			foreach ele [invitelist $inviteTo] {
				lassign $ele hostmask comment expiration added active creator
				if {![string match -nocase $mask $hostmask]} continue
				if {[scan $comment {%d%d} n e] !=2} {
					set comment [list 0 [expr $now + $resetTime]]
				} else {
					set comment [list [incr n] $e]
				}
				killchaninvite $inviteTo $hostmask
				newchaninvite $inviteTo $hostmask $creator $comment $expiration
				lassign $comment n e
				if {$n <= $maxInvites} {
					putserv "INVITE $nick $inviteTo"
				}
			}
		}
		checkExpired
	}
	
	proc resetInvites {min hour day month weekday} {
		checkExpired
	}

	proc checkExpired args {
		variable resetTime
		variable inviteTo
		set now [unixtime]
		foreach ele [invitelist $inviteTo] {
			lassign $ele hostmask comment expiration added active creator
			if {[scan $comment {%d%d} n e] !=2} {
				set comment [list 0 [expr $now + $resetTime]]
				if {[killchaninvite $inviteTo $hostmask]} {
					newchaninvite $inviteTo $hostmask $creator $comment $expiration
				}
			}
			lassign $comment n e
			if {$e > $now} continue
			if {[killchaninvite $inviteTo $hostmask]} {
				newchaninvite $inviteTo $hostmask $creator [list 0 [expr $now + $resetTime]] $expiration
			}
		}
	}
	
	proc isInvite {mask chan} {
		set match 0
		foreach ele [invitelist $chan] {
			lassign $ele hostmask comment expiration added active creator
			if {![string match -nocase $mask $hostmask]} continue
			incr match
			break
		}
		return $match
	}
}
Once the game is over, the king and the pawn go back in the same box.
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

Thanks again caesar.
I have not tried the new code because I 'm struggling with another problem that already shared here and final here.

By using the command newchaninvite the bot change channel modes depending on the letters of nick (see post above to understand this problem).

I solved the problem at that time, keeping the initial channel modes in a variable, and then, compare them with the changes made by the BoT, for then remove it.

Code: Select all

proc pub:addinvite {nick uhost hand chan text} {
  if {$text == ""} { putmsg $chan "Please enter \002nick\002 to add."; return 0 }
	set t [lindex [split $text] 0]
    set modos [getchanmode $chan]
    set modes1 [split "$modos" {}]
	set ti "$t[join !*@*]"
	if {![isinvite $ti $chan]} {
		newchaninvite $chan $ti invite 0 sticky
		utimer 5 [list rest_of_commands $modes1 $chan $t]
		proc rest_of_commands {modes1 chan t} {
			set modes2 [getchanmode $chan]
			set largo [string length $modes2]
			set x 0
			while  {$x < $largo} {
				set x [expr {$x + 1}]
				if {[string index $modes2 $x] in $modes1 == 0} {
					set modchange [string index $modes2 $x]
					pushmode $chan "-[join $modchange]"
					unset modchange
				}
			}
		}
    putmsg $chan "$t has been added to the autoinvite database $chan"
    } else { putmsg $chan "$t is already in the autoinvite database $chan" } 
}
What I could not get it to mount this part of the code in the code proposed by caesar.

This part would have to go before each newchaninvite command:

Code: Select all

set modos [getchanmode $chan]
set modes1 [split "$modos" {}]
And this, after newchaninvite command:

Code: Select all

utimer 5 [list rest_of_commands $modes1 $chan $t]
proc rest_of_commands {modes1 chan t} {
     set modes2 [getchanmode $chan]
     set largo [string length $modes2]
     set x 0
     while  {$x < $largo} {
     set x [expr {$x + 1}]
      if {[string index $modes2 $x] in $modes1 == 0} {
          set modchange [string index $modes2 $x]
          pushmode $chan "-[join $modchange]"
          unset modchange
       }
	}
}
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

Yeah, I was getting weird results on test bot (was setting some channel modes when it shouldn't) so this is why i dropped the testing completely.

To be honest I would rather make my own "invite list" and store them in a flat file (meaning text file) than rely on the internal invite list that apparently is bugged, or at least I don't understand why the bot is setting some channel modes that match the letters in the hostmask.
Once the game is over, the king and the pawn go back in the same box.
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

caesar wrote:Yeah, I was getting weird results on test bot (was setting some channel modes when it shouldn't) so this is why i dropped the testing completely.

To be honest I would rather make my own "invite list" and store them in a flat file (meaning text file) than rely on the internal invite list that apparently is bugged, or at least I don't understand why the bot is setting some channel modes that match the letters in the hostmask.

The guest list is created by the BoT in a txt (text plain).
But I use commands to add and to remove nicks from that list.

The problem that Bot puts modes, depending on the letters of nicks is NOT problem of your code.

I think the problem is that the network is not ready or configurated for the eggdrops bots operations.

It was very difficult to explain the subject of the modes, when the newchanvite command is used.

In the opportunities I shared these problems here, no one understood.

Then, with the help I received from other users of this forum I solved the problem of modes, eliminating those that the bot added, at the time to add a new user to the guest list.

The code I have build to eliminate modes added by my BoT, works very well.

If there is any way to put this code in your own code, I think we've solved an important part of the problem.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
User avatar
caesar
Mint Rubber
Posts: 3776
Joined: Sun Oct 14, 2001 8:00 pm
Location: Mint Factory

Post by caesar »

I was thinking about the same "solution" (or better called workaround to circumvent the problem) you mentioned but if another script is setting some modes at the same time, well not at the same time cos elements in queue are executed one after the other, then "workaround" will notice the modes it set and consider those a mistake thus remove them thus will cause a problem.

Anyway, i was actually thinking about storing the invites into an array (that would saved on a flat file and loaded when needed) rather than on the internal invites list that is causing some unwanted behavior.

Will get back to this tomorrow at work when will have some time to test things out.
Once the game is over, the king and the pawn go back in the same box.
j
juanamores
Master
Posts: 317
Joined: Sun Mar 15, 2015 9:59 am

Post by juanamores »

caesar wrote: Will get back to this tomorrow at work when will have some time to test things out.
caesar have you had time to review the code?

I was thinking...
It could be a variable value when the Bot will perform the first invite and then compare it to not invite him again.
If you do not understand my ideas is because I can not think in English, I help me with Google Translate. I only speak Spanish. Bear with me. Thanks :)
Post Reply