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.

Mass Kick Protection

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 »

Here is the *upgraded* version of the above code.

Code: Select all

namespace eval MassKick {

  # set the masskick limit (count:time)
  set mass(limit) "3:10"
  
  # timeout of the check access command sent to ChanServ
  set mass(timeout) "60"

  # memo to be sent when an AOP was removed
  set memo(mass) "The AOP of %nick user on %chan channel has been deleted due to attempt to masskick."
  
  # memo to be sent when bot was kicked by an AOP
  set memo(bot) "The AOP of %nick user on %chan channel has been deleted cos he kicked me."
  
  # memo to be sent when SOP or higher masskicked and bot didn't triggered any actions
  set memo(skip) "User %nick has level %level (%rank) on the %chan channel, so his action (%action) has been ignored, also added him to the skip list."
  
  # memo to be sent when someone without any access triggered a masskick or kicked the bot
  set memo(zero) "Someone oped user %nick on the %chan channel and %action the channel..."

  # customize the text of %action in the lines above
  set memo(action) {
	"masskicked"
	"booted me off"
  }
	
  # ignore the actions of the users that have this flags
  set mass(friends) "f|f"

  # don't edit below this line
  setudef flag massKick
  
  set flags { "massKicker" "massCount" "checkList" "checkAct" "massSkip" }
  foreach flag $flags {
	setudef str $flag
  }

  # binds
  bind kick * * [namespace current]::kicked
  bind part - * [namespace current]::remove
  bind sign - * [namespace current]::remove
  bind nick - * [namespace current]::nickCh
  bind notc * * [namespace current]::checkReply
  #bind raw - MODE [namespace current]::massMode

  # bot kicked
  proc botKicked {chan nick} {
	channel set $chan checkList [lappend [channel get $chan checkAct] $nick "1"]
    massCheck $chan $nick
  }

  # reset
  proc resetChan {chan} {
	if {![validchan $chan]} return
	set flags { "massKicker" "massCount" "checkList" "checkAct" }
	foreach flag $flags {
		channel set $chan $flag {}
	}
  }
  
  # access checking
  proc massCheck {chan nick} {
	set checkList [channel get $chan checkList]
	if {$nick in $checkList} {
		if {$nick in [channel get $chan massSkip]} {
			set pos [lsearch $checkList	$nick]
			channel set $chan checkList [lreplace $checkList $pos $pos]
		}
		return
	}
	variable mass
	channel set $chan checkList [lappend checkList $nick]
	puthelp "ChanServ access $chan $nick"
	utimer $mass(timeout) [list [namespace current]::doThis "5" $chan $nick]
  }

  # reply of ACC command from ChanServ
  proc checkReply {nick uhost hand text {dest ""}} {
	if {[string equal -length 1 # $dest]} return
	if {$nick eq "ChanServ"} {
		foreach {user cmd chan level rank} [split $text] { break }
		set checkList [channel get $chan checkList]
		if {$nick ni $checkList} return
		set pos [lsearch $checkList	$nick]
		set act [lindex [channel get $chan checkAct] $pos]
		actLevel $chan $user $level $rank $act
	}
  }
  
  # access trigger actions
  proc actLevel {chan nick level rank act} {
	variable memo
	set action [lindex $memo(action) $act]
	set rank [string trim [lindex [split $rank] 0] {()}]
	switch -- $level {
		"0" {
			putserv "Chanserv deop $chan $nick"
			set message [string map -nocase [list "%chan" "$chan" "%nick" "$nick" "%action" "$action"] $memo(zero)]
		}
		"10" {
			putserv "Chanserv deop $chan $nick"
			putserv "Chanserv aop $chan del $nick"
			putlog "del aop & deop"
			if {$act eq "0"} {
				set message [string map -nocase [list "%chan" "$chan" "%nick" "$nick"] $memo(mass)]
			} elseif {$act eq "1"} {
				set message [string map -nocase [list "%chan" "$chan" "%nick" "$nick"] $memo(bot)]
			}
		}
		"20" - "30" - "40" - "50" - "60" {
			channel set $chan massSkip [lappend [channel get $chan massSkip] $nick]
			set message [string map -nocase [list "%chan" "$chan" "%nick" "$nick" "%level" "$level" "%action" "$action" "%rank" "$rank"] $memo(skip)]
		}
	}
	putserv "Memoserv send $chan $message"
	doThis "2" $chan $nick
	doThis "5" $chan $nick
  }
  
  # triggers:
  # 1 - add, 2 - remove massKicker/massCount, 3 - replace nick
  # 4 - replace count, 5 - remove checklist
  proc doThis {act chan nick {pos ""} {count ""} {newNick ""}} {
	set massKicker [channel get $chan massKicker]
    set massCount [channel get $chan massCount]
	set checkAct [channel get $chan checkAct]
    switch -- $act {
      "1" {
        lappend massKicker $nick
        lappend massCount 1
		lappend checkAct 0
      }
      "2" {
		set pos [lsearch $massKicker $nick]
        set massKicker [lreplace $massKicker $pos $pos]
        set massCount [lreplace $massCount $pos $pos]
      }
      "3" {
        set massKicker [lreplace $massKicker $pos $pos $newNick]
      }
      "4" {
        set massCount [lreplace $massCount $pos $pos $count]
      }
	  "5" {
		set checkList [channel get $chan checkList]
		if {$nick ni $checkList} return
		set pos [lsearch $checkList $nick]
		channel set $chan checkList [lreplace $checkList $pos $pos]
		set checkAct [lreplace $checkAct $pos $pos]
	  }
	  "6" {
		set checkList [channel get $chan checkList]
		if {$nick in $checkList} {
			set pos [lsearch $checkList $nick]
			channel set $chan checkList [lreplace $checkList $pos $pos]
		}
		set massSkip [channel get $chan massSkip]		
		if {$nick in $massSkip} {
			set pos [lsearch $massSkip $nick]
			channel set $chan massSkip [lreplace $massSkip $pos $pos]
		}
	  }
    }
    channel set $chan massKicker $massKicker
    channel set $chan massCount $massCount
	channel set $chan checkAct $checkAct
  }

  # triggers:
  # 1 - part & sign, 2 - nick change
  proc eventThis {event chan nick {newNick ""}} {
    set massKicker [channel get $chan massKicker]
    if {$nick ni $massKicker} return
    set pos [lsearch $massKicker $nick]
    switch -- $event {
      "1" {
        doThis "2" $chan $nick
		doThis "5" $chan $nick
      }
      "2" {
        doThis "3" $chan $nick $pos "0" $newNick
		doThis "6" $chan $nick $newNick  
      }
    }
  }

  # part & sign
  proc remove {nick uhost handle chan {text ""}} {
    if {![channel get $chan massKick]} return
    if {[isbotnick $nick]} {
      resetChan $chan
      } else {
      eventThis "1" $chan $nick
    }
  }

  # nick
  proc nickCh {nick uhost handle chan newnick} {
    if {![channel get $chan massKick]} return
    if {[isbotnick $nick]} return
    eventThis "2" $chan $nick $newNick
  }

  # kick
  proc kicked {nick uhost hand chan target reason} {
    if {![channel get $chan massKick]} return
    variable mass
    if {[matchattr $hand $mass(friends) $chan]} return
    if {[isbotnick $nick]} return
    if {$nick eq "ChanServ"} return
	if {$nick in [channel get $chan massSkip]} return
    if {[isbotnick $target]} {
      botKicked $chan $nick
      return
    }
    set massKicker [channel get $chan massKicker]
    if {$nick ni $massKicker} {
      doThis "1" $chan $nick
      return
    }
    set pos [lsearch $massKicker $nick]
    set count [lindex [channel get $chan massCount] $pos]
    set info [split $mass(limit) :]
    if {$count >= [lindex $info 0]} {
		massCheck $chan $nick
      return
      } else {
      incr count
    }
    utimer [lindex $info 1] [list [namespace current]::doThis "2" $chan $nick]
    doThis "4" $chan $nick $pos $count
  }
}
I did only a few tests on this, so you will have to let me know if something is not working properly. I'll add that missing massMode proc later on that will help out at maintaining the massSkip list.

To be honest I would rather create a "special" user (like massUser) to the bot and give him some flags that aren't used in any other script and set that flag in mass(friends) in the previous code, then add the host masks of the people that I want to be skipped from any punishment, than depend on ChanServ's reply with the access level of a person that's mass kicking. Right now the bot won't react until it receives a reply of that access command from ChanServ and removes the user from his check list after the timeout that is set at mass(timeout).

In the massMode I was thinking on monitoring all +o on the channel, then issue an WHY command and store that user in massSkip list if it's level is above the requirements. This should save some time but in case some user that isn't in that list the script still will depend on how fast ChanServ will reply to the access command.

If you got any other idea feel free to contribute. :)
Once the game is over, the king and the pawn go back in the same box.
g
gamble27
Halfop
Posts: 71
Joined: Tue Aug 05, 2008 7:51 am

Post by gamble27 »

i have checked the tcl caesar, there is no error in the tcl however its not doing anything too. no deletion on kicking the bot or when the user does mkick. I do see on dcc [09:50:54] -ChanServ (service@dal.net)- test ACC #test 10 (AOP) but thats about it. It checks access but doesnt react on any trigger. Thanks : )
j
jerkiejerx
Voice
Posts: 3
Joined: Wed Aug 21, 2013 10:34 pm

What if...

Post by jerkiejerx »

hello, I hope this thread is still active.

What if the masskicker is using another nick which is NOT the same as the one with the aop access? The bot only deop and del aop using the nick.. but not the actual nick with the access.

Say for example:

blahblah has AOP access to #channelx. Reason: Identification to the nickname xlite.

The nick "blahblah" will be deopped.. However, its access will still be active because the script only aop delete the nick being used for masskicking, not the actual nick with the access.

Can the script still be improved? Thank you.
Post Reply