jcs
/subtext
/amendments
/290
chat: Implement private messaging
Assign each guest their own unique chat username so it's not so
confusing if multiple guests are chatting.
jcs made amendment 290 over 2 years ago
--- chat.c Tue Sep 27 12:44:42 2022
+++ chat.c Sun Nov 20 00:02:40 2022
@@ -32,6 +32,7 @@ static char chat_tbuf[256];
void chat_output_bar(struct session *s, char *left_str, char *right_str);
void chat_help(struct session *s);
void chat_who(struct session *s);
+void chat_privmsg(struct session *s, char *user_and_msg);
void
chat_broadcast(struct session *s, char *str)
@@ -41,8 +42,8 @@ chat_broadcast(struct session *s, char *str)
for (n = 0; n < nsessions; n++) {
if (!sessions[n]->chatting)
continue;
- if (strcmp((char *)s->chatting_with_node,
- (char *)sessions[n]->chatting_with_node) != 0)
+ if (strcmp(s->chatting_with_node,
+ sessions[n]->chatting_with_node) != 0)
continue;
chat_printf_line(sessions[n], 1, "%s", str);
@@ -148,20 +149,41 @@ void
chat_start(struct session *s, char *with_node)
{
static char chat_bar[255];
- size_t len;
+ char chatting_with[DB_USERNAME_LENGTH + 1];
+ size_t len, n;
char *input;
bool lagged = false;
- s->chatting = 1;
- if (with_node[0])
- strlcpy((char *)s->chatting_with_node, with_node,
+ chatting_with[0] = '\0';
+ s->chatting_with_node[0] = '\0';
+ if (with_node) {
+ for (n = 0; n < MAX_SESSIONS; n++) {
+ if (sessions[n] == NULL || !sessions[n]->logged_in)
+ continue;
+ if (strcmp(sessions[n]->node, with_node) == 0) {
+ strlcpy(chatting_with, sessions[n]->chat_username,
+ sizeof(chatting_with));
+ break;
+ }
+ }
+
+ if (chatting_with[0] == '\0') {
+ session_logf(s, "Tried to enter chat with node %s but no "
+ "user logged in there", with_node);
+ session_printf(s, "Error: Couldn't find user on node %s",
+ with_node);
+ return;
+ }
+
+ strlcpy(s->chatting_with_node, with_node,
sizeof(s->chatting_with_node));
- else
- s->chatting_with_node[0] = '\0';
+ }
- session_logf(s, "Entered chat with %s", with_node[0] ? with_node :
- "everyone");
+ s->chatting = 1;
+ session_logf(s, "Entered chat with %s", chatting_with[0] ?
+ chatting_with : "everyone");
+
session_printf(s,
ansi(s, ANSI_CURSOR_LINE_COL, s->terminal_lines, 1, ANSI_END));
@@ -173,8 +195,7 @@ chat_start(struct session *s, char *with_node)
len = snprintf(chat_bar, sizeof(chat_bar),
" [ %s ] [ Chatting with %s ] ",
- s->user ? s->user->username : "guest",
- s->chatting_with_node[0] ? "..." : "everyone");
+ s->chat_username, chatting_with[0] ? chatting_with : "everyone");
while (len < sizeof(chat_bar) && len < s->terminal_columns) {
chat_bar[len - 1] = ' ';
@@ -191,8 +212,7 @@ chat_start(struct session *s, char *with_node)
snprintf(chat_tbuf, sizeof(chat_tbuf),
"*** %s%s has joined chat",
- s->user ? s->user->username : "guest",
- s->user && s->user->is_sysop ? " (sysop)" : "");
+ s->chat_username, s->user && s->user->is_sysop ? " (sysop)" : "");
chat_broadcast(s, chat_tbuf);
session_flush(s);
@@ -215,9 +235,9 @@ chat_start(struct session *s, char *with_node)
break;
} else if (strcmp(input, "/help") == 0) {
chat_help(s);
- } else if (strncmp(input, "/msg ", 5) == 0) {
- /* TODO */
- chat_printf_line(s, 1, "*** TODO :(");
+ } else if (strncmp(input, "/msg ", 5) == 0 ||
+ strcmp(input, "/msg") == 0) {
+ chat_privmsg(s, input + 5);
session_flush(s);
} else if (strcmp(input, "/who") == 0) {
chat_who(s);
@@ -228,7 +248,7 @@ chat_start(struct session *s, char *with_node)
}
} else {
snprintf(chat_tbuf, sizeof(chat_tbuf), "<%s> %s",
- s->user ? s->user->username : "guest", input);
+ s->chat_username, input);
chat_broadcast(s, chat_tbuf);
session_flush(s);
}
@@ -241,8 +261,7 @@ chat_start(struct session *s, char *with_node)
snprintf(chat_tbuf, sizeof(chat_tbuf),
"*** %s%s has left chat",
- s->user ? s->user->username : "guest",
- s->user && s->user->is_sysop ? " (sysop)" : "");
+ s->chat_username, s->user && s->user->is_sysop ? " (sysop)" : "");
if (s->ending)
strlcat(chat_tbuf, " (disconnected)", sizeof(chat_tbuf));
@@ -299,13 +318,13 @@ chat_who(struct session *s)
for (n = 0; n < nsessions; n++) {
if (!sessions[n]->chatting)
continue;
- if (strcmp((char *)s->chatting_with_node,
- (char *)sessions[n]->chatting_with_node) != 0)
+ if (strcmp(s->chatting_with_node,
+ sessions[n]->chatting_with_node) != 0)
continue;
len += snprintf(chat_tbuf + len, sizeof(chat_tbuf), "[ %c%-16s ]",
sessions[n]->user && sessions[n]->user->is_sysop ? '@' : ' ',
- sessions[n]->user ? sessions[n]->user->username : "guest");
+ sessions[n]->chat_username);
if (++printed == 3) {
chat_printf_line(s, 1, chat_tbuf);
@@ -316,4 +335,50 @@ chat_who(struct session *s)
if (printed)
chat_printf_line(s, 1, chat_tbuf);
+}
+
+void
+chat_privmsg(struct session *s, char *user_and_msg)
+{
+ char *username = NULL;
+ size_t n;
+ bool found = false;
+
+ for (n = 0; user_and_msg[n] != '\0'; n++) {
+ if (user_and_msg[n] == ' ') {
+ user_and_msg[n] = '\0';
+
+ username = user_and_msg;
+ user_and_msg = user_and_msg + n + 1;
+ break;
+ }
+ }
+
+ if (username == NULL || user_and_msg[0] == '\0') {
+ chat_printf_line(s, 1, "*** Usage: /msg user message");
+ session_flush(s);
+ return;
+ }
+
+ for (n = 0; n < MAX_SESSIONS; n++) {
+ if (sessions[n] == NULL || !sessions[n]->logged_in ||
+ !sessions[n]->chatting)
+ continue;
+ if (strcmp(sessions[n]->chat_username, username) != 0)
+ continue;
+
+ chat_printf_line(sessions[n], 1, "*[priv] %s* %s",
+ s->chat_username, user_and_msg);
+ found = true;
+ }
+
+ if (!found) {
+ chat_printf_line(s, 1, "*** User %s does not exist or "
+ "is not chatting", username);
+ session_flush(s);
+ return;
+ }
+
+ chat_printf_line(s, 1, "*-> %s* %s", username, user_and_msg);
+ session_flush(s);
}
--- session.c Sun Nov 13 09:32:40 2022
+++ session.c Sat Nov 19 23:09:52 2022
@@ -148,8 +148,14 @@ session_run(struct uthread *uthread, void *arg)
strlcpy(s->log.username, s->user->username,
sizeof(s->log.username));
- } else
+ strlcpy(s->chat_username, s->user->username,
+ sizeof(s->chat_username));
+ } else {
strlcpy(s->log.username, GUEST_USERNAME, sizeof(s->log.username));
+ /* guest + ttyt0 -> guest[t0] */
+ snprintf(s->chat_username, sizeof(s->chat_username), "%s[%s]",
+ GUEST_USERNAME, s->node + 3);
+ }
strlcpy(s->log.via, s->via, sizeof(s->log.via));
s->log.tspeed = s->tspeed;
--- session.h Wed Nov 9 09:33:00 2022
+++ session.h Sat Nov 19 23:19:14 2022
@@ -93,7 +93,8 @@ struct session {
bool cp437;
bool transferring_file;
bool is_telnet;
- unsigned char chatting_with_node[10];
+ char chatting_with_node[10];
+ char chat_username[DB_USERNAME_LENGTH + 1];
bool chatting;
struct session_log log;
struct user *user;