Peace & Protection 4.00 — File Browser

PeaceProtection4.00v4.0 / PeaceProtection4.00v4.0 / SCRIPT / OPCMD.MRC

OPCMD.MRC — 29.17 KB — Download this file

; #= P&P -rs
; ########################################
; Peace & Protection
; Basic op commands
; ########################################

;;; protect against kicking self (in inline kick?)

; inline kick- won't kick same person many times (10 sec or until a join or you gain op/help)
alias _kick if (%-kicked. [ $+ [ $1 ] $+ [ $2 ] ] ) return | set -u10 %-kicked. $+ $1 $+ $2 1 | if (%`delay.kicks) _linedance .raw kick $1 $2 : $+ $3- | else .raw kick $1 $2 : $+ $3-

;
; Unset inline kick counters; mode/topic on op/join
;
on *:JOIN:#:unset %-kicked. $+ $chan $+ $nick
on *:OP:#:{
  if ($opnick == $me) {
    unset %-kicked. $+ $chan $+ .*
    if (%-didstrict. [ $+ [ $chan ] ] ) return
    set -u5 %-didstrict. $+ $2 1
    var %strict = $_getsm($chan)
    if ($chan($chan).mode == $null) {
      var %enforce = $gettok(%strict,4,44)
      if ((%enforce != +) && (%enforce != $null)) var %junk = $_enforcemode($chan,%enforce,$chan($chan).mode,1)
    }
    var %enforce = $gettok(%strict,3,44)
    if ((%enforce != +) && (%enforce != $null)) var %junk = $_enforcemode($chan,%enforce,$chan($chan).mode,1)
    var %enforce = $gettok(%strict,2,44)
    if ((%enforce != +) && (%enforce != $null)) var %junk = $_enforcemode($chan,%enforce,$chan($chan).mode,1)
    if (($gettok(%strict,1,44) isnum 1-2) || ($chan($chan).topic == $null)) if ($_getst($chan)) _linedance .raw topic $chan : $+ $_finalmsg($replace($_premsg($ifmatch),&chan&,$chan))
  }
}
raw 366:*:{
  if (($me isop $2) && ($nick($2,0) == 1) && ($istok(%-joining,$2,32))) {
    set -u5 %-didstrict. $+ $2 1
    var %strict = $_getsm($2),%num = 4
    :loop
    var %enforce = $gettok(%strict,%num,44)
    if ((%enforce != +) && (%enforce != $null)) var %junk = $_enforcemode($2,%enforce,$chan($2).mode,1)
    if (%num > 2) { dec %num | goto loop }
    if ($_getst($2)) _linedance .raw topic $2 : $+ $_finalmsg($replace($_premsg($ifmatch),&chan&,$2))
  }
}

; ban [-u#] [#chan] [who[ who][,who]] [n]
alias ban _ssplit ban 25 $1- | if (%.targ.ban == $null) mode %.chan.ban b | elseif ($gettok(%.msg.ban,$numtok(%.msg.ban,32),32) isnum) _ban² %.opt.ban %.chan.ban $ifmatch %.targ.ban $remtok(%.msg.ban,$ifmatch,32) | else _ban² %.opt.ban %.chan.ban 3 %.targ.ban %.msg.ban
alias _ban² _ban³ $1-3 $_c2s($4-)
alias _ban³ {
  _operr $2 ban ban
  ; Must nick complete OUTSIDE loop
  var %total,%num,%ban,%ban2,%usebot = %.usebot,%bans = $_nccs(32,$2,$4-),%num = 1
  _init.mass $2
  :loopB
  %ban = $gettok(%bans,%num,32)
  if (%ban) {
    %ban2 = $_ppmask(%ban,$_stmask($3))
    if (%ban2) {
      if (%usebot) $ifmatch ! $2 ban %ban2
      else _add.mass + b %ban2
      %total = %total %ban2
    }
    else {
      disprs $2 Looking up address of $:t(%ban) for ban...
      _Q.userhost ban $+ $1 $+  $+ $2 $+ &n!&a $+ $3 disprs $+ $2 $+ User $+ $:t(%ban) $+ notfoundtoban! %ban
    }
    inc %num | goto loopB
  }
  if ((-u* iswm $1) && ($remove($1,-u) isnum) && (%total != $null)) {
    if ($numtok(%total,32) > 1) .timer 1 $remove($1,-u) .unban $2 %total
    else .timer. [ $+ [ $replace(%total,*,`,?,') ] ] 1 $remove($1,-u) .unban $2 %total
  }
}

; reban [-u#] [#chan]
alias reban _ssplit ban 27 $1- | if (%-=lastunban. [ $+ [ %.chan.ban ] ] == $null) _error No recent unban to reban in %.chan.ban $+ !Use /ban to ban or view the banlist. | ban %.opt.ban %.chan.ban %-=lastunban. [ $+ [ %.chan.ban ] ]

; banlast [-u#] [#chan]
alias banlast _ssplit ban 28 $1- | if (%-=lastleave. [ $+ [ %.chan.ban ] ] == $null) _error No recent parting user to ban in %.chan.ban $+ !Use /ban to ban or view the banlist. | ban %.opt.ban %.chan.ban %-=lastleave. [ $+ [ %.chan.ban ] ]

; unban [-s] [#chan] [who[ who][,who]]
alias unban _ssplit ban 26 $1- | if (%.targ.ban == $null) { %.targ.ban = %-=lastban. [ $+ [ %.chan.ban ] ] | if (%.targ.ban == $null) _error No recent ban to unban in %.chan.ban $+ !Specify a user to unban or use /ban to view the banlist. } | _unban² %.opt.ban %.chan.ban %.targ.ban %.msg.ban
alias _unban² _unban³ $1-2 $_c2s($3-)
alias _unban³ {
  _operr $2 unban unban
  if ($1 == -s) { unset %-scanunban | %-scanmiss = 0 }
  else _init.mass $2
  var %ban,%num = 1
  :loopB
  %ban = $gettok($3-,%num,32)
  if (%ban) {
    if (%.usebot) $ifmatch ! $2 unban %ban
    elseif ($1 == -s) {
      if (($_ismask(%ban)) || (! isin %ban) || (@ isin %ban) || (. isin %ban)) %-scanunban = $addtok(%-scanunban,%ban,32)
      elseif ($address(%ban,5)) %-scanunban = $addtok(%-scanunban,$ifmatch,32)
      else {
        inc %-scanmiss
        disprs $2 Looking up address of $:t(%ban) for unban...
        _Q.userhost _scanu2&n!&a $+ $2 _scanu2 $+ %ban $+  $+ $2 %ban
      }
    }
    else _add.mass - b $_fixmask(%ban)
    inc %num | goto loopB
  }
  if (($1 == -s) && (%-scanmiss == 0)) _scanu3 $2
}
alias _scanu2 {
  if (! isin $1) %-scanunban = $addtok(%-scanunban,$1,32)
  else disprs $2 User $:t($1) not found to ban!
  dec %-scanmiss
  if (%-scanmiss < 1) _scanu3 $2
}
alias _scanu3 {
  unset %-scanmiss
  if (%-scanunban == $null) disprs $1 No one to unban!
  else {
    disprs $1 Scanning banlist to find matching bans...
    unset %-scanhit
    %-scanchan = $1
    .raw mode $1 b
  }
}
alias _scanu4 {
  if (%-scanhit == $null) disprs $1 No matching bans found.
  else {
    _init.mass $1
    var %num = $numtok(%-scanhit,32)
    disprs $1 Unbanned $:t(%num) matching bans.
    :loop
    _add.mass - b $gettok(%-scanhit,%num,32)
    if (%num > 1) { dec %num | goto loop }
  }
  unset %-scanhit %-scanchan %-scanunban
}

; kick [#chan] who[,who]|mask [comment]
alias k kick $1-
alias kick {
  if ($1 == $null) _qhelp /kick | _split k 1 $1- | if (%.targ.k == $null) _qhelp /kick $1-
  if ($_ismask(%.targ.k)) fk $1-
  else {
    _operr %.chan.k kick kick
    var %who,%chan = %.chan.k,%targ = %.targ.k,%msg = %.msg.k,%num = 1,%usebot = %.usebot
    _flush.mass
    :loop
    if ($gettok(%targ,%num,44)) {
      %who = $_ncc($gettok($ifmatch,1,33),%chan)
      %who = %who $_finalmsg($replace($_msgwrap(kwrap,kick,%msg),&chan&,%chan,&nick&,%who,&count&,%num))
      if (%usebot) $ifmatch ! %chan kick %who
      else _kick %chan %who
      inc %num | goto loop
    }
    if ((%msg) && (%.punishwait == $null)) _recent2 kick 9 %msg
  }
}

; fk [-ovnu] [#chan] mask [comment]
; -ovn = only kick ops, vocs, nonops (regs) add -u = don't kick known users
alias fknop fk -vn $1-
alias fk {
  if ($1 == $null) _qhelp /fk | _ssplit k 21 $1- | if (%.targ.k == $null) _qhelp /fk $1-
  _operr %.chan.k kick filterkick
  if ($ial == $false) _error The IAL is not enabled!You need the IAL to do filterkicks.
  if ($chan(%.chan.k).ial != $true) _error The IAL is not fully updated.Wait a few seconds and try again.
  if ($_ppmask(%.targ.k,$_stmask(2))) %.targ.k = $ifmatch
  else %.targ.k = %.targ.k $+ !*@*
  _flush.mass
  var %nick,%count = 1,%num = 1
  :loop
  %nick = $ialchan(%.targ.k,%.chan.k,%num).nick
  if (%nick) {
    if ((u isin %.opt.k) && (($notify(%nick) != $null) || (($level($address(%nick,5)) > 1) && ($istok($level($address(%nick,5)),=black,44) == $false)))) { inc %num | goto loop }
    if (-?* iswm $remove(%.opt.k,u)) {
      if ((%.opt.k != -u) && ((%nick isop %.chan.k) && (o !isin %.opt.k)) || ((%nick isvo %.chan.k) && (%nick !isop %.chan.k) && (v !isin %.opt.k)) || ((%nick isreg %.chan.k) && (n !isin %.opt.k))) { inc %num | goto loop }
    }
    if (%nick != $me) {
      %nick = $ifmatch $_finalmsg($replace($_msgwrap(kwrap,kick,%.msg.k),&chan&,%.chan.k,&nick&,$ifmatch,&count&,%count,&mask&,%.targ.k))
      inc %count
      if (%.usebot) $ifmatch ! %.chan.k kick %nick
      else _kick %.chan.k %nick
    }
    inc %num | goto loop
  }
  if ((%.msg.k) && (%.punishwait == $null)) _recent2 kick 9 %.msg.k
  if (%num == 1) _error No matching users found to filterkick!(mask used- %.targ.k $+ )
}

; tempban [-u#] [#chan] who|mask[,who|mask] [n] [comment]
alias tempban {
  if (-u* iswm $1) _kb² $_cfgi(tempban.type) /tempban $1-
  else _kb² $_cfgi(tempban.type) /tempban -u $+ $_cfgi(tempban.time) $1-
}

dialog tempban {
  title "Tempban"
  size -1 -1 350 120

  text "&Reason for tempban?", 203, 14 10 290 20
  combo 1, 10 30 330 160, drop result edit

  text "&Tempban for:", 2, 20 60 65 20
  edit "", 3, 88 56 40 22
  text "seconds", 4, 130 60 50 20

  button "OK", 101, 30 86 80 25, OK default
  button "Cancel", 102, 140 86 80 25, cancel
  button "Clear list", 103, 270 88 70 21, disable
}
on *:DIALOG:tempban:init:*:{
  did -a $dname 3 %.time
  if (%.time < 20) did -a $dname 4 minutes
  _fillrec $dname 1 103 $_cfg(kick.lis) 0 $_msg(kick)
  unset %.time
}
on *:DIALOG:tempban:sclick:101:{
  if ($did(4) == seconds) %.time = $did(3)
  else %.time = 60 * $did(3)
  if (%.time isnum) set -u1 %.time -u $+ %.time
  else unset %.time
}
on *:DIALOG:tempban:sclick:103:{
  did -b $dname 103
  .remove $_cfg(kick.lis)
  :loop | if ($did(1,1) != $null) { did -d $dname 1 1 | goto loop }
}

; kb/kb0/kb2/cb [-u#] [#chan] who|mask[,who|mask] [n] [comment]
alias bk kb $1-
alias kb _kb² 3 /kb $1-
alias bk0 kb0 $1-
alias kb0 _kb² 2 /kb0 $1-
alias bk2 kb2 $1-
alias kb2 _kb² 4 /kb2 $1-
alias bc cb $1-
alias cb _kb² -1 /cb $1-
alias _kb² if ($3 == $null) _qhelp $2 | _ssplit k $iif($1 > 0,$1,24) $3- | if (%.targ.k == $null) _qhelp $iif($2 == /tempban,$deltok($2-,2,32),$2-) | _kb³ %.opt.k %.chan.k %.targ.k $iif($gettok(%.msg.k,1,32) !isnum,$1) %.msg.k
alias _kb³ {
  _operr $2 ban kickban
  var %targ.ban,%targ.kick,%who,%mask,%mask2,%num2,%wrap,%dur,%usebot = %.usebot,%num = $numtok($3,44)
  :loop1
  %who = $_ncc($gettok($3,%num,44),$2)
  if ($4 >= 0) %mask = $_ppmask(%who,$_stmask($4))
  else {
    %mask = $_ppmask(%who,0,0,1)
    %mask2 = $_ppmask(%who,$_stmask(3))
    if ($ialchan(%mask,$2,0) == $ialchan(%mask2,$2,0)) %mask = %mask2
  }
  if (%mask == $null) {
    if ($_ismask(%who)) {
      if ($ial == $false) _error The IAL is not enabled!You need the IAL to do filterkicks.
      if ($chan($2).ial != $true) _error The IAL is not fully updated.Wait a few seconds and try again.
    }
    else {
      disprs $2 Looking up address of $:t(%who) for kickban...
      _Q.userhost kb $+ $1 $+  $+ $2 $+ &n!&a $+ $_s2p($4-) disprs $+ $2 $+ User $+ $:t(%who) $+ notfoundtoban! %who
    }
  }
  else {
    %targ.ban = $addtok(%targ.ban,%mask,32)
    if (%usebot) $ifmatch ! $2 ban %mask $_finalmsg($replace($_msgwrap(kwrap,kick,$5-),&chan&,$2,&nick&,%who,&count&,%num))
    else {
      if (%who == $me) %targ.kick = $addtok(%targ.kick,%who,32)
      %num2 = $ialchan(%mask,$2,0)
      :loopC
      if (%num2 >= 1) {
        if ($ialchan(%mask,$2,%num2).nick != $me) %targ.kick = $addtok(%targ.kick,$ifmatch,32)
        if (%num2 > 1) { dec %num2 | goto loopC }
      }
    }
  }
  if (%num > 1) { dec %num | goto loop1 }
  if (%usebot) goto botdone
  _init.mass $2
  %num = $numtok(%targ.kick,32)
  :loopD
  if ($gettok(%targ.kick,%num,32) isop $2) _add.mass - o $ifmatch
  if (%num > 1) { dec %num | goto loopD }
  %num = $numtok(%targ.ban,32)
  :loopB
  if (%num >= 1) {
    _add.mass + b $gettok(%targ.ban,%num,32)
    if (%num > 1) { dec %num | goto loopB }
  }
  _flush.mass
  %num = 1
  if ((-u* iswm $1) && ($remove($1,-u) isnum) && (%targ.ban != $null)) { %wrap = tbwrap | %dur = $gettok($_dur($remove($1,-u)),1-2,32) }
  else %wrap = kwrap
  :loopK
  if ($gettok(%targ.kick,%num,32) ison $2) _kick $2 $ifmatch $_finalmsg($replace($_msgwrap(%wrap,kick,$5-),&chan&,$2,&nick&,$ifmatch,&count&,%num,&dur&,%dur))
  if (%num < $numtok(%targ.kick,32)) { inc %num | goto loopK }
  if (%wrap = tbwrap) {
    if ($numtok(%targ.ban,32) > 1) .timer 1 $remove($1,-u) .unban $2 %targ.ban
    else .timer. [ $+ [ $replace(%targ.ban,*,`,?,') ] ] 1 $remove($1,-u) .unban $2 %targ.ban
  }
  :botdone
  if (($5) && (%.punishwait == $null)) _recent2 kick 9 $5-
}

; op/deop/voc/devoc [#chan] who[ who][,who]|mask
alias opme op $1- $me
alias op _op² /op fop 5 op give ops + o $1-
alias dop deop $1-
alias deop _op² /deop fdeop 6 deop remove ops - o $1-
alias voc _op² /voc fvoc 7 voice give voice + v $1-
alias dvoc devoc $1-
alias devoc _op² /devoc fdevoc 8 devoice remove voice - v $1-
alias _op² {
  if ($9 == $null) _qhelp $1 | _simsplit o $3 $9- | if (%.msg.o == $null) _qhelp $1 $9-
  if ($_ismask(%.msg.o)) $2 $9-
  else {
    if ((%.msg.o == $me) && ($1 == /op)) _operr %.chan.o opme op yourself
    else _operr %.chan.o $4-6
    ; Have to do nick completion OUTSIDE of loop
    var %chan = %.chan.o,%num = 1,%usebot = %.usebot,%who = $_nccs(32,%.chan.o,$_c2s(%.msg.o))
    if (%usebot) $ifmatch ! %chan $4 %who
    else {
      _init.mass %chan
      :loop
      if ($gettok(%who,%num,32)) { _add.mass $7 $8 $ifmatch | inc %num | goto loop }
    }
  }
}

; fop/fdeop/fvoc/fdevoc [#chan] who|mask
alias fop _fop² /fop 9 filter op + o !isop $1-
alias fdop fdeop $1-
alias fdeop _fop² /fdeop 10 filter deop - o isop $1-
alias fvoc _fop² /fvoc 11 filter voice + v isreg $1-
alias fdvoc fdevoc $1-
alias fdevoc _fop² /fdevoc 12 filter devoice - v isvo $1-
alias _fop² {
  if ($ial == $false) _error Filter commands do not work without IAL.See P&P help for details.
  if ($8 == $null) _qhelp $1 | _split o $2 $8- | if (%.targ.o == $null) _qhelp $1 $8-
  if ($chan(%.chan.o).ial != $true) $_doerror(Please wait-,The IAL is still updating.Please wait a few moments and try your command again.)
  _operr %.chan.o $4 $3-4
  %.targ.o = $_usermask(%.targ.o)
  var %total,%num = $ialchan(%.targ.o,%.chan.o,0)
  if (%.usebot) {
    :loop1
    if ($ialchan(%.targ.o,%.chan.o,%num).nick $7 %.chan.o) if ($ifmatch != $me) %total = %total $ifmatch
    if (%num > 1) { dec %num | goto loop1 }
    if (%total == $null) { if ($show) _error No matching users found to $4 $+ !(mask used- %.targ.o $+ ) | else return }
    %.usebot ! %.chan.o $4 %total
  }
  else {
    _init.mass %.chan.o
    :loop2
    if ($ialchan(%.targ.o,%.chan.o,%num).nick $7 %.chan.o) { if ($ifmatch != $me) { %total = 1 | _add.mass $5 $6 $ifmatch } }
    if (%num > 1) { dec %num | goto loop2 }
    if (%total == $null) { if ($show) _error No matching users found to $4 $+ !(mask used- %.targ.o $+ ) | else return }
  }
}

; topic [#chan] [topic]
alias topic {
  _simsplit t 13 $1-
  if (%.msg.t) {
    _operr %.chan.t topic change the topic
    if (%.usebot) $ifmatch ! %.chan.t topic %.msg.t
    else .raw topic %.chan.t : $+ %.msg.t
  }
  else {
    .raw topic %.chan.t
    disprs %.chan.t $:c(%.chan.t) Requesting topic...
  }
}

; etopic [#chan] [topic]
alias etopic _simsplit t 17 $1- | topic %.chan.t $_rentry(topic,%.chan.t,$_s2p($iif(%.msg.t,%.msg.t,$chan(%.chan.t).topic)),New topic for,%.chan.t,?)

; rtopic [#chan]
alias rtopic _simsplit t 17 $1- | topic %.chan.t $iif(%.msg.t,%.msg.t,$chan(%.chan.t).topic)

; atopic [#chan]
alias atopic _simsplit t 17 $1- | var %chan = %.chan.t | if (%.msg.t == $null) set -u %.msg.t $_entry(0,$null,Add what to topic? (a separator is not needed)) | topic %chan $chan(%chan).topic $iif($chan(%chan).topic != $null,//) %.msg.t

; stopic [#chan]
alias stopic _simsplit t 17 $1- | if ($_getst(%.chan.t)) topic %.chan.t $_finalmsg($replace($_premsg($ifmatch),&chan&,%.chan.t)) | else dispr %.chan.t $:cl(%.chan.t) No strict topic set for channel (see /strict to set one)

; mtn [#chan]
alias mtn _simsplit m 19 $1- | var %old = $chan(%.chan.m).mode | if (%old != $null) var %old = $remove(%old,+,n,t) | if (%old != $null) %old = - $+ %old | mode %.chan.m %old $+ +tn $chan(%.chan.m).key

; _mtog #chan mode
alias _mtog mode $1 $iif($2 isincs $gettok($chan($1).mode,1,32),-,+) $+ $2

; mode [#chan] [modes]
alias mode {
  if ($1 == $me) { umode $2- | return }
  _simsplit m 14 $1-
  if (%.msg.m) {
    if ($remove(%.msg.m,-,+) === b) {
      .raw mode %.chan.m b
      disprs %.chan.m $:c(%.chan.m) Requesting channel banlist...
    }
    else {
      _operr %.chan.m mode
      if (%.usebot) $ifmatch ! %.chan.m mode %.msg.m
      else .raw mode %.chan.m %.msg.m
    }
  }
  else {
    .raw mode %.chan.m
    disprs %.chan.m $:c(%.chan.m) Requesting channel modes...
  }
}

; Splitting for command parameters
alias _ssplit if (-* iswm $3) { set -u %.opt. [ $+ [ $1 ] ] $3 | _split $1-2 $4- } | else { set -u %.opt. [ $+ [ $1 ] ] - | _split $1- }
alias _simsplit {
  if ($left($3,1) isin &#) { set -u %.chan. [ $+ [ $1 ] ] $3 | set -u %.msg. [ $+ [ $1 ] ] $4- }
  elseif ($chan ischan) { set -u %.chan. [ $+ [ $1 ] ] $chan | set -u %.msg. [ $+ [ $1 ] ] $3- }
  elseif ($active ischan) { set -u %.chan. [ $+ [ $1 ] ] $active | set -u %.msg. [ $+ [ $1 ] ] $3- }
  else _error $read -tl [ $+ [ $2 ] ] script\spliterr.dat
}
alias _split {
  if ($left($3,1) isin &#) { set -u %.chan. [ $+ [ $1 ] ] $3 | set -u %.targ. [ $+ [ $1 ] ] $4 | set -u %.msg. [ $+ [ $1 ] ] $5- }
  elseif ($chan ischan) { set -u %.chan. [ $+ [ $1 ] ] $chan | set -u %.targ. [ $+ [ $1 ] ] $3 | set -u %.msg. [ $+ [ $1 ] ] $4- }
  elseif ($active ischan) { set -u %.chan. [ $+ [ $1 ] ] $active | set -u %.targ. [ $+ [ $1 ] ] $3 | set -u %.msg. [ $+ [ $1 ] ] $4- }
  else _error $read -tl [ $+ [ $2 ] ] script\spliterr.dat
}
; Ops check and error message
; /_operr #chan type error message
; type is used for bot checks (use - for no check)
; no error = no error if no bot found
alias _operr {
  unset %.usebot
  if (($2 == topic) && (t !isin $chan($1).mode)) return
  if (($me !isop $1) && (o !isin $usermode)) {
    if ((%!addon.i.bot) && ($2 != -)) {
      var %num = $numtok($ifmatch,44)
      :loop
      $gettok(%!addon.i.bot,%num,44) ? $1 $2
      if ($result) { set -u %.usebot $gettok(%!addon.i.bot,%num,44) | return }
      if (%num > 1) { dec %num | goto loop }
    }
    if (($_cfgi(check.ops)) && ($3)) {
      if ($1 ischan) _error You are not opped on $1 $+ !(you must have ops to $3-.)
      else _error You are not on $1 $+ !(You must be on a channel and opped to $3-.)
    }
  }
}

; mass mode aliases; work as groups and from routine to routine, even if the target channel changes
; call before a massmode set (if you specify $2 it is the amount of seconds to delay)
alias _init.mass .timer.massunset 1 $calc(1 + [ $2 ] ) unset % $+ .mass.* | .timer.massmode 1 $iif($2 isnum,$2,0) _flush.mass | if (%.mass.chan == $1) return | if (%.mass.gunk) _flush.mass | else { unset %.mass.gunk %.mass.who %.mass.ovh | %.mass.bit = + } | %.mass.chan = $1
; call to add to the modes- /_add.mass +|- o|v|b|etc [target]
; can specify a chunk of modes w/targets but not gaurunteed to work properly at all times
;;; h/e/l need -own- line?
alias _add.mass if ((m !isin %!feat) && ($2 isincs ovh)) { if ((%.mass.ovh != $null) && (%.mass.ovh !== $2)) _flush.mass | %.mass.ovh = $2 } | if ($1 != %.mass.bit) { %.mass.bit = $1 | %.mass.gunk = %.mass.gunk $+ $1 $+ $2 } | else %.mass.gunk = %.mass.gunk $+ $2 | %.mass.who = %.mass.who $3- | if ($numtok(%.mass.who,32) >= %!modes) _flush.mass
; finished
alias _flush.mass if (%.mass.gunk) { .raw mode %.mass.chan %.mass.gunk %.mass.who | unset %.mass.gunk %.mass.who %.mass.ovh | %.mass.bit = + }

;
; Recent topic remember, strict topic
;
on *:TOPIC:#:{
  if ($1) _recent2 topic 15 $replace($1-,$chan,&channel&)
  if (($nick == $me) || ($me !isop $chan) || ($_level($chan,$level($fulladdress)) >= 25)) return
  var %enforce = $gettok($_getsm($chan),1,44)
  if ((%enforce == 1) && ($_getst($chan))) {
    var %topic = $_finalmsg($replace($_premsg($ifmatch),&chan&,$chan))
    if (%topic != $1-) {
      _linedance .raw topic $chan : $+ %topic
      inc -u20 %-strictmode. [ $+ [ $chan ] ]
      if (%-strictmode. [ $+ [ $chan ] ] > 2) .deop %chan $nick
    }
  }
}
raw 332:*:_recent2 topic 15 $replace($3-,$2,&channel&)

;
; Track recent kick/parts and ban/unbans, cancel unban timers
;
on *:KICK:#:%-=lastleave. [ $+ [ $chan ] ] = $address($knick,5)
on *:PART:#:%-=lastleave. [ $+ [ $chan ] ] = $fulladdress
on *:QUIT:{
  var %num = $comchan($nick,0)
  :loop
  if (%num > 0) {
    %-=lastleave. [ $+ [ $comchan($nick,%num) ] ] = $fulladdress
    dec %num | goto loop
  }
}
on *:BAN:#:{
  %-=lastban. [ $+ [ $chan ] ] = $banmask
  if ($banmask == %-=lastunban. [ $+ [ $chan ] ] ) unset %-=lastunban. $+ $chan
  if ($nick != $me) .timer. [ $+ [ $replace($banmask,*,`,?,') ] ] off
}
on *:UNBAN:#:{
  %-=lastunban. [ $+ [ $chan ] ] = $banmask
  if ($banmask == %-=lastban. [ $+ [ $chan ] ] ) unset %-=lastban. $+ $chan
  .timer. [ $+ [ $replace($banmask,*,`,?,') ] ] off
}

;
; Nicklist popups
;
alias _banpop {
  if ($snick(#,1)) {
    if ($address($snick(#,1),5)) {
      set -u %.ban2 $_ppmask($snick(#,1),0,%`ban.id,2)
      if ($_ppmask($snick(#,1),0,%`ban.id,4) != %.ban2) set -u %.ban3 $ifmatch
      else unset %.ban3
      set -u %.ban4 $_ppmask($snick(#,1),0,%`ban.id,3)
      if ((%.ban4 == %.ban2) || (%.ban4 == %.ban3)) unset %.ban4
      set -u %.ban5 $_ppmask($snick(#,1),0,%`ban.id,6)
      if ((%.ban5 == %.ban2) || (%.ban5 == %.ban3) || (%.ban5 == %.ban4)) unset %.ban5
      set -u %.banD $_ppmask($snick(#,1),$_stmask(4))
      if ($_ppmask($snick(#,1),$_stmask(2)) != %.banD) set -u %.banS $ifmatch
      else unset %.banS
    }
    else {
      set -u %.ban2 Standard (*!ident@*.domain.com)
      set -u %.banD Full domain (*!*@*.domain.com)
      set -u %.banS Site (*!*@site.domain.com)
      unset %.ban3 %.ban4 %.ban5
    }
  }
}
alias _nurple var %num = $snick($1,0) | :loop | if (%num > 0) { $reptok($2-,**,$snick($1,%num),1,32) | dec %num | goto loop }

;
; Stricts
;
alias strict {
  if ($_ischan($1)) set %.chan $1
  elseif ($active ischan) set %.chan $active
  _dialog -am strictm strictm
}
dialog strictm {
  title "Strict Modes / Topics"
  size -1 -1 450 250

  text "View strict settings for:", 1, 10 11 110 20
  combo 2, 120 7 200 100, drop sort
  button "Add...", 3, 325 7 50 21
  button "Remove", 4, 380 7 60 21

  box "Modes:", 5, 10 40 430 98
  text "Always enforced:", 6, 20 60 132 20, right
  text "Always set on op:", 7, 20 85 132 20, right
  text "Set if no modes set:", 8, 20 110 132 20, right
  edit "", 9, 155 56 120 22, autohs
  edit "", 10, 155 81 120 22, autohs
  edit "", 11, 155 106 120 22, autohs

  box "Topics:", 12, 10 150 430 48
  combo 13, 20 166 132 100, drop
  edit "", 14, 155 166 275 22, autohs

  edit "", 15, 1 1 1 1, hide autohs

  button "Close", 100, 260 215 80 25, ok default
  button "Help", 101, 350 215 80 25, disable
}
on *:DIALOG:strictm:init:*:{
  did -ac $dname 2 (all other channels)
  window -hln @.vars
  filter -fw $_cfg(cfgvar.dat) @.vars stricts.*
  var %ln = $line(@.vars,0)
  :loop
  if (%ln) {
    var %chan = $right($gettok($line(@.vars,%ln),1,32),-8)
    did -a $+ $iif(%chan == %.chan,c) $dname 2 %chan
    dec %ln | goto loop
  }
  window -c @.vars
  loadbuf -otstrictm $dname 13 script\dlgtext.dat
  unset %.chan
  _loadsm
}
on *:DIALOG:strictm:sclick:2:_savesm | _loadsm
on *:DIALOG:strictm:sclick:100:_savesm
alias -l _loadsm {
  did -o strictm 15 1 $did(strictm,2,$did(strictm,2).sel)
  var %chan = . $+ $did(strictm,2,$did(strictm,2).sel)
  if ($chr(32) isin %chan) { var %chan | did -b strictm 4 }
  else did -e strictm 4
  var %opt = %`stricts [ $+ [ %chan ] ]
  if (%opt == $null) %opt = 3,+,+tn,+
  if ($gettok(%opt,1,44) isnum 1-3) did -c strictm 13 $ifmatch
  else did -c strictm 13 3
  did -o strictm 9 1 $gettok(%opt,2,44)
  did -o strictm 10 1 $gettok(%opt,3,44)
  did -o strictm 11 1 $gettok(%opt,4,44)
  did -o strictm 14 1 %`stricttopic [ $+ [ %chan ] ]
}
alias -l _savesm {
  var %chan = . $+ $did(strictm,15)
  if ($chr(32) isin %chan) var %chan
  var %opt = $iif($did(strictm,14) == $null,0,$did(strictm,13).sel),%num = 9
  :loop
  if ($did(strictm,%num) != $null) %opt = %opt $+ , $+ $ifmatch
  else %opt = %opt $+ ,+
  if (%num < 11) { inc %num | goto loop }
  `set stricts $+ %chan %opt
  `set stricttopic $+ %chan $did(strictm,14)
}
on *:DIALOG:strictm:sclick:3:_juryrig _addsm
on *:DIALOG:strictm:sclick:4:{
  var %chan = . $+ $did(strictm,2,$did(strictm,2).sel)
  `set stricts $+ %chan
  `set stricttopic $+ %chan
  did -d strictm 2 $did(strictm,2).sel
  did -c strictm 2 $did(strictm,2).lines
  _loadsm
}
alias -l _addsm {
  var %chan = $iif($active ischan,$active,$iif($chan(1),$chan(1)))
  var %chan = $_entry(-1,%chan,Channel to add settings for?)
  if (%`stricts. [ $+ [ %chan ] ] ) return
  did -ac strictm 2 %chan
  `set stricts. $+ %chan 3,+,+tn,+
  _loadsm
}
alias _getsm if (%`stricts. [ $+ [ $1 ] ] != $null) return $ifmatch | return %`stricts
alias _getst if (%`stricts. [ $+ [ $1 ] ] != $null) return %`stricttopic. [ $+ [ $1 ] ] | return %`stricttopic
on @!*:MODE:#:{
  if ($_level($chan,$level($fulladdress)) >= 25) return
  var %enforce = $gettok($_getsm($chan),2,44)
  if ((%enforce == +) || (%enforce == $null)) return
  if ($_enforcemode($chan,%enforce,$1-)) {
    inc -u20 %-strictmode. [ $+ [ $chan ] ]
    if (%-strictmode. [ $+ [ $chan ] ] > 2) {
      unset %.mass.bit
      _add.mass - o $nick
    }
  }
}
; $1 = channel $2 = modes to enforce (include key/limit)
; $3 = current modes/changes (include key/limit) $4 = assume -mode if not given in $3 (IE, current modes)
; performs enforcement, returns 1 if any enforcement made
alias _enforcemode {
  var %enforce = $_fixmode($gettok($2,1,32)),%change = $replace($_fixmode($gettok($3,1,32)),+,/,-,+,/,-),%num = 1,%revert
  if ($3 == $null) var %change
  :loop
  var %bit = $mid(%enforce,%num,2)
  if (%bit isincs %change) %revert = %revert $+ %bit
  elseif (($4) && (+? iswm %bit) && ($right(%bit,1) !isincs %change)) %revert = %revert $+ %bit
  inc %num 2
  if (%num < $len(%enforce)) goto loop
  ; -k here (and -l below) are really +k/+l (as we swapped them)
  if ((+k isincs %enforce) && (-k isincs %change)) {
    var %oldkey = $_whichkey($3),%forcekey = $_whichkey($2)
    if (%oldkey !== %forcekey) {
      .raw mode $1 -k %oldkey
      %revert = %revert $+ +k
    }
  }
  if ((+l isincs %enforce) && (-l isincs %change)) {
    if ($_whichlimit($3) != $_whichlimit($2)) %revert = %revert $+ +l
  }
  elseif (+l isincs %revert) %revert = $removecs(%revert,+l) $+ +l
  if (+k isincs %revert) %revert = %revert $_whichkey($2)
  elseif (-k isincs %revert) %revert = %revert $_whichkey($3)
  if (+l isincs %revert) %revert = %revert $_whichlimit($2)
  if (%revert) {
    _init.mass $1
    unset %.mass.bit
    _add.mass $left(%revert,1) $right(%revert,-1)
    return 1
  }
  return 0
}
; reduces a set of modes to only those that take params
alias _parammodes {
  var %set = $_fixmode($1),%num = 1
  :loop
  if ($mid(%set,%num,2) !isincs +b-b+o-o+h-h+v-v+I-I+e-e+l+k-k) %set = $removecs(%set,$ifmatch)
  else inc %num 2
  if (%num < $len(%set)) goto loop
  return %set
}
; returns the key in a set of modes
alias _whichkey {
  var %set = $_parammodes($gettok($1,1,32))
  if (k !isincs %set) return
  return $gettok($1-,$calc($pos(%set,k,1) / 2 + 1),32)
}
; returns the limit in a set of modes
alias _whichlimit {
  var %set = $_parammodes($gettok($1,1,32))
  if (+l !isincs %set) return
  return $gettok($1-,$calc(($pos(%set,+l,1) + 1) / 2 + 1),32)
}

;
; Recent offenders
;
alias f8 {
  if ($active !ischan) _error F8 can only be used in channel windows(to view and punish recent offenders.)
  if (%>offend [ $+ [ $active ] ] == $null) _error No recent offenders in $active $+ .F8 is used to view and punish recent channel offenders.
  _dialog -am recond recond
}
alias -l _rosel {
  did -c recond 2 $1
  did -r recond 8
  var %sel = $gettok($did(21),$did(2).sel,32)
  _ddaddm recond 8 $gettok(%sel,1,127) 022 030 002 001 111
  did -c recond 8 1
  did -d recond 4 1
  did -ic recond 4 1 $replace($_protwarnmsg(k,$gettok($gettok(%sel,2,127),1,9)),&a&,$_p2s($gettok($gettok(%sel,2,127),2,9)),&b&,$_p2s($gettok($gettok(%sel,2,127),3,9)))
}
dialog recond {
  title "Recent Offenders"
  size -1 -1 480 282

  box "", 1, 10 10 340 91
  list 2, 20 30 320 70

  box "&Kick reason:", 3, 10 110 340 54
  combo 4, 21 130 318 150, drop edit

  box "&Action:", 5, 10 173 340 98
  button "&Kick", 6, 20 194 50 25, default
  button "&Ban:", 7, 20 231 50 25
  combo 8, 80 233 259 150, drop edit

  text "1) Select a recent offender from the list.", 201, 360 30 110 100
  text "2) Optionally change the kick reason.", 202, 360 130 110 100
  text "3) Select Kick or Ban to punish.", 203, 360 190 110 100

  button "Cancel", 101, 415 245 50 25, cancel

  edit "", 20, 1 1 1 1, hide autohs
  edit "", 21, 1 1 1 1, hide autohs
}
on *:DIALOG:recond:sclick:2:_rosel $did(2).sel | did -t $dname 6
on *:DIALOG:recond:init:*:{
  did -o $dname 20 1 $active
  did -o $dname 1 1 &Recent offenders on $replace($active,&,&&) $+ :
  did -r $dname 2
  did -o $dname 21 1 %>offend [ $+ [ $active ] ]
  var %token,%num = 1
  :loop
  %token = $gettok($did(21),%num,32)
  did -a $dname 2 $gettok(%token,1,33) ( $+ $gettok($gettok(%token,2-,33),1,127) $+ ) - $gettok($gettok(%token,2,127),1,9)
  if (%num < $numtok($did(21),32)) { inc %num | goto loop }
  _fillrec $dname 4 0 $_cfg(kick.lis) $active
  _rosel 1
}
on *:DIALOG:recond:sclick:6:kick $did(20) $gettok($did(2,$did(2).sel),1,32) $did(4) | dialog -x $dname
on *:DIALOG:recond:sclick:7:if ($did(8) == $null) _error You must have a mask to ban selected. | kb $did(20) $did(8) $did(4) | dialog -x $dname
on *:DIALOG:recond:sclick:8:did -t $dname 7
on *:DIALOG:recond:edit:8:did -t $dname 7