|
|
|
@ -18,6 +18,7 @@
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
|
|
#include <weechat/weechat-plugin.h>
|
|
|
|
|
#include <tox/tox.h>
|
|
|
|
@ -34,59 +35,138 @@
|
|
|
|
|
|
|
|
|
|
#include "twc-commands.h"
|
|
|
|
|
|
|
|
|
|
enum TWC_FRIEND_MATCH
|
|
|
|
|
{
|
|
|
|
|
TWC_FRIEND_MATCH_AMBIGUOUS = -1,
|
|
|
|
|
TWC_FRIEND_MATCH_NOMATCH = -2,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make sure a command is executed on a Tox profile buffer. If not, warn user
|
|
|
|
|
* and abort.
|
|
|
|
|
*/
|
|
|
|
|
#define TWC_CHECK_PROFILE(profile) \
|
|
|
|
|
if (!profile) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(NULL, \
|
|
|
|
|
"%s%s: command \"%s\" must be executed on a Tox buffer", \
|
|
|
|
|
weechat_prefix("error"), weechat_plugin->name, \
|
|
|
|
|
argv[0]); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
} \
|
|
|
|
|
#define TWC_CHECK_PROFILE(profile) \
|
|
|
|
|
if (!profile) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(NULL, \
|
|
|
|
|
"%s%s: command \"%s\" must be executed on a Tox " \
|
|
|
|
|
"buffer", \
|
|
|
|
|
weechat_prefix("error"), weechat_plugin->name, \
|
|
|
|
|
argv[0]); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
} \
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make sure a command is executed in a chat buffer. If not, warn user and
|
|
|
|
|
* abort.
|
|
|
|
|
*/
|
|
|
|
|
#define TWC_CHECK_CHAT(chat) \
|
|
|
|
|
if (!chat) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(NULL, \
|
|
|
|
|
"%s%s: command \"%s\" must be executed in a chat buffer", \
|
|
|
|
|
weechat_prefix("error"), weechat_plugin->name, argv[0]); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
#define TWC_CHECK_CHAT(chat) \
|
|
|
|
|
if (!chat) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(NULL, \
|
|
|
|
|
"%s%s: command \"%s\" must be executed in a chat " \
|
|
|
|
|
"buffer", \
|
|
|
|
|
weechat_prefix("error"), \
|
|
|
|
|
weechat_plugin->name, \
|
|
|
|
|
argv[0]); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make sure a profile with the given name exists. If not, warn user and
|
|
|
|
|
* abort.
|
|
|
|
|
*/
|
|
|
|
|
#define TWC_CHECK_PROFILE_EXISTS(profile) \
|
|
|
|
|
if (!profile) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(NULL, \
|
|
|
|
|
"%s%s: profile \"%s\" does not exist.", \
|
|
|
|
|
weechat_prefix("error"), weechat_plugin->name, \
|
|
|
|
|
name); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
#define TWC_CHECK_PROFILE_EXISTS(profile) \
|
|
|
|
|
if (!profile) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(NULL, \
|
|
|
|
|
"%s%s: profile \"%s\" does not exist.", \
|
|
|
|
|
weechat_prefix("error"), weechat_plugin->name, \
|
|
|
|
|
name); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make sure a profile is loaded.
|
|
|
|
|
*/
|
|
|
|
|
#define TWC_CHECK_PROFILE_LOADED(profile) \
|
|
|
|
|
if (!(profile->tox)) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(profile->buffer, \
|
|
|
|
|
"%sprofile must be loaded for command \"%s\"", \
|
|
|
|
|
weechat_prefix("error"), argv[0]); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
#define TWC_CHECK_PROFILE_LOADED(profile) \
|
|
|
|
|
if (!(profile->tox)) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(profile->buffer, \
|
|
|
|
|
"%sprofile must be loaded for command \"%s\"", \
|
|
|
|
|
weechat_prefix("error"), argv[0]); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Make sure friend exists.
|
|
|
|
|
*/
|
|
|
|
|
#define TWC_CHECK_FRIEND_NUMBER(number, string) \
|
|
|
|
|
if (number == TWC_FRIEND_MATCH_NOMATCH) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(profile->buffer, \
|
|
|
|
|
"%sno friend number, name or Tox ID found matching " \
|
|
|
|
|
"\"%s\"", \
|
|
|
|
|
weechat_prefix("error"), string); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
} \
|
|
|
|
|
if (number == TWC_FRIEND_MATCH_AMBIGUOUS) \
|
|
|
|
|
{ \
|
|
|
|
|
weechat_printf(profile->buffer, \
|
|
|
|
|
"%smultiple friends with name \"%s\" found; please " \
|
|
|
|
|
"use Tox ID instead", \
|
|
|
|
|
weechat_prefix("error"), string); \
|
|
|
|
|
return WEECHAT_RC_OK; \
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get number of friend matching string. Tries to match number, name and
|
|
|
|
|
* Tox ID.
|
|
|
|
|
*/
|
|
|
|
|
enum TWC_FRIEND_MATCH
|
|
|
|
|
twc_match_friend(struct t_twc_profile *profile, const char *search_string)
|
|
|
|
|
{
|
|
|
|
|
uint32_t friend_count = tox_count_friendlist(profile->tox);
|
|
|
|
|
int32_t *friend_numbers = malloc(sizeof(int32_t) * friend_count);
|
|
|
|
|
tox_get_friendlist(profile->tox, friend_numbers, friend_count);
|
|
|
|
|
|
|
|
|
|
int32_t match = TWC_FRIEND_MATCH_NOMATCH;
|
|
|
|
|
|
|
|
|
|
char *endptr;
|
|
|
|
|
unsigned long friend_number = strtoul(search_string, &endptr, 10);
|
|
|
|
|
if (endptr == search_string + strlen(search_string)
|
|
|
|
|
&& tox_friend_exists(profile->tox, friend_number))
|
|
|
|
|
return friend_number;
|
|
|
|
|
|
|
|
|
|
size_t search_size = strlen(search_string);
|
|
|
|
|
for (uint32_t i = 0; i < friend_count; ++i)
|
|
|
|
|
{
|
|
|
|
|
if (search_size == TOX_CLIENT_ID_SIZE * 2)
|
|
|
|
|
{
|
|
|
|
|
uint8_t tox_id[TOX_CLIENT_ID_SIZE];
|
|
|
|
|
char hex_id[TOX_CLIENT_ID_SIZE * 2 + 1];
|
|
|
|
|
|
|
|
|
|
tox_get_client_id(profile->tox, friend_numbers[i], tox_id);
|
|
|
|
|
twc_bin2hex(tox_id, TOX_CLIENT_ID_SIZE, hex_id);
|
|
|
|
|
|
|
|
|
|
if (weechat_strcasecmp(hex_id, search_string) == 0)
|
|
|
|
|
return friend_number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *name = twc_get_name_nt(profile->tox, friend_numbers[i]);
|
|
|
|
|
if (weechat_strcasecmp(name, search_string) == 0)
|
|
|
|
|
{
|
|
|
|
|
if (match == TWC_FRIEND_MATCH_NOMATCH)
|
|
|
|
|
match = friend_numbers[i];
|
|
|
|
|
else
|
|
|
|
|
return TWC_FRIEND_MATCH_AMBIGUOUS;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return match;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Command /bootstrap callback.
|
|
|
|
|
*/
|
|
|
|
@ -238,19 +318,11 @@ twc_cmd_friend(void *data, struct t_gui_buffer *buffer,
|
|
|
|
|
return WEECHAT_RC_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// /friend remove <number>
|
|
|
|
|
else if (argc == 3 && (weechat_strcasecmp(argv[1], "remove") == 0))
|
|
|
|
|
// /friend remove
|
|
|
|
|
else if (argc >= 3 && (weechat_strcasecmp(argv[1], "remove") == 0))
|
|
|
|
|
{
|
|
|
|
|
char *endptr;
|
|
|
|
|
unsigned long friend_number = strtoul(argv[2], &endptr, 10);
|
|
|
|
|
|
|
|
|
|
if (endptr == argv[2] || !tox_friend_exists(profile->tox, friend_number))
|
|
|
|
|
{
|
|
|
|
|
weechat_printf(profile->buffer,
|
|
|
|
|
"%sInvalid friend number.",
|
|
|
|
|
weechat_prefix("error"));
|
|
|
|
|
return WEECHAT_RC_OK;
|
|
|
|
|
}
|
|
|
|
|
int32_t friend_number = twc_match_friend(profile, argv[2]);
|
|
|
|
|
TWC_CHECK_FRIEND_NUMBER(friend_number, argv[2]);
|
|
|
|
|
|
|
|
|
|
char *name = twc_get_name_nt(profile->tox, friend_number);
|
|
|
|
|
if (tox_del_friend(profile->tox, friend_number) == 0)
|
|
|
|
@ -483,23 +555,35 @@ twc_cmd_msg(void *data, struct t_gui_buffer *buffer,
|
|
|
|
|
TWC_CHECK_PROFILE(profile);
|
|
|
|
|
TWC_CHECK_PROFILE_LOADED(profile);
|
|
|
|
|
|
|
|
|
|
char *endptr;
|
|
|
|
|
unsigned long friend_number = strtoul(argv[1], &endptr, 10);
|
|
|
|
|
// do a shell split in case a friend has spaces in his name and we need
|
|
|
|
|
// quotes
|
|
|
|
|
int shell_argc;
|
|
|
|
|
char **shell_argv = weechat_string_split_shell(argv_eol[0], &shell_argc);
|
|
|
|
|
|
|
|
|
|
if (endptr == argv[1] || !tox_friend_exists(profile->tox, friend_number))
|
|
|
|
|
char recipient[TOX_MAX_NAME_LENGTH + 1];
|
|
|
|
|
snprintf(recipient, TOX_MAX_NAME_LENGTH, "%s", shell_argv[1]);
|
|
|
|
|
weechat_string_free_split(shell_argv);
|
|
|
|
|
|
|
|
|
|
char *message = NULL;
|
|
|
|
|
if (shell_argc >= 3)
|
|
|
|
|
{
|
|
|
|
|
weechat_printf(profile->buffer,
|
|
|
|
|
"%sInvalid friend number.",
|
|
|
|
|
weechat_prefix("error"));
|
|
|
|
|
return WEECHAT_RC_OK;
|
|
|
|
|
// extract message, add two if quotes are used
|
|
|
|
|
message = argv_eol[1] + strlen(recipient);
|
|
|
|
|
if (*argv[1] == '"' || *argv[1] == '\'')
|
|
|
|
|
message += 2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int32_t friend_number = twc_match_friend(profile, recipient);
|
|
|
|
|
TWC_CHECK_FRIEND_NUMBER(friend_number, recipient);
|
|
|
|
|
|
|
|
|
|
// create chat buffer if it does not exist
|
|
|
|
|
struct t_twc_chat *chat = twc_chat_search_friend(profile, friend_number, true);
|
|
|
|
|
|
|
|
|
|
// send a message if provided
|
|
|
|
|
if (argc >= 3)
|
|
|
|
|
twc_chat_send_message(chat, argv_eol[2], TWC_MESSAGE_TYPE_MESSAGE);
|
|
|
|
|
if (message)
|
|
|
|
|
twc_chat_send_message(chat,
|
|
|
|
|
weechat_string_strip(message, 1, 1, " "),
|
|
|
|
|
TWC_MESSAGE_TYPE_MESSAGE);
|
|
|
|
|
|
|
|
|
|
return WEECHAT_RC_OK;
|
|
|
|
|
}
|
|
|
|
@ -851,8 +935,8 @@ twc_commands_init()
|
|
|
|
|
" || add"
|
|
|
|
|
" || remove %(tox_friend_name)|%(tox_friend_tox_id)"
|
|
|
|
|
" || requests"
|
|
|
|
|
" || accept %(tox_friend_name)|%(tox_friend_tox_id)"
|
|
|
|
|
" || decline %(tox_friend_name)|%(tox_friend_tox_id)",
|
|
|
|
|
" || accept"
|
|
|
|
|
" || decline",
|
|
|
|
|
twc_cmd_friend, NULL);
|
|
|
|
|
|
|
|
|
|
weechat_hook_command("group",
|
|
|
|
|