summaryrefslogtreecommitdiff
path: root/handle.c
diff options
context:
space:
mode:
Diffstat (limited to 'handle.c')
-rw-r--r--handle.c115
1 files changed, 61 insertions, 54 deletions
diff --git a/handle.c b/handle.c
index 29b354c..4d2d4b1 100644
--- a/handle.c
+++ b/handle.c
@@ -23,14 +23,17 @@
#include "chat.h"
-static int color(const char *s) {
- if (!s) return 0;
- int x = 0;
- for (; s[0]; ++s) {
- x ^= s[0];
+// Adapted from <https://github.com/cbreeden/fxhash/blob/master/lib.rs>.
+static int color(const char *str) {
+ if (!str) return IRC_GRAY;
+ uint32_t hash = 0;
+ for (; str[0]; ++str) {
+ hash = (hash << 5) | (hash >> 27);
+ hash ^= str[0];
+ hash *= 0x27220A95;
}
- x &= 15;
- return (x == 1) ? 0 : x;
+ hash &= IRC_LIGHT_GRAY;
+ return (hash == IRC_BLACK) ? IRC_GRAY : hash;
}
static char *paramField(char **params) {
@@ -90,44 +93,41 @@ static void handlePing(char *prefix, char *params) {
ircFmt("PONG %s\r\n", params);
}
-static void handle432(char *prefix, char *params) {
+static void handleReplyErroneousNickname(char *prefix, char *params) {
char *mesg;
shift(prefix, NULL, NULL, NULL, params, 3, 0, NULL, NULL, &mesg);
- uiLog(TAG_DEFAULT, L"You can't use that name here");
- uiFmt(TAG_DEFAULT, "Sheriff says, \"%s\"", mesg);
- uiLog(TAG_DEFAULT, L"Type /nick <name> to choose a new one");
+ uiLog(TAG_STATUS, L"You can't use that name here");
+ uiFmt(TAG_STATUS, "Sheriff says, \"%s\"", mesg);
+ uiLog(TAG_STATUS, L"Type /nick <name> to choose a new one");
}
-static void handle001(char *prefix, char *params) {
+static void handleReplyWelcome(char *prefix, char *params) {
char *nick;
shift(prefix, NULL, NULL, NULL, params, 1, 0, &nick);
if (strcmp(nick, self.nick)) selfNick(nick);
- tabTouch(TAG_DEFAULT, self.nick);
+ tabTouch(TAG_STATUS, self.nick);
if (self.join) ircFmt("JOIN %s\r\n", self.join);
- uiLog(TAG_DEFAULT, L"You have arrived");
+ uiLog(TAG_STATUS, L"You have arrived");
}
-static void handle372(char *prefix, char *params) {
+static void handleReplyMOTD(char *prefix, char *params) {
char *mesg;
shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &mesg);
if (mesg[0] == '-' && mesg[1] == ' ') mesg = &mesg[2];
- uiFmt(TAG_DEFAULT, "%s", mesg);
+ urlScan(TAG_STATUS, mesg);
+ uiFmt(TAG_STATUS, "%s", mesg);
}
static void handleJoin(char *prefix, char *params) {
char *nick, *user, *chan;
shift(prefix, &nick, &user, NULL, params, 1, 0, &chan);
struct Tag tag = tagFor(chan);
- if (isSelf(nick, user)) {
- tabTouch(TAG_DEFAULT, chan);
- uiFocus(tag);
- } else {
- tabTouch(tag, nick);
- }
+ tabTouch(tag, nick);
uiFmt(
tag, "\3%d%s\3 arrives in \3%d%s\3",
color(user), nick, color(chan), chan
);
+ if (isSelf(nick, user)) uiViewTag(tag);
}
static void handlePart(char *prefix, char *params) {
@@ -136,6 +136,7 @@ static void handlePart(char *prefix, char *params) {
struct Tag tag = tagFor(chan);
(void)(isSelf(nick, user) ? tabClear(tag) : tabRemove(tag, nick));
if (mesg) {
+ urlScan(tag, mesg);
uiFmt(
tag, "\3%d%s\3 leaves \3%d%s\3, \"%s\"",
color(user), nick, color(chan), chan, mesg
@@ -154,6 +155,7 @@ static void handleKick(char *prefix, char *params) {
struct Tag tag = tagFor(chan);
(void)(isSelf(nick, user) ? tabClear(tag) : tabRemove(tag, nick));
if (mesg) {
+ urlScan(tag, mesg);
uiFmt(
tag, "\3%d%s\3 kicks \3%d%s\3 out of \3%d%s\3, \"%s\"",
color(user), nick, color(kick), kick, color(chan), chan, mesg
@@ -169,20 +171,23 @@ static void handleKick(char *prefix, char *params) {
static void handleQuit(char *prefix, char *params) {
char *nick, *user, *mesg;
shift(prefix, &nick, &user, NULL, params, 0, 1, &mesg);
- // TODO: Send to tags where nick is in tab.
- tabRemove(TAG_ALL, nick);
- if (mesg) {
- char *quot = (mesg[0] == '"') ? "" : "\"";
- uiFmt(
- TAG_DEFAULT, "\3%d%s\3 leaves, %s%s%s",
- color(user), nick, quot, mesg, quot
- );
- } else {
- uiFmt(TAG_DEFAULT, "\3%d%s\3 leaves", color(user), nick);
+ char *quot = (mesg && mesg[0] == '"') ? "" : "\"";
+ struct Tag tag;
+ while (TAG_NONE.id != (tag = tabTag(nick)).id) {
+ tabRemove(tag, nick);
+ if (mesg) {
+ urlScan(tag, mesg);
+ uiFmt(
+ tag, "\3%d%s\3 leaves, %s%s%s",
+ color(user), nick, quot, mesg, quot
+ );
+ } else {
+ uiFmt(tag, "\3%d%s\3 leaves", color(user), nick);
+ }
}
}
-static void handle332(char *prefix, char *params) {
+static void handleReplyTopic(char *prefix, char *params) {
char *chan, *topic;
shift(prefix, NULL, NULL, NULL, params, 3, 0, NULL, &chan, &topic);
struct Tag tag = tagFor(chan);
@@ -207,7 +212,7 @@ static void handleTopic(char *prefix, char *params) {
);
}
-static void handle366(char *prefix, char *params) {
+static void handleReplyEndOfNames(char *prefix, char *params) {
char *chan;
shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &chan);
ircFmt("WHO %s\r\n", chan);
@@ -219,14 +224,14 @@ static struct {
size_t len;
} who;
-static void handle352(char *prefix, char *params) {
+static void handleReplyWho(char *prefix, char *params) {
char *chan, *user, *nick;
shift(
prefix, NULL, NULL, NULL,
params, 6, 0, NULL, &chan, &user, NULL, NULL, &nick
);
struct Tag tag = tagFor(chan);
- if (!isSelf(nick, user)) tabTouch(tag, nick);
+ tabTouch(tag, nick);
size_t cap = sizeof(who.buf) - who.len;
int len = snprintf(
&who.buf[who.len], cap,
@@ -236,7 +241,7 @@ static void handle352(char *prefix, char *params) {
if ((size_t)len < cap) who.len += len;
}
-static void handle315(char *prefix, char *params) {
+static void handleReplyEndOfWho(char *prefix, char *params) {
char *chan;
shift(prefix, NULL, NULL, NULL, params, 2, 0, NULL, &chan);
struct Tag tag = tagFor(chan);
@@ -251,12 +256,14 @@ static void handleNick(char *prefix, char *params) {
char *prev, *user, *next;
shift(prefix, &prev, &user, NULL, params, 1, 0, &next);
if (isSelf(prev, user)) selfNick(next);
- // TODO: Send to tags where prev is in tab.
- tabReplace(prev, next);
- uiFmt(
- TAG_DEFAULT, "\3%d%s\3 is now known as \3%d%s\3",
- color(user), prev, color(user), next
- );
+ struct Tag tag;
+ while (TAG_NONE.id != (tag = tabTag(prev)).id) {
+ tabReplace(tag, prev, next);
+ uiFmt(
+ tag, "\3%d%s\3 is now known as \3%d%s\3",
+ color(user), prev, color(user), next
+ );
+ }
}
static void handleCTCP(struct Tag tag, char *nick, char *user, char *mesg) {
@@ -288,13 +295,13 @@ static void handlePrivmsg(char *prefix, char *params) {
tag, "%c\3%d%c%s%c\17 %s",
ping["\17\26"], color(user), self["<("], nick, self[">)"], mesg
);
- if (ping) uiBeep();
+ // TODO: always be beeping.
}
static void handleNotice(char *prefix, char *params) {
char *nick, *user, *chan, *mesg;
shift(prefix, &nick, &user, NULL, params, 2, 0, &chan, &mesg);
- struct Tag tag = TAG_DEFAULT;
+ struct Tag tag = TAG_STATUS;
if (user) tag = (strcmp(chan, self.nick) ? tagFor(chan) : tagFor(nick));
if (!isSelf(nick, user)) tabTouch(tag, nick);
urlScan(tag, mesg);
@@ -308,15 +315,15 @@ static const struct {
const char *command;
Handler handler;
} HANDLERS[] = {
- { "001", handle001 },
- { "315", handle315 },
- { "332", handle332 },
- { "352", handle352 },
- { "366", handle366 },
- { "372", handle372 },
- { "375", handle372 },
- { "432", handle432 },
- { "433", handle432 },
+ { "001", handleReplyWelcome },
+ { "315", handleReplyEndOfWho },
+ { "332", handleReplyTopic },
+ { "352", handleReplyWho },
+ { "366", handleReplyEndOfNames },
+ { "372", handleReplyMOTD },
+ { "375", handleReplyMOTD },
+ { "432", handleReplyErroneousNickname },
+ { "433", handleReplyErroneousNickname },
{ "JOIN", handleJoin },
{ "KICK", handleKick },
{ "NICK", handleNick },