diff --git a/src/execute.c b/src/execute.c index ea64117..c2c2803 100644 --- a/src/execute.c +++ b/src/execute.c @@ -83,6 +83,8 @@ static struct cmd_func chat_commands[] = { static struct cmd_func group_commands[] = { { "/topic", cmd_set_topic }, { "/chatid", cmd_chatid }, + { "/ignore", cmd_ignore }, + { "/unignore", cmd_unignore }, #ifdef AUDIO { "/mute", cmd_mute }, { "/sense", cmd_sense }, @@ -90,10 +92,65 @@ static struct cmd_func group_commands[] = { { NULL, NULL }, }; -/* Parses input command and puts args into arg array. - Returns number of arguments on success, -1 on failure. */ +#define SPECIAL_COMMANDS 9 +static const char special_commands[SPECIAL_COMMANDS][MAX_CMDNAME_SIZE] = { + "/ban", + "/deop", + "/group", + "/ignore", + "/nick", + "/note", + "/op", + "/topic", + "/unignore" +}; + +/* return true if input command is in the special_commands array. False otherwise.*/ +static bool is_special_command(const char *input) +{ + int s = char_find(0, input, ' '); + + if (s == strlen(input)) + return false; + + int i; + + for (i = 0; i < SPECIAL_COMMANDS; ++i) { + if (strncmp(input, special_commands[i], s) == 0) + return true; + } + + return false; +} + +/* Parses commands in the special_commands array which take exactly one argument that may contain spaces. + * Unlike parse_command, this function does not split the input string at spaces. + * Returns number of arguments on success, returns -1 on failure + */ +static int parse_special_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE]) +{ + int len = strlen(input); + int s = char_find(0, input, ' '); + + if (s + 1 >= len) + return -1; + + memcpy(args[0], input, s); + args[0][s++] = '\0'; /* increment to remove space after /command */ + memcpy(args[1], input + s, len - s); + args[1][len - s] = '\0'; + + return 2; +} + +/* Parses input command and puts args (split by spaces) into args array. + * Returns number of arguments on success, -1 on failure. + */ static int parse_command(WINDOW *w, ToxWindow *self, const char *input, char (*args)[MAX_STR_SIZE]) { + if (is_special_command(input)) + return parse_special_command(w, self, input, args); + char *cmd = strdup(input); if (cmd == NULL) diff --git a/src/global_commands.c b/src/global_commands.c index c78e5ce..d812649 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -524,18 +524,7 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA return; } - if (argv[1][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Note must be enclosed in quotes."); - return; - } - - /* remove opening and closing quotes */ - char msg[MAX_STR_SIZE]; - snprintf(msg, sizeof(msg), "%s", &argv[1][1]); - int len = strlen(msg) - 1; - msg[len] = '\0'; - - prompt_update_statusmessage(prompt, m, msg); + prompt_update_statusmessage(prompt, m, argv[1]); } void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) diff --git a/src/group_commands.c b/src/group_commands.c index 8f54c2a..f4a6c17 100644 --- a/src/group_commands.c +++ b/src/group_commands.c @@ -27,17 +27,17 @@ #include "line_info.h" #include "misc_tools.h" #include "log.h" +#include "groupchat.h" void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) { - char topic[MAX_STR_SIZE]; - if (argc < 1) { - int tlen = tox_group_get_topic(m, self->num, (uint8_t *) topic); + char cur_topic[MAX_STR_SIZE]; + int tlen = tox_group_get_topic(m, self->num, (uint8_t *) cur_topic); if (tlen > 0) { - topic[tlen] = '\0'; - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic is set to: %s", topic); + cur_topic[tlen] = '\0'; + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic is set to: %s", cur_topic); } else { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic is not set"); } @@ -45,17 +45,9 @@ void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*arg return; } - if (argv[1][0] != '\"') { - line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Topic must be enclosed in quotes."); - return; - } + const char *topic = argv[1]; - /* remove opening and closing quotes */ - snprintf(topic, sizeof(topic), "%s", &argv[1][1]); - int len = strlen(topic) - 1; - topic[len] = '\0'; - - if (tox_group_set_topic(m, self->num, (uint8_t *) topic, len) != 0) { + if (tox_group_set_topic(m, self->num, (uint8_t *) topic, strlen(topic)) != 0) { line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to set topic."); return; } @@ -67,7 +59,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, NAME_CHANGE, 0, 0, " set the group topic to: %s", topic); + line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, MAGENTA, "-!- You set the topic to: %s", topic); char tmp_event[MAX_STR_SIZE]; snprintf(tmp_event, sizeof(tmp_event), "set topic to %s", topic); @@ -90,3 +82,55 @@ void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "%s", chatid); } + +void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) +{ + if (argc < 1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Who do you want to ignore?"); + return; + } + + const char *nick = argv[1]; + int peernum = group_get_nick_peernumber(self->num, nick); + + if (peernum == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer '%s' does not exist", nick); + return; + } + + if (tox_group_toggle_ignore(m, self->num, peernum, 1) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to ignore %s", nick); + return; + } + + char timefrmt[TIME_STR_SIZE]; + get_time_str(timefrmt, sizeof(timefrmt)); + + line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- Ignoring %s", nick); +} + +void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]) +{ + if (argc < 1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Who do you want to unignore?"); + return; + } + + const char *nick = argv[1]; + int peernum = group_get_nick_peernumber(self->num, nick); + + if (peernum == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Peer '%s' does not exist", nick); + return; + } + + if (tox_group_toggle_ignore(m, self->num, peernum, 0) == -1) { + line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Failed to unignore %s", nick); + return; + } + + char timefrmt[TIME_STR_SIZE]; + get_time_str(timefrmt, sizeof(timefrmt)); + + line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, BLUE, "-!- You are no longer ignoring %s", nick); +} diff --git a/src/group_commands.h b/src/group_commands.h index 17c3eeb..dc41f40 100644 --- a/src/group_commands.h +++ b/src/group_commands.h @@ -28,5 +28,7 @@ void cmd_set_topic(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_chatid(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); +void cmd_unignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); +void cmd_ignore(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]); #endif /* GROUP_COMMANDS_H */ diff --git a/src/groupchat.c b/src/groupchat.c index 703a31e..4ed95d2 100644 --- a/src/groupchat.c +++ b/src/groupchat.c @@ -70,9 +70,9 @@ extern struct user_settings *user_settings; extern struct Winthread Winthread; #ifdef AUDIO -#define AC_NUM_GROUP_COMMANDS 24 +#define AC_NUM_GROUP_COMMANDS 26 #else -#define AC_NUM_GROUP_COMMANDS 20 +#define AC_NUM_GROUP_COMMANDS 22 #endif /* AUDIO */ /* groupchat command names used for tab completion. */ @@ -88,6 +88,8 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = { { "/exit" }, { "/group" }, { "/help" }, + { "/ignore" }, + { "/unignore" }, { "/join" }, { "/log" }, { "/myid" }, @@ -218,6 +220,18 @@ void set_status_all_groups(Tox *m, uint8_t status) } } +int group_get_nick_peernumber(int groupnum, const char *nick) +{ + int i; + + for (i = 0; i < groupchats[groupnum].num_peers; ++i) { + if (strcasecmp(nick, (char *) &groupchats[groupnum].peer_names[i * TOX_MAX_NAME_LENGTH]) == 0) + return i; + } + + return -1; +} + /* destroys and re-creates groupchat window with or without the peerlist */ void redraw_groupchat_win(ToxWindow *self) { @@ -359,7 +373,7 @@ static void groupchat_onGroupTopicChange(ToxWindow *self, Tox *m, int groupnum, char nick[TOX_MAX_NAME_LENGTH]; get_group_nick_truncate(m, nick, peernum, groupnum); - line_info_add(self, timefrmt, nick, NULL, NAME_CHANGE, 0, 0, " set the group topic to: %s", topic); + line_info_add(self, timefrmt, NULL, NULL, SYS_MSG, 1, MAGENTA, "-!- %s set the topic to: %s", nick, topic); char tmp_event[MAX_STR_SIZE]; snprintf(tmp_event, sizeof(tmp_event), " set the group topic to %s", topic); @@ -537,6 +551,9 @@ static void groupchat_onGroupRejected(ToxWindow *self, Tox *m, int groupnum, uin case TOX_GJ_INVITES_DISABLED: msg = "Invites for this group have been disabled."; break; + case TOX_GJ_INVITE_FAILED: + msg = "Invite failed. Please try again.\n"; + break; default: return; } @@ -677,7 +694,7 @@ static void groupchat_onKey(ToxWindow *self, Tox *m, wint_t key, bool ltr) int diff; /* TODO: make this not suck */ - if (ctx->line[0] != L'/' || wcscmp(ctx->line, L"/me") == 0) { + if (ctx->line[0] != L'/' || wcschr(ctx->line, L' ') != NULL) { diff = complete_line(self, groupchats[self->num].peer_names, groupchats[self->num].num_peers, TOX_MAX_NAME_LENGTH); } else if (wcsncmp(ctx->line, L"/avatar \"", wcslen(L"/avatar \"")) == 0) { diff --git a/src/groupchat.h b/src/groupchat.h index 9b235b3..2af61d6 100644 --- a/src/groupchat.h +++ b/src/groupchat.h @@ -76,6 +76,7 @@ void close_groupchat(ToxWindow *self, Tox *m, int groupnum, const char *partmess 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); +int group_get_nick_peernumber(int groupnum, const char *nick); /* destroys and re-creates groupchat window with or without the peerlist */ void redraw_groupchat_win(ToxWindow *self); diff --git a/src/help.c b/src/help.c index 3087c35..e05028e 100644 --- a/src/help.c +++ b/src/help.c @@ -243,7 +243,9 @@ static void help_draw_group(ToxWindow *self) wattroff(win, A_BOLD | COLOR_PAIR(RED)); wprintw(win, " /topic : Set group topic (show current topic if no msg)\n"); - wprintw(win, " /chatid : Print the group chat id to share with others.\n\n"); + wprintw(win, " /chatid : Print the group chat id to share with others.\n"); + wprintw(win, " /ignore : Ignore peer\n"); + wprintw(win, " /unignore : Unignore peer \n\n"); #ifdef AUDIO wattron(win, A_BOLD); @@ -310,9 +312,9 @@ void help_onKey(ToxWindow *self, wint_t key) case 'r': #ifdef AUDIO - help_init_window(self, 11, 80); + help_init_window(self, 13, 80); #else - help_init_window(self, 7, 80); + help_init_window(self, 9, 80); #endif self->help->type = HELP_GROUP; break; diff --git a/src/misc_tools.c b/src/misc_tools.c index 6c87602..4d8373e 100644 --- a/src/misc_tools.c +++ b/src/misc_tools.c @@ -300,9 +300,8 @@ int get_group_nick_truncate(Tox *m, char *buf, int peernum, int groupnum) uint16_t copy_tox_str(char *msg, size_t size, const char *data, uint16_t length) { if (length > size - 1) { - length = 0; msg[0] = '\0'; - return length; + return 0; } memcpy(msg, data, length);