# IdealIRC Essentials script v1.0 # (Map) Used if we try to ban someone but we haven't registered their hostname yet. global banqueue, kickqueue; hook start() { # Queue for host lookup if a ban is issued, but hostname is unknown. # Key: nickname, Value: channel to issue ban. banqueue = map(); # Same as above, but value is the kick reason. kickqueue = map(); } menu status { "Server stats" => /lusers "Join channel" => { channel = input("Join channel", "Enter a channel name:"); if (channel == void || channel == "") return; # Todo: Implement new function "ischannelprefix" or something. if (channel[0] != "#") channel = "#" + channel; /join %channel } "Change nickname" => { nickname = input("Set nickname", "Enter nickname:"); if (nickname == void || nickname == "") return; /nick %nickname } } menu private { "Whois" => /whois %nickname divide "CTCP" { "Ping" => /ctcp %nickname PING "Version" => /ctcp %nickname VERSION "Time" => /ctcp %nickname TIME divide "Custom..." => { msg = input("Custom CTCP message", "Message:"); if (msg == void) return; if (msg == "") return; /ctcp %nickname %msg } } } menu memberlist { "Whois" => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members to show /whois for. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; /whois %nick i = i + 1; } } "Query" => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members to open a query dialog for. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; /query %nick i = i + 1; } } divide "Privileges" { "Give op" => privilege(channel, "+", "o", selected); "Take op" => privilege(channel, "-", "o", selected); divide "Give half-op" => privilege(channel, "+", "h", selected); "Take half-op" => privilege(channel, "-", "h", selected); divide "Give voice" => privilege(channel, "+", "v", selected); "Take voice" => privilege(channel, "-", "v", selected); } divide "Kick..." => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for kicking. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; reason = input("Kick " + nick + " from " + channel, "Enter a reason for " + nick + ":"); if (reason != void) /kick %channel %nick %reason i = i + 1; } } "Ban" => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for ban. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; host = userhost(nick); if (host == void) { banqueue[nick] = channel; /userhost %nick } else { /mode %channel +b %host } i = i + 1; } } "Ban + kick..." => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for ban + kick. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; reason = input("Ban + kick " + nick + " from " + channel, "Enter a reason for " + nick + ":"); if (reason != void) { host = userhost(nick); if (host == void) { banqueue[nick] = channel; kickqueue[nick] = reason; /userhost %nick } else { /mode %channel +b %host /kick %channel %nick %reason } } i = i + 1; } } divide "CTCP" { "Ping" => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for CTCP PING. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; /ctcp %nick PING i = i + 1; } } "Version" => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for CTCP VERSION. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; /ctcp %nick VERSION i = i + 1; } } "Time" => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for CTCP TIME. Continue?", "question", "yn"); if (button == "n") return; } i = 0; while (selected[i] != void) { nick = selected[i]; /ctcp %nick TIME i = i + 1; } } divide "Custom..." => { if (maplen(selected) > 1) { button = showmessage("Multiple members selected", "You have selected " + maplen(selected) + " members for custom CTCP. Continue?", "question", "yn"); if (button == "n") return; } msg = input("Custom CTCP message", "Message:"); if (msg == void || msg == "") return; i = 0; while (selected[i] != void) { nick = selected[i]; /ctcp %nick %msg i = i + 1; } } } } hook numeric(code, args, msg) { if (code == "302") { # ::= ['*'] '=' <'+'|'-'> # The '*' indicates whether the client has registered # as an Operator. The '-' or '+' characters represent # whether the client has set an AWAY message or not # respectively. nickend = strfind(msg, "="); if (msg[nickend - 1] == "*") nickend = nickend - 1; nickname = strmid(msg, 0, nickend); if (banqueue[nickname] != void) { channel = banqueue[nickname]; mapremove(&banqueue, nickname); host = userhost(nickname); /mode %channel +b %host if (kickqueue[nickname] != void) { reason = kickqueue[nickname]; mapremove(&kickqueue, nickname); /kick %channel %nickname %reason } } } } # # Generate a /MODE message that can handle all selected nicknames in # a nickname list, based on the amount of concurrent modes the server supports. # function privilege(channel, action, mode, members) { maxmodes = toint(isupport("MODES")); totalmodes = maplen(&members); i = 0; while (i < totalmodes) { modelen = maxmodes; if ((totalmodes - i) < maxmodes) modelen = totalmodes - i; j = i; nicks = ""; while (j < (i + modelen)) { nicks = nicks + members[j] + " "; j = j + 1; } modestr = action + strrep(mode, modelen); /mode %channel %modestr %nicks i = i + modelen; } }