# IdealIRC Essentials script v1.0 # (Map) Used if we try to ban someone but we haven't registered their hostname yet. global banqueue, kickqueue; command j(channel, key) { if (channel == void) { /echo Usage: /j channel return; } if (channel[0] != "#") channel = "#" + channel; if (key == void) /join %channel else /join %channel %key } command p(channel, message) { if (channel == void) { if (subwintype() == "Channel") { channel = subwinname(); } else { /echo -G /p: Not in a channel. Try /p channel return; } } if (channel[0] != "#") channel = "#" + channel; if (message == void) /part %channel else /part %channel %message } command w(nickname) /whois %nickname hook ctcprequest(sender, target, command, message) { # For simplicity, set following to "false" if this is undesirable: response_CTCP_TIME = true; if (command == "TIME" && response_CTCP_TIME) { t = now("yyyy/MM/dd hh:mm:ss t"); /ctcpreply TIME %sender %t } } 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 PING %nickname "Version" => /ctcp VERSION %nickname "Time" => /ctcp TIME %nickname divide "Custom..." => { msg = input("Custom CTCP message", "Message:"); if (msg == void) return; if (msg == "") return; sidx = strfind(msg, " "); if (sidx < 0) /ctcp %msg %nickname else { command = strmid(msg, 0, sidx); message = strmid(msg, sidx + 1, strlen(msg) - strlen(command) - 1); /ctcp %command %nickname %message } } } } 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 PING %nick 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 VERSION %nick 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 TIME %nick 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; command = ""; message = ""; sidx = strfind(msg, " "); if (sidx < 0) { command = msg; } else { command = strmid(msg, 0, sidx); message = strmid(msg, sidx + 1, strlen(msg) - strlen(command) - 1); } i = 0; while (selected[i] != void) { nick = selected[i]; /ctcp %command %nick %message i = i + 1; } } } } # # Used as a callback when trying to ban someone we don't know the hostname of, # and this numeric responds with a hostname to ban. # 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; } }