Added ChannelSettings and Essentials script

master
Tomatix 4 years ago
commit 856b18d60c
  1. 843
      ChannelSettings.iis
  2. 303
      Essentials.iis

@ -0,0 +1,843 @@
# IdealIRC channel settings v1.0
# All of the maps below are indexed by a channel name.
# Map of channel settings dialog handles.
global chansethndl;
# Map of booleans if the instance supports these.
global hasInvites, hasExceptions;
# Map of current channel settings. Limit, Key and currentTopic might not be set.
global chanmodes, modeLimit, modeKey, currentTopic;
# Map of what's done receiving from the server.
global topicDone, modesDone, bansDone, invitesDone, exceptionsDone;
# Map of which channels we're currently receiving for.
global inProgress;
########################################################################
# Date/time format to use in ban/invite/except list. See hook load() for definition.
global DateTimeFormat;
hook load()
{
# Again, the key is always a channel name, for each one of the maps below.
chansethndl = map();
hasInvites = map();
hasExceptions = map();
chanmodes = map();
modeLimit = map();
modeKey = map();
currentTopic = map();
topicDone = map();
modesDone = map();
bansDone = map();
invitesDone = map();
exceptionsDone = map();
inProgress = map();
DateTimeFormat = "ddd MMMM dd yyyy, HH:mm:ss";
}
menu channel
{
"Channel settings" => {
ctx = context();
if (ctx["online"] == false) {
showmessage("Not connected", "You are not connected to the server", "warn", "o");
return;
}
if (chansethndl[channel] != void && dlgvalidhndl(chansethndl[channel]))
dlgclose(chansethndl[channel]);
chansethndl[channel] = dialog("channelsettings");
hndl = chansethndl[channel];
is = strsplit(isupport("CHANMODES"), ",");
hasInvites[channel] = strfind(&is[0], "I") >= 0;
hasExceptions[channel] = strfind(&is[0], "e") >= 0;
topicDone[channel] = false;
modesDone[channel] = false;
bansDone[channel] = false;
invitesDone[channel] = hasInvites[channel] == false;
exceptionsDone[channel] = hasExceptions[channel] == false;
inProgress[channel] = true;
# Custom attribute to keep track of which channel the dialog has an effect to
dlgsetattr(hndl, "channel", channel);
dlgsetattr(hndl, "title", "Settings for " + channel);
dlgsetwidgetattr(hndl, "bantable", "header", list("Mask", "Set by", "Date"));
if (hasInvites[channel])
dlgsetwidgetattr(hndl, "invitetable", "header", list("Mask", "Set by", "Date"));
else {
dlgsetwidgetattr(hndl, "invitetable", "header", list("Server does not support invite list"));
dlgsetwidgetattr(hndl, "inviteadd", "enabled", false);
dlgsetwidgetattr(hndl, "inviteremove", "enabled", false);
}
if (hasExceptions[channel])
dlgsetwidgetattr(hndl, "exceptiontable", "header", list("Mask", "Set by", "Date"));
else {
dlgsetwidgetattr(hndl, "exceptiontable", "header", list("Server does not support exception list"));
dlgsetwidgetattr(hndl, "exceptionadd", "enabled", false);
dlgsetwidgetattr(hndl, "exceptionremove", "enabled", false);
}
/muteresp 331 332 333 324 329 367 368 346 347 348 349
/mode %channel
/mode %channel +b
if (hasInvites[channel])
/mode %channel +I
if (hasExceptions[channel])
/mode %channel +e
/topic %channel
}
}
hook numeric(code, params, message)
{
channel = params[1];
if (channel == void)
return;
if (inProgress[channel] != true)
return;
hndl = chansethndl[channel];
# No topic is set.
if (code == "331") {
topicDone[channel] = true;
}
# Topic received
else if (code == "332") {
dlgsetwidgetattr(hndl, "topic", "text", message);
topicDone[channel] = true;
currentTopic[channel] = message;
}
else if (code == "333") {
/unmuteresp 333
}
# Mode list received
else if (code == "324") {
args = list();
i = 3; # 3rd position starts the possible first argument (key, limit)
while (i < listlen(&params)) {
listpush(&args, &params[i]);
i = i + 1;
}
chanmodes[channel] = params[2];
parseChannelModes(channel, params[2], args);
modesDone[channel] = true;
}
# Ban list item received
else if (code == "367") {
handle = chansethndl[params[1]];
mask = params[2];
setby = params[3];
ts = toint(params[4]);
dlgtableinsert(handle, "bantable", list(mask, setby, unixts(ts, &DateTimeFormat)));
}
# Ban list end received
else if (code == "368") {
bansDone[channel] = true;
}
# Invites list item received
else if (code == "346") {
handle = chansethndl[params[1]];
mask = params[2];
setby = params[3];
ts = toint(params[4]);
dlgtableinsert(handle, "invitetable", list(mask, setby, unixts(ts, &DateTimeFormat)));
}
# Invites list end received
else if (code == "347") {
invitesDone[channel] = true;
}
# Exceptions list item received
else if (code == "348") {
handle = chansethndl[params[1]];
mask = params[2];
setby = params[3];
ts = toint(params[4]);
dlgtableinsert(handle, "exceptiontable", list(mask, setby, unixts(ts, &DateTimeFormat)));
}
# Exceptions list end received
else if (code == "349") {
exceptionsDone[channel] = true;
}
checkAndHandleAllDone(channel);
}
#
# Hooking onto 'mode' to receive any new/deleted entries in
# the ban/invite/except list for the given channel.
#
hook mode(sender, target, modes)
{
if (chansethndl[target] == void)
return;
handle = chansethndl[target];
len = strlen(&modes);
i = 0;
add = false;
pidx = 0;
params = strsplit(&modes, " ");
while (i < len) {
c = modes[i];
if (c == "+" || c == "-") {
add = c == "+";
i = i + 1;
continue;
}
if (c == "b") {
pidx = pidx + 1;
if (add) {
row = list(params[pidx], sender, now(DateTimeFormat));
dlgtableinsert(handle, "bantable", row);
}
else
findAndRemoveFromTable(handle, "bantable", params[pidx]);
}
else if (c == "I") {
pidx = pidx + 1;
if (add) {
row = list(params[pidx], sender, now(DateTimeFormat));
dlgtableinsert(handle, "invitetable", row);
}
else
findAndRemoveFromTable(handle, "invitetable", params[pidx]);
}
else if (c == "e") {
pidx = pidx + 1;
if (add) {
row = list(params[pidx], sender, now(DateTimeFormat));
dlgtableinsert(handle, "exceptiontable", row);
}
else
findAndRemoveFromTable(handle, "exceptiontable", params[pidx]);
}
else
break;
i = i + 1;
}
}
#
# Delete a hostmask from a table widget.
# Valid table widgets are obviously; bantable, invitetable, exceptiontable.
#
function findAndRemoveFromTable(handle, table, mask)
{
rowcount = dlgtablecount(handle, table);
i = 0;
while (i < rowcount) {
row = dlgtablerow(handle, table, i);
if (row[0] == mask) {
dlgtableremove(handle, table, i);
return;
}
i = i + 1;
}
}
#
# Checks if receiving all modes and lists is done.
# Side-effect, if done, clean up the receiving process.
#
function checkAndHandleAllDone(channel)
{
if ((topicDone[channel] == false)
|| (modesDone[channel] == false)
|| (bansDone[channel] == false)
|| (invitesDone[channel] == false)
|| (exceptionsDone[channel] == false))
{
return false;
}
/unmuteresp 331 332 324 329 367 368 346 347 348 349
inProgress[channel] = false;
return true;
}
#
# Parse channel modes and set the checkboxes for the supported modes.
#
function parseChannelModes(channel, modes, args)
{
hndl = chansethndl[channel];
i = 0;
argi = 0; # Index of 'args', increments on group B and C.
while (i < strlen(&modes)) {
c = modes[i];
if (c == "n") {
dlgsetwidgetattr(hndl, "mode_n", "checked", true);
}
else if (c == "t") {
dlgsetwidgetattr(hndl, "mode_t", "checked", true);
}
else if (c == "i") {
dlgsetwidgetattr(hndl, "mode_i", "checked", true);
}
else if (c == "p") {
dlgsetwidgetattr(hndl, "mode_p", "checked", true);
}
else if (c == "s") {
dlgsetwidgetattr(hndl, "mode_s", "checked", true);
}
else if (c == "m") {
dlgsetwidgetattr(hndl, "mode_m", "checked", true);
}
else if (c == "k") {
dlgsetwidgetattr(hndl, "mode_k", "checked", true);
dlgsetwidgetattr(hndl, "channel_key", "text", args[argi]);
modeKey[channel] = args[argi];
argi = argi + 1;
}
else if (c == "l") {
dlgsetwidgetattr(hndl, "mode_l", "checked", true);
dlgsetwidgetattr(hndl, "channel_limit", "value", toint(args[argi]));
modeLimit[channel] = args[argi];
argi = argi + 1;
}
i = i + 1;
}
}
dialog channelsettings
{
width = 500;
height = 380;
icon = ":/Icons/options.png";
button btncommon {
text = "Common";
checkable = true;
checked = true;
width = 80;
height = 30;
hook clicked => chanset_change_page(handle, "btncommon");
}
button btnbans {
text = "Bans";
checkable = true;
x = 85;
width = 80;
height = 30;
hook clicked => chanset_change_page(handle, "btnbans");
}
button btnexceptions {
text = "Exceptions";
checkable = true;
x = 170;
width = 80;
height = 30;
hook clicked => chanset_change_page(handle, "btnexceptions");
}
button btninvites {
text = "Invites";
checkable = true;
x = 255;
width = 80;
height = 30;
hook clicked => chanset_change_page(handle, "btninvites");
}
######################
# Common #
######################
label labeltopic {
text = "Topic";
x = 5;
y = 40;
width = 60;
height = 20;
}
textline topic {
x = 45;
y = 40;
width = 450;
height = 25;
}
groupbox modesbox {
text = "Channel modes";
x = 5;
y = 65;
width = 490;
height = 280;
}
checkbox mode_n {
x = 15;
y = 90;
height = 25;
width = 200;
text = "(n) No external messages";
}
checkbox mode_t {
x = 15;
y = 120;
height = 25;
width = 210;
text = "(t) Only operators can set topic";
}
checkbox mode_i {
x = 15;
y = 150;
height = 25;
width = 110;
text = "(i) Invite only";
}
checkbox mode_p {
x = 15;
y = 180;
height = 25;
width = 100;
text = "(p) Private";
}
checkbox mode_s {
x = 15;
y = 210;
height = 25;
width = 100;
text = "(s) Secret";
}
checkbox mode_m {
x = 15;
y = 240;
height = 25;
width = 350;
text = "(m) Moderated, only privileged can send messages";
}
checkbox mode_k {
x = 250;
y = 90;
height = 25;
width = 210;
text = "(k) Channel key";
}
textline channel_key {
x = 270;
y = 120;
height = 25;
width = 100;
}
checkbox mode_l {
x = 250;
y = 150;
height = 25;
width = 210;
text = "(l) User limit";
}
spinbox channel_limit {
x = 270;
y = 180;
height = 25;
width = 100;
min = 1;
max = 999999;
}
######################
# Bans #
######################
groupbox bansbox {
text = "Ban list";
x = 5;
y = 40;
width = 490;
height = 305;
visible = false;
}
table bantable {
x = 15;
y = 70;
width = 470;
height = 240;
visible = false;
}
button banremove {
text = "Remove";
x = 15;
y = 315;
width = 100;
height = 25;
visible = false;
hook clicked => {
selectedRow = dlgtableselected(handle, "bantable");
if (selectedRow > -1) {
row = dlgtablerow(handle, "bantable", selectedRow);
mask = row[0];
channel = dlggetattr(handle, "channel");
/mode %channel -b %mask
}
}
}
button banadd {
text = "New ...";
x = 120;
y = 315;
width = 100;
height = 25;
visible = false;
hook clicked => {
channel = dlggetattr(handle, "channel");
mask = input("New ban", "Add a new ban mask:");
if (mask != void && strlen(mask) > 0)
/mode %channel +b %mask
}
}
######################
# Invites #
######################
groupbox invitesbox {
text = "Invites list";
x = 5;
y = 40;
width = 490;
height = 305;
visible = false;
}
table invitetable {
x = 15;
y = 70;
width = 470;
height = 240;
visible = false;
}
button inviteremove {
text = "Remove";
x = 15;
y = 315;
width = 100;
height = 25;
visible = false;
hook clicked => {
selectedRow = dlgtableselected(handle, "invitetable");
if (selectedRow > -1) {
row = dlgtablerow(handle, "invitetable", selectedRow);
mask = row[0];
channel = dlggetattr(handle, "channel");
/mode %channel -I %mask
}
}
}
button inviteadd {
text = "New ...";
x = 120;
y = 315;
width = 100;
height = 25;
visible = false;
hook clicked => {
channel = dlggetattr(handle, "channel");
mask = input("New invite", "Add a new invite mask:");
if (mask != void && strlen(mask) > 0)
/mode %channel +I %mask
}
}
######################
# Exceptions #
######################
groupbox exceptionsbox {
text = "Exceptions list";
x = 5;
y = 40;
width = 490;
height = 305;
visible = false;
}
table exceptiontable {
x = 15;
y = 70;
width = 470;
height = 240;
visible = false;
}
button exceptionremove {
text = "Remove";
x = 15;
y = 315;
width = 100;
height = 25;
visible = false;
hook clicked => {
selectedRow = dlgtableselected(handle, "exceptiontable");
if (selectedRow > -1) {
row = dlgtablerow(handle, "exceptiontable", selectedRow);
mask = row[0];
channel = dlggetattr(handle, "channel");
/mode %channel -e %mask
}
}
}
button exceptionadd {
text = "New ...";
x = 120;
y = 315;
width = 100;
height = 25;
visible = false;
hook clicked => {
channel = dlggetattr(handle, "channel");
mask = input("New exception", "Add a new exception mask:");
if (mask != void && strlen(mask) > 0)
/mode %channel +e %mask
}
}
######################
# Cancel / save #
######################
button btncancel {
text = "Cancel";
x = 290;
y = 350;
width = 100;
height = 25;
hook clicked => dlgclose(handle);
}
button btnsave {
text = "Save && Close";
x = 395;
y = 350;
width = 100;
height = 25;
hook clicked => {
channel = dlggetattr(handle, "channel");
newModes = createModeDiff(channel);
if (strlen(newModes) > 0)
/mode %channel %newModes
dlgclose(handle);
}
}
}
#
# Returns a string of modes that reflect the changes in the dialog.
# Note that bans/invite/except lists are handled on-the-fly.
#
function createModeDiff(channel)
{
hndl = chansethndl[channel];
unsetmodes = "";
setmodes = "";
params = "";
# Find which modes to unset
m = &chanmodes[channel];
i = 0;
while (i < strlen(m)) {
c = m[i];
if ( (c == "n" && dlggetwidgetattr(hndl, "mode_n", "checked") == false)
|| (c == "t" && dlggetwidgetattr(hndl, "mode_t", "checked") == false)
|| (c == "i" && dlggetwidgetattr(hndl, "mode_i", "checked") == false)
|| (c == "p" && dlggetwidgetattr(hndl, "mode_p", "checked") == false)
|| (c == "s" && dlggetwidgetattr(hndl, "mode_s", "checked") == false)
|| (c == "m" && dlggetwidgetattr(hndl, "mode_m", "checked") == false)
|| (c == "l" && dlggetwidgetattr(hndl, "mode_l", "checked") == false) )
{
unsetmodes = unsetmodes + c;
}
else if (c == "k" && dlggetwidgetattr(hndl, "mode_k", "checked") == false) {
unsetmodes = unsetmodes + c;
params = modeKey[channel];
}
i = i + 1;
}
# Find new modes to set
if (strfind(m, "n") < 0 && dlggetwidgetattr(hndl, "mode_n", "checked") == true) {
setmodes = setmodes + "n";
}
if (strfind(m, "t") < 0 && dlggetwidgetattr(hndl, "mode_t", "checked") == true) {
setmodes = setmodes + "t";
}
if (strfind(m, "i") < 0 && dlggetwidgetattr(hndl, "mode_i", "checked") == true) {
setmodes = setmodes + "i";
}
if (strfind(m, "p") < 0 && dlggetwidgetattr(hndl, "mode_p", "checked") == true) {
setmodes = setmodes + "p";
}
if (strfind(m, "s") < 0 && dlggetwidgetattr(hndl, "mode_s", "checked") == true) {
setmodes = setmodes + "s";
}
if (strfind(m, "m") < 0 && dlggetwidgetattr(hndl, "mode_m", "checked") == true) {
setmodes = setmodes + "m";
}
if (strfind(m, "k") < 0 && dlggetwidgetattr(hndl, "mode_k", "checked") == true) {
setmodes = setmodes + "k";
newkey = dlggetwidgetattr(hndl, "channel_key", "text");
if (newkey == "") {
showmessage("Missing key", "The field for channel key is empty, yet marked as set", "warn", "o");
return void;
}
params = newkey;
}
else if (strfind(m, "k") > -1 && dlggetwidgetattr(hndl, "mode_k", "checked") == true) {
newkey = dlggetwidgetattr(hndl, "channel_key", "text");
oldkey = modeKey[channel];
if (newkey == "") {
showmessage("Missing key", "The field for channel key is empty, yet marked as set", "warn", "o");
return void;
}
if (newkey != oldkey) {
unsetmodes = unsetmodes + "k";
setmodes = setmodes + "k";
params = oldkey + " " + newkey;
}
}
if (strfind(m, "l") < 0 && dlggetwidgetattr(hndl, "mode_l", "checked") == true) {
setmodes = setmodes + "l";
newlimit = dlggetwidgetattr(hndl, "channel_limit", "value");
if (strlen(params) > 0)
params = params + " " + newlimit;
else
params = tostr(newlimit);
}
else if (strfind(m, "l") > -1 && dlggetwidgetattr(hndl, "mode_l", "checked") == true) {
newlimit = tostr( dlggetwidgetattr(hndl, "channel_limit", "value") );
mapdump(&modeLimit);
if (newlimit != modeLimit[channel]) {
setmodes = setmodes + "l";
if (strlen(params) > 0)
params = params + " " + newlimit;
else
params = newlimit;
}
}
if (unsetmodes != "")
unsetmodes = "-" + unsetmodes;
if (setmodes != "")
setmodes = "+" + setmodes;
if (params != "")
params = " " + params;
return unsetmodes + setmodes + params;
}
#
# Change to the "Common" view
#
function chanset_show_common(handle, visible)
{
dlgsetwidgetattr(handle, "btncommon", "checked", visible);
dlgsetwidgetattr(handle, "labeltopic", "visible", visible);
dlgsetwidgetattr(handle, "topic", "visible", visible);
dlgsetwidgetattr(handle, "modesbox", "visible", visible);
dlgsetwidgetattr(handle, "mode_n", "visible", visible);
dlgsetwidgetattr(handle, "mode_t", "visible", visible);
dlgsetwidgetattr(handle, "mode_i", "visible", visible);
dlgsetwidgetattr(handle, "mode_p", "visible", visible);
dlgsetwidgetattr(handle, "mode_s", "visible", visible);
dlgsetwidgetattr(handle, "mode_m", "visible", visible);
dlgsetwidgetattr(handle, "mode_k", "visible", visible);
dlgsetwidgetattr(handle, "channel_key", "visible", visible);
dlgsetwidgetattr(handle, "mode_l", "visible", visible);
dlgsetwidgetattr(handle, "channel_limit", "visible", visible);
}
#
# Change to the "Bans" view
#
function chanset_show_bans(handle, visible)
{
dlgsetwidgetattr(handle, "btnbans", "checked", visible);
dlgsetwidgetattr(handle, "bansbox", "visible", visible);
dlgsetwidgetattr(handle, "bantable", "visible", visible);
dlgsetwidgetattr(handle, "banadd", "visible", visible);
dlgsetwidgetattr(handle, "banremove", "visible", visible);
}
#
# Change to the "Invites" view
#
function chanset_show_invites(handle, visible)
{
dlgsetwidgetattr(handle, "btninvites", "checked", visible);
dlgsetwidgetattr(handle, "invitesbox", "visible", visible);
dlgsetwidgetattr(handle, "invitetable", "visible", visible);
dlgsetwidgetattr(handle, "inviteadd", "visible", visible);
dlgsetwidgetattr(handle, "inviteremove", "visible", visible);
}
#
# Change to the "Exceptions" view
#
function chanset_show_exceptions(handle, visible)
{
dlgsetwidgetattr(handle, "btnexceptions", "checked", visible);
dlgsetwidgetattr(handle, "exceptionsbox", "visible", visible);
dlgsetwidgetattr(handle, "exceptiontable", "visible", visible);
dlgsetwidgetattr(handle, "exceptionadd", "visible", visible);
dlgsetwidgetattr(handle, "exceptionremove", "visible", visible);
}
#
# Called when clicking either of the buttons Common, Bans, Invites or Exceptions.
#
function chanset_change_page(handle, button)
{
chanset_show_common(handle, button == "btncommon");
chanset_show_bans(handle, button == "btnbans");
chanset_show_invites(handle, button == "btninvites");
chanset_show_exceptions(handle, button == "btnexceptions");
}

@ -0,0 +1,303 @@
# 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") {
# <reply> ::= <nick>['*'] '=' <'+'|'-'><hostname>
# 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;
}
}
Loading…
Cancel
Save