Repository for "official" scripts deployed with IdealIRC
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
scripts/ChannelSettings.iis

867 lines
20 KiB

# 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;
}
channelOrig = channel;
channel = strlower(channel);
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 " + channelOrig);
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 = strlower(params[1]);
if (channel == void)
return;
if (inProgress[channel] != true)
return;
hndl = chansethndl[channel];
# No topic is set
if (code == "331") {
topicDone[channel] = true;
currentTopic[channel] = "";
}
# Topic received
else if (code == "332") {
dlgsetwidgetattr(hndl, "topic", "text", message);
topicDone[channel] = true;
currentTopic[channel] = message;
}
# Topic-by message is always a bit late to the party so must be unmuted separately.
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[channel];
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[channel];
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[channel];
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)
{
target = strlower(target);
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)
{
channel = strlower(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)
{
channel = strlower(channel);
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
newTopic = dlggetwidgetattr(handle, "topic", "text");
if (newTopic != currentTopic[channel]) {
if (newTopic == "")
/topic -c %channel
else
/topic %channel %newTopic
}
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)
{
channel = strlower(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");
}