From e4a28d1839278a5a5ab2e6a022eaa379b8d9c151 Mon Sep 17 00:00:00 2001 From: Jfreegman Date: Thu, 9 Oct 2014 01:39:22 -0400 Subject: [PATCH] make groupchat announcements behave properly --- src/groupchat.c | 99 +++++++++++++++++++++++++++++++++++++++--------- src/groupchat.h | 1 + src/help.c | 4 +- src/misc_tools.c | 10 +++++ src/misc_tools.h | 3 ++ src/toxic.h | 1 + 6 files changed, 99 insertions(+), 19 deletions(-) diff --git a/src/groupchat.c b/src/groupchat.c index 2706a7e..0c2b0b3 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -29,6 +29,7 @@ #include #include #include +#include #include "windows.h" #include "toxic.h" @@ -51,6 +52,7 @@ static GroupChat groupchats[MAX_GROUPCHAT_NUM]; static int max_groupchat_index = 0; extern struct user_settings *user_settings; +extern struct Winthread Winthread; /* temporary until group chats have unique commands */ extern const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE]; @@ -67,6 +69,7 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum) groupchats[i].chatwin = add_window(m, new_group_chat(m, groupnum)); groupchats[i].active = true; groupchats[i].num_peers = 0; + groupchats[i].start_time = get_unix_time(); groupchats[i].peer_names = malloc(sizeof(uint8_t) * TOX_MAX_NAME_LENGTH); groupchats[i].oldpeer_names = malloc(sizeof(uint8_t) * TOX_MAX_NAME_LENGTH); @@ -173,10 +176,7 @@ static void groupchat_onGroupMessage(ToxWindow *self, Tox *m, int groupnum, int ChatContext *ctx = self->chatwin; char nick[TOX_MAX_NAME_LENGTH]; - int n_len = tox_group_peername(m, groupnum, peernum, (uint8_t *) nick); - n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); /* enforce client max name length */ - nick[n_len] = '\0'; - filter_str(nick, n_len); + get_group_nick_truncate(m, nick, peernum, groupnum); char selfnick[TOX_MAX_NAME_LENGTH]; uint16_t sn_len = tox_get_self_name(m, (uint8_t *) selfnick); @@ -214,6 +214,9 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p ChatContext *ctx = self->chatwin; + char nick[TOX_MAX_NAME_LENGTH]; + get_group_nick_truncate(m, nick, peernum, groupnum); + char selfnick[TOX_MAX_NAME_LENGTH]; uint16_t n_len = tox_get_self_name(m, (uint8_t *) selfnick); selfnick[n_len] = '\0'; @@ -221,11 +224,6 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p if (strcasestr(action, selfnick)) { sound_notify(self, generic_message, NT_WNDALERT_0, NULL); - char nick[TOX_MAX_NAME_LENGTH]; - int n_len = tox_group_peername(m, groupnum, peernum, (uint8_t *) nick); - n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); /* enforce client max name length */ - nick[n_len] = '\0'; - if (self->active_box != -1) box_silent_notify2(self, NT_NOFOCUS, self->active_box, "* %s %s", nick, action ); else @@ -235,11 +233,6 @@ static void groupchat_onGroupAction(ToxWindow *self, Tox *m, int groupnum, int p sound_notify(self, silent, NT_WNDALERT_1, NULL); } - char nick[TOX_MAX_NAME_LENGTH]; - n_len = tox_group_peername(m, groupnum, peernum, (uint8_t *) nick); - n_len = MIN(n_len, TOXIC_MAX_NAME_LENGTH - 1); - nick[n_len] = '\0'; - char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); @@ -289,6 +282,55 @@ static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], ui memcpy(groupchats[gnum].oldpeer_name_lengths, groupchats[gnum].peer_name_lengths, sizeof(uint16_t) * npeers); } +struct group_add_thrd { + Tox *m; + ToxWindow *self; + int peernum; + int groupnum; + uint64_t timestamp; + pthread_t tid; + pthread_attr_t attr; +}; + +#define GROUP_EVENT_WAIT 2 + +/* Waits GROUP_EVENT_WAIT seconds for a new peer to set their name before announcing them */ +void *group_add_wait(void *data) +{ + struct group_add_thrd *thrd = (struct group_add_thrd *) data; + ToxWindow *self = thrd->self; + Tox *m = thrd->m; + char peername[TOX_MAX_NAME_LENGTH]; + + /* keep polling for a name that differs from the default until we run out of time */ + while (true) { + usleep(100000); + + pthread_mutex_lock(&Winthread.lock); + get_group_nick_truncate(m, peername, thrd->peernum, thrd->groupnum); + + if (strcmp(peername, DEFAULT_TOX_NAME) || timed_out(thrd->timestamp, get_unix_time(), GROUP_EVENT_WAIT)) { + pthread_mutex_unlock(&Winthread.lock); + break; + } + + pthread_mutex_unlock(&Winthread.lock); + } + + const char *event = "has joined the room"; + char timefrmt[TIME_STR_SIZE]; + get_time_str(timefrmt, sizeof(timefrmt)); + + pthread_mutex_lock(&Winthread.lock); + line_info_add(self, timefrmt, (char *) peername, NULL, CONNECTION, 0, GREEN, event); + write_to_log(event, (char *) peername, self->chatwin->log, true); + pthread_mutex_unlock(&Winthread.lock); + + pthread_attr_destroy(&thrd->attr); + free(thrd); + pthread_exit(NULL); +} + static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnum, int peernum, uint8_t change) { @@ -344,9 +386,25 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu switch (change) { case TOX_CHAT_CHANGE_PEER_ADD: - event = "has joined the room"; - line_info_add(self, timefrmt, (char *) peername, NULL, CONNECTION, 0, GREEN, event); - write_to_log(event, (char *) peername, ctx->log, true); + if (!timed_out(groupchats[self->num].start_time, get_unix_time(), GROUP_EVENT_WAIT)) + break; + + struct group_add_thrd *thrd = malloc(sizeof(struct group_add_thrd)); + thrd->m = m; + thrd->peernum = peernum; + thrd->groupnum = groupnum; + thrd->self = self; + thrd->timestamp = get_unix_time(); + + if (pthread_attr_init(&thrd->attr) != 0) + exit_toxic_err("failed in groupchat_onGroupNamelistChange", FATALERR_THREAD_ATTR); + + if (pthread_attr_setdetachstate(&thrd->attr, PTHREAD_CREATE_DETACHED) != 0) + exit_toxic_err("failed in groupchat_onGroupNamelistChange", FATALERR_THREAD_ATTR); + + if (pthread_create(&thrd->tid, &thrd->attr, group_add_wait, (void *) thrd) != 0) + exit_toxic_err("failed in groupchat_onGroupNamelistChange", FATALERR_THREAD_CREATE); + break; case TOX_CHAT_CHANGE_PEER_DEL: @@ -360,6 +418,13 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu break; case TOX_CHAT_CHANGE_PEER_NAME: + if (!timed_out(groupchats[self->num].start_time, get_unix_time(), GROUP_EVENT_WAIT)) + return; + + /* ignore initial name change (TODO: this is a bad way to do this) */ + if (strcmp((char *) oldpeername, DEFAULT_TOX_NAME) == 0) + return; + event = " is now known as "; line_info_add(self, timefrmt, (char *) oldpeername, (char *) peername, NAME_CHANGE, 0, 0, event); diff --git a/src/groupchat.h b/src/groupchat.h index 7de171d..7d3333d 100644 --- a/src/groupchat.h +++ b/src/groupchat.h @@ -35,6 +35,7 @@ typedef struct { bool active; int num_peers; int side_pos; /* current position of the sidebar - used for scrolling up and down */ + uint64_t start_time; uint8_t *peer_names; uint8_t *oldpeer_names; uint16_t *peer_name_lengths; diff --git a/src/help.c b/src/help.c index f142a4e..bc92cc7 100644 --- a/src/help.c +++ b/src/help.c @@ -217,8 +217,8 @@ static void help_draw_keys(ToxWindow *self) wprintw(win, " Page Up and Page Down : Scroll window history one line\n"); wprintw(win, " Ctrl+F and Ctrl+V : Scroll window history half a page\n"); wprintw(win, " Ctrl+H : Move to the bottom of window history\n"); - wprintw(win, " Ctrl+[ and Ctrl+] : Scroll peer list in groupchats\n\n"); - wprintw(win, " Ctrl+b : Toggle the groupchat peerlist\n\n"); + wprintw(win, " Ctrl+[ and Ctrl+] : Scroll peer list in groupchats\n"); + wprintw(win, " Ctrl+B : Toggle the groupchat peerlist\n\n"); wprintw(win, " (Note: Custom keybindings override these defaults.)\n\n"); help_draw_bottom_menu(win); diff --git a/src/misc_tools.c b/src/misc_tools.c index 45c9a1f..76191ac 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -271,6 +271,16 @@ int get_nick_truncate(Tox *m, char *buf, int friendnum) return len; } +/* same as get_nick_truncate but for groupchats */ +int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum) +{ + int len = tox_group_peername(m, groupnum, peernum, (uint8_t *) buf); + len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); + buf[len] = '\0'; + filter_str(buf, len); + return len; +} + /* copies data to msg buffer. returns length of msg, which will be no larger than size-1 */ uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length) diff --git a/src/misc_tools.h b/src/misc_tools.h index 1d47e9b..3699a6c 100644 --- a/src/misc_tools.h +++ b/src/misc_tools.h @@ -104,6 +104,9 @@ void str_to_lower(char *str); Returns nick len on success, -1 on failure */ int get_nick_truncate(Tox *m, char *buf, int friendnum); +/* same as get_nick_truncate but for groupchats */ +int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum); + /* copies data to msg buffer. returns length of msg, which will be no larger than size-1 */ uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length); diff --git a/src/toxic.h b/src/toxic.h index 80374b3..a1bb5d4 100644 --- a/src/toxic.h +++ b/src/toxic.h @@ -41,6 +41,7 @@ #include #define UNKNOWN_NAME "Anonymous" +#define DEFAULT_TOX_NAME "Tox User" /* should always be the same as toxcore's default name */ #define MAX_STR_SIZE TOX_MAX_MESSAGE_LENGTH /* must be >= TOX_MAX_MESSAGE_LENGTH */ #define MAX_CMDNAME_SIZE 64