From 122d68e78277316999bcc7dab248399e7f7ad8c6 Mon Sep 17 00:00:00 2001 From: jfreegman Date: Fri, 29 Nov 2024 10:12:55 -0500 Subject: [PATCH] feat: make invite and cinvite commands global These commands can now be used with a nick argument when executed outside of a friend's chat window. Behaviour is unchanged in friend chat windows. --- src/conference.c | 2 + src/execute.c | 2 + src/friendlist.c | 19 +++++++++ src/friendlist.h | 7 ++++ src/global_commands.c | 97 +++++++++++++++++++++++++++++++++++++++++++ src/global_commands.h | 2 + src/groupchats.c | 2 + src/prompt.c | 2 + 8 files changed, 133 insertions(+) diff --git a/src/conference.c b/src/conference.c index d348e15dc..31a7b0740 100644 --- a/src/conference.c +++ b/src/conference.c @@ -67,6 +67,7 @@ static const char *const conference_cmd_list[] = { #endif "/avatar", "/chatid", + "/cinvite", "/clear", "/close", "/color", @@ -79,6 +80,7 @@ static const char *const conference_cmd_list[] = { "/game", #endif "/help", + "/invite", "/join", "/log", #ifdef AUDIO diff --git a/src/execute.c b/src/execute.c index 3afa2863a..dc3bcc292 100644 --- a/src/execute.c +++ b/src/execute.c @@ -41,6 +41,8 @@ static struct cmd_func global_commands[] = { { "/game", cmd_game }, #endif { "/help", cmd_prompt_help }, + { "/invite", cmd_group_invite_g}, + { "/cinvite", cmd_conference_invite_g }, { "/join", cmd_join }, { "/log", cmd_log }, { "/myid", cmd_myid }, diff --git a/src/friendlist.c b/src/friendlist.c index f5eed70bc..b90908ee6 100644 --- a/src/friendlist.c +++ b/src/friendlist.c @@ -1477,6 +1477,25 @@ Tox_Connection get_friend_connection_status(uint32_t friendnumber) return Friends.list[friendnumber].connection_status; } +int64_t get_friend_number(const char *name) +{ + int64_t num = -1; + size_t count = 0; + + for (size_t i = 0; i < Friends.max_idx; ++i) { + if (memcmp(name, Friends.list[i].name, Friends.list[i].namelength) == 0) { + num = Friends.list[i].num; + ++count; + } + } + + if (count > 1) { + return -2; + } + + return num; +} + /* * Returns true if friend associated with `public_key` is in the block list. * diff --git a/src/friendlist.h b/src/friendlist.h index 93eed3ae0..08eeca5be 100644 --- a/src/friendlist.h +++ b/src/friendlist.h @@ -162,6 +162,13 @@ bool friend_get_auto_accept_files(uint32_t friendnumber); */ uint16_t get_friend_name(char *buf, size_t buf_size, uint32_t friendnumber); +/* + * Returns the friend number associated with `nick`. + * Returns -1 if `nick` does not designate a friend in the friend list. + * Returns -2 if `nick` matches more than one friend in the friend list. + */ +int64_t get_friend_number(const char *nick); + /* * Puts a friend's public key in `pk`, which must have room for at least * TOX_PUBLIC_KEY_SIZE bytes. diff --git a/src/global_commands.c b/src/global_commands.c index 072bd4d5f..8dc6ae275 100644 --- a/src/global_commands.c +++ b/src/global_commands.c @@ -300,6 +300,56 @@ void cmd_color(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*a self->colour = colour_val; } +void cmd_conference_invite_g(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]) +{ + UNUSED_VAR(window); + + if (toxic == NULL || self == NULL) { + return; + } + + Tox *tox = toxic->tox; + const Client_Config *c_config = toxic->c_config; + + if (argc < 2) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Conference number and name required."); + return; + } + + const long int conferencenum = strtol(argv[1], NULL, 10); + + if ((conferencenum == 0 && strcmp(argv[1], "0")) || conferencenum < 0 || conferencenum == LONG_MAX) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid conference number."); + return; + } + + const char *nick = argv[2]; + int64_t friend_number = get_friend_number(nick); + + if (friend_number == -1) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, + "Friend '%s' not found (this command is case-sensitive)", nick); + return; + } + + if (friend_number == -2) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, + "There are multiple friends in your friend list with this name. To invite this friend, navigate to their chat window and try again"); + return; + } + + Tox_Err_Conference_Invite err; + + if (!tox_conference_invite(tox, (uint32_t)friend_number, conferencenum, &err)) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, + "Failed to invite contact to conference (error %d)", err); + return; + } + + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Conference %ld.", + conferencenum); +} + void cmd_connect(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]) { UNUSED_VAR(window); @@ -604,6 +654,53 @@ void cmd_groupchat(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char } } +void cmd_group_invite_g(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]) +{ + if (toxic == NULL || self == NULL) { + return; + } + + Tox *tox = toxic->tox; + const Client_Config *c_config = toxic->c_config; + + if (argc < 2) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Group number and name required."); + return; + } + + const int groupnumber = atoi(argv[1]); + + if (groupnumber == 0 && strcmp(argv[1], "0")) { /* atoi returns 0 value on invalid input */ + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Invalid group number."); + return; + } + + const char *nick = argv[2]; + int64_t friend_number = get_friend_number(nick); + + if (friend_number == -1) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, + "Friend '%s' not found (this command is case-sensitive)", nick); + return; + } + + if (friend_number == -2) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, + "There are multiple friends in your friend list with this name. To invite this friend, navigate to their chat window and try again"); + return; + } + + Tox_Err_Group_Invite_Friend err; + + if (!tox_group_invite_friend(tox, groupnumber, (uint32_t)friend_number, &err)) { + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Failed to invite contact to group (error %d).", + err); + return; + } + + line_info_add(self, c_config, false, NULL, NULL, SYS_MSG, 0, 0, "Invited contact to Group %d.", groupnumber); +} + void cmd_join(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]) { if (toxic == NULL || self == NULL) { diff --git a/src/global_commands.h b/src/global_commands.h index 8e9947f29..e47209f4f 100644 --- a/src/global_commands.h +++ b/src/global_commands.h @@ -18,9 +18,11 @@ void cmd_avatar(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX void cmd_clear(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_color(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_conference(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); +void cmd_conference_invite_g(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_connect(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_decline(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_groupchat(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); +void cmd_group_invite_g(WINDOW *window, ToxWindow *self, Toxic *toxic, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_join(WINDOW *window, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_log(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); void cmd_myid(WINDOW *, ToxWindow *, Toxic *, int argc, char (*argv)[MAX_STR_SIZE]); diff --git a/src/groupchats.c b/src/groupchats.c index 6aa4f9c86..d7c195dcf 100644 --- a/src/groupchats.c +++ b/src/groupchats.c @@ -62,6 +62,7 @@ static const char *const group_cmd_list[] = { "/add", "/avatar", "/chatid", + "/cinvite", "/clear", "/close", "/color", @@ -73,6 +74,7 @@ static const char *const group_cmd_list[] = { "/group", "/help", "/ignore", + "/invite", "/join", "/kick", "/list", diff --git a/src/prompt.c b/src/prompt.c index 6d3880fab..8dfa0c4b0 100644 --- a/src/prompt.c +++ b/src/prompt.c @@ -39,6 +39,7 @@ static const char *const glob_cmd_list[] = { "/accept", "/add", "/avatar", + "/cinvite", "/clear", "/color", "/connect", @@ -50,6 +51,7 @@ static const char *const glob_cmd_list[] = { "/game", #endif "/help", + "/invite", "/join", "/log", "/myid",