diff --git a/src/global_commands.c b/src/global_commands.c index 9d5d2e6..c78e5ce 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -326,7 +326,7 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg } if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error: Please specify the group name."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group name required"); return; } @@ -334,7 +334,7 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg int len = strlen(tmp_name); if (len == 0 || len > TOX_MAX_GROUP_NAME_LENGTH) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error: Invalid group name."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid group name."); return; } @@ -370,14 +370,14 @@ void cmd_join(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA } if (argc < 1) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error: Group chat ID is required."); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Group chat ID is required."); return; } const char *chat_id = argv[1]; if (strlen(chat_id) != TOX_GROUP_CHAT_ID_SIZE * 2) { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Error: Invalid chat ID"); + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Invalid chat ID"); return; } @@ -506,8 +506,13 @@ void cmd_nick(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA len = MIN(len, TOXIC_MAX_NAME_LENGTH - 1); nick[len] = '\0'; - tox_set_name(m, (uint8_t *) nick, (uint16_t) len); + if (tox_set_name(m, (uint8_t *) nick, (uint16_t) len) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Core error setting nick."); + return; + } + prompt_update_nick(prompt, nick); + set_nick_all_groups(m, nick, len); store_data(m, DATA_FILE); } @@ -604,7 +609,12 @@ void cmd_status(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ return; } - tox_set_user_status(m, status_kind); + if (tox_set_user_status(m, status_kind) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Core failed to set status\n"); + return; + } + + set_status_all_groups(m, status_kind); prompt_update_status(prompt, status_kind); if (have_note) { diff --git a/src/group_commands.c b/src/group_commands.c index 3692c8a..8f54c2a 100644 --- a/src/group_commands.c +++ b/src/group_commands.c @@ -67,7 +67,7 @@ void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg int sn_len = tox_group_get_self_name(m, self->num, (uint8_t *) selfnick); selfnick[sn_len] = '\0'; - line_info_add(self, timefrmt, selfnick, NULL, SYS_MSG, 0, 0, " set the group topic to: %s", topic); + line_info_add(self, timefrmt, selfnick, NULL, NAME_CHANGE, 0, 0, " set the group topic to: %s", topic); char tmp_event[MAX_STR_SIZE]; snprintf(tmp_event, sizeof(tmp_event), "set topic to %s", topic); diff --git a/src/groupchat.c b/src/groupchat.c index 80a5988..ff89a42 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -129,7 +129,8 @@ int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, const char *grou groupchats[i].chatwin = add_window(m, self); groupchats[i].active = true; groupchats[i].peer_names = malloc(sizeof(uint8_t) * TOX_MAX_NAME_LENGTH); - groupchats[i].peer_name_lengths = malloc(sizeof(uint32_t)); + groupchats[i].peer_name_lengths = malloc(sizeof(uint16_t)); + groupchats[i].groupnumber = groupnum; if (groupchats[i].peer_names == NULL || groupchats[i].peer_name_lengths == NULL) exit_toxic_err("failed in init_groupchat_win", FATALERR_MEMORY); @@ -184,6 +185,33 @@ void close_groupchat(ToxWindow *self, Tox *m, int groupnum, const char *partmess kill_groupchat_window(self); } +/* Note: the arguments to these functions are validated in the caller functions */ +void set_nick_all_groups(Tox *m, const char *nick, uint16_t length) +{ + char timefrmt[TIME_STR_SIZE]; + get_time_str(timefrmt, sizeof(timefrmt)); + + int i; + + for (i = 0; i < max_groupchat_index; ++i) { + if (groupchats[i].active) { + ToxWindow *self = get_window_ptr(groupchats[i].chatwin); + tox_group_set_name(m, groupchats[i].groupnumber, (uint8_t *) nick, length); + line_info_add(self, timefrmt, NULL, nick, NAME_CHANGE, 0, MAGENTA, "You are now known as "); + } + } +} + +void set_status_all_groups(Tox *m, uint8_t status) +{ + int i; + + for (i = 0; i < max_groupchat_index; ++i) { + if (groupchats[i].active) + tox_group_set_status(m, groupchats[i].groupnumber, status); + } +} + /* destroys and re-creates groupchat window with or without the peerlist */ void redraw_groupchat_win(ToxWindow *self) { @@ -328,20 +356,20 @@ static void groupchat_onGroupTopicChange(ToxWindow *self, Tox *m, int groupnum, line_info_add(self, timefrmt, nick, NULL, NAME_CHANGE, 0, 0, " set the group topic to: %s", topic); char tmp_event[MAX_STR_SIZE]; - snprintf(tmp_event, sizeof(tmp_event), "set topic to %s", topic); + snprintf(tmp_event, sizeof(tmp_event), " set the group topic to %s", topic); write_to_log(tmp_event, nick, ctx->log, true); } /* Copies peer names/lengths */ -static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], uint32_t lengths[], int npeers) +static void copy_peernames(int gnum, uint8_t peerlist[][TOX_MAX_NAME_LENGTH], uint16_t lengths[], int npeers) { free(groupchats[gnum].peer_names); free(groupchats[gnum].peer_name_lengths); int N = TOX_MAX_NAME_LENGTH; - groupchats[gnum].peer_names = calloc(1, sizeof(uint8_t) * npeers * N); - groupchats[gnum].peer_name_lengths = calloc(1, sizeof(uint32_t) * npeers); + groupchats[gnum].peer_names = calloc(1, sizeof(uint8_t) * MAX(1, npeers) * N); + groupchats[gnum].peer_name_lengths = calloc(1, sizeof(uint32_t) * MAX(1, npeers)); if (groupchats[gnum].peer_names == NULL || groupchats[gnum].peer_name_lengths == NULL) exit_toxic_err("failed in copy_peernames", FATALERR_MEMORY); @@ -373,14 +401,14 @@ static void groupchat_onGroupNamelistChange(ToxWindow *self, Tox *m, int groupnu return; int num_peers = tox_group_get_number_peers(m, groupnum); - groupchats[groupnum].num_peers = num_peers; uint8_t tmp_peerlist[num_peers][TOX_MAX_NAME_LENGTH]; - uint32_t tmp_peerlens[num_peers]; + uint16_t tmp_peerlens[num_peers]; if (tox_group_get_names(m, groupnum, tmp_peerlist, tmp_peerlens, num_peers) == -1) - return; + num_peers = 0; + groupchats[groupnum].num_peers = num_peers; copy_peernames(groupnum, tmp_peerlist, tmp_peerlens, num_peers); } @@ -422,7 +450,7 @@ static void groupchat_onGroupPeerExit(ToxWindow *self, Tox *m, int groupnum, uin char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); - line_info_add(self, timefrmt, name, NULL, CONNECTION, 0, GREEN, "has left the room (%s)", partmessage); + line_info_add(self, timefrmt, name, NULL, CONNECTION, 0, RED, "has left the room (%s)", partmessage); char log_str[TOXIC_MAX_NAME_LENGTH + MAX_STR_SIZE]; snprintf(log_str, sizeof(log_str), "%s has left the room (%s)", name, partmessage); @@ -436,20 +464,25 @@ static void groupchat_onGroupSelfJoin(ToxWindow *self, Tox *m, int groupnum) if (groupnum != self->num) return; - char groupname[TOX_MAX_GROUP_NAME_LENGTH]; - int len = tox_group_get_group_name(m, groupnum, (uint8_t *) groupname); + char tmp_groupname[TOX_MAX_GROUP_NAME_LENGTH]; + int glen = tox_group_get_group_name(m, groupnum, (uint8_t *) tmp_groupname); - if (len > 0) - set_window_title(self, groupname, len); + char groupname[TOX_MAX_GROUP_NAME_LENGTH]; + copy_tox_str(groupname, sizeof(groupname), tmp_groupname, glen); + + if (glen > 0) + set_window_title(self, groupname, glen); + + char tmp_topic[TOX_MAX_GROUP_TOPIC_LENGTH]; + int tlen = tox_group_get_topic(m, groupnum, (uint8_t *) tmp_topic); char topic[TOX_MAX_GROUP_TOPIC_LENGTH]; - tox_group_get_topic(m, groupnum, (uint8_t *) topic); + copy_tox_str(topic, sizeof(topic), tmp_topic, tlen); char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); - line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, "Connected."); - line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, 0, "Topic set to: %s", topic); + line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 0, MAGENTA, "-!- Topic set to: %s", topic); } static void groupchat_onGroupSelfTimeout(ToxWindow *self, Tox *m, int groupnum) @@ -507,7 +540,7 @@ static void groupchat_onGroupNickChange(ToxWindow *self, Tox *m, int groupnum, u char timefrmt[TIME_STR_SIZE]; get_time_str(timefrmt, sizeof(timefrmt)); - line_info_add(self, timefrmt, oldnick, (char *) newnick, NAME_CHANGE, 0, MAGENTA, "is now known as"); + line_info_add(self, timefrmt, oldnick, newnick, NAME_CHANGE, 0, MAGENTA, " is now known as "); } @@ -631,7 +664,12 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) if (line[0] == '/') { if (strncmp(line, "/close", 6) == 0) { - close_groupchat(self, m, self->num, line + 6, ctx->len - 6); + int offset = 6; + + if (line[offset] != '\0') + ++offset; + + close_groupchat(self, m, self->num, line + offset, ctx->len - offset); return; } else if (strncmp(line, "/me ", strlen("/me ")) == 0) { send_group_action(self, m, self->num, line + strlen("/me ")); @@ -693,7 +731,18 @@ static void groupchat_onDraw(ToxWindow *self, Tox *m) memcpy(tmpnck, &groupchats[self->num].peer_names[peer * TOX_MAX_NAME_LENGTH], maxlen); tmpnck[maxlen] = '\0'; + /* TODO: Make this not poll */ + uint8_t status = tox_group_get_status(m, self->num, i); + int colour = WHITE; + + if (status == TOX_GS_AWAY) + colour = YELLOW; + else if (status == TOX_GS_BUSY) + colour = RED; + + wattron(ctx->sidebar, COLOR_PAIR(colour)); wprintw(ctx->sidebar, "%s\n", tmpnck); + wattroff(ctx->sidebar, COLOR_PAIR(colour)); } } @@ -736,14 +785,6 @@ static void groupchat_onInit(ToxWindow *self, Tox *m) execute(ctx->history, self, m, "/log", GLOBAL_COMMAND_MODE); - char selfname[TOX_MAX_NAME_LENGTH]; - uint16_t len = tox_get_self_name(m, (uint8_t *) selfname); - selfname[len] = '\0'; - tox_group_set_name(m, self->num, (uint8_t *) selfname, len); - - uint8_t status = tox_get_self_user_status(m); - tox_group_set_status(m, self->num, status); - scrollok(ctx->history, 0); wmove(self->window, y2 - CURS_Y_OFFSET, 0); } diff --git a/src/groupchat.h b/src/groupchat.h index 1118e58..0305358 100644 --- a/src/groupchat.h +++ b/src/groupchat.h @@ -59,12 +59,13 @@ struct GAudio { #endif /* AUDIO */ typedef struct { + int groupnumber; int chatwin; bool active; int num_peers; int side_pos; /* current position of the sidebar - used for scrolling up and down */ uint8_t *peer_names; - uint32_t *peer_name_lengths; + uint16_t *peer_name_lengths; #ifdef AUDIO struct GAudio audio; #endif @@ -72,6 +73,8 @@ typedef struct { void close_groupchat(ToxWindow *self, Tox *m, int groupnum, const char *partmessage, int length); int init_groupchat_win(ToxWindow *prompt, Tox *m, int groupnum, const char *groupname, int length); +void set_nick_all_groups(Tox *m, const char *nick, uint16_t length); +void set_status_all_groups(Tox *m, uint8_t status); /* destroys and re-creates groupchat window with or without the peerlist */ void redraw_groupchat_win(ToxWindow *self); diff --git a/src/misc_tools.c b/src/misc_tools.c index 62cdd2c..6c87602 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -295,13 +295,19 @@ 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 */ + returns length of msg. + returns 0 and nulls msg if length is too big for buffer size */ uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length) { - int len = MIN(length, size - 1); - memcpy(msg, data, len); - msg[len] = '\0'; - return len; + if (length > size - 1) { + length = 0; + msg[0] = '\0'; + return length; + } + + memcpy(msg, data, length); + msg[length] = '\0'; + return length; } /* returns index of the first instance of ch in s starting at idx. diff --git a/src/misc_tools.h b/src/misc_tools.h index 20fd17e..970faaa 100644 --- a/src/misc_tools.h +++ b/src/misc_tools.h @@ -108,7 +108,8 @@ int get_nick_truncate(Tox *m, char *buf, int friendnum); 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 */ + returns length of msg. + returns 0 and nulls msg if length is too big for buffer size */ uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length); /* returns index of the first instance of ch in s starting at idx. @@ -128,7 +129,7 @@ bool file_exists(const char *path); /* returns file size or -1 on error */ off_t file_size(const char *path); -/* compares the first size bytes of fp and signature. +/* compares the first size bytes of fp and signature. Returns 0 if they are the same, 1 if they differ, and -1 on error. On success this function will seek back to the beginning of fp */ diff --git a/src/prompt.c b/src/prompt.c index 99c2a4a..66f8838 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -49,9 +49,9 @@ extern struct Winthread Winthread; FriendRequests FrndRequests; #ifdef AUDIO -#define AC_NUM_GLOB_COMMANDS 18 +#define AC_NUM_GLOB_COMMANDS 19 #else -#define AC_NUM_GLOB_COMMANDS 16 +#define AC_NUM_GLOB_COMMANDS 17 #endif /* AUDIO */ /* Array of global command names used for tab completion. */ @@ -65,6 +65,7 @@ static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = { { "/exit" }, { "/group" }, { "/help" }, + { "/join" }, { "/log" }, { "/myid" }, { "/nick" }, @@ -81,7 +82,7 @@ static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = { #endif /* AUDIO */ }; -void kill_prompt_window(ToxWindow *self) +void kill_prompt_window(ToxWindow *self) { ChatContext *ctx = self->chatwin; StatusBar *statusbar = self->stb; @@ -116,7 +117,7 @@ void prompt_update_statusmessage(ToxWindow *prompt, Tox *m, const char *statusms snprintf(statusbar->statusmsg, sizeof(statusbar->statusmsg), "%s", statusmsg); int len = strlen(statusbar->statusmsg); statusbar->statusmsg_len = len; - tox_set_status_message(m, (uint8_t *) statusmsg, (uint64_t) len); + tox_set_status_message(m, (uint8_t *) statusmsg, (uint64_t) len); } /* Updates own status in prompt statusbar */ @@ -350,7 +351,7 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum write_to_log(msg, nick, ctx->log, true); if (self->active_box != -1) - box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, + box_notify2(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, "%s has come online", nick ); else box_notify(self, user_log_in, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, @@ -361,7 +362,7 @@ static void prompt_onConnectionChange(ToxWindow *self, Tox *m, int32_t friendnum write_to_log(msg, nick, ctx->log, true); if (self->active_box != -1) - box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, + box_notify2(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, self->active_box, "%s has gone offline", nick ); else box_notify(self, user_log_out, NT_WNDALERT_2 | NT_NOTIFWND | NT_RESTOL, &self->active_box, @@ -501,6 +502,6 @@ ToxWindow new_prompt(void) ret.help = help; ret.active_box = -1; - + return ret; } diff --git a/src/windows.c b/src/windows.c index 21c9215..bd25d27 100644 --- a/src/windows.c +++ b/src/windows.c @@ -229,7 +229,7 @@ void on_group_peer_exit(Tox *m, int groupnumber, uint32_t peernumber, const uint char msg[MAX_STR_SIZE + 1]; if (length == 0 || !partmsg) { - strcpy(msg, "Quit."); + strcpy(msg, "Quit"); length = 5; } else { length = copy_tox_str(msg, sizeof(msg), (const char *) partmsg, length); @@ -260,10 +260,12 @@ void on_group_topic_change(Tox *m, int groupnumber, uint32_t peernumber, const u void on_group_nick_change(Tox *m, int groupnumber, uint32_t peernumber, const uint8_t *newname, uint16_t length, void *userdata) { + fprintf(stderr, "newname before: %s. len: %d\n", newname, length); char name[TOXIC_MAX_NAME_LENGTH + 1]; length = copy_tox_str(name, sizeof(name), (const char *) newname, length); filter_str(name, length); + fprintf(stderr, "newname before: %s. len: %d\n", name, length); int i; for (i = 0; i < MAX_WINDOWS_NUM; ++i) {