Add /mode, /except, /invex and handle lists replies

master
C. McEnroe 2020-02-25 02:12:35 -05:00
parent c3c40d738b
commit 3c5e1c95a4
4 changed files with 134 additions and 18 deletions

View File

@ -1,4 +1,4 @@
.Dd February 19, 2020
.Dd February 23, 2020
.Dt CATGIRL 1
.Os
.
@ -242,16 +242,12 @@ can be typed
.Bl -tag -width Ds
.It Ic /away Op Ar message
Set or clear your away status.
.It Ic /ban Op Ar mask ...
List or ban masks from the channel.
.It Ic /cs Ar command
Send a command to ChanServ.
.It Ic /invite Ar nick
Invite a user to the channel.
.It Ic /join Ar channel
Join a channel.
.It Ic /kick Ar nick Op Ar message
Kick a user from the channel.
.It Ic /list Op Ar channel
List channels.
.It Ic /me Op Ar action
@ -276,8 +272,6 @@ Quit IRC.
Send a raw IRC command.
.It Ic /topic Op Ar topic
Show or set the topic of the channel.
.It Ic /unban Ar mask ...
Unban masks from the channel.
.It Ic /whois Ar nick
Query information about a user.
.El
@ -326,6 +320,30 @@ Switch to window by name.
Switch to window by number.
.El
.
.Ss Operator Commands
.Bl -tag -width Ds
.It Ic /ban Op Ar mask ...
List or ban masks from the channel.
.It Ic /except Op Ar mask ...
List or add masks to the channel ban exception list.
.It Ic /invex Op Ar mask ...
List or add masks to the channel invite list.
.It Ic /kick Ar nick Op Ar message
Kick a user from the channel.
.It Ic /mode Oo Ar modes Oc Op Ar param ...
Show or set channel modes.
In the
.Sy <network>
window,
show or set user modes.
.It Ic /unban Ar mask ...
Unban masks from the channel.
.It Ic /unexcept Ar mask ...
Remove masks from the channel ban exception list.
.It Ic /uninvex Ar mask ...
Remove masks from the channel invite list.
.El
.
.Sh KEY BINDINGS
The
.Nm

2
chat.h
View File

@ -176,6 +176,8 @@ static inline void utilPush(struct Util *util, const char *arg) {
extern struct Replies {
uint away;
uint ban;
uint excepts;
uint invex;
uint join;
uint list;
uint names;

View File

@ -143,14 +143,34 @@ static void commandKick(uint id, char *params) {
}
}
static void commandBan(uint id, char *params) {
static void commandMode(uint id, char *params) {
if (id == Network) {
if (params) {
ircFormat("MODE %s %s\r\n", self.nick, params);
} else {
ircFormat("MODE %s\r\n", self.nick);
}
} else {
if (params) {
ircFormat("MODE %s %s\r\n", idNames[id], params);
} else {
ircFormat("MODE %s\r\n", idNames[id]);
}
}
}
static void channelListMode(uint id, char pm, char l, char *params) {
int count = 1;
for (char *ch = params; *ch; ++ch) {
if (*ch == ' ') count++;
}
char b[ParamCap - 2] = "bbbbbbbbbbbbb";
ircFormat("MODE %s +%.*s %s\r\n", idNames[id], count, b, params);
char modes[ParamCap - 2] = { l, l, l, l, l, l, l, l, l, l, l, l, l };
ircFormat("MODE %s %c%.*s %s\r\n", idNames[id], pm, count, modes, params);
}
static void commandBan(uint id, char *params) {
if (params) {
channelListMode(id, '+', 'b', params);
} else {
ircFormat("MODE %s b\r\n", idNames[id]);
replies.ban++;
@ -159,12 +179,35 @@ static void commandBan(uint id, char *params) {
static void commandUnban(uint id, char *params) {
if (!params) return;
int count = 1;
for (char *ch = params; *ch; ++ch) {
if (*ch == ' ') count++;
channelListMode(id, '-', 'b', params);
}
static void commandExcept(uint id, char *params) {
if (params) {
channelListMode(id, '+', network.excepts, params);
} else {
ircFormat("MODE %s %c\r\n", idNames[id], network.excepts);
replies.excepts++;
}
char b[ParamCap - 2] = "bbbbbbbbbbbbb";
ircFormat("MODE %s -%.*s %s\r\n", idNames[id], count, b, params);
}
static void commandUnexcept(uint id, char *params) {
if (!params) return;
channelListMode(id, '-', network.excepts, params);
}
static void commandInvex(uint id, char *params) {
if (params) {
channelListMode(id, '+', network.invex, params);
} else {
ircFormat("MODE %s %c\r\n", idNames[id], network.invex);
replies.invex++;
}
}
static void commandUninvex(uint id, char *params) {
if (!params) return;
channelListMode(id, '-', network.invex, params);
}
static void commandList(uint id, char *params) {
@ -293,13 +336,16 @@ static const struct Handler {
{ "/copy", .fn = commandCopy, .restricted = true },
{ "/cs", .fn = commandCS },
{ "/debug", .fn = commandDebug, .restricted = true },
{ "/except", .fn = commandExcept },
{ "/exec", .fn = commandExec, .restricted = true },
{ "/help", .fn = commandHelp },
{ "/invex", .fn = commandInvex },
{ "/invite", .fn = commandInvite },
{ "/join", .fn = commandJoin, .restricted = true },
{ "/kick", .fn = commandKick },
{ "/list", .fn = commandList },
{ "/me", .fn = commandMe },
{ "/mode", .fn = commandMode },
{ "/move", .fn = commandMove },
{ "/msg", .fn = commandMsg, .restricted = true },
{ "/names", .fn = commandNames },
@ -313,6 +359,8 @@ static const struct Handler {
{ "/quote", .fn = commandQuote, .restricted = true },
{ "/topic", .fn = commandTopic },
{ "/unban", .fn = commandUnban },
{ "/unexcept", .fn = commandUnexcept },
{ "/uninvex", .fn = commandUninvex },
{ "/whois", .fn = commandWhois },
{ "/window", .fn = commandWindow },
};

View File

@ -606,6 +606,50 @@ static void handleReplyEndOfBanList(struct Message *msg) {
if (replies.ban) replies.ban--;
}
static void onList(const char *list, struct Message *msg) {
uint id = idFor(msg->params[1]);
if (msg->params[3] && msg->params[4]) {
char since[sizeof("0000-00-00 00:00:00")];
time_t time = strtol(msg->params[4], NULL, 10);
strftime(since, sizeof(since), "%F %T", localtime(&time));
uiFormat(
id, Cold, tagTime(msg),
"On the \3%02d%s\3 %s list since %s by \3%02d%s\3: %s",
hash(msg->params[1]), msg->params[1], list,
since, completeColor(id, msg->params[3]), msg->params[3],
msg->params[2]
);
} else {
uiFormat(
id, Cold, tagTime(msg),
"On the \3%02d%s\3 %s list: %s",
hash(msg->params[1]), msg->params[1], list, msg->params[2]
);
}
}
static void handleReplyExceptList(struct Message *msg) {
require(msg, false, 3);
if (!replies.excepts) return;
onList("except", msg);
}
static void handleReplyEndOfExceptList(struct Message *msg) {
(void)msg;
if (replies.excepts) replies.excepts--;
}
static void handleReplyInviteList(struct Message *msg) {
require(msg, false, 3);
if (!replies.invex) return;
onList("invite", msg);
}
static void handleReplyEndOfInviteList(struct Message *msg) {
(void)msg;
if (replies.invex) replies.invex--;
}
static void handleReplyList(struct Message *msg) {
require(msg, false, 4);
if (!replies.list) return;
@ -881,6 +925,10 @@ static const struct Handler {
{ "331", handleReplyNoTopic },
{ "332", handleReplyTopic },
{ "341", handleReplyInviting },
{ "346", handleReplyInviteList },
{ "347", handleReplyEndOfInviteList },
{ "348", handleReplyExceptList },
{ "349", handleReplyEndOfExceptList },
{ "353", handleReplyNames },
{ "366", handleReplyEndOfNames },
{ "367", handleReplyBanList },