AmendHub

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 2 months 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;