####################################################
# by wiebe @ QuakeNet
#
####################################################


####################################################
# cmd:help:pubm
####################################################
bind pubm fvlomn|fvlomn "% ${botnet-nick} help cmd" cmd:help:pubm
proc cmd:help:pubm { n u h c t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "cmd: usage cmd <command>"
  lappend o "cmd: shows info for the given IRC command"
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "" } }
  putloglev c $c "help: $n $u $h $c cmd"
  return 1
}


####################################################
# cmd:help:msg
####################################################
bind msgm fvlomn|fvlomn "help cmd" cmd:help:msgm
proc cmd:help:msgm { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  lappend o "cmd: usage cmd <command>"
  lappend o "cmd: shows info for the given IRC command"
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "" } }
  putcmdlog "($n!$u) !$h! help cmd"
  return 1
}


####################################################
# cmd:pubm
####################################################
bind pubm fvlomn|fvlomn "% ${botnet-nick} cmd" cmd:pubm
bind pubm fvlomn|fvlomn "% ${botnet-nick} cmd *" cmd:pubm
proc cmd:pubm { n u h c t } {
  if {[matchattr $h bkZ]} { return 0 }
  set t [lindex [split $t] 2]
  if {[string equal $t ""]} {
    lappend o "cmd: usage cmd <command>"
  } else {
    set o [cmd:list $t]; set m [lindex [split [getchanmode $c]] 0]
    if {![string match *m* $m] || [botisop $c] || [botishalfop $c] || [botisvoice $c]} {
      if {[string match *c* $m] } { set o [stripcodes bcru $o] }
      if {[string equal [info procs privmsg] ""]} { foreach l $o { puthelp "PRIVMSG $c :$l" }
      } else { foreach l $o { privmsg $c $l puthelp "" } }
      set o ""
    }
  }
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "" } }
  putloglev c $c "cmd: $n $u $h $c $t"
  return 1
}


####################################################
# cmd:msg
####################################################
bind msg fvlomn|fvlomn cmd cmd:msg
proc cmd:msg { n u h t } {
  if {[matchattr $h bkZ]} { return 0 }
  set t [lindex [split $t] 0]
  if {[string equal $t ""]} { lappend o "cmd: usage cmd <command>"
  } else { set o [cmd:list $t] }
  if {[string equal [info procs cnotice] ""]} { foreach l $o { puthelp "NOTICE $n :$l" }
  } else { foreach l $o { cnotice $n $l puthelp "" } }
  return 1
}


####################################################
# cmd:dcc
####################################################
bind dcc -|- cmd cmd:dcc
proc cmd:dcc { h i t } {
  set t [lindex [split $t] 0]
  if {[string equal $t ""]} {
    lappend o "cmd: usage cmd <command>"
    lappend o "cmd: shows info for the given IRC command"
  } else { set o [cmd:list $t] }
  foreach l $o { putidx $i $l }
  return 1
}


####################################################
# cmd:list
####################################################
proc cmd:list { t } {
  set t [string tolower $t]

  set c(account) {
    "format (P10): <source server numeric> AC <target user numeric> <account name>"
    "info: sets a user's account name. they are sent by a service which supports ACCOUNT when someone logs in to it. if a user's account name field is set, the ircd knows the user is \"logged in\", and can have a \"is logged in as\" line in the whois reply."
    "info: it can be set exactly once for a user; it can't be changed or unset. the source of an account message may be any server, but not a user."
  }

  set c(admin) {
    "format: ADMIN \[<server>\]"
    "info: shows administrative contact for the local or specified server."
  }

  set c(asll) {
    "format: ASLL <server> \[<remote_server>\]"
    "info: shows 'Asymmetric Link Latency' ping results from local/remote server to the given server."
  }

  set c(away) {
    "format: AWAY \[:<message>\]"
    "AWAY: used to to (un)mark yourself as being away."
  }

  set c(burst) {
    "format (P10): <source server numeric> B <chan> <timestamp> +\[<modes> \[<mode extra parameters>\]\] \[<users>\] \[<bans>\]"
    "info: when a server link is established, a netburst is sent to tell the other end of the link about the complete network state."
  }

  set c(check) {
    "format: CHECK <chan>|<server>|<nick>|<hostmask> \[<flags>\]"
    "info: shows detailed information about a nick!user@host, channel or server."
    "info: where valid flags are: -c (show channels when checking a hostmask)   -i (show IPs instead of hostnames when displaying results)   -o (only show channel operators when checking a channel)   -u (hide users when checking a channel)"
    "info: <hostmask> can be of the form host, user@host, nick!user@host, with host being host.domain.cc, 127.0.0.1 or 127.0.0.0/24. wildcards are supported."
  }

  set c(clearmode) {
    "format: CLEARMODE \[!\]<chan> \[<modes>\]"
    "info: makes the server clear all or the given modes from the target channel."
    "info: depending on server settings, the ! may be used to override Q:lines."
  }

  set c(close) {
    "format: CLOSE"
    "info: closes unregistered connections to the server."
  }

  set c(cnotice) {
    "format: CNOTICE <nick> <chan> :<message>"
    "info: sends a notice to nick. this command bypasses the target flood limit. you must be voiced or opped on <chan> and <nick> must be on it."
  }

  set c(connect) {
    "format: CONNECT <server> \[<port> \[<remote_server>\]\]"
    "info: makes the (remote) server connect to the server specified."
  }

  set c(cprivmsg) {
    "format: CPRIVMSG <nick> <chan> :<message>"
    "info: sends a privmsg to nick. this command bypasses the target flood limit. you must be voiced or opped on the <chan> and <nick> must be on it."
  }

  set c(create) {
    "format (P10): <source user numeric> C <chan> <timestamp>"
    "info: user creates channel - is the first to join and gets op. <chan> is a comma seperated list of one or more channels."
  }

  set c(die) {
    "format: DIE"
    "info: terminates the server."
  }

  set c(dns) {
    "format: DNS \[r\]"
    "info: shows info related to dns for the server. the r option restarts the dns resolver."
  }

  set c(destruct) {
    "format (P10): <source numeric> DE <chan> <timestamp>"
    "info: destruct is going to be used in ircu 2.10.12 where a channel is not destroyed when the last user leaves. they are not sent in earlier versions. current implementation is propagating the message to all other servers if the channel does not exist, and ignored if the channel exists (has users)."
  }

  set c(desynch) {
    "format (P10): <source numeric> DS :<message>"
    "info: desynch wallops. broadcasted to all servers on the net. they are used as \"global server notice\". ircu sends them as wallops to all users with mode +g set."
  }

  set c(end_of_burst) {
    "format (P10): <source server numeric> EB"
    "info: the END_OF_BURST message (EB token) must be the last message of a netburst. if it is received from a directly connected server which has not ended burst yet, the end of burst must be acknowledged by sending an EOB_ACK (EA token) message back."
  }

  set c(end_of_burst_ack) {
    "format (P10): <source server numeric> EA"
    "info: the END_OF_BURST message (EB token) must be the last message of a netburst. if it is received from a directly connected server which has not ended burst yet, the end of burst must be acknowledged by sending an EOB_ACK (EA token) message back."
  }

  set c(error) {
    "format (P10): <source server numeric> Y :<message>"
    "info: send from a server to a server link before the connection is closed."
  }

  set c(get) {
    "format: GET <feature>"
    "info: shows the current setting/value of a feature, F line."
  }

  set c(gline) {
    "format: GLINE \[\[!\]\[+|-\]<mask> \[\[<target>\] <duration> :<reason>\]\]"
    "info: to look up, set/activate or remove/deactivate a gline."
    "info: <mask> can be a nick!user@host format or a channel. if target is not specified the local server is assumed, a * means global. duration is given in seconds. the ! is needed to set a wide gline."
  }

  set c(hash) {
    "format: HASH"
    "info: shows hash table statistics for the server."
  }

  set c(help) {
    "format: HELP"
    "info: shows the list of commands supported by the server."
  }

  set c(info) {
    "format: INFO \[<server>\]"
    "info: shows info about the ircd."
   }

  set c(invite) {
    "format: INVITE \[<nick> <chan>\]"
    "info: shows your invite list or invites a user to a channel. after being invited, the user can join the channel regardless of any restrictive modes, including channel bans."
  }

  set c(ison) {
    "format: ISON <nick>"
    "info: returns the nicks which are on IRC. <nick> is a comma seperated list of one or more nicks."
  }

  set c(join) {
    "format: JOIN <chan> \[<key>\]"
    "info: makes you join a channel. <chan> is a comma seperated list of one or more channels. <key> is a comma seperated list of one or more keys."
    "info: joining channel 0 makes you part all channels. all channels before the 0 are not joined. channels behind 0 are joined after parting all current channels."
  }

  set c(jupe) {
    "format: JUPE \[\[+|-\]<server> \[\[<target>\] <duration> :<reason>\]\]"
    "info: shows, add or remove entries from the JUPE list. a JUPE prevents a server from linking."
  }

  set c(kick) {
    "format: KICK <chan> <nick> \[:<message>\]"
    "info: to kick a user from a channel, optional with a reason."
  }

  set c(kill) {
    "format: KILL <nick> :<message>"
    "info: disconnects a user from IRC with the given message."
  }

  set c(links) {
    "format: LINKS \[\[<remote server>\] <server>\]"
    "info: shows the network structure."
  }

  set c(list) {
    "format: LIST \[stop|<chan>|<parameters>\]"
    "info: to list channels. 'stop' to end the current list request. channel is a comma seperated list of one or more channels. for info about <parameters>, '/QUOTE LIST :'"
  }

  set c(lusers) {
    "format: LUSERS \[<dummy> \[<remote server>\]\]"
    "info: shows number of visible and invisible users on the network, number of servers, number IRC operators, number of unknown connections, number of channels formed, number of local clients and servers and the highest connection count for the (remote) server."
  }
 
  set c(map) {
    "format: MAP"
    "info: shows the network structure."
  }

  set c(mode) {
    "format: MODE <your_nick>|<chan> \[<modes> \[<params>\]\]"
    "info: to view, set or unset a usermode/chanmode, if no - or + precedes the mode a + is assumed."
  }

  set c(motd) {
    "format: MOTD \[<server>\]"
    "info: shows the MESSAGE OF THE DAY for the local or specified server."
   }

  set c(names) {
    "format: NAMES \[-d\] <chan> \[<server>\]"
    "info: shows the users in the given channel (hidden users if -d option is used), for the local or specified server. <chan> is a comma seperated list of one or more channels."
   }

  set c(nick) {
    "format: NICK <newnick>"
    "info: changes your nickname."
  }

  set c(notice) {
    "format: NOTICE <target> :<message>"
    "info: sends a notice, a kind of message to which one should not auto respond. <target> is a comma seperated list of one or more nicks and/or channels. using @<chan> as target sends a notice to all channel operators."
    "info: using \$<hostmask> or \$<server> as target sends a notice to all users matching the hostmask or on the given server. sending to <nick>@<server> works for targets with usermode +k."
  }

  set c(oper) {
    "format: OPER <oper_id> <password>"
    "info: if successfull sets usermode +o (global operator) or usermode +O (local operator)."
  }

  set c(opmode) {
    "format: OPMODE \[!\]<chan> <modes> \[<params>\]"
    "info: makes the server change channel modes."
    "info: depending on server settings, the ! may be used to override Q:lines."
  }

  set c(part) {
    "format: PART <chan> \[:<message>\]"
    "info: parts a channel. <chan> is a comma seperated list of one or more channels. to part the channel(s) supplied, optional with a message."
  }

  set c(pass) {
    "format: PASS <password>"
    "info: used to logon the IRC server, if the server is password protected."
  }

  set c(ping) {
    "format: PING :<string>"
    "info: makes the server respond with a PONG followed by the <string> specified."
  }

  set c(pong) {
    "format: PONG :<string>"
    "info: needed to keep connected to the server. if the server sends a PING, a PONG with the <string> must be send back."
  }

  set c(post) {
    "format: POST"
    "info: this command is an alias for QUIT during the unregistered part of the server. this is because someone jumping via a broken web proxy will send a 'POST' as their first command - which we will obviously disconnect them immediately for, stopping people abusing open gateways."
  }

  set c(privmsg) {
    "format: PRIVMSG <target> :<message>"
    "info: sends a message. <target> is a comma seperated list of one or more nick and/or channels."
    "info: using \$<hostmask> or \$<server> as target sends a message to all users matching the hostmask or on the given server. sending to nick@server works for targets with usermode +k."
  }

  set c(privs) {
    "format: PRIVS \[<nick>\]"
    "info: shows the privileges you or the nick specified have. <nick> is a space seperated list of one or more nicks."
  }

  set c(proto) {
    "format: PROTO <param1> <param2>
    "info: a prototype or example command for coders."
  }

  set c(quit) {
    "format: QUIT \[:<message>\]"
    "info: disconnects you from the server."
  }

  set c(rehash) {
    "format: REHASH \[l|m\]"
    "info: reloads the server settings and the motd. if l (lower case L) is specified, log files are reopened. if m is specified, the MOTD cache is flushed."
  }

  set c(reset) {
    "format: RESET <feature>"
    "info: resets a value of a feature, F line."
  }

  set c(restart) {
    "format: RESTART"
    "info: restarts the server."
  }

  set c(rping) {
    "format: RPING <server> \[:<string>\]"
    "info: pings the server specified and returns the delay in milli seconds and optionaly the string specified."
  }

  set c(rpong) {
    "format (P10): <source server numeric> RO <pinged server> <start server name> <requesting oper numeric> <start timestamp, seconds> <start timestamp, microseconds> <optional remark>"
    "info: RPING request, from pinged server to start server - or from start server to requesting oper"
  }

  set c(server) {
    "format: SERVER <name of new server> <hops> <boot TS> <link TS> <protocol> <numeric of new server><max client numeric> <flags> :<description of new server>"
    "info: registering the connection to become server link."
  }

  set c(set) {
    "format: SET <feature> <value>"
    "info: sets a value of a feature, F line."
  }

  set c(sethost) {
    "format (user): SETHOST <hostname> <password>    or    MODE <nick> +h <hostname> <password>"
    "format (oper): SETHOST <username> <hostname>    or    MODE <nick> +h \[<user>@\]<host>"
    "info: changes your (user)host. to remove a sethost, 'SETHOST undo' or 'MODE <nick> -h' can be used."
  }

  set c(settime) {
    "format: SETTIME \[+|-\]<seconds> \[<server>\]"
    "info: to adjust the servertime."
  }

  set c(silence) {
    "format: SILENCE \[\[+|-\]<mask>|<nick>\]"
    "info: to show your own silence list or for the nick specified. + and - can be used to add/remove entries."
  }

  set c(squit) {
    "format: SQUIT <server> \[:<reason>\]"
    "info: disconnects the server specified (and everything behind it) from the network, the reason is shown in the server notice."
  }

  set c(stats) {
    "format: STATS \[\[<char>\] \[\[<server>\] \[<mask>\]\]\]"
    "info: shows STATS info for the given letter (case sensitive) for the local server or the server specified."
  }

  set c(time) {
    "format: TIME \[<server>\]"
    "info: shows the time of the server, and the bias from UTC (timezone) and the server's timestamp."
  }

  set c(topic) {
    "format: TOPIC <chan> \[:\[<topic>\]\]"
    "info: shows or changes the topic on the given channel. when re-setting the same topic, the change is only shown to you and for whom it changes. this allows resynching the topic without showing unneeded topic changes. <chan> is a comma seperated list of one or more channels."
  }

  set c(trace) {
    "format: TRACE \[<nick>|<server>\]"
    "info: shows the route on the network from the server to the given nick or server."
   }

  set c(uping) {
    "format: UPING <server>"
    "info: pings the ip of given server with UDP packets and shows the result."
  }

  set c(user) {
    "format: USER <username> 0 0 :<realname>"
    "info: needed to register with the server."
  }

  set c(userhost) {
    "format: USERHOST <nick>"
    "info: shows user@host for each of the given nicks, away status and IRC operator status. <nick> is a space seperated list of one or more nicks."
  }

  set c(userip) {
    "format: USERIP <nick>"
    "info: shows user@ip for each of the given nicks, away status and IRC operator status. <nick> is a space seperated list of one or more nicks."
  }

  set c(version) {
    "format: VERSION \[<server>\]"
    "info: shows version info and what features are supported for the local or specified server."
  }

  set c(wallchops) {
    "format: WALLCHOPS <chan> :<message>"
    "info: sends a notice to the channel ops. this is the same as using 'NOTICE @<chan> :<message>'."
  }

  set c(wallops) {
    "format: WALLOPS :<message>"
    "info: sends a wallops message to all users on the network with usermode +w."
  }

  set c(wallusers) {
    "format: WALLUSERS :<message>"
    "info: sends a wallusers message to all users on the network with usermode +w."
  }

  set c(wallvoices) {
    "format: WALLVOICES <chan> :<message>"
    "info: sends a notice to the channel ops and voices."
  }

  set c(who) {
    "format: WHO <mask1> \[\[<flags>\]\[%\[<fields>\[,<query-type>\]\]\] \[:<mask2>\]\]"
    "info: returns a line for each match, showing information for the user. for more info see http://ircu.sourceforge.net/release.2.10.01-who.html"
  }

  set c(whois) {
    "format: WHOIS \[<nick>|<server>\] <nick>"
    "info: shows info for the given user. <nick> is a comma seperated list of one or more nicks. wildcards are supported. using the server field shows the results from that server, using the nick twice gives the result from nick's server."
  }

  set c(whowas) {
    "format: WHOWAS <nick> \[<max> \[<server>\]\]"
    "info: shows who the given user was. <nick> is a comma seperated list of one or more nicks. <max> specifies how many results should be returned at most. using the server field shows the results from that server."
  }

  if {[info exists c($t)]} { set o $c($t)
  } else { lappend o "list of commands: [join [lsort -dictionary [array names c]]]" }
  return $o
}


set scriptdb(cmd) {
  "provides cmd command showing info for IRC commands"
}

