Peace & Protection 4.00 — File Browser

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

CTCP.MRC — 21.49 KB — Download this file

; #= P&P -rs
; ########################################
; Peace & Protection
; CTCP, CTCP reply, self-ping, DCC ping
; ########################################

;
; Random nickname
;
alias rn if (%-oldrnick == $null) %-oldrnick = $me | var %nick = $left($me,6) | :loop | if ($len(%nick) < 9) { %nick = %nick $+ $r(0,9) | goto loop } | if ($server) .raw nick %nick | else nick %nick | dispa Changing nick to $:s(%nick) ( $+ $_Q.fkey(1,$calc($ctime + 120),urn) to undo)
alias urn if (%-oldrnick == $null) _error No previous nick to return to(use this after /rn to undo a random nick) | nick %-oldrnick | unset %-oldrnick
on *:DISCONNECT:if (%-oldrnick) nick %-oldrnick
; only do one random nick within X seconds, and only if option is set
alias -l _trn if (%`myflood.prot & 4) { inc -u30 %-delayrnick | if (%-delayrnick == 1) rn }

; Reset PnP flood counters
alias defld {
  unset %--* %-recd.ctcp* %-quick.ctcp %-recd.ver %-ignore.ctcp* %-recd.dcc* %-echo.ctcp %-recd.ctcpr* %-recd.inv* %-opme.* %-xqhalt %-extremequery %-xnhalt.* %-xnotice.* %_dccping %_dcc.*
  .ignore -r **!**@**
  dispa Flood counters reset.
}

;
; CTCP flood protection, DCC protect and auto accept/reject
;

; no replies after any 2 within 3 seconds
; no replies after any 2 from an address or any 4 total within 16 seconds
; any 4 from an address or any 7 total within 16 seconds is a flood and causes a 45 second 'ignore'
alias -l _repl.ctcp {
  if (%.ctcp.reply) return %.ctcp.reply
  var %reply = $read -nts [ $+ [ $1 ] ] $_cfg(ctcp.dat)
  if (%reply == $null) return
  if (%reply == !Ignore) halt
  if (($2 != $null) && ($1 != PING) && (&parms& !isin %reply)) return
  if (!Random:* iswm %reply) set -u %.replrand 1
  else set -u %.replrand 0
  %reply = $replace($_premsg(%reply),&mircver&,$version,&bits&,$bits,&os&,$os,&idle&,$_dur($idle),&date&,$_date,&time&,$_time,&fulldate&,$_datetime,&uptime&,$_dur($int($calc($ticks / 1000))),&parms&,$1-)
  if (&addons& isin %reply) %reply = $replace(%reply,&addons&,$_addon.names(1))
  if (&addondebug& isin %reply) %reply = $replace(%reply,&addondebug&,$_addon.names(2))
  if (!Command:* iswm %reply) {
    $right(%reply,-9)
    return $result
  }
  return $_finalmsg(%reply)
}
alias _do.rctcp {
  if (%`myflood.prot & 1) {
    if ($1- == VERSION) {
      if ($istok(%-recd.ver,$site,32) == $false) {
        %-recd.ver = %-recd.ver $site
        .timer 1 25 % $+ -recd.ver = $!remtok(%-recd.ver, $+ $site $+ ,1,32)
        inc -u3 %-quick.ctcp
        inc -u16 %-recd.ctcp
        inc -u16 %-recd.ctcp. $+ $site
      }
      if (%-ignore.ctcp) .ignore -tu20 **!**@**
      elseif (%-ignore.ctcp. [ $+ [ $site ] ] ) .ignore -tu20 $wildsite
    }

    inc -u16 %-recd.ctcp
    inc -u16 %-recd.ctcp. $+ $site

    if ((%-ignore.ctcp) || (%-ignore.ctcp. [ $+ [ $site ] ] )) { unset %.ctcp.reply | halt }
  }

  if (($1 == DCC) && ($istok(CHAT SEND RESUME ACCEPT,$2,32))) {
    if (%`myflood.prot !& 2) return
    ; if (standard) DCC, check for invalid
    if (%.dcc.invalid) { <ctcp.dcc> $nick $address %.dcc.invalid $1- | halt }

    ; no further handling for resumes
    if ($istok(RESUME ACCEPT,$2,32)) return

    ; accept modes
    if ($istok($level($fulladdress),=dcc,44)) var %type = 2
    elseif ($_known($nick,$fulladdress)) var %type = 0
    else {
      var %type = 1

      ; Only unknown users can contribute to flood, and settings are higher
      inc -u16 %-recd.dcc
      inc -u16 %-recd.dcc. $+ $site

      if (%-recd.dcc > 8) {
        ; Overall flood activated
        inc -u45 %-ignore.ctcp
        _alert FLOOD DCC flood detected- Further CTCPs won't be shown (ignored)
        halt
      }
      elseif (%-recd.dcc. [ $+ [ $site ] ] > 6) {
        ; Site flood activated
        inc -u45 %-ignore.ctcp. $+ $site
        _alert FLOOD DCC flood from $:b($nick) ( $+ $address $+ ) Further CTCPs from address won't be shown (ignored)
        halt
      }
    }
    if (%!away) %type = $mid(%`dcc.opt,$calc(%type * 2 + 4 + $findtok(CHAT SEND,$2,32)),1)
    elseif (%type == 2) %type = 0
    else %type = $mid(%`dcc.opt,$calc(%type * 2 + $findtok(CHAT SEND,$2,32)),1)
    if ($2 == CHAT) {
      .timer.dccreset1 -om 1 0 .creq $creq
      var %open = $gettok(auto ignore ignore ask,$calc(%type + 1),32)
      %_chat.open. [ $+ [ $nick ] ] = $iif(%open != ignore,%open)
      .creq %open
      if (%type == 2) _linedance .notice $nick $_finalmsg($replace($_msg($iif(%!away,rejectchata,rejectchat)),&nick&,$nick))
    }
    else {
      .timer.dccreset2 -om 1 0 .sreq $sreq
      .sreq $gettok(auto ignore ignore ask,$calc(%type + 1),32)
      if (%type == 2) _linedance .notice $nick $_finalmsg($replace($_msg($iif(%!away,rejectsenda,rejectsend)),&nick&,$nick))
    }
    return
  }

  if (%`myflood.prot !& 1) goto ctcpokay

  _recseen user $nick
  inc -u3 %-quick.ctcp

  if (%-recd.ctcp > 6) {
    ; Overall flood activated
    inc -u45 %-ignore.ctcp
    if ($1- == VERSION) .ignore -tu20 **!**@**
    _alert FLOOD CTCP flood detected- Further CTCPs won't be shown (ignored)
    if ($chan !ischan) _trn
  }
  elseif (%-recd.ctcp. [ $+ [ $site ] ] > 3) {
    ; Site flood activated
    inc -u45 %-ignore.ctcp. $+ $site
    if ($1- == VERSION) .ignore -tu20 $wildsite
    _alert FLOOD CTCP flood from $:b($nick) ( $+ $address $+ ) Further CTCPs from address won't be shown (ignored)
    if ($chan !ischan) _trn
  }
  elseif (($1 == ECHO) || (($1 == PING) && ($len($2-) > 30))) {
    ; Oversized ping or echo
    if (%-echo.ctcp) {
      inc -u45 %-ignore.ctcp. $+ $site
      _alert FLOOD Flood $upper($1) ( $+ $len($1-) bytes) from $:b($nick) ( $+ $address $+ ) Further CTCPs from address won't be shown (ignored)
      if ($chan !ischan) _trn
    }
    else { inc -u15 %-echo.ctcp | <ctcp.echo> $nick $address $1- }
  }
  elseif ((%-recd.ctcp > 4) || (%-recd.ctcp. [ $+ [ $site ] ] > 2) || (%-quick.ctcp > 2)) {
    ; Show but no reply
    <ctcp.ignore> $nick $address $1-
  }
  else {
    :ctcpokay
    var %reply = $_repl.ctcp($1,$2-)

    if ($1 == PING) {
      ; Standard ping
      _qcr $nick $1-
      if (%reply) {
        _linedance _qnotice $nick %reply
        set -u1 %.creply %reply
        if (%.replrand) <ctcp.ping2> $nick $address $1-
        else <ctcp.ping1> $nick $address $1-
      }
      else {
        <ctcp.ping1> $nick $address $1-
      }
    }

    elseif (%reply) {
      ; Normal reply
      _linedance _qcr $nick $1 %reply
      set -u1 %.creply %reply
      if (%.replrand) <ctcp.other2> $nick $address $1-
      else <ctcp.other3> $nick $address $1-
    }
    elseif (($1- == VERSION) || (%.ctcp.reply == 0)) <ctcp.other3> $nick $address $1-
    else {
      ; No known reply
      _Q.fkey 1 $calc($ctime + 180) ctcpreply $nick $1 $!_entry(0,$null, $+ $1 reply to send to $nick $+ ?)
      <ctcp.other1> $nick $address $result $1-
    }
  }

  unset %.ctcp.reply | halt
}

;
; Self pings
;

raw 421:& *§ *:{
  if (%-sp. [ $+ [ $round($2,0) ] ] ) %-self.lag = $_dur($calc(($ticks - $ifmatch) / 1000))
  else { unset %-sp.* | _qsp | halt }
  if (R isin $2) disp Self-Ping of $:s(%-self.lag)
  if ($round($2,0) == %-sp.index) .timer 1 0 unset % $+ -sp.*
  else .timer 1 0 unset % $+ -sp. $+ $round($2,0)
  if ($_cfgi(sptime)) {
    if ((min isin %-self.lag) || ($gettok(%-self.lag,1,46) > 20)) .timer.selfping 1 $calc($_cfgi(sptime) / 2) _qsp
    else .timer.selfping 1 $_cfgi(sptime) _qsp
    _upd.title
  }
  else { .timer.selfping 0 99 if ($_cfgi(sptime)) _qsp | unset %-self.lag }
  .timer.selfwarn? off
  .timer.selflagup off
  unset %-sp.count
  halt
}
alias ps sp
alias sp _qsp R | disp Self-Ping...
alias _qsp {
  inc %-sp.index
  %-sp. [ $+ [ %-sp.index ] ] = $ticks
  %-sp.index $+ $1 $+ §
  if ($_cfgi(sptime)) .timer.selfping 1 $int($calc($ifmatch * 1.5)) _qsp X
  else { .timer.selfping 0 99 if ($_cfgi(sptime)) _qsp | unset %-self.lag }
  if (X !isin $1) {
    if ($_cfgi(spwarn1)) .timer.selfwarn1 1 $ifmatch _alert SELFLAG Warning- Over $:b($ifmatch) sec lag to self!
    if ($_cfgi(spwarn2)) .timer.selfwarn2 1 $ifmatch _alert SELFLAG Warning- Over $:b($ifmatch) sec lag to self!
    %-sp.count = 0
    .timer.selflagup -c 0 1 inc %-sp.count $chr(124) % $+ -self.lag = % $+ -sp.count $!+ + s
  }
}
raw 1:*:if ($_cfgi(sptime)) { .timer.selfping 1 $ifmatch _qsp | %-self.lag = ?? s } | else .timer.selfping 0 99 if ($_cfgi(sptime)) _qsp

; Update address (and possibly titlebar) instantly on nickchange
on me:*:NICK:%!myself = $newnick $+ ! $+ $gettok($fulladdress,2-,33) | _upd.title

;
; CTCP-related commands
;
alias uinfo userinfo $1-
alias userinfo if ($1) var %target = $_ncs(44,$_s2c($1-)) | else _qhelp /userinfo | <send.ctcp> %target USERINFO | _qc %target USERINFO
alias cinfo clientinfo $1-
alias clientinfo if ($1) var %target = $_ncs(44,$_s2c($1-)) | else _qhelp /clientinfo | <send.ctcp> %target CLIENTINFO | _qc %target CLIENTINFO
alias script if ($1) var %target = $_ncs(44,$_s2c($1-)) | else _qhelp /script | <send.ctcp> %target SCRIPT | _qc %target SCRIPT
alias fing if ($1) var %target = $_ncs(44,$_s2c($1-)) | else _qhelp /fing | <send.ctcp> %target FINGER | _qc %target FINGER
alias date time $1-
alias time {
  if ($1 == $null) dispa It is currently - $_datetime
  else {
    var %target = $_ncs(44,$_s2c($1-))
    <send.ctcp> %target TIME
    _qc %target TIME
  }
}
alias ver version $1-
alias version {
  if ($1 == $null) {
    dispa You are using Peace & Protection $:t($:ver)) by misspai
    dispa Homepage- $:s($:www())
    if (%!addon.ids != $null) dispa Addons- $_addon.names(1)
  }
  else {
    var %target = $_ncs(44,$_s2c($1-))
    <send.ctcp> %target VERSION
    _qc %target VERSION
  }
}
alias page if ($1) var %target = $_ncs(44,$1) | else _qhelp /page | <send.ctcp> %target PAGE $2- | _qc %target PAGE $2-
alias ctcp {
  if (($2 == PING) && ((($3 isnum) && ($3 != 0)) || ($3 == $null))) { ping $1 | return }
  var %target
  if ($2) %target = $_ncs(44,$1)
  else _qhelp /ctcp $1
  if ($istok(XDCC PING ECHO PAGE TIME USERINFO VERSION,$2,32) == $false) _recent ctcp 5 $upper($2) $3-
  <send.ctcp> %target $upper($2) $3-
  _qc %target $upper($2) $3-
}
alias ctcpreply if ($2) var %target = $_ncs(44,$1) | else _qhelp /ctcpreply $1 | <send.reply> %target $2- | _qcr %target $2-

;
; Pinging and CTCP replies
;

alias ping {
  if ($1) var %target = $_ncs(44,$_s2c($1-))
  elseif ($_targ(=?#)) var %target = $active
  else _error You must specify a user or channel to /ping.(or use /ping in a query or channel window)
  if (=* iswm %target) dcp %target
  else { var %ticks = $ticks | _qc %target PING $ctime 0 %ticks | <send.ping> %target PING $ctime 0 %ticks | _prepping %target %ticks PING }
}
alias vping verping $1-
alias verping {
  if ($1) var %target = $_ncs(44,$1)
  elseif ($_targ(=?#)) var %target = $active
  else _error You must specify a user or channel to /verping.(or use /verping in a query or channel window)
  if (=* iswm %target) dcp %target
  else { var %ticks = $ticks | _qc %target $iif($2,$upper($2),VERSION) | <send.ping> %target $iif($2,$upper($2),VERSION) %ticks | _prepping %target %ticks $iif($2,$upper($2),VERSION) }
}
alias -l _prepping {
  var %targ,%file,%nick,%count,%num = $numtok($1,44)
  :loop
  %targ = $gettok($1,%num,44)
  if (%targ ischan) {
    %file = $_temp($_repl.fn(%targ))
    .remove %file
    %count = $nick(%targ,0)
    if ($_cfgi(nickcol)) {
      :loop2
      %nick = $nick(%targ,%count)
      %-ping. [ $+ [ %nick ] ] = $2 %targ $3
      %-nickflags. [ $+ [ %nick ] ] = $remove(%-nickflags. [ $+ [ %nick ] ] ,L) $+ p
      if (%count > 1) { dec %count | goto loop2 }
    }
    else {
      :loop3
      %nick = $nick(%targ,%count)
      %-ping. [ $+ [ %nick ] ] = $2 %targ $3
      if (%count > 1) { dec %count | goto loop3 }
    }
    unset %-ping. $+ $me
    %-nickflags. [ $+ [ $me ] ] = $remove(%-nickflags. [ $+ [ $me ] ] ,p)
    %-ping. [ $+ [ %targ ] ] = $nick(%targ,0) - 1
    %-pingtot. [ $+ [ %targ ] ] = 0
    %-pingnum. [ $+ [ %targ ] ] = 0
    if (%!servnick) {
      %count = $numtok(%!servnick,32)
      :loop4
      if ($gettok(%!servnick,%count,32) ison %targ) {
        unset %-ping. $+ $ifmatch
        dec %-ping. $+ %targ
        %-nickflags. [ $+ [ $ifmatch ] ] = $remove(%-nickflags. [ $+ [ $ifmatch ] ] ,p)
      }
      if (%count > 1) { dec %count | goto loop4 }
    }
    if ($_cfgi(nickcol)) col.nicklist %targ
  }
  else %-ping. [ $+ [ %targ ] ] = $2 %targ $3
  if (%num > 1) { dec %num | goto loop }
}
on *:QUIT:_rempingcol $nick
on *:PART:#:_rempingcol $nick $chan
on *:KICK:#:_rempingcol $knick $chan
;;; follow nick changes?
alias _rempingcol {
  var %ping = %-ping. [ $+ [ $1 ] ]
  if (%ping) {
    var %type = $gettok(%ping,3,32),%ping = $gettok(%ping,2,32)
    if ($_ischan(%ping)) {
      if (($2) && (%ping != $2)) return
      dec %-ping. $+ %ping
      if ((%-ping. [ $+ [ %ping ] ] == 0) && (%-pingavg. [ $+ [ %ping ] ] )) <ping.avg> %ping %type 0 %-pingavg. [ $+ [ %ping ] ]
      var %win = @Ping [ $+ [ $chr(160) ] $+ [ $2 ] ]
      if ($window(%win)) rline $iif($sline(%win,1).ln == 1,-a) $:d %win 1 $<ping.summary>(%-pingavg. [ $+ [ $2 ] ] ,%-ping. [ $+ [ $2 ] ] )
    }
    unset %-ping. $+ $nick
  }
}
on *:NOTICE:*:?:var %ping = %-ping. [ $+ [ $nick ] ] | if (($gettok(%ping,2,32) ischan) && ($_cfgi(nickcol))) _removepc $gettok(%ping,2,32) $nick
alias _do.creply {
  ; $show stuff and returns are for ezping support ;)
  ;;; reduce this junk and return to old 00$ticks method? :/
  ;;; need flood prot against pings too; make global reply prot looser
  var %ping = %-ping. [ $+ [ $nick ] ]
  if (($1 == PING) && ($2 isnum) && ($3 == 0) && ($4 isnum)) %ping = $4 $iif(%ping,$gettok(%ping,2,32),$nick) PING
  if ((%ping) && ($gettok(%ping,3,32) == $1)) {
    var %ticks = $ticks,%time = $gettok(%ping,1,32),%target = $gettok(%ping,2,32)
    unset %-ping. $+ $nick
    if ($show == $false) { haltdef | return $calc(%ticks - %time) }
    if ($_ischan(%target)) {
      inc %-pingtot. $+ %target $calc(%ticks - %time)
      inc %-pingnum. $+ %target
      %-pingavg. [ $+ [ %target ] ] = $_round($calc(%-pingtot. [ $+ [ %target ] ] / %-pingnum. [ $+ [ %target ] ] / 1000),3)
      dec %-ping. $+ %target
      set -u180 %-titleavg. $+ %target lag [[ $+ $_dur(%-pingavg. [ $+ [ %target ] ] ) $+ ]] $iif(%-ping. [ $+ [ %target ] ] , need [ [[ $+ [ %-ping. [ $+ [ %target ] ] ] $+ ]] ] ping)
      if (%`ping.bulk == *) <ping.reply> %target %target $nick $calc((%ticks - %time) / 1000) $1-
      elseif (%`ping.bulk == @Ping) {
        var %win = @Ping [ $+ [ $chr(160) ] $+ [ %target ] ]
        if ($window(%win) == $null) {
          _window 2.1 $iif(%`ping.focus == min,-ln,-l) + %win -1 -1 -1 -1 @Ping
          if (%`ping.retain) _loadbuf %win $_temp($_repl.fn(%target))
        }
        elseif (%`ping.focus == front) window -a %win
        rline $iif($sline(%win,1).ln == 1,-a) $:d %win 1 $<ping.summary>(%-pingavg. [ $+ [ %target ] ] ,%-ping. [ $+ [ %target ] ] )
        <ping.reply> %win %target $nick $calc((%ticks - %time) / 1000) $1-
        window -b %win
      }
      elseif (%`ping.bulk != none) <ping.reply> %`ping.bulk %target $nick $calc((%ticks - %time) / 1000) $1-
      if (%-ping. [ $+ [ %target ] ] == 0) <ping.avg> %target $1 0 %-pingavg. [ $+ [ %target ] ]
      if (%`ping.retain) write $_temp($_repl.fn(%target)) $:x $iif($1 != PING,$:s($1)) $:s(PING) reply of $:s($_dur($calc((%ticks - %time) / 1000))) from $:t($nick) $iif(($1 != PING) && ($2),(reply of [ [ $:q($2-) ] $+ ) ] )
      if ((%target ischan) && ($_cfgi(nickcol))) _removepc %target $nick $iif($calc((%ticks - %time) / 1000) > %`lagtime,L)
    }
    else <ping.reply> $iif(%`ping.one == *,%target,%`ping.one) 0 $nick $calc((%ticks - %time) / 1000) $1-
    haltdef
    return $calc(%ticks - %time)
  }
  elseif ($halted == $false) {
    if (($gettok(%ping,2,32) ischan) && ($_cfgi(nickcol))) _removepc $gettok(%ping,2,32) $nick
    _recd.reply $1-
  }
}
alias -l _removepc {
  %-nickflags. [ $+ [ $2 ] ] = $remove(%-nickflags. [ $+ [ $2 ] ] ,p,L) $+ $3
  upd.nick.col $1 $2
}
alias avglag {
  if ($1) var %target = $1 | else var %target = $active
  if ($_not($_ischan(%target))) _error You can only check average lag of a channel.Either use in a channel or specify a channel name.
  <ping.avg> %target ping 1 %-pingavg. [ $+ [ %target ] ]
  if ($_cfgi(nickcol)) {
    var %num = $nick(%target,0)
    :loop
    %-nickflags. [ $+ [ $nick(%target,%num) ] ] = $remove(%-nickflags. [ $+ [ $nick(%target,%num) ] ] ,p,L)
    upd.nick.col %target $nick(%target,%num)
    if (%num > 1) { dec %num | goto loop }
  }
}
alias pwin {
  if ($1) var %target = $1 | else var %target = $active
  if ($_not($_ischan(%target))) _error You can only view stored pings for a channel.Either use in a channel or specify a channel name.
  var %win = @Ping [ $+ [ $chr(160) ] $+ [ %target ] ]
  if ($window(%win) == $null) {
    if ($exists($_temp($_repl.fn(%target)))) {
      _window 2.1 -l + %win -1 -1 -1 -1 @Ping
      _loadbuf %win $_temp($_repl.fn(%target))
      window -b %win
      iline $:d %win 1 $<ping.summary>(%-pingavg. [ $+ [ %target ] ] ,%-ping. [ $+ [ %target ] ] )
    }
    else _doerror Warning- No stored pings for %target $+ .Verify that the option to retain ping replies is enabled.
  }
  else window -a %win
}
alias -l _recd.reply {
  if ((%-ignore.ctcp) || (%-ignore.ctcp. [ $+ [ $site ] ] )) halt

  inc -u3 %-recd.ctcpr
  inc -u5 %-recd.ctcpr. $+ $site
  if ((%-recd.ctcpr. [ $+ [ $site ] ] > 4) || (%-recd.ctcpr > 8)) {
    ; Reply flood activated
    inc -u3 %-ignore.ctcp
    inc -u20 %-ignore.ctcp. $+ $site
    halt
  }
  <ctcp.reply> $target $nick $address $1-
  haltdef
}
menu @Ping {
  Configure...:config pi
}

;
; Basic messaging/ctcp'ing
;

; quiet privmsg, notice, ctcp, action, ctcp reply
alias _privmsg .raw privmsg $1 : $+ $2-
alias _qnotice .raw notice $1 : $+ $2-
alias _tnotice _qnotice $1- | echo $colour(notice) -si2 $<priv.you.not>($me,-,-,-,$1,$2-)
alias _qc if (=* iswm $1) .msg $1  $+ $2- $+  | else .raw privmsg $1 : $+ $2- $+ 
alias _qca if (=* iswm $1) .msg $1 ACTION $2- $+  | else .raw privmsg $1 :ACTION $2- $+ 
alias _qcr if (=* iswm $1) .msg $1 \ $+ $2- $+  | else .raw notice $1 : $+ $2- $+ 

;
; CTCP reply editing
;
alias ctcpedit dialog -dm ctcpedit ctcpedit
dialog ctcpedit {
  title "CTCP replies"
  size -1 -1 400 348

  box "CTCPs:", 21, 10 10 380 185
  list 2, 20 30 360 120, extsel sort

  button "Add...", 10, 21 155 80 25
  button "Remove", 11, 111 155 80 25
  button "Load defaults", 12, 269 155 110 25

  box "Response to CTCP:", 22, 10 210 380 85

  combo 4, 20 230 100 100, drop
  edit "", 5, 130 230 250 22, autohs
  button "Select...", 8, 20 260 60 22
  button "Default", 9, 310 260 70 22

  button "OK", 100, 10 310 80 25, ok
  button "Cancel", 101, 100 310 80 25, cancel
  button "Help", 102, 310 310 80 25, disable
}
on *:DIALOG:ctcpedit:init:*:{
  loadbuf -otctcp $dname 4 script\dlgtext.dat
  if ($exists($_cfg(ctcp.dat))) loadbuf -o $dname 2 $_cfg(ctcp.dat)
  _loadctcp
}
on *:DIALOG:ctcpedit:sclick:100:{
  filter -cif $dname 2 $_cfg(ctcp.dat) *
}
on *:DIALOG:ctcpedit:sclick:2:_loadctcp
alias -l _loadctcp {
  var %count = $did(ctcpedit,2,0).sel
  did $iif(%count,-e,-b) ctcpedit 11
  if (%count == 1) {
    var %ctcp = $did(ctcpedit,2,$did(ctcpedit,2).sel)
    var %name = $gettok(%ctcp,1,32)
    did -ae ctcpedit 22 Response to %name $+ :
    var %def = $read -ns [ $+ [ %name ] ] script\defcfg\ctcp.dat
    did $iif(%def,-e,-b) ctcpedit 9
    %ctcp = $gettok(%ctcp,2-,32)
    if (!Random:* iswm %ctcp) {
      did -ce ctcpedit 4 2
      did -era ctcpedit 5 $right(%ctcp,-9)
      did -e ctcpedit 8
    }
    elseif (!Command:* iswm %ctcp) {
      did -ce ctcpedit 4 3
      did -era ctcpedit 5 $right(%ctcp,-9)
      did -b ctcpedit 8
    }
    elseif (!Ignore == %ctcp) {
      did -ce ctcpedit 4 4
      did -rb ctcpedit 5
      did -b ctcpedit 8
    }
    else {
      did -ce ctcpedit 4 1
      did -era ctcpedit 5 %ctcp
      did -b ctcpedit 8
    }
  }
  else {
    did -ab ctcpedit 22 Response to CTCP:
    did -ub ctcpedit 4
    did -rb ctcpedit 5
    did -b ctcpedit 8,9
  }
}
alias -l _savectcp {
  var %ctcp = $gettok($did(ctcpedit,2,$did(ctcpedit,2).sel),1,32)
  if ($did(ctcpedit,4).sel > 1) var %text = $gettok(. !Random: !Command: !Ignore,$ifmatch,32) $+ $did(ctcpedit,5)
  else var %text = $did(ctcpedit,5)
  did -oc ctcpedit 2 $did(ctcpedit,2).sel %ctcp %text
}
on *:DIALOG:ctcpedit:sclick:9:{
  did -oe $dname 5 1 $read -ns [ $+ [ $gettok($did(2,$did(2).sel),1,32) ] ] script\defcfg\ctcp.dat
  did -c $dname 4 1
  did -b $dname 8
  _savectcp
}
on *:DIALOG:ctcpedit:edit:5:_savectcp
on *:DIALOG:ctcpedit:sclick:4:{
  did $iif($did(4).sel == 2,-e,-b) $dname 8
  did $iif($did(4).sel == 4,-br,-e) $dname 5
  _savectcp
}
on *:DIALOG:ctcpedit:sclick:8:_juryrig _ctcppf
alias _ctcppf {
  var %new = $dir="File to take random replies from?" $did(ctcpedit,5)
  if (%new == $null) { dialog -v ctcpedit | $$$ }
  did -o ctcpedit 5 1 %new
  _savectcp
  dialog -v ctcpedit
}
on *:DIALOG:ctcpedit:sclick:10:_juryrig _ctcpadd
alias _ctcpadd {
  var %new = $_entry(-1,$null,CTCP to add a reply for?)
  if ($_finddid(ctcpedit,2,%new)) did -c ctcpedit 2 $ifmatch
  else did -ac ctcpedit 2 $upper(%new)
  _loadctcp
}
on *:DIALOG:ctcpedit:sclick:11:{
  :loop
  if ($did(2).sel) {
    did -d $dname 2 $ifmatch
    goto loop
  }
  _loadctcp
}
on *:DIALOG:ctcpedit:sclick:12:{
  did -r $dname 2
  loadbuf -o $dname 2 script\defcfg\ctcp.dat
  _loadctcp
}